summaryrefslogtreecommitdiff
path: root/drivers/dma/imx-sdma.c
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2013-05-30 22:23:32 +0800
committerVinod Koul <vinod.koul@intel.com>2013-07-05 11:40:40 +0530
commit9479e17c9bb455c01b369d294e01de8fa9b0a8d3 (patch)
treea451ce4afb0c68c4a206f35d23cd899131f60a5d /drivers/dma/imx-sdma.c
parentadd93b578edda2a952b9b481ce8da2a9dc412cee (diff)
dma: imx-sdma: move to generic device tree bindings
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>
Diffstat (limited to 'drivers/dma/imx-sdma.c')
-rw-r--r--drivers/dma/imx-sdma.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 092867bf795c..1e44b8cf95da 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -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: