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....@linaro.org>
> Tested-by: Kai Yang <jean.yang...@huawei.com>

Acked-by: Arnd Bergmann <a...@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@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@fcb08000 {
> +                     compatible = "snps,designware-i2c";
> +                     dmas =  <&dma0 18          /* read channel */
> +                              &dma0 19>;        /* write channel */
> +                     dma-names = "rx", "tx";
> +             };
> +
> +             i2c1: i2c@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
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

Reply via email to