Re: [RFC 4/4] Atmel MCI: Driver for Atmel on-chip MMC controllers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 23 Nov 2007 13:20:13 +0100
Haavard Skinnemoen <[email protected]> wrote:

> This is a driver for the MMC controller on the AP7000 chips from
> Atmel. It should in theory work on AT91 systems too with some
> tweaking, but since the DMA interface is quite different, it's not
> entirely clear if it's worth it.
> 
> This driver has been around for a while in BSPs and kernel sources
> provided by Atmel, but this particular version uses the generic DMA
> Engine framework (with the slave extensions) instead of an
> avr32-only DMA controller framework.
> 
> Signed-off-by: Haavard Skinnemoen <[email protected]>

Why didn't I get a cc? Don't you love me any more? :'(


> ---
>  arch/avr32/boards/atngw100/setup.c      |    6 +
>  arch/avr32/boards/atstk1000/atstk1002.c |    3 +
>  arch/avr32/mach-at32ap/at32ap7000.c     |   31 +-
>  drivers/mmc/host/Kconfig                |   10 +
>  drivers/mmc/host/Makefile               |    1 +
>  drivers/mmc/host/atmel-mci.c            | 1170 +++++++++++++++++++++++++++++++
>  drivers/mmc/host/atmel-mci.h            |  192 +++++
>  include/asm-avr32/arch-at32ap/board.h   |   10 +-
>  8 files changed, 1417 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/mmc/host/atmel-mci.c
>  create mode 100644 drivers/mmc/host/atmel-mci.h
> 

Could you add a note to MAINTAINERS as well?

> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 5fef678..687cf8b 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -91,6 +91,16 @@ config MMC_AT91
>  
>  	  If unsure, say N.
>  
> +config MMC_ATMELMCI
> +	tristate "Atmel Multimedia Card Interface support"
> +	depends on AVR32 && DMA_ENGINE
> +	help
> +	  This selects the Atmel Multimedia Card Interface. If you have
> +	  a AT91 (ARM) or AT32 (AVR32) platform with a Multimedia Card
> +	  slot, say Y or M here.
> +
> +	  If unsure, say N.
> +
>  config MMC_IMX
>  	tristate "Motorola i.MX Multimedia Card Interface support"
>  	depends on ARCH_IMX

Now this gets a bit confusing as we'll have two drivers for AT91. Any status report on merging these?

I can accept having two drivers (for a while at least), but the Kconfig help texts should explain the sordid details.

> +
> +/* Those printks take an awful lot of time... */
> +#ifndef DEBUG
> +static unsigned int fmax = 15000000U;
> +#else
> +static unsigned int fmax = 1000000U;
> +#endif
> +module_param(fmax, uint, 0444);
> +MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
> +

Why is this needed and is it perhaps something that can be moved to the MMC core?

> +
> +static int req_dbg_open(struct inode *inode, struct file *file)
> +{

This also looks like something that can be made general.

> +
> +	if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN)
> +		cmdr |= MCI_BIT(OPDCMD);
> +
> +	dev_dbg(&mmc->class_dev,
> +		"cmd: op %02x arg %08x flags %08x, cmdflags %08lx\n",
> +		cmd->opcode, cmd->arg, cmd->flags, (unsigned long)cmdr);
> +

The debug output in the core should make this redundant.


> +
> +static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> +{

I seem to recall that atmci couldn't currently handle transfers that weren't a multiple of four. Could you please add a check for this and fail the request with -EINVAL when that happens?

> +
> +static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> +	struct atmel_mci	*host = mmc_priv(mmc);
> +	u32			mr;
> +
> +	if (ios->clock) {
> +		u32 clkdiv;
> +
> +		/* Set clock rate */
> +		clkdiv = host->bus_hz / (2 * ios->clock) - 1;
> +		if (clkdiv > 255) {
> +			dev_warn(&mmc->class_dev,
> +				"clock %u too slow; using %lu\n",
> +				ios->clock, host->bus_hz / (2 * 256));
> +			clkdiv = 255;
> +		}
> +
> +		mr = mci_readl(host, MR);
> +		mr = MCI_BFINS(CLKDIV, clkdiv, mr)
> +			| MCI_BIT(WRPROOF) | MCI_BIT(RDPROOF);
> +		mci_writel(host, MR, mr);
> +
> +		/* Enable the MCI controller */
> +		mci_writel(host, CR, MCI_BIT(MCIEN));
> +	} else {
> +		/* Disable the MCI controller */
> +		mci_writel(host, CR, MCI_BIT(MCIDIS));
> +	}
> +

I hope "disable" here doesn't power down the card, as that would be incorrect.

> +
> +		if (status & MCI_BIT(DCRCE)) {
> +			dev_dbg(&mmc->class_dev, "data CRC error\n");
> +			data->error = -EILSEQ;
> +		} else if (status & MCI_BIT(DTOE)) {
> +			dev_dbg(&mmc->class_dev, "data timeout error\n");
> +			data->error = -ETIMEDOUT;
> +		} else {
> +			dev_dbg(&mmc->class_dev, "data FIFO error\n");
> +			data->error = -EIO;
> +		}
> +		dev_dbg(&mmc->class_dev, "bytes xfered: %u\n",
> +				data->bytes_xfered);
> +

The debug output here is already provided by the MMC core.

> +
> +static int __exit atmci_remove(struct platform_device *pdev)
> +{
> +	struct atmel_mci *host = platform_get_drvdata(pdev);
> +
> +	platform_set_drvdata(pdev, NULL);
> +
> +	if (host) {
> +		atmci_cleanup_debugfs(host);
> +
> +		if (host->detect_pin >= 0) {
> +			free_irq(gpio_to_irq(host->detect_pin), host->mmc);
> +			cancel_delayed_work(&host->mmc->detect);

Not for driver poking. Hands off! :)

Rgds
-- 
     -- Pierre Ossman

  Linux kernel, MMC maintainer        http://www.kernel.org
  PulseAudio, core developer          http://pulseaudio.org
  rdesktop, core developer          http://www.rdesktop.org
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux