aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-04-19 07:42:55 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-06-17 07:54:27 -0400
commitfaadc6e3d5e0ab718dc1e131fb14bbb52f144238 (patch)
treed7ea30a3eb7728c7d2319cf8a143bcd449b1f9be
parentba078d1bd4ec56460c5317287033d97859374d7d (diff)
dma: coh901318: add devicetree support
This adds support for probing the COH 901 318 DMA controller and channels from the device tree. Contains portions of a sketch patch from Arnd Bergmann. Cc: Arnd Bergmann <arnd@arndb.de> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/dma/ste-coh901318.txt32
-rw-r--r--drivers/dma/coh901318.c43
2 files changed, 75 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/dma/ste-coh901318.txt b/Documentation/devicetree/bindings/dma/ste-coh901318.txt
new file mode 100644
index 000000000000..091ad057e9cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/ste-coh901318.txt
@@ -0,0 +1,32 @@
1ST-Ericsson COH 901 318 DMA Controller
2
3This is a DMA controller which has begun as a fork of the
4ARM PL08x PrimeCell VHDL code.
5
6Required properties:
7- compatible: should be "stericsson,coh901318"
8- reg: register locations and length
9- interrupts: the single DMA IRQ
10- #dma-cells: must be set to <1>, as the channels on the
11 COH 901 318 are simple and identified by a single number
12- dma-channels: the number of DMA channels handled
13
14Example:
15
16dmac: dma-controller@c00020000 {
17 compatible = "stericsson,coh901318";
18 reg = <0xc0020000 0x1000>;
19 interrupt-parent = <&vica>;
20 interrupts = <2>;
21 #dma-cells = <1>;
22 dma-channels = <40>;
23};
24
25Consumers example:
26
27uart0: serial@c0013000 {
28 compatible = "...";
29 (...)
30 dmas = <&dmac 17 &dmac 18>;
31 dma-names = "tx", "rx";
32};
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
index 3b23061cdb41..9bfaddd57ef1 100644
--- a/drivers/dma/coh901318.c
+++ b/drivers/dma/coh901318.c
@@ -22,6 +22,7 @@
22#include <linux/uaccess.h> 22#include <linux/uaccess.h>
23#include <linux/debugfs.h> 23#include <linux/debugfs.h>
24#include <linux/platform_data/dma-coh901318.h> 24#include <linux/platform_data/dma-coh901318.h>
25#include <linux/of_dma.h>
25 26
26#include "coh901318.h" 27#include "coh901318.h"
27#include "dmaengine.h" 28#include "dmaengine.h"
@@ -1788,6 +1789,35 @@ bool coh901318_filter_id(struct dma_chan *chan, void *chan_id)
1788} 1789}
1789EXPORT_SYMBOL(coh901318_filter_id); 1790EXPORT_SYMBOL(coh901318_filter_id);
1790 1791
1792struct coh901318_filter_args {
1793 struct coh901318_base *base;
1794 unsigned int ch_nr;
1795};
1796
1797static bool coh901318_filter_base_and_id(struct dma_chan *chan, void *data)
1798{
1799 struct coh901318_filter_args *args = data;
1800
1801 if (&args->base->dma_slave == chan->device &&
1802 args->ch_nr == to_coh901318_chan(chan)->id)
1803 return true;
1804
1805 return false;
1806}
1807
1808static struct dma_chan *coh901318_xlate(struct of_phandle_args *dma_spec,
1809 struct of_dma *ofdma)
1810{
1811 struct coh901318_filter_args args = {
1812 .base = ofdma->of_dma_data,
1813 .ch_nr = dma_spec->args[0],
1814 };
1815 dma_cap_mask_t cap;
1816 dma_cap_zero(cap);
1817 dma_cap_set(DMA_SLAVE, cap);
1818
1819 return dma_request_channel(cap, coh901318_filter_base_and_id, &args);
1820}
1791/* 1821/*
1792 * DMA channel allocation 1822 * DMA channel allocation
1793 */ 1823 */
@@ -2735,12 +2765,19 @@ static int __init coh901318_probe(struct platform_device *pdev)
2735 if (err) 2765 if (err)
2736 goto err_register_memcpy; 2766 goto err_register_memcpy;
2737 2767
2768 err = of_dma_controller_register(pdev->dev.of_node, coh901318_xlate,
2769 base);
2770 if (err)
2771 goto err_register_of_dma;
2772
2738 platform_set_drvdata(pdev, base); 2773 platform_set_drvdata(pdev, base);
2739 dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n", 2774 dev_info(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n",
2740 (u32) base->virtbase); 2775 (u32) base->virtbase);
2741 2776
2742 return err; 2777 return err;
2743 2778
2779 err_register_of_dma:
2780 dma_async_device_unregister(&base->dma_memcpy);
2744 err_register_memcpy: 2781 err_register_memcpy:
2745 dma_async_device_unregister(&base->dma_slave); 2782 dma_async_device_unregister(&base->dma_slave);
2746 err_register_slave: 2783 err_register_slave:
@@ -2752,17 +2789,23 @@ static int coh901318_remove(struct platform_device *pdev)
2752{ 2789{
2753 struct coh901318_base *base = platform_get_drvdata(pdev); 2790 struct coh901318_base *base = platform_get_drvdata(pdev);
2754 2791
2792 of_dma_controller_free(pdev->dev.of_node);
2755 dma_async_device_unregister(&base->dma_memcpy); 2793 dma_async_device_unregister(&base->dma_memcpy);
2756 dma_async_device_unregister(&base->dma_slave); 2794 dma_async_device_unregister(&base->dma_slave);
2757 coh901318_pool_destroy(&base->pool); 2795 coh901318_pool_destroy(&base->pool);
2758 return 0; 2796 return 0;
2759} 2797}
2760 2798
2799static const struct of_device_id coh901318_dt_match[] = {
2800 { .compatible = "stericsson,coh901318" },
2801 {},
2802};
2761 2803
2762static struct platform_driver coh901318_driver = { 2804static struct platform_driver coh901318_driver = {
2763 .remove = coh901318_remove, 2805 .remove = coh901318_remove,
2764 .driver = { 2806 .driver = {
2765 .name = "coh901318", 2807 .name = "coh901318",
2808 .of_match_table = coh901318_dt_match,
2766 }, 2809 },
2767}; 2810};
2768 2811