diff options
author | Barry Song <Baohua.Song@csr.com> | 2014-03-27 03:49:31 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2014-03-29 09:50:13 -0400 |
commit | 2e041c94628c2f0b8b704dc092802ddeaa70c6e9 (patch) | |
tree | 5dce0f4735a928382b5e47be8d84c6ffe80b03f8 | |
parent | 80b0e0abfbcf9897ee263a79bc4cbdcfeca72431 (diff) |
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>
-rw-r--r-- | Documentation/devicetree/bindings/dma/sirfsoc-dma.txt | 43 | ||||
-rw-r--r-- | arch/arm/boot/dts/atlas6.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/prima2.dtsi | 2 | ||||
-rw-r--r-- | drivers/dma/sirf-dma.c | 23 |
4 files changed, 70 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt b/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt new file mode 100644 index 000000000000..ecbc96ad36f8 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/sirfsoc-dma.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | * CSR SiRFSoC DMA controller | ||
2 | |||
3 | See dma.txt first | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: Should be "sirf,prima2-dmac" or "sirf,marco-dmac" | ||
7 | - reg: Should contain DMA registers location and length. | ||
8 | - interrupts: Should contain one interrupt shared by all channel | ||
9 | - #dma-cells: must be <1>. used to represent the number of integer | ||
10 | cells in the dmas property of client device. | ||
11 | - clocks: clock required | ||
12 | |||
13 | Example: | ||
14 | |||
15 | Controller: | ||
16 | dmac0: dma-controller@b00b0000 { | ||
17 | compatible = "sirf,prima2-dmac"; | ||
18 | reg = <0xb00b0000 0x10000>; | ||
19 | interrupts = <12>; | ||
20 | clocks = <&clks 24>; | ||
21 | #dma-cells = <1>; | ||
22 | }; | ||
23 | |||
24 | |||
25 | Client: | ||
26 | Fill the specific dma request line in dmas. In the below example, spi0 read | ||
27 | channel request line is 9 of the 2nd dma controller, while write channel uses | ||
28 | 4 of the 2nd dma controller; spi1 read channel request line is 12 of the 1st | ||
29 | dma controller, while write channel uses 13 of the 1st dma controller: | ||
30 | |||
31 | spi0: spi@b00d0000 { | ||
32 | compatible = "sirf,prima2-spi"; | ||
33 | dmas = <&dmac1 9>, | ||
34 | <&dmac1 4>; | ||
35 | dma-names = "rx", "tx"; | ||
36 | }; | ||
37 | |||
38 | spi1: spi@b0170000 { | ||
39 | compatible = "sirf,prima2-spi"; | ||
40 | dmas = <&dmac0 12>, | ||
41 | <&dmac0 13>; | ||
42 | dma-names = "rx", "tx"; | ||
43 | }; | ||
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index f8674bcc4489..ec23b5c86fb7 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi | |||
@@ -269,6 +269,7 @@ | |||
269 | reg = <0xb00b0000 0x10000>; | 269 | reg = <0xb00b0000 0x10000>; |
270 | interrupts = <12>; | 270 | interrupts = <12>; |
271 | clocks = <&clks 24>; | 271 | clocks = <&clks 24>; |
272 | #dma-cells = <1>; | ||
272 | }; | 273 | }; |
273 | 274 | ||
274 | dmac1: dma-controller@b0160000 { | 275 | dmac1: dma-controller@b0160000 { |
@@ -277,6 +278,7 @@ | |||
277 | reg = <0xb0160000 0x10000>; | 278 | reg = <0xb0160000 0x10000>; |
278 | interrupts = <13>; | 279 | interrupts = <13>; |
279 | clocks = <&clks 25>; | 280 | clocks = <&clks 25>; |
281 | #dma-cells = <1>; | ||
280 | }; | 282 | }; |
281 | 283 | ||
282 | vip@b00C0000 { | 284 | vip@b00C0000 { |
diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index 0e219932d7cc..3a15dee2e8ab 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi | |||
@@ -286,6 +286,7 @@ | |||
286 | reg = <0xb00b0000 0x10000>; | 286 | reg = <0xb00b0000 0x10000>; |
287 | interrupts = <12>; | 287 | interrupts = <12>; |
288 | clocks = <&clks 24>; | 288 | clocks = <&clks 24>; |
289 | #dma-cells = <1>; | ||
289 | }; | 290 | }; |
290 | 291 | ||
291 | dmac1: dma-controller@b0160000 { | 292 | dmac1: dma-controller@b0160000 { |
@@ -294,6 +295,7 @@ | |||
294 | reg = <0xb0160000 0x10000>; | 295 | reg = <0xb0160000 0x10000>; |
295 | interrupts = <13>; | 296 | interrupts = <13>; |
296 | clocks = <&clks 25>; | 297 | clocks = <&clks 25>; |
298 | #dma-cells = <1>; | ||
297 | }; | 299 | }; |
298 | 300 | ||
299 | vip@b00C0000 { | 301 | vip@b00C0000 { |
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); |