diff options
author | Barry Song <Baohua.Song@csr.com> | 2014-03-27 08:49:31 +0100 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-03-29 14:50:13 +0100 |
commit | 2e041c94628c2f0b8b704dc092802ddeaa70c6e9 (patch) | |
tree | 5dce0f4735a928382b5e47be8d84c6ffe80b03f8 /drivers/dma/sirf-dma.c | |
parent | dma: omap-dma: Implement device_slave_caps callback (diff) | |
download | linux-2e041c94628c2f0b8b704dc092802ddeaa70c6e9.tar.xz linux-2e041c94628c2f0b8b704dc092802ddeaa70c6e9.zip |
dmaengine: sirf: enable generic dt binding for dma channels
move to support of_dma_request_slave_channel() and dma_request_slave_channel.
we add a xlate() to let dma clients be able to find right dma_chan by generic
"dmas" properties in dts.
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/sirf-dma.c')
-rw-r--r-- | drivers/dma/sirf-dma.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index d4d3a3109b16..a1bd8298d55f 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c @@ -18,6 +18,7 @@ #include <linux/of_device.h> #include <linux/of_platform.h> #include <linux/clk.h> +#include <linux/of_dma.h> #include <linux/sirfsoc_dma.h> #include "dmaengine.h" @@ -659,6 +660,18 @@ static int sirfsoc_dma_device_slave_caps(struct dma_chan *dchan, return 0; } +static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct sirfsoc_dma *sdma = ofdma->of_dma_data; + unsigned int request = dma_spec->args[0]; + + if (request > SIRFSOC_DMA_CHANNELS) + return NULL; + + return dma_get_slave_channel(&sdma->channels[request].chan); +} + static int sirfsoc_dma_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; @@ -764,11 +777,20 @@ static int sirfsoc_dma_probe(struct platform_device *op) if (ret) goto free_irq; + /* Device-tree DMA controller registration */ + ret = of_dma_controller_register(dn, of_dma_sirfsoc_xlate, sdma); + if (ret) { + dev_err(dev, "failed to register DMA controller\n"); + goto unreg_dma_dev; + } + pm_runtime_enable(&op->dev); dev_info(dev, "initialized SIRFSOC DMAC driver\n"); return 0; +unreg_dma_dev: + dma_async_device_unregister(dma); free_irq: free_irq(sdma->irq, sdma); irq_dispose: @@ -781,6 +803,7 @@ static int sirfsoc_dma_remove(struct platform_device *op) struct device *dev = &op->dev; struct sirfsoc_dma *sdma = dev_get_drvdata(dev); + of_dma_controller_free(op->dev.of_node); dma_async_device_unregister(&sdma->dma); free_irq(sdma->irq, sdma); irq_dispose_mapping(sdma->irq); |