[PATCH] mxcmmc: use dmaengine API

Russell King - ARM Linux linux at arm.linux.org.uk
Wed Jan 12 05:26:32 EST 2011


On Wed, Jan 12, 2011 at 11:09:56AM +0100, Sascha Hauer wrote:
> +	host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg,
> +				     data->sg_len,  host->dma_dir);

As recently discussed, you don't need to save dma_nents - the value to
be passed to dma_unmap_sg() is data->sg_len, not host->dma_nents.

You should also do the map/unmap against the DMA engine device (which
is the device actually doing DMA) rather than the peripheral (which is
only the recipient of DMA).  The reason is - while the peripheral can
see the DMA controller, the peripheral may be able to see all RAM but
the DMA controller may have an IOMMU or limited view of RAM.

> +static int mxcmci_setup_dma(struct mmc_host *mmc)
> +{
> +	struct mxcmci_host *host = mmc_priv(mmc);
> +	struct dma_slave_config *config = &host->dma_slave_config;
> +
> +	config->direction = DMA_FROM_DEVICE;

I would like to get some concensus on removing config->direction from
the slave configuration entirely - and make all the fields below
refer purely to the peripheral device parameters.  At the moment,
the API allows them to be used ambiguously.

> +static bool filter(struct dma_chan *chan, void *param)
> +{
> +	struct mxcmci_host *host = param;
> +
> +	if (!imx_dma_is_general_purpose(chan)) {
> +		printk("no general\n");
> +		return false;
> +	}
> +
> +        chan->private = &host->dma_data;
> +
> +        return true;

Looks like something went wrong with the tabbing here?

> @@ -794,7 +823,7 @@ static int mxcmci_probe(struct platform_device *pdev)
>  	mmc->max_blk_size = 2048;
>  	mmc->max_blk_count = 65535;
>  	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
> -	mmc->max_seg_size = mmc->max_req_size;
> +	mmc->max_seg_size = 65535;

You can get this from the DMA parameters for the DMA engine device:

	mmc->max_seg_size = dma_get_max_seg_size(dev);

where 'dev' is the DMA engine struct device - chan->dma_device->dev.

Also just spotted this left in your patch:
> +	if (!mxcmci_use_dma(host))
> +		return 0;
> +
>  	for_each_sg(data->sg, sg, data->sg_len, i) {
>  		if (sg->offset & 3 || sg->length & 3) {
> 			host->do_dma = 0;

Shouldn't this be a decision made by the DMA engine rather than the
driver?  Having looked at the MMCI code also doing this, I think this
should cause prep_slave_sg() to return NULL if it can't handle the
scatterlist.  On MMCI, we fall back to PIO if prep_slave_sg() returns
NULL.



More information about the linux-arm-kernel mailing list