diff options
-rw-r--r-- | Documentation/devicetree/bindings/dma/shdma.txt | 61 | ||||
-rw-r--r-- | drivers/dma/sh/Makefile | 2 | ||||
-rw-r--r-- | drivers/dma/sh/shdma-base.c | 15 | ||||
-rw-r--r-- | drivers/dma/sh/shdma-of.c | 3 | ||||
-rw-r--r-- | drivers/dma/sh/shdma.h | 1 | ||||
-rw-r--r-- | drivers/dma/sh/shdmac.c (renamed from drivers/dma/sh/shdma.c) | 30 | ||||
-rw-r--r-- | drivers/dma/sh/sudmac.c | 3 | ||||
-rw-r--r-- | include/linux/shdma-base.h | 2 |
8 files changed, 69 insertions, 48 deletions
diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt index c15994aa1939..2a3f3b8946b9 100644 --- a/Documentation/devicetree/bindings/dma/shdma.txt +++ b/Documentation/devicetree/bindings/dma/shdma.txt | |||
@@ -22,42 +22,51 @@ Optional properties (currently unused): | |||
22 | * DMA controller | 22 | * DMA controller |
23 | 23 | ||
24 | Required properties: | 24 | Required properties: |
25 | - compatible: should be "renesas,shdma" | 25 | - compatible: should be of the form "renesas,shdma-<soc>", where <soc> should |
26 | be replaced with the desired SoC model, e.g. | ||
27 | "renesas,shdma-r8a73a4" for the system DMAC on r8a73a4 SoC | ||
26 | 28 | ||
27 | Example: | 29 | Example: |
28 | dmac: dma-mux0 { | 30 | dmac: dma-multiplexer@0 { |
29 | compatible = "renesas,shdma-mux"; | 31 | compatible = "renesas,shdma-mux"; |
30 | #dma-cells = <1>; | 32 | #dma-cells = <1>; |
31 | dma-channels = <6>; | 33 | dma-channels = <20>; |
32 | dma-requests = <256>; | 34 | dma-requests = <256>; |
33 | reg = <0 0>; /* Needed for AUXDATA */ | 35 | #address-cells = <2>; |
34 | #address-cells = <1>; | 36 | #size-cells = <2>; |
35 | #size-cells = <1>; | ||
36 | ranges; | 37 | ranges; |
37 | 38 | ||
38 | dma0: shdma@fe008020 { | 39 | dma0: dma-controller@e6700020 { |
39 | compatible = "renesas,shdma"; | 40 | compatible = "renesas,shdma-r8a73a4"; |
40 | reg = <0xfe008020 0x270>, | 41 | reg = <0 0xe6700020 0 0x89e0>; |
41 | <0xfe009000 0xc>; | ||
42 | interrupt-parent = <&gic>; | 42 | interrupt-parent = <&gic>; |
43 | interrupts = <0 34 4 | 43 | interrupts = <0 220 4 |
44 | 0 28 4 | 44 | 0 200 4 |
45 | 0 29 4 | 45 | 0 201 4 |
46 | 0 30 4 | 46 | 0 202 4 |
47 | 0 31 4 | 47 | 0 203 4 |
48 | 0 32 4 | 48 | 0 204 4 |
49 | 0 33 4>; | 49 | 0 205 4 |
50 | 0 206 4 | ||
51 | 0 207 4 | ||
52 | 0 208 4 | ||
53 | 0 209 4 | ||
54 | 0 210 4 | ||
55 | 0 211 4 | ||
56 | 0 212 4 | ||
57 | 0 213 4 | ||
58 | 0 214 4 | ||
59 | 0 215 4 | ||
60 | 0 216 4 | ||
61 | 0 217 4 | ||
62 | 0 218 4 | ||
63 | 0 219 4>; | ||
50 | interrupt-names = "error", | 64 | interrupt-names = "error", |
51 | "ch0", "ch1", "ch2", "ch3", | 65 | "ch0", "ch1", "ch2", "ch3", |
52 | "ch4", "ch5"; | 66 | "ch4", "ch5", "ch6", "ch7", |
53 | }; | 67 | "ch8", "ch9", "ch10", "ch11", |
54 | 68 | "ch12", "ch13", "ch14", "ch15", | |
55 | dma1: shdma@fe018020 { | 69 | "ch16", "ch17", "ch18", "ch19"; |
56 | ... | ||
57 | }; | ||
58 | |||
59 | dma2: shdma@fe028020 { | ||
60 | ... | ||
61 | }; | 70 | }; |
62 | }; | 71 | }; |
63 | 72 | ||
diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile index c962138dde96..893ee095f93c 100644 --- a/drivers/dma/sh/Makefile +++ b/drivers/dma/sh/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o | 1 | obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o |
2 | obj-$(CONFIG_SH_DMAE) += shdma.o | 2 | obj-$(CONFIG_SH_DMAE) += shdma.o |
3 | shdma-y := shdmac.o | ||
4 | shdma-objs := $(shdma-y) | ||
3 | obj-$(CONFIG_SUDMAC) += sudmac.o | 5 | obj-$(CONFIG_SUDMAC) += sudmac.o |
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c index c5ea256c2819..d94ab592cc1b 100644 --- a/drivers/dma/sh/shdma-base.c +++ b/drivers/dma/sh/shdma-base.c | |||
@@ -171,7 +171,8 @@ static struct shdma_desc *shdma_get_desc(struct shdma_chan *schan) | |||
171 | return NULL; | 171 | return NULL; |
172 | } | 172 | } |
173 | 173 | ||
174 | static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) | 174 | static int shdma_setup_slave(struct shdma_chan *schan, int slave_id, |
175 | dma_addr_t slave_addr) | ||
175 | { | 176 | { |
176 | struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); | 177 | struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); |
177 | const struct shdma_ops *ops = sdev->ops; | 178 | const struct shdma_ops *ops = sdev->ops; |
@@ -179,7 +180,7 @@ static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) | |||
179 | 180 | ||
180 | if (schan->dev->of_node) { | 181 | if (schan->dev->of_node) { |
181 | match = schan->hw_req; | 182 | match = schan->hw_req; |
182 | ret = ops->set_slave(schan, match, true); | 183 | ret = ops->set_slave(schan, match, slave_addr, true); |
183 | if (ret < 0) | 184 | if (ret < 0) |
184 | return ret; | 185 | return ret; |
185 | 186 | ||
@@ -194,7 +195,7 @@ static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) | |||
194 | if (test_and_set_bit(slave_id, shdma_slave_used)) | 195 | if (test_and_set_bit(slave_id, shdma_slave_used)) |
195 | return -EBUSY; | 196 | return -EBUSY; |
196 | 197 | ||
197 | ret = ops->set_slave(schan, match, false); | 198 | ret = ops->set_slave(schan, match, slave_addr, false); |
198 | if (ret < 0) { | 199 | if (ret < 0) { |
199 | clear_bit(slave_id, shdma_slave_used); | 200 | clear_bit(slave_id, shdma_slave_used); |
200 | return ret; | 201 | return ret; |
@@ -236,7 +237,7 @@ bool shdma_chan_filter(struct dma_chan *chan, void *arg) | |||
236 | if (!schan->dev->of_node && match >= slave_num) | 237 | if (!schan->dev->of_node && match >= slave_num) |
237 | return false; | 238 | return false; |
238 | 239 | ||
239 | ret = ops->set_slave(schan, match, true); | 240 | ret = ops->set_slave(schan, match, 0, true); |
240 | if (ret < 0) | 241 | if (ret < 0) |
241 | return false; | 242 | return false; |
242 | 243 | ||
@@ -259,7 +260,7 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan) | |||
259 | */ | 260 | */ |
260 | if (slave) { | 261 | if (slave) { |
261 | /* Legacy mode: .private is set in filter */ | 262 | /* Legacy mode: .private is set in filter */ |
262 | ret = shdma_setup_slave(schan, slave->slave_id); | 263 | ret = shdma_setup_slave(schan, slave->slave_id, 0); |
263 | if (ret < 0) | 264 | if (ret < 0) |
264 | goto esetslave; | 265 | goto esetslave; |
265 | } else { | 266 | } else { |
@@ -680,7 +681,9 @@ static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
680 | * channel, while using it... | 681 | * channel, while using it... |
681 | */ | 682 | */ |
682 | config = (struct dma_slave_config *)arg; | 683 | config = (struct dma_slave_config *)arg; |
683 | ret = shdma_setup_slave(schan, config->slave_id); | 684 | ret = shdma_setup_slave(schan, config->slave_id, |
685 | config->direction == DMA_DEV_TO_MEM ? | ||
686 | config->src_addr : config->dst_addr); | ||
684 | if (ret < 0) | 687 | if (ret < 0) |
685 | return ret; | 688 | return ret; |
686 | break; | 689 | break; |
diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c index 11bcb05cd79c..2acf7b62d6b6 100644 --- a/drivers/dma/sh/shdma-of.c +++ b/drivers/dma/sh/shdma-of.c | |||
@@ -45,9 +45,6 @@ static int shdma_of_probe(struct platform_device *pdev) | |||
45 | const struct of_dev_auxdata *lookup = pdev->dev.platform_data; | 45 | const struct of_dev_auxdata *lookup = pdev->dev.platform_data; |
46 | int ret; | 46 | int ret; |
47 | 47 | ||
48 | if (!lookup) | ||
49 | return -EINVAL; | ||
50 | |||
51 | ret = of_dma_controller_register(pdev->dev.of_node, | 48 | ret = of_dma_controller_register(pdev->dev.of_node, |
52 | shdma_of_xlate, pdev); | 49 | shdma_of_xlate, pdev); |
53 | if (ret < 0) | 50 | if (ret < 0) |
diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h index 3d9dca177860..ff2f93b612ca 100644 --- a/drivers/dma/sh/shdma.h +++ b/drivers/dma/sh/shdma.h | |||
@@ -31,6 +31,7 @@ struct sh_dmae_chan { | |||
31 | void __iomem *base; | 31 | void __iomem *base; |
32 | char dev_id[16]; /* unique name per DMAC of channel */ | 32 | char dev_id[16]; /* unique name per DMAC of channel */ |
33 | int pm_error; | 33 | int pm_error; |
34 | dma_addr_t slave_addr; | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | struct sh_dmae_device { | 37 | struct sh_dmae_device { |
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdmac.c index 3b4bee933dd7..a47b70879e05 100644 --- a/drivers/dma/sh/shdma.c +++ b/drivers/dma/sh/shdmac.c | |||
@@ -20,6 +20,8 @@ | |||
20 | 20 | ||
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_device.h> | ||
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
24 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
25 | #include <linux/dmaengine.h> | 27 | #include <linux/dmaengine.h> |
@@ -333,7 +335,7 @@ static const struct sh_dmae_slave_config *dmae_find_slave( | |||
333 | } else { | 335 | } else { |
334 | for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) | 336 | for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) |
335 | if (cfg->mid_rid == match) { | 337 | if (cfg->mid_rid == match) { |
336 | sh_chan->shdma_chan.slave_id = cfg->slave_id; | 338 | sh_chan->shdma_chan.slave_id = i; |
337 | return cfg; | 339 | return cfg; |
338 | } | 340 | } |
339 | } | 341 | } |
@@ -342,7 +344,7 @@ static const struct sh_dmae_slave_config *dmae_find_slave( | |||
342 | } | 344 | } |
343 | 345 | ||
344 | static int sh_dmae_set_slave(struct shdma_chan *schan, | 346 | static int sh_dmae_set_slave(struct shdma_chan *schan, |
345 | int slave_id, bool try) | 347 | int slave_id, dma_addr_t slave_addr, bool try) |
346 | { | 348 | { |
347 | struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, | 349 | struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, |
348 | shdma_chan); | 350 | shdma_chan); |
@@ -350,8 +352,10 @@ static int sh_dmae_set_slave(struct shdma_chan *schan, | |||
350 | if (!cfg) | 352 | if (!cfg) |
351 | return -ENXIO; | 353 | return -ENXIO; |
352 | 354 | ||
353 | if (!try) | 355 | if (!try) { |
354 | sh_chan->config = cfg; | 356 | sh_chan->config = cfg; |
357 | sh_chan->slave_addr = slave_addr ? : cfg->addr; | ||
358 | } | ||
355 | 359 | ||
356 | return 0; | 360 | return 0; |
357 | } | 361 | } |
@@ -641,7 +645,7 @@ static dma_addr_t sh_dmae_slave_addr(struct shdma_chan *schan) | |||
641 | * This is an exclusive slave DMA operation, may only be called after a | 645 | * This is an exclusive slave DMA operation, may only be called after a |
642 | * successful slave configuration. | 646 | * successful slave configuration. |
643 | */ | 647 | */ |
644 | return sh_chan->config->addr; | 648 | return sh_chan->slave_addr; |
645 | } | 649 | } |
646 | 650 | ||
647 | static struct shdma_desc *sh_dmae_embedded_desc(void *buf, int i) | 651 | static struct shdma_desc *sh_dmae_embedded_desc(void *buf, int i) |
@@ -663,9 +667,14 @@ static const struct shdma_ops sh_dmae_shdma_ops = { | |||
663 | .get_partial = sh_dmae_get_partial, | 667 | .get_partial = sh_dmae_get_partial, |
664 | }; | 668 | }; |
665 | 669 | ||
670 | static const struct of_device_id sh_dmae_of_match[] = { | ||
671 | {} | ||
672 | }; | ||
673 | MODULE_DEVICE_TABLE(of, sh_dmae_of_match); | ||
674 | |||
666 | static int sh_dmae_probe(struct platform_device *pdev) | 675 | static int sh_dmae_probe(struct platform_device *pdev) |
667 | { | 676 | { |
668 | const struct sh_dmae_pdata *pdata = pdev->dev.platform_data; | 677 | const struct sh_dmae_pdata *pdata; |
669 | unsigned long irqflags = IRQF_DISABLED, | 678 | unsigned long irqflags = IRQF_DISABLED, |
670 | chan_flag[SH_DMAE_MAX_CHANNELS] = {}; | 679 | chan_flag[SH_DMAE_MAX_CHANNELS] = {}; |
671 | int errirq, chan_irq[SH_DMAE_MAX_CHANNELS]; | 680 | int errirq, chan_irq[SH_DMAE_MAX_CHANNELS]; |
@@ -674,6 +683,11 @@ static int sh_dmae_probe(struct platform_device *pdev) | |||
674 | struct dma_device *dma_dev; | 683 | struct dma_device *dma_dev; |
675 | struct resource *chan, *dmars, *errirq_res, *chanirq_res; | 684 | struct resource *chan, *dmars, *errirq_res, *chanirq_res; |
676 | 685 | ||
686 | if (pdev->dev.of_node) | ||
687 | pdata = of_match_device(sh_dmae_of_match, &pdev->dev)->data; | ||
688 | else | ||
689 | pdata = pdev->dev.platform_data; | ||
690 | |||
677 | /* get platform data */ | 691 | /* get platform data */ |
678 | if (!pdata || !pdata->channel_num) | 692 | if (!pdata || !pdata->channel_num) |
679 | return -ENODEV; | 693 | return -ENODEV; |
@@ -902,12 +916,6 @@ static int sh_dmae_remove(struct platform_device *pdev) | |||
902 | return 0; | 916 | return 0; |
903 | } | 917 | } |
904 | 918 | ||
905 | static const struct of_device_id sh_dmae_of_match[] = { | ||
906 | { .compatible = "renesas,shdma", }, | ||
907 | { } | ||
908 | }; | ||
909 | MODULE_DEVICE_TABLE(of, sh_dmae_of_match); | ||
910 | |||
911 | static struct platform_driver sh_dmae_driver = { | 919 | static struct platform_driver sh_dmae_driver = { |
912 | .driver = { | 920 | .driver = { |
913 | .owner = THIS_MODULE, | 921 | .owner = THIS_MODULE, |
diff --git a/drivers/dma/sh/sudmac.c b/drivers/dma/sh/sudmac.c index 4808b45141b4..4600b429603e 100644 --- a/drivers/dma/sh/sudmac.c +++ b/drivers/dma/sh/sudmac.c | |||
@@ -150,7 +150,8 @@ static const struct sudmac_slave_config *sudmac_find_slave( | |||
150 | return NULL; | 150 | return NULL; |
151 | } | 151 | } |
152 | 152 | ||
153 | static int sudmac_set_slave(struct shdma_chan *schan, int slave_id, bool try) | 153 | static int sudmac_set_slave(struct shdma_chan *schan, int slave_id, |
154 | dma_addr_t slave_addr, bool try) | ||
154 | { | 155 | { |
155 | struct sudmac_chan *sc = to_chan(schan); | 156 | struct sudmac_chan *sc = to_chan(schan); |
156 | const struct sudmac_slave_config *cfg = sudmac_find_slave(sc, slave_id); | 157 | const struct sudmac_slave_config *cfg = sudmac_find_slave(sc, slave_id); |
diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h index 31cf89fb1d5b..f92c0a43c54c 100644 --- a/include/linux/shdma-base.h +++ b/include/linux/shdma-base.h | |||
@@ -96,7 +96,7 @@ struct shdma_ops { | |||
96 | dma_addr_t (*slave_addr)(struct shdma_chan *); | 96 | dma_addr_t (*slave_addr)(struct shdma_chan *); |
97 | int (*desc_setup)(struct shdma_chan *, struct shdma_desc *, | 97 | int (*desc_setup)(struct shdma_chan *, struct shdma_desc *, |
98 | dma_addr_t, dma_addr_t, size_t *); | 98 | dma_addr_t, dma_addr_t, size_t *); |
99 | int (*set_slave)(struct shdma_chan *, int, bool); | 99 | int (*set_slave)(struct shdma_chan *, int, dma_addr_t, bool); |
100 | void (*setup_xfer)(struct shdma_chan *, int); | 100 | void (*setup_xfer)(struct shdma_chan *, int); |
101 | void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); | 101 | void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); |
102 | struct shdma_desc *(*embedded_desc)(void *, int); | 102 | struct shdma_desc *(*embedded_desc)(void *, int); |