Commit 2e041c94628c2f0b8b704dc092802ddeaa70c6e9
Committed by
Vinod Koul
1 parent
80b0e0abfb
Exists in
master
and in
13 other branches
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>
Showing 4 changed files with 70 additions and 0 deletions Side-by-side Diff
Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
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 | +}; |
arch/arm/boot/dts/atlas6.dtsi
... | ... | @@ -269,6 +269,7 @@ |
269 | 269 | reg = <0xb00b0000 0x10000>; |
270 | 270 | interrupts = <12>; |
271 | 271 | clocks = <&clks 24>; |
272 | + #dma-cells = <1>; | |
272 | 273 | }; |
273 | 274 | |
274 | 275 | dmac1: dma-controller@b0160000 { |
... | ... | @@ -277,6 +278,7 @@ |
277 | 278 | reg = <0xb0160000 0x10000>; |
278 | 279 | interrupts = <13>; |
279 | 280 | clocks = <&clks 25>; |
281 | + #dma-cells = <1>; | |
280 | 282 | }; |
281 | 283 | |
282 | 284 | vip@b00C0000 { |
arch/arm/boot/dts/prima2.dtsi
... | ... | @@ -286,6 +286,7 @@ |
286 | 286 | reg = <0xb00b0000 0x10000>; |
287 | 287 | interrupts = <12>; |
288 | 288 | clocks = <&clks 24>; |
289 | + #dma-cells = <1>; | |
289 | 290 | }; |
290 | 291 | |
291 | 292 | dmac1: dma-controller@b0160000 { |
... | ... | @@ -294,6 +295,7 @@ |
294 | 295 | reg = <0xb0160000 0x10000>; |
295 | 296 | interrupts = <13>; |
296 | 297 | clocks = <&clks 25>; |
298 | + #dma-cells = <1>; | |
297 | 299 | }; |
298 | 300 | |
299 | 301 | vip@b00C0000 { |
drivers/dma/sirf-dma.c
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | #include <linux/of_device.h> |
19 | 19 | #include <linux/of_platform.h> |
20 | 20 | #include <linux/clk.h> |
21 | +#include <linux/of_dma.h> | |
21 | 22 | #include <linux/sirfsoc_dma.h> |
22 | 23 | |
23 | 24 | #include "dmaengine.h" |
... | ... | @@ -659,6 +660,18 @@ |
659 | 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 | 675 | static int sirfsoc_dma_probe(struct platform_device *op) |
663 | 676 | { |
664 | 677 | struct device_node *dn = op->dev.of_node; |
665 | 678 | |
... | ... | @@ -764,11 +777,20 @@ |
764 | 777 | if (ret) |
765 | 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 | 787 | pm_runtime_enable(&op->dev); |
768 | 788 | dev_info(dev, "initialized SIRFSOC DMAC driver\n"); |
769 | 789 | |
770 | 790 | return 0; |
771 | 791 | |
792 | +unreg_dma_dev: | |
793 | + dma_async_device_unregister(dma); | |
772 | 794 | free_irq: |
773 | 795 | free_irq(sdma->irq, sdma); |
774 | 796 | irq_dispose: |
... | ... | @@ -781,6 +803,7 @@ |
781 | 803 | struct device *dev = &op->dev; |
782 | 804 | struct sirfsoc_dma *sdma = dev_get_drvdata(dev); |
783 | 805 | |
806 | + of_dma_controller_free(op->dev.of_node); | |
784 | 807 | dma_async_device_unregister(&sdma->dma); |
785 | 808 | free_irq(sdma->irq, sdma); |
786 | 809 | irq_dispose_mapping(sdma->irq); |