aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/dma/dma.txt28
-rw-r--r--Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt52
-rw-r--r--drivers/dma/Kconfig4
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/dmaengine.c7
-rw-r--r--drivers/dma/of-dma.c89
-rw-r--r--drivers/dma/omap-dma.c29
-rw-r--r--drivers/dma/ti-dma-crossbar.c188
-rw-r--r--include/linux/dmaengine.h17
-rw-r--r--include/linux/of_dma.h21
10 files changed, 430 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
index 82104271e754..6312fb00ce8d 100644
--- a/Documentation/devicetree/bindings/dma/dma.txt
+++ b/Documentation/devicetree/bindings/dma/dma.txt
@@ -31,6 +31,34 @@ Example:
31 dma-requests = <127>; 31 dma-requests = <127>;
32 }; 32 };
33 33
34* DMA router
35
36DMA routers are transparent IP blocks used to route DMA request lines from
37devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
38integrated with DMA requests than what the DMA controller can handle directly.
39
40Required property:
41- dma-masters: phandle of the DMA controller or list of phandles for
42 the DMA controllers the router can direct the signal to.
43- #dma-cells: Must be at least 1. Used to provide DMA router specific
44 information. See DMA client binding below for more
45 details.
46
47Optional properties:
48- dma-requests: Number of incoming request lines the router can handle.
49- In the node pointed by the dma-masters:
50 - dma-requests: The router driver might need to look for this in order
51 to configure the routing.
52
53Example:
54 sdma_xbar: dma-router@4a002b78 {
55 compatible = "ti,dra7-dma-crossbar";
56 reg = <0x4a002b78 0xfc>;
57 #dma-cells = <1>;
58 dma-requests = <205>;
59 ti,dma-safe-map = <0>;
60 dma-masters = <&sdma>;
61 };
34 62
35* DMA client 63* DMA client
36 64
diff --git a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
new file mode 100644
index 000000000000..63a48928f3a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
@@ -0,0 +1,52 @@
1Texas Instruments DMA Crossbar (DMA request router)
2
3Required properties:
4- compatible: "ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
5- reg: Memory map for accessing module
6- #dma-cells: Should be set to <1>.
7 Clients should use the crossbar request number (input)
8- dma-requests: Number of DMA requests the crossbar can receive
9- dma-masters: phandle pointing to the DMA controller
10
11The DMA controller node need to have the following poroperties:
12- dma-requests: Number of DMA requests the controller can handle
13
14Optional properties:
15- ti,dma-safe-map: Safe routing value for unused request lines
16
17Example:
18
19/* DMA controller */
20sdma: dma-controller@4a056000 {
21 compatible = "ti,omap4430-sdma";
22 reg = <0x4a056000 0x1000>;
23 interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
24 <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
25 <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
26 <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
27 #dma-cells = <1>;
28 dma-channels = <32>;
29 dma-requests = <127>;
30};
31
32/* DMA crossbar */
33sdma_xbar: dma-router@4a002b78 {
34 compatible = "ti,dra7-dma-crossbar";
35 reg = <0x4a002b78 0xfc>;
36 #dma-cells = <1>;
37 dma-requests = <205>;
38 ti,dma-safe-map = <0>;
39 dma-masters = <&sdma>;
40};
41
42/* DMA client */
43uart1: serial@4806a000 {
44 compatible = "ti,omap4-uart";
45 reg = <0x4806a000 0x100>;
46 interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
47 ti,hwmods = "uart1";
48 clock-frequency = <48000000>;
49 status = "disabled";
50 dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
51 dma-names = "tx", "rx";
52};
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index bda2cb06dc7a..0205ade0ba32 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -245,6 +245,9 @@ config TI_EDMA
245 Enable support for the TI EDMA controller. This DMA 245 Enable support for the TI EDMA controller. This DMA
246 engine is found on TI DaVinci and AM33xx parts. 246 engine is found on TI DaVinci and AM33xx parts.
247 247
248config TI_DMA_CROSSBAR
249 bool
250
248config ARCH_HAS_ASYNC_TX_FIND_CHANNEL 251config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
249 bool 252 bool
250 253
@@ -330,6 +333,7 @@ config DMA_OMAP
330 depends on ARCH_OMAP 333 depends on ARCH_OMAP
331 select DMA_ENGINE 334 select DMA_ENGINE
332 select DMA_VIRTUAL_CHANNELS 335 select DMA_VIRTUAL_CHANNELS
336 select TI_DMA_CROSSBAR if SOC_DRA7XX
333 337
334config DMA_BCM2835 338config DMA_BCM2835
335 tristate "BCM2835 DMA engine support" 339 tristate "BCM2835 DMA engine support"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 69f77d5ba53b..535919559f12 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
38obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o 38obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
39obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o 39obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
40obj-$(CONFIG_DMA_OMAP) += omap-dma.o 40obj-$(CONFIG_DMA_OMAP) += omap-dma.o
41obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
41obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o 42obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
42obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o 43obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
43obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o 44obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index c0793818bb99..052a2bd1a5cf 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -267,6 +267,13 @@ static void dma_chan_put(struct dma_chan *chan)
267 /* This channel is not in use anymore, free it */ 267 /* This channel is not in use anymore, free it */
268 if (!chan->client_count && chan->device->device_free_chan_resources) 268 if (!chan->client_count && chan->device->device_free_chan_resources)
269 chan->device->device_free_chan_resources(chan); 269 chan->device->device_free_chan_resources(chan);
270
271 /* If the channel is used via a DMA request router, free the mapping */
272 if (chan->router && chan->router->route_free) {
273 chan->router->route_free(chan->router->dev, chan->route_data);
274 chan->router = NULL;
275 chan->route_data = NULL;
276 }
270} 277}
271 278
272enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie) 279enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index cbd4a8aff120..1e1f2986eba8 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -45,6 +45,50 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
45} 45}
46 46
47/** 47/**
48 * of_dma_router_xlate - translation function for router devices
49 * @dma_spec: pointer to DMA specifier as found in the device tree
50 * @of_dma: pointer to DMA controller data (router information)
51 *
52 * The function creates new dma_spec to be passed to the router driver's
53 * of_dma_route_allocate() function to prepare a dma_spec which will be used
54 * to request channel from the real DMA controller.
55 */
56static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
57 struct of_dma *ofdma)
58{
59 struct dma_chan *chan;
60 struct of_dma *ofdma_target;
61 struct of_phandle_args dma_spec_target;
62 void *route_data;
63
64 /* translate the request for the real DMA controller */
65 memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
66 route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
67 if (IS_ERR(route_data))
68 return NULL;
69
70 ofdma_target = of_dma_find_controller(&dma_spec_target);
71 if (!ofdma_target)
72 return NULL;
73
74 chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
75 if (chan) {
76 chan->router = ofdma->dma_router;
77 chan->route_data = route_data;
78 } else {
79 ofdma->dma_router->route_free(ofdma->dma_router->dev,
80 route_data);
81 }
82
83 /*
84 * Need to put the node back since the ofdma->of_dma_route_allocate
85 * has taken i