[PATCH] dmaengine: Add hisilicon k3 DMA engine driver
Arnd Bergmann
arnd at arndb.de
Mon Jun 17 16:58:07 EDT 2013
On Monday 17 June 2013, Zhangfei Gao wrote:
> Add dmaengine driver for hisilicon k3 platform based on virt_dma
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao at linaro.org>
> Tested-by: Kai Yang <jean.yangkai at huawei.com>
Acked-by: Arnd Bergmann <arnd at arndb.de>
> diff --git a/Documentation/devicetree/bindings/dma/k3dma.txt b/Documentation/devicetree/bindings/dma/k3dma.txt
> new file mode 100644
> index 0000000..cf156f2
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/k3dma.txt
> @@ -0,0 +1,44 @@
> +* Hisilicon K3 DMA controller
> +
> +See dma.txt first
> +
> +Required properties:
> +- compatible: Should be "hisilicon,k3-dma-1.0"
> +- reg: Should contain DMA registers location and length.
> +- interrupts: Should contain one interrupt shared by all channel
> +- #dma-cells: see dma.txt, should be 1, para number
> +- dma-channels: virtual channels supported, each virtual channel
> + have specific request line
> +- clocks: clock required
> +
> +Example:
> +
> +Controller:
> + dma0: dma at fcd02000 {
> + compatible = "hisilicon,k3-dma-1.0";
> + reg = <0xfcd02000 0x1000>;
> + #dma-cells = <1>;
> + dma-channels = <27>;
> + interrupts = <0 12 4>;
> + clocks = <&pclk>;
> + status = "disable";
> + };
> +
> +Client:
> +Use specific request line passing from dmax
> +For example, i2c0 read channel request line is 18, while write channel use 19
> +
> + i2c0: i2c at fcb08000 {
> + compatible = "snps,designware-i2c";
> + dmas = <&dma0 18 /* read channel */
> + &dma0 19>; /* write channel */
> + dma-names = "rx", "tx";
> + };
> +
> + i2c1: i2c at fcb09000 {
> + compatible = "snps,designware-i2c";
> + dmas = <&dma0 20 /* read channel */
> + &dma0 21>; /* write channel */
> + dma-names = "rx", "tx";
> + };
The binding looks good to me.
I'd like to make sure the "dma-channels" property is right though:
You specify that number in DT but ...
> +#define DRIVER_NAME "k3-dma"
> +#define NR_PHY_CHAN 16
> +#define DMA_ALIGN 3
... you also hardcode the number to 16. Shouldn't the channels be
allocated dynamically based on the dma-channels property?
You do allocate "virtual channels" based on the "dma-channels"
later. Wouldn't that be request line numbers, i.e. "dma-requests"
rather than "dma-channels"?
> +static struct of_dma_filter_info k3_dma_filter;
> +static bool k3_dma_filter_fn(struct dma_chan *chan, void *param)
> +{
> + return (*(int *)param == chan->chan_id);
> +}
This filter function works only as long as there is no more than
one DMA engine in the system, which is something that needs to
be documented better. Unfortunately, providing a filter
function to be called by .xlate is currently the only way that
the dma-engine API supports, but we should really get over that.
Vinod: I think we need to add a way for a dmaengine driver to
just return one of its channels to the xlate function. The
current method is getting very silly, and it adds run-time and
code complexity without any need.
How about something like
int dma_get_slave_channel(struct dma_chan *chan)
{
/* lock against __dma_request_channel */
mutex_lock(&dma_list_mutex);
if (chan->client_count == 0)
ret = dma_chan_get(chan);
else
ret = -EBUSY;
mutex_unlock(&dma_list_mutex);
return ret;
}
EXPORT_SYMBOL_GPL(dma_get_slave_channel);
> + /* init virtual channel */
> + for (i = 0; i < dma_channels; i++) {
> + struct k3_dma_chan *c;
> +
> + c = devm_kzalloc(&op->dev,
> + sizeof(struct k3_dma_chan), GFP_KERNEL);
> + if (c == NULL)
> + return -ENOMEM;
> +
> + INIT_LIST_HEAD(&c->node);
> + c->vc.desc_free = k3_dma_free_desc;
> + vchan_init(&c->vc, &d->slave);
> + }
Note that a single devm_kzalloc would be slightly more space efficient
here.
Arnd
More information about the linux-arm-kernel
mailing list