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>
This commit is contained in:
parent
80b0e0abfb
commit
2e041c9462
4 changed files with 70 additions and 0 deletions
43
Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
Normal file
43
Documentation/devicetree/bindings/dma/sirfsoc-dma.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
* CSR SiRFSoC DMA controller
|
||||
|
||||
See dma.txt first
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "sirf,prima2-dmac" or "sirf,marco-dmac"
|
||||
- reg: Should contain DMA registers location and length.
|
||||
- interrupts: Should contain one interrupt shared by all channel
|
||||
- #dma-cells: must be <1>. used to represent the number of integer
|
||||
cells in the dmas property of client device.
|
||||
- clocks: clock required
|
||||
|
||||
Example:
|
||||
|
||||
Controller:
|
||||
dmac0: dma-controller@b00b0000 {
|
||||
compatible = "sirf,prima2-dmac";
|
||||
reg = <0xb00b0000 0x10000>;
|
||||
interrupts = <12>;
|
||||
clocks = <&clks 24>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
|
||||
Client:
|
||||
Fill the specific dma request line in dmas. In the below example, spi0 read
|
||||
channel request line is 9 of the 2nd dma controller, while write channel uses
|
||||
4 of the 2nd dma controller; spi1 read channel request line is 12 of the 1st
|
||||
dma controller, while write channel uses 13 of the 1st dma controller:
|
||||
|
||||
spi0: spi@b00d0000 {
|
||||
compatible = "sirf,prima2-spi";
|
||||
dmas = <&dmac1 9>,
|
||||
<&dmac1 4>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
||||
|
||||
spi1: spi@b0170000 {
|
||||
compatible = "sirf,prima2-spi";
|
||||
dmas = <&dmac0 12>,
|
||||
<&dmac0 13>;
|
||||
dma-names = "rx", "tx";
|
||||
};
|
|
@ -269,6 +269,7 @@
|
|||
reg = <0xb00b0000 0x10000>;
|
||||
interrupts = <12>;
|
||||
clocks = <&clks 24>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
dmac1: dma-controller@b0160000 {
|
||||
|
@ -277,6 +278,7 @@
|
|||
reg = <0xb0160000 0x10000>;
|
||||
interrupts = <13>;
|
||||
clocks = <&clks 25>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
vip@b00C0000 {
|
||||
|
|
|
@ -286,6 +286,7 @@
|
|||
reg = <0xb00b0000 0x10000>;
|
||||
interrupts = <12>;
|
||||
clocks = <&clks 24>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
dmac1: dma-controller@b0160000 {
|
||||
|
@ -294,6 +295,7 @@
|
|||
reg = <0xb0160000 0x10000>;
|
||||
interrupts = <13>;
|
||||
clocks = <&clks 25>;
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
vip@b00C0000 {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/of_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of_dma.h>
|
||||
#include <linux/sirfsoc_dma.h>
|
||||
|
||||
#include "dmaengine.h"
|
||||
|
@ -659,6 +660,18 @@ static int sirfsoc_dma_device_slave_caps(struct dma_chan *dchan,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec,
|
||||
struct of_dma *ofdma)
|
||||
{
|
||||
struct sirfsoc_dma *sdma = ofdma->of_dma_data;
|
||||
unsigned int request = dma_spec->args[0];
|
||||
|
||||
if (request > SIRFSOC_DMA_CHANNELS)
|
||||
return NULL;
|
||||
|
||||
return dma_get_slave_channel(&sdma->channels[request].chan);
|
||||
}
|
||||
|
||||
static int sirfsoc_dma_probe(struct platform_device *op)
|
||||
{
|
||||
struct device_node *dn = op->dev.of_node;
|
||||
|
@ -764,11 +777,20 @@ static int sirfsoc_dma_probe(struct platform_device *op)
|
|||
if (ret)
|
||||
goto free_irq;
|
||||
|
||||
/* Device-tree DMA controller registration */
|
||||
ret = of_dma_controller_register(dn, of_dma_sirfsoc_xlate, sdma);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register DMA controller\n");
|
||||
goto unreg_dma_dev;
|
||||
}
|
||||
|
||||
pm_runtime_enable(&op->dev);
|
||||
dev_info(dev, "initialized SIRFSOC DMAC driver\n");
|
||||
|
||||
return 0;
|
||||
|
||||
unreg_dma_dev:
|
||||
dma_async_device_unregister(dma);
|
||||
free_irq:
|
||||
free_irq(sdma->irq, sdma);
|
||||
irq_dispose:
|
||||
|
@ -781,6 +803,7 @@ static int sirfsoc_dma_remove(struct platform_device *op)
|
|||
struct device *dev = &op->dev;
|
||||
struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
|
||||
|
||||
of_dma_controller_free(op->dev.of_node);
|
||||
dma_async_device_unregister(&sdma->dma);
|
||||
free_irq(sdma->irq, sdma);
|
||||
irq_dispose_mapping(sdma->irq);
|
||||
|
|
Loading…
Reference in a new issue