dma: imx-sdma: move to generic device tree bindings
authorShawn Guo <shawn.guo@linaro.org>
Thu, 30 May 2013 14:23:32 +0000 (22:23 +0800)
committerVinod Koul <vinod.koul@intel.com>
Fri, 5 Jul 2013 06:10:40 +0000 (11:40 +0530)
Update imx-sdma driver to adopt generic DMA device tree bindings.  It
calls of_dma_controller_register() with imx-sdma specific of_dma_xlate
to get the generic DMA device tree helper support.  The #dma-cells for
imx-sdma must be 3, which includes request ID, peripheral type and
priority.

The existing way of requesting channel, clients directly call
dma_request_channel(), still work there, and will be removed after
all imx-sdma clients get converted to generic DMA device tree helper.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt
drivers/dma/imx-sdma.c

index d1e3f443e205b2c95c1bb577e1fa1e8232dd96a5..68cee4f5539fcbf8274ab08456ab5fff54ea9b46 100644 (file)
@@ -4,14 +4,70 @@ Required properties:
 - compatible : Should be "fsl,<chip>-sdma"
 - reg : Should contain SDMA registers location and length
 - interrupts : Should contain SDMA interrupt
+- #dma-cells : Must be <3>.
+  The first cell specifies the DMA request/event ID.  See details below
+  about the second and third cell.
 - fsl,sdma-ram-script-name : Should contain the full path of SDMA RAM
   scripts firmware
 
+The second cell of dma phandle specifies the peripheral type of DMA transfer.
+The full ID of peripheral types can be found below.
+
+       ID      transfer type
+       ---------------------
+       0       MCU domain SSI
+       1       Shared SSI
+       2       MMC
+       3       SDHC
+       4       MCU domain UART
+       5       Shared UART
+       6       FIRI
+       7       MCU domain CSPI
+       8       Shared CSPI
+       9       SIM
+       10      ATA
+       11      CCM
+       12      External peripheral
+       13      Memory Stick Host Controller
+       14      Shared Memory Stick Host Controller
+       15      DSP
+       16      Memory
+       17      FIFO type Memory
+       18      SPDIF
+       19      IPU Memory
+       20      ASRC
+       21      ESAI
+
+The third cell specifies the transfer priority as below.
+
+       ID      transfer priority
+       -------------------------
+       0       High
+       1       Medium
+       2       Low
+
 Examples:
 
 sdma@83fb0000 {
        compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
        reg = <0x83fb0000 0x4000>;
        interrupts = <6>;
+       #dma-cells = <3>;
        fsl,sdma-ram-script-name = "sdma-imx51.bin";
 };
+
+DMA clients connected to the i.MX SDMA controller must use the format
+described in the dma.txt file.
+
+Examples:
+
+ssi2: ssi@70014000 {
+       compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+       reg = <0x70014000 0x4000>;
+       interrupts = <30>;
+       clocks = <&clks 49>;
+       dmas = <&sdma 24 1 0>,
+              <&sdma 25 1 0>;
+       dma-names = "rx", "tx";
+       fsl,fifo-depth = <15>;
+};
index 092867bf795c0d939b57ef3a9e4622c833f463a1..1e44b8cf95dabca6b220c05e8afd33740f8a8455 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/dmaengine.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_dma.h>
 
 #include <asm/irq.h>
 #include <linux/platform_data/dma-imx-sdma.h>
@@ -1296,6 +1297,35 @@ err_dma_alloc:
        return ret;
 }
 
+static bool sdma_filter_fn(struct dma_chan *chan, void *fn_param)
+{
+       struct imx_dma_data *data = fn_param;
+
+       if (!imx_dma_is_general_purpose(chan))
+               return false;
+
+       chan->private = data;
+
+       return true;
+}
+
+static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
+                                  struct of_dma *ofdma)
+{
+       struct sdma_engine *sdma = ofdma->of_dma_data;
+       dma_cap_mask_t mask = sdma->dma_device.cap_mask;
+       struct imx_dma_data data;
+
+       if (dma_spec->args_count != 3)
+               return NULL;
+
+       data.dma_request = dma_spec->args[0];
+       data.peripheral_type = dma_spec->args[1];
+       data.priority = dma_spec->args[2];
+
+       return dma_request_channel(mask, sdma_filter_fn, &data);
+}
+
 static int __init sdma_probe(struct platform_device *pdev)
 {
        const struct of_device_id *of_id =
@@ -1443,10 +1473,20 @@ static int __init sdma_probe(struct platform_device *pdev)
                goto err_init;
        }
 
+       if (np) {
+               ret = of_dma_controller_register(np, sdma_xlate, sdma);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to register controller\n");
+                       goto err_register;
+               }
+       }
+
        dev_info(sdma->dev, "initialized\n");
 
        return 0;
 
+err_register:
+       dma_async_device_unregister(&sdma->dma_device);
 err_init:
        kfree(sdma->script_addrs);
 err_alloc: