diff options
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 @@ | |||
18 | #include <linux/of_device.h> | 18 | #include <linux/of_device.h> |
19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | #include <linux/of_dma.h> | ||
21 | #include <linux/sirfsoc_dma.h> | 22 | #include <linux/sirfsoc_dma.h> |
22 | 23 | ||
23 | #include "dmaengine.h" | 24 | #include "dmaengine.h" |
@@ -659,6 +660,18 @@ static int sirfsoc_dma_device_slave_caps(struct dma_chan *dchan, | |||
659 | return 0; | 660 | return 0; |
660 | } | 661 | } |
661 | 662 | ||
663 | static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec, | ||
664 | struct of_dma *ofdma) | ||
665 | { | ||
666 | struct sirfsoc_dma *sdma = ofdma->of_dma_data; | ||
667 | unsigned int request = dma_spec->args[0]; | ||
668 | |||
669 | if (request > SIRFSOC_DMA_CHANNELS) | ||
670 | return NULL; | ||
671 | |||
672 | return dma_get_slave_channel(&sdma->channels[request].chan); | ||
673 | } | ||
674 | |||
662 | static int sirfsoc_dma_probe(struct platform_device *op) | 675 | static int sirfsoc_dma_probe(struct platform_device *op) |
663 | { | 676 | { |
664 | struct device_node *dn = op->dev.of_node; | 677 | struct device_node *dn = op->dev.of_node; |
@@ -764,11 +777,20 @@ static int sirfsoc_dma_probe(struct platform_device *op) | |||
764 | if (ret) | 777 | if (ret) |
765 | goto free_irq; | 778 | goto free_irq; |
766 | 779 | ||
780 | /* Device-tree DMA controller registration */ | ||
781 | ret = of_dma_controller_register(dn, of_dma_sirfsoc_xlate, sdma); | ||
782 | if (ret) { | ||
783 | dev_err(dev, "failed to register DMA controller\n"); | ||
784 | goto unreg_dma_dev; | ||
785 | } | ||
786 | |||
767 | pm_runtime_enable(&op->dev); | 787 | pm_runtime_enable(&op->dev); |
768 | dev_info(dev, "initialized SIRFSOC DMAC driver\n"); | 788 | dev_info(dev, "initialized SIRFSOC DMAC driver\n"); |
769 | 789 | ||
770 | return 0; | 790 | return 0; |
771 | 791 | ||
792 | unreg_dma_dev: | ||
793 | dma_async_device_unregister(dma); | ||
772 | free_irq: | 794 | free_irq: |
773 | free_irq(sdma->irq, sdma); | 795 | free_irq(sdma->irq, sdma); |
774 | irq_dispose: | 796 | irq_dispose: |
@@ -781,6 +803,7 @@ static int sirfsoc_dma_remove(struct platform_device *op) | |||
781 | struct device *dev = &op->dev; | 803 | struct device *dev = &op->dev; |
782 | struct sirfsoc_dma *sdma = dev_get_drvdata(dev); | 804 | struct sirfsoc_dma *sdma = dev_get_drvdata(dev); |
783 | 805 | ||
806 | of_dma_controller_free(op->dev.of_node); | ||
784 | dma_async_device_unregister(&sdma->dma); | 807 | dma_async_device_unregister(&sdma->dma); |
785 | free_irq(sdma->irq, sdma); | 808 | free_irq(sdma->irq, sdma); |
786 | irq_dispose_mapping(sdma->irq); | 809 | irq_dispose_mapping(sdma->irq); |