Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e041c94 authored by Barry Song's avatar Barry Song Committed by Vinod Koul
Browse files

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: default avatarBarry Song <Baohua.Song@csr.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
parent 80b0e0ab
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
* 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";
};
+2 −0
Original line number Diff line number Diff line
@@ -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 {
+2 −0
Original line number Diff line number Diff line
@@ -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 {
+23 −0
Original line number Diff line number Diff line
@@ -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);