Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux.git] / drivers / dma / sirf-dma.c
index d4d3a3109b163f3c3a4a471cfdbc82c838024437..a1bd8298d55f1973313b969bf560c76967212dc4 100644 (file)
@@ -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);