diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2013-04-19 07:42:55 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2013-06-17 07:54:27 -0400 |
commit | faadc6e3d5e0ab718dc1e131fb14bbb52f144238 (patch) | |
tree | d7ea30a3eb7728c7d2319cf8a143bcd449b1f9be | |
parent | ba078d1bd4ec56460c5317287033d97859374d7d (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.txt | 32 | ||||
-rw-r--r-- | drivers/dma/coh901318.c | 43 |
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 @@ | |||
1 | ST-Ericsson COH 901 318 DMA Controller | ||
2 | |||
3 | This is a DMA controller which has begun as a fork of the | ||
4 | ARM PL08x PrimeCell VHDL code. | ||
5 | |||
6 | Required 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 | |||
14 | Example: | ||
15 | |||
16 | dmac: 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 | |||
25 | Consumers example: | ||
26 | |||
27 | uart0: 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 | } |
1789 | EXPORT_SYMBOL(coh901318_filter_id); | 1790 | EXPORT_SYMBOL(coh901318_filter_id); |
1790 | 1791 | ||
1792 | struct coh901318_filter_args { | ||
1793 | struct coh901318_base *base; | ||
1794 | unsigned int ch_nr; | ||
1795 | }; | ||
1796 | |||
1797 | static 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 | |||
1808 | static 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 | ||
2799 | static const struct of_device_id coh901318_dt_match[] = { | ||
2800 | { .compatible = "stericsson,coh901318" }, | ||
2801 | {}, | ||
2802 | }; | ||
2761 | 2803 | ||
2762 | static struct platform_driver coh901318_driver = { | 2804 | static 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 | ||