[PATCH v2 2/3] serial: mxs-auart: add the DMA support for mx28

Vinod Koul vkoul at infradead.org
Thu Oct 25 00:18:09 EDT 2012


On Wed, 2012-10-24 at 18:27 +0800, Huang Shijie wrote:
> Only we meet the following conditions, we can enable the DMA support for
> auart:
> 
>   (1) We enable the DMA support in the dts file, such as
>       arch/arm/boot/dts/imx28.dtsi.
> 
>   (2) We enable the hardware flow control.
> 
>   (3) We use the mx28, not the mx23. Due to hardware bug(see errata: 2836),
>       we can not add the DMA support to mx23.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>

>  
>  #define to_auart_port(u) container_of(u, struct mxs_auart_port, port)

> +
> +static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size)
> +{
> +	struct dma_async_tx_descriptor *desc;
> +	struct scatterlist *sgl = &s->tx_sgl;
> +	struct dma_chan *channel = s->tx_dma_chan;
> +	u32 pio;
> +
> +	/* [1] : send PIO. Note, the first pio word is CTRL1. */
> +	pio = AUART_CTRL1_XFER_COUNT(size);
> +	desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio,
> +					1, DMA_TRANS_NONE, 0);
this seems like a hack. API expects a scatterlist as argument.
Same thing about direction, NONE doesnt mean anything for dma transfer.
> +	if (!desc) {
> +		dev_err(s->dev, "step 1 error\n");
> +		return -EINVAL;
> +	}
> +
> +	/* [2] : set DMA buffer. */
> +	sg_init_one(sgl, s->tx_dma_buf, size);
> +	dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE);
> +	desc = dmaengine_prep_slave_sg(channel, sgl,
> +			1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
> +	if (!desc) {
> +		dev_err(s->dev, "step 2 error\n");
> +		return -EINVAL;
> +	}
> +
> +	/* [3] : submit the DMA */
> +	desc->callback = dma_tx_callback;
> +	desc->callback_param = s;
> +	dmaengine_submit(desc);
> +	dma_async_issue_pending(channel);
> +	return 0;
> +}
> +

>  
> +static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
> +{
> +	struct mxs_auart_port *s = param;
> +
> +	if (!mxs_dma_is_apbx(chan))
> +		return false;
> +
> +	if (s->dma_channel == chan->chan_id) {
> +		chan->private = &s->dma_data;
dont use chan->private. You need to dmaengine_slave_config API

> +		return true;
> +	}
> +	return false;
> +}
> +

-- 
Vinod Koul
Intel Corp.




More information about the linux-arm-kernel mailing list