History

Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma

* 'next' of git://git.infradead.org/users/vkoul/slave-dma: (63 commits) dmaengine: mid_dma: mask_peripheral_interrupt only when dmac is idle dmaengine/ep93xx_dma: add module.h include pch_dma: Reduce wasting memory pch_dma: Fix suspend issue dma/timberdale: free_irq() on an error path dma: shdma: transfer based runtime PM dmaengine: shdma: protect against the IRQ handler dmaengine i.MX DMA/SDMA: add missing include of linux/module.h dmaengine: delete redundant chan_id and chancnt initialization in dma drivers dmaengine/amba-pl08x: Check txd->llis_va before freeing dma_pool dmaengine/amba-pl08x: Add support for sg len greater than one for slave transfers serial: sh-sci: don't filter on DMA device, use only channel ID ARM: SAMSUNG: Remove Samsung specific enum type for dma direction ASoC: Samsung: Update DMA interface spi/s3c64xx: Merge dma control code spi/s3c64xx: Add support DMA engine API ARM: SAMSUNG: Remove S3C-PL330-DMA driver ARM: S5P64X0: Use generic DMA PL330 driver ARM: S5PC100: Use generic DMA PL330 driver ARM: S5PV210: Use generic DMA PL330 driver ... Fix up fairly trivial conflicts in - arch/arm/mach-exynos4/{Kconfig,clock.c} - arch/arm/mach-s5p64x0/dma.c

Linus Torvalds committed 15 years ago

Commit fba95692 parents 3d0a8d1 4598fc260 files · +2304 −2447Browse files

Unified · Split

60 files
  1. arch/arm/include/asm/hardware/pl080.h +4 −0
  2. arch/arm/mach-exynos4/Kconfig +1 −1
  3. arch/arm/mach-exynos4/clock.c +12 −2
  4. arch/arm/mach-exynos4/dma.c +188 −111
  5. arch/arm/mach-exynos4/include/mach/dma.h +2 −2
  6. arch/arm/mach-s3c2410/include/mach/dma.h +13 −7
  7. arch/arm/mach-s3c2412/dma.c +2 −2
  8. arch/arm/mach-s3c64xx/dma.c +5 −5
  9. arch/arm/mach-s3c64xx/include/mach/dma.h +6 −2
  10. arch/arm/mach-s5p64x0/Kconfig +2 −2
  11. arch/arm/mach-s5p64x0/clock-s5p6440.c +8 −1
  12. arch/arm/mach-s5p64x0/clock-s5p6450.c +8 −1
  13. arch/arm/mach-s5p64x0/dma.c +181 −88
  14. arch/arm/mach-s5p64x0/include/mach/dma.h +2 −2
  15. arch/arm/mach-s5pc100/Kconfig +1 −1
  16. arch/arm/mach-s5pc100/clock.c +9 −2
  17. arch/arm/mach-s5pc100/dma.c +211 −112
  18. arch/arm/mach-s5pc100/include/mach/dma.h +2 −2
  19. arch/arm/mach-s5pv210/Kconfig +1 −1
  20. arch/arm/mach-s5pv210/clock.c +8 −2
  21. arch/arm/mach-s5pv210/dma.c +204 −112
  22. arch/arm/mach-s5pv210/include/mach/dma.h +2 −2
  23. arch/arm/plat-s3c24xx/dma.c +5 −5
  24. arch/arm/plat-samsung/Kconfig +6 −3
  25. arch/arm/plat-samsung/Makefile +2 −2
  26. arch/arm/plat-samsung/dma-ops.c +131 −0
  27. arch/arm/plat-samsung/include/plat/dma-ops.h +63 −0
  28. arch/arm/plat-samsung/include/plat/dma-pl330.h +15 −9
  29. arch/arm/plat-samsung/include/plat/dma-s3c24xx.h +1 −1
  30. arch/arm/plat-samsung/include/plat/dma.h +4 −6
  31. arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h +0 −32
  32. arch/arm/plat-samsung/s3c-dma-ops.c +130 −0
  33. arch/arm/plat-samsung/s3c-pl330.c +0 −1244
  34. drivers/dma/Kconfig +2 −1
  35. drivers/dma/amba-pl08x.c +316 −324
  36. drivers/dma/at_hdmac.c +127 −37
  37. drivers/dma/at_hdmac_regs.h +24 −0
  38. drivers/dma/dmatest.c +21 −2
  39. drivers/dma/dw_dmac.c +2 −3
  40. drivers/dma/ep93xx_dma.c +1 −0
  41. drivers/dma/imx-dma.c +1 −0
  42. drivers/dma/imx-sdma.c +39 −9
  43. drivers/dma/intel_mid_dma.c +3 −6
  44. drivers/dma/mpc512x_dma.c +0 −1
  45. drivers/dma/mxs-dma.c +24 −21
  46. drivers/dma/pch_dma.c +2 −5
  47. drivers/dma/pl330.c +207 −24
  48. drivers/dma/shdma.c +86 −43
  49. drivers/dma/shdma.h +7 −0
  50. drivers/dma/timb_dma.c +2 −3
  51. drivers/mmc/host/s3cmci.c +3 −3
  52. drivers/spi/spi-s3c64xx.c +92 −83
  53. drivers/tty/serial/sh-sci.c +8 −17
  54. include/linux/amba/pl08x.h +25 −5
  55. include/linux/amba/pl330.h +1 −5
  56. include/linux/dmaengine.h +11 −2
  57. include/linux/serial_sci.h +0 −2
  58. sound/soc/samsung/ac97.c +8 −2
  59. sound/soc/samsung/dma.c +60 −86
  60. sound/soc/samsung/dma.h +3 −1
arch/arm/include/asm/hardware/pl080.h+4−0
@@ -21,6 +21,9 @@ · 20 unmodified lines
2121 * OneNAND features.
2222 */
2323
24+#ifndef ASM_PL080_H
25+#define ASM_PL080_H
26+
2427 #define PL080_INT_STATUS (0x00)
2528 #define PL080_TC_STATUS (0x04)
2629 #define PL080_TC_CLEAR (0x08)
@@ -138,3 +141,4 @@ struct pl080s_lli { · 111 unmodified lines
138141 u32 control1;
139142 };
140143
144+#endif /* ASM_PL080_H */
arch/arm/mach-exynos4/Kconfig+1−1
@@ -11,7 +11,7 @@ if ARCH_EXYNOS4 · 10 unmodified lines
1111
1212 config CPU_EXYNOS4210
1313 bool
14− select S3C_PL330_DMA
14+ select SAMSUNG_DMADEV
1515 select ARM_CPU_SUSPEND if PM
1616 help
1717 Enable EXYNOS4210 CPU support
arch/arm/mach-exynos4/clock.c+12−2
@@ -111,6 +111,11 @@ struct clk clk_sclk_usbphy1 = { · 110 unmodified lines
111111 .name = "sclk_usbphy1",
112112 };
113113
114+static struct clk dummy_apb_pclk = {
115+ .name = "apb_pclk",
116+ .id = -1,
117+};
118+
114119 static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
115120 {
116121 return s5p_gatectrl(S5P_CLKSRC_MASK_TOP, clk, enable);
@@ -503,12 +508,12 @@ static struct clk init_clocks_off[] = { · 386 unmodified lines
503508 .enable = exynos4_clk_ip_fsys_ctrl,
504509 .ctrlbit = (1 << 9),
505510 }, {
506− .name = "pdma",
511+ .name = "dma",
507512 .devname = "s3c-pl330.0",
508513 .enable = exynos4_clk_ip_fsys_ctrl,
509514 .ctrlbit = (1 << 0),
510515 }, {
511− .name = "pdma",
516+ .name = "dma",
512517 .devname = "s3c-pl330.1",
513518 .enable = exynos4_clk_ip_fsys_ctrl,
514519 .ctrlbit = (1 << 1),
@@ -1281,6 +1286,11 @@ void __init exynos4_register_clocks(void) · 766 unmodified lines
12811286 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
12821287 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
12831288
1289+<<<<<<< HEAD
12841290 register_syscore_ops(&exynos4_clock_syscore_ops);
1291+=======
1292+ s3c24xx_register_clock(&dummy_apb_pclk);
1293+
1294+>>>>>>> 4598fc2c94b68740e0269db03c98a1e7ad5af773
12851295 s3c_pwmclk_init();
12861296 }
arch/arm/mach-exynos4/dma.c+188−111
@@ -21,151 +21,228 @@ · 20 unmodified lines
2121 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2222 */
2323
24−#include <linux/platform_device.h>
2524 #include <linux/dma-mapping.h>
25+#include <linux/amba/bus.h>
26+#include <linux/amba/pl330.h>
2627
28+#include <asm/irq.h>
2729 #include <plat/devs.h>
2830 #include <plat/irqs.h>
2931
3032 #include <mach/map.h>
3133 #include <mach/irqs.h>
32−
33−#include <plat/s3c-pl330-pdata.h>
34+#include <mach/dma.h>
3435
3536 static u64 dma_dmamask = DMA_BIT_MASK(32);
3637
37−static struct resource exynos4_pdma0_resource[] = {
38− [0] = {
39− .start = EXYNOS4_PA_PDMA0,
40− .end = EXYNOS4_PA_PDMA0 + SZ_4K,
41− .flags = IORESOURCE_MEM,
42− },
43− [1] = {
44− .start = IRQ_PDMA0,
45− .end = IRQ_PDMA0,
46− .flags = IORESOURCE_IRQ,
38+struct dma_pl330_peri pdma0_peri[28] = {
39+ {
40+ .peri_id = (u8)DMACH_PCM0_RX,
41+ .rqtype = DEVTOMEM,
42+ }, {
43+ .peri_id = (u8)DMACH_PCM0_TX,
44+ .rqtype = MEMTODEV,
45+ }, {
46+ .peri_id = (u8)DMACH_PCM2_RX,
47+ .rqtype = DEVTOMEM,
48+ }, {
49+ .peri_id = (u8)DMACH_PCM2_TX,
50+ .rqtype = MEMTODEV,
51+ }, {
52+ .peri_id = (u8)DMACH_MSM_REQ0,
53+ }, {
54+ .peri_id = (u8)DMACH_MSM_REQ2,
55+ }, {
56+ .peri_id = (u8)DMACH_SPI0_RX,
57+ .rqtype = DEVTOMEM,
58+ }, {
59+ .peri_id = (u8)DMACH_SPI0_TX,
60+ .rqtype = MEMTODEV,
61+ }, {
62+ .peri_id = (u8)DMACH_SPI2_RX,
63+ .rqtype = DEVTOMEM,
64+ }, {
65+ .peri_id = (u8)DMACH_SPI2_TX,
66+ .rqtype = MEMTODEV,
67+ }, {
68+ .peri_id = (u8)DMACH_I2S0S_TX,
69+ .rqtype = MEMTODEV,
70+ }, {
71+ .peri_id = (u8)DMACH_I2S0_RX,
72+ .rqtype = DEVTOMEM,
73+ }, {
74+ .peri_id = (u8)DMACH_I2S0_TX,
75+ .rqtype = MEMTODEV,
76+ }, {
77+ .peri_id = (u8)DMACH_UART0_RX,
78+ .rqtype = DEVTOMEM,
79+ }, {
80+ .peri_id = (u8)DMACH_UART0_TX,
81+ .rqtype = MEMTODEV,
82+ }, {
83+ .peri_id = (u8)DMACH_UART2_RX,
84+ .rqtype = DEVTOMEM,
85+ }, {
86+ .peri_id = (u8)DMACH_UART2_TX,
87+ .rqtype = MEMTODEV,
88+ }, {
89+ .peri_id = (u8)DMACH_UART4_RX,
90+ .rqtype = DEVTOMEM,
91+ }, {
92+ .peri_id = (u8)DMACH_UART4_TX,
93+ .rqtype = MEMTODEV,
94+ }, {
95+ .peri_id = (u8)DMACH_SLIMBUS0_RX,
96+ .rqtype = DEVTOMEM,
97+ }, {
98+ .peri_id = (u8)DMACH_SLIMBUS0_TX,
99+ .rqtype = MEMTODEV,
100+ }, {
101+ .peri_id = (u8)DMACH_SLIMBUS2_RX,
102+ .rqtype = DEVTOMEM,
103+ }, {
104+ .peri_id = (u8)DMACH_SLIMBUS2_TX,
105+ .rqtype = MEMTODEV,
106+ }, {
107+ .peri_id = (u8)DMACH_SLIMBUS4_RX,
108+ .rqtype = DEVTOMEM,
109+ }, {
110+ .peri_id = (u8)DMACH_SLIMBUS4_TX,
111+ .rqtype = MEMTODEV,
112+ }, {
113+ .peri_id = (u8)DMACH_AC97_MICIN,
114+ .rqtype = DEVTOMEM,
115+ }, {
116+ .peri_id = (u8)DMACH_AC97_PCMIN,
117+ .rqtype = DEVTOMEM,
118+ }, {
119+ .peri_id = (u8)DMACH_AC97_PCMOUT,
120+ .rqtype = MEMTODEV,
47121 },
48122 };
49123
50−static struct s3c_pl330_platdata exynos4_pdma0_pdata = {
51− .peri = {
52− [0] = DMACH_PCM0_RX,
53− [1] = DMACH_PCM0_TX,
54− [2] = DMACH_PCM2_RX,
55− [3] = DMACH_PCM2_TX,
56− [4] = DMACH_MSM_REQ0,
57− [5] = DMACH_MSM_REQ2,
58− [6] = DMACH_SPI0_RX,
59− [7] = DMACH_SPI0_TX,
60− [8] = DMACH_SPI2_RX,
61− [9] = DMACH_SPI2_TX,
62− [10] = DMACH_I2S0S_TX,
63− [11] = DMACH_I2S0_RX,
64− [12] = DMACH_I2S0_TX,
65− [13] = DMACH_I2S2_RX,
66− [14] = DMACH_I2S2_TX,
67− [15] = DMACH_UART0_RX,
68− [16] = DMACH_UART0_TX,
69− [17] = DMACH_UART2_RX,
70− [18] = DMACH_UART2_TX,
71− [19] = DMACH_UART4_RX,
72− [20] = DMACH_UART4_TX,
73− [21] = DMACH_SLIMBUS0_RX,
74− [22] = DMACH_SLIMBUS0_TX,
75− [23] = DMACH_SLIMBUS2_RX,
76− [24] = DMACH_SLIMBUS2_TX,
77− [25] = DMACH_SLIMBUS4_RX,
78− [26] = DMACH_SLIMBUS4_TX,
79− [27] = DMACH_AC97_MICIN,
80− [28] = DMACH_AC97_PCMIN,
81− [29] = DMACH_AC97_PCMOUT,
82− [30] = DMACH_MAX,
83− [31] = DMACH_MAX,
84− },
124+struct dma_pl330_platdata exynos4_pdma0_pdata = {
125+ .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
126+ .peri = pdma0_peri,
85127 };
86128
87−static struct platform_device exynos4_device_pdma0 = {
88− .name = "s3c-pl330",
89− .id = 0,
90− .num_resources = ARRAY_SIZE(exynos4_pdma0_resource),
91− .resource = exynos4_pdma0_resource,
92− .dev = {
129+struct amba_device exynos4_device_pdma0 = {
130+ .dev = {
131+ .init_name = "dma-pl330.0",
93132 .dma_mask = &dma_dmamask,
94133 .coherent_dma_mask = DMA_BIT_MASK(32),
95134 .platform_data = &exynos4_pdma0_pdata,
96135 },
136+ .res = {
137+ .start = EXYNOS4_PA_PDMA0,
138+ .end = EXYNOS4_PA_PDMA0 + SZ_4K,
139+ .flags = IORESOURCE_MEM,
140+ },
141+ .irq = {IRQ_PDMA0, NO_IRQ},
142+ .periphid = 0x00041330,
97143 };
98144
99−static struct resource exynos4_pdma1_resource[] = {
100− [0] = {
101− .start = EXYNOS4_PA_PDMA1,
102− .end = EXYNOS4_PA_PDMA1 + SZ_4K,
103− .flags = IORESOURCE_MEM,
104− },
105− [1] = {
106− .start = IRQ_PDMA1,
107− .end = IRQ_PDMA1,
108− .flags = IORESOURCE_IRQ,
145+struct dma_pl330_peri pdma1_peri[25] = {
146+ {
147+ .peri_id = (u8)DMACH_PCM0_RX,
148+ .rqtype = DEVTOMEM,
149+ }, {
150+ .peri_id = (u8)DMACH_PCM0_TX,
151+ .rqtype = MEMTODEV,
152+ }, {
153+ .peri_id = (u8)DMACH_PCM1_RX,
154+ .rqtype = DEVTOMEM,
155+ }, {
156+ .peri_id = (u8)DMACH_PCM1_TX,
157+ .rqtype = MEMTODEV,
158+ }, {
159+ .peri_id = (u8)DMACH_MSM_REQ1,
160+ }, {
161+ .peri_id = (u8)DMACH_MSM_REQ3,
162+ }, {
163+ .peri_id = (u8)DMACH_SPI1_RX,
164+ .rqtype = DEVTOMEM,
165+ }, {
166+ .peri_id = (u8)DMACH_SPI1_TX,
167+ .rqtype = MEMTODEV,
168+ }, {
169+ .peri_id = (u8)DMACH_I2S0S_TX,
170+ .rqtype = MEMTODEV,
171+ }, {
172+ .peri_id = (u8)DMACH_I2S0_RX,
173+ .rqtype = DEVTOMEM,
174+ }, {
175+ .peri_id = (u8)DMACH_I2S0_TX,
176+ .rqtype = MEMTODEV,
177+ }, {
178+ .peri_id = (u8)DMACH_I2S1_RX,
179+ .rqtype = DEVTOMEM,
180+ }, {
181+ .peri_id = (u8)DMACH_I2S1_TX,
182+ .rqtype = MEMTODEV,
183+ }, {
184+ .peri_id = (u8)DMACH_UART0_RX,
185+ .rqtype = DEVTOMEM,
186+ }, {
187+ .peri_id = (u8)DMACH_UART0_TX,
188+ .rqtype = MEMTODEV,
189+ }, {
190+ .peri_id = (u8)DMACH_UART1_RX,
191+ .rqtype = DEVTOMEM,
192+ }, {
193+ .peri_id = (u8)DMACH_UART1_TX,
194+ .rqtype = MEMTODEV,
195+ }, {
196+ .peri_id = (u8)DMACH_UART3_RX,
197+ .rqtype = DEVTOMEM,
198+ }, {
199+ .peri_id = (u8)DMACH_UART3_TX,
200+ .rqtype = MEMTODEV,
201+ }, {
202+ .peri_id = (u8)DMACH_SLIMBUS1_RX,
203+ .rqtype = DEVTOMEM,
204+ }, {
205+ .peri_id = (u8)DMACH_SLIMBUS1_TX,
206+ .rqtype = MEMTODEV,
207+ }, {
208+ .peri_id = (u8)DMACH_SLIMBUS3_RX,
209+ .rqtype = DEVTOMEM,
210+ }, {
211+ .peri_id = (u8)DMACH_SLIMBUS3_TX,
212+ .rqtype = MEMTODEV,
213+ }, {
214+ .peri_id = (u8)DMACH_SLIMBUS5_RX,
215+ .rqtype = DEVTOMEM,
216+ }, {
217+ .peri_id = (u8)DMACH_SLIMBUS5_TX,
218+ .rqtype = MEMTODEV,
109219 },
110220 };
111221
112−static struct s3c_pl330_platdata exynos4_pdma1_pdata = {
113− .peri = {
114− [0] = DMACH_PCM0_RX,
115− [1] = DMACH_PCM0_TX,
116− [2] = DMACH_PCM1_RX,
117− [3] = DMACH_PCM1_TX,
118− [4] = DMACH_MSM_REQ1,
119− [5] = DMACH_MSM_REQ3,
120− [6] = DMACH_SPI1_RX,
121− [7] = DMACH_SPI1_TX,
122− [8] = DMACH_I2S0S_TX,
123− [9] = DMACH_I2S0_RX,
124− [10] = DMACH_I2S0_TX,
125− [11] = DMACH_I2S1_RX,
126− [12] = DMACH_I2S1_TX,
127− [13] = DMACH_UART0_RX,
128− [14] = DMACH_UART0_TX,
129− [15] = DMACH_UART1_RX,
130− [16] = DMACH_UART1_TX,
131− [17] = DMACH_UART3_RX,
132− [18] = DMACH_UART3_TX,
133− [19] = DMACH_SLIMBUS1_RX,
134− [20] = DMACH_SLIMBUS1_TX,
135− [21] = DMACH_SLIMBUS3_RX,
136− [22] = DMACH_SLIMBUS3_TX,
137− [23] = DMACH_SLIMBUS5_RX,
138− [24] = DMACH_SLIMBUS5_TX,
139− [25] = DMACH_SLIMBUS0AUX_RX,
140− [26] = DMACH_SLIMBUS0AUX_TX,
141− [27] = DMACH_SPDIF,
142− [28] = DMACH_MAX,
143− [29] = DMACH_MAX,
144− [30] = DMACH_MAX,
145− [31] = DMACH_MAX,
146− },
222+struct dma_pl330_platdata exynos4_pdma1_pdata = {
223+ .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
224+ .peri = pdma1_peri,
147225 };
148226
149−static struct platform_device exynos4_device_pdma1 = {
150− .name = "s3c-pl330",
151− .id = 1,
152− .num_resources = ARRAY_SIZE(exynos4_pdma1_resource),
153− .resource = exynos4_pdma1_resource,
154− .dev = {
227+struct amba_device exynos4_device_pdma1 = {
228+ .dev = {
229+ .init_name = "dma-pl330.1",
155230 .dma_mask = &dma_dmamask,
156231 .coherent_dma_mask = DMA_BIT_MASK(32),
157232 .platform_data = &exynos4_pdma1_pdata,
158233 },
159−};
160−
161−static struct platform_device *exynos4_dmacs[] __initdata = {
162− &exynos4_device_pdma0,
163− &exynos4_device_pdma1,
234+ .res = {
235+ .start = EXYNOS4_PA_PDMA1,
236+ .end = EXYNOS4_PA_PDMA1 + SZ_4K,
237+ .flags = IORESOURCE_MEM,
238+ },
239+ .irq = {IRQ_PDMA1, NO_IRQ},
240+ .periphid = 0x00041330,
164241 };
165242
166243 static int __init exynos4_dma_init(void)
167244 {
168− platform_add_devices(exynos4_dmacs, ARRAY_SIZE(exynos4_dmacs));
245+ amba_device_register(&exynos4_device_pdma0, &iomem_resource);
169246
170247 return 0;
171248 }
arch/arm/mach-exynos4/include/mach/dma.h+2−2
@@ -20,7 +20,7 @@ · 19 unmodified lines
2020 #ifndef __MACH_DMA_H
2121 #define __MACH_DMA_H
2222
23−/* This platform uses the common S3C DMA API driver for PL330 */
24−#include <plat/s3c-dma-pl330.h>
23+/* This platform uses the common DMA API driver for PL330 */
24+#include <plat/dma-pl330.h>
2525
2626 #endif /* __MACH_DMA_H */
arch/arm/mach-s3c2410/include/mach/dma.h+13−7
@@ -13,7 +13,6 @@ · 12 unmodified lines
1313 #ifndef __ASM_ARCH_DMA_H
1414 #define __ASM_ARCH_DMA_H __FILE__
1515
16−#include <plat/dma.h>
1716 #include <linux/sysdev.h>
1817
1918 #define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
@@ -51,6 +50,18 @@ enum dma_ch { · 31 unmodified lines
5150 DMACH_MAX, /* the end entry */
5251 };
5352
53+static inline bool samsung_dma_has_circular(void)
54+{
55+ return false;
56+}
57+
58+static inline bool samsung_dma_is_dmadev(void)
59+{
60+ return false;
61+}
62+
63+#include <plat/dma.h>
64+
5465 #define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
5566
5667 /* we have 4 dma channels */
@@ -163,7 +174,7 @@ struct s3c2410_dma_chan { · 106 unmodified lines
163174 struct s3c2410_dma_client *client;
164175
165176 /* channel configuration */
166− enum s3c2410_dmasrc source;
177+ enum dma_data_direction source;
167178 enum dma_ch req_ch;
168179 unsigned long dev_addr;
169180 unsigned long load_timeout;
@@ -196,9 +207,4 @@ struct s3c2410_dma_chan { · 26 unmodified lines
196207
197208 typedef unsigned long dma_device_t;
198209
199−static inline bool s3c_dma_has_circular(void)
200−{
201− return false;
202−}
203−
204210 #endif /* __ASM_ARCH_DMA_H */
arch/arm/mach-s3c2412/dma.c+2−2
@@ -130,11 +130,11 @@ static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { · 129 unmodified lines
130130
131131 static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
132132 struct s3c24xx_dma_map *map,
133− enum s3c2410_dmasrc dir)
133+ enum dma_data_direction dir)
134134 {
135135 unsigned long chsel;
136136
137− if (dir == S3C2410_DMASRC_HW)
137+ if (dir == DMA_FROM_DEVICE)
138138 chsel = map->channels_rx[0];
139139 else
140140 chsel = map->channels[0];
arch/arm/mach-s3c64xx/dma.c+5−5
@@ -147,14 +147,14 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan, · 146 unmodified lines
147147 u32 control0, control1;
148148
149149 switch (chan->source) {
150− case S3C2410_DMASRC_HW:
150+ case DMA_FROM_DEVICE:
151151 src = chan->dev_addr;
152152 dst = data;
153153 control0 = PL080_CONTROL_SRC_AHB2;
154154 control0 |= PL080_CONTROL_DST_INCR;
155155 break;
156156
157− case S3C2410_DMASRC_MEM:
157+ case DMA_TO_DEVICE:
158158 src = data;
159159 dst = chan->dev_addr;
160160 control0 = PL080_CONTROL_DST_AHB2;
@@ -416,7 +416,7 @@ EXPORT_SYMBOL(s3c2410_dma_enqueue); · 255 unmodified lines
416416
417417
418418 int s3c2410_dma_devconfig(enum dma_ch channel,
419− enum s3c2410_dmasrc source,
419+ enum dma_data_direction source,
420420 unsigned long devaddr)
421421 {
422422 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
@@ -437,11 +437,11 @@ int s3c2410_dma_devconfig(enum dma_ch channel, · 14 unmodified lines
437437 pr_debug("%s: peripheral %d\n", __func__, peripheral);
438438
439439 switch (source) {
440− case S3C2410_DMASRC_HW:
440+ case DMA_FROM_DEVICE:
441441 config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
442442 config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
443443 break;
444− case S3C2410_DMASRC_MEM:
444+ case DMA_TO_DEVICE:
445445 config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
446446 config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
447447 break;
arch/arm/mach-s3c64xx/include/mach/dma.h+6−2
@@ -58,11 +58,15 @@ enum dma_ch { · 57 unmodified lines
5858 DMACH_MAX /* the end */
5959 };
6060
61−static __inline__ bool s3c_dma_has_circular(void)
61+static inline bool samsung_dma_has_circular(void)
6262 {
6363 return true;
6464 }
6565
66+static inline bool samsung_dma_is_dmadev(void)
67+{
68+ return false;
69+}
6670 #define S3C2410_DMAF_CIRCULAR (1 << 0)
6771
6872 #include <plat/dma.h>
@@ -95,7 +99,7 @@ struct s3c2410_dma_chan { · 26 unmodified lines
9599 unsigned char peripheral;
96100
97101 unsigned int flags;
98− enum s3c2410_dmasrc source;
102+ enum dma_data_direction source;
99103
100104
101105 dma_addr_t dev_addr;
arch/arm/mach-s5p64x0/Kconfig+2−2
@@ -9,14 +9,14 @@ if ARCH_S5P64X0 · 8 unmodified lines
99
1010 config CPU_S5P6440
1111 bool
12− select S3C_PL330_DMA
12+ select SAMSUNG_DMADEV
1313 select S5P_HRT
1414 help
1515 Enable S5P6440 CPU support
1616
1717 config CPU_S5P6450
1818 bool
19− select S3C_PL330_DMA
19+ select SAMSUNG_DMADEV
2020 select S5P_HRT
2121 help
2222 Enable S5P6450 CPU support
arch/arm/mach-s5p64x0/clock-s5p6440.c+8−1
@@ -146,7 +146,7 @@ static struct clk init_clocks_off[] = { · 145 unmodified lines
146146 .enable = s5p64x0_hclk0_ctrl,
147147 .ctrlbit = (1 << 8),
148148 }, {
149− .name = "pdma",
149+ .name = "dma",
150150 .parent = &clk_hclk_low.clk,
151151 .enable = s5p64x0_hclk0_ctrl,
152152 .ctrlbit = (1 << 12),
@@ -499,6 +499,11 @@ static struct clksrc_clk *sysclks[] = { · 346 unmodified lines
499499 &clk_pclk_low,
500500 };
501501
502+static struct clk dummy_apb_pclk = {
503+ .name = "apb_pclk",
504+ .id = -1,
505+};
506+
502507 void __init_or_cpufreq s5p6440_setup_clocks(void)
503508 {
504509 struct clk *xtal_clk;
@@ -581,5 +586,7 @@ void __init s5p6440_register_clocks(void) · 76 unmodified lines
581586 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
582587 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
583588
589+ s3c24xx_register_clock(&dummy_apb_pclk);
590+
584591 s3c_pwmclk_init();
585592 }
arch/arm/mach-s5p64x0/clock-s5p6450.c+8−1
@@ -179,7 +179,7 @@ static struct clk init_clocks_off[] = { · 178 unmodified lines
179179 .enable = s5p64x0_hclk0_ctrl,
180180 .ctrlbit = (1 << 3),
181181 }, {
182− .name = "pdma",
182+ .name = "dma",
183183 .parent = &clk_hclk_low.clk,
184184 .enable = s5p64x0_hclk0_ctrl,
185185 .ctrlbit = (1 << 12),
@@ -553,6 +553,11 @@ static struct clksrc_clk *sysclks[] = { · 367 unmodified lines
553553 &clk_sclk_audio0,
554554 };
555555
556+static struct clk dummy_apb_pclk = {
557+ .name = "apb_pclk",
558+ .id = -1,
559+};
560+
556561 void __init_or_cpufreq s5p6450_setup_clocks(void)
557562 {
558563 struct clk *xtal_clk;
@@ -632,5 +637,7 @@ void __init s5p6450_register_clocks(void) · 73 unmodified lines
632637 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
633638 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
634639
640+ s3c24xx_register_clock(&dummy_apb_pclk);
641+
635642 s3c_pwmclk_init();
636643 }
arch/arm/mach-s5p64x0/dma.c+181−88
@@ -21,115 +21,208 @@ · 20 unmodified lines
2121 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2222 */
2323
24−#include <linux/platform_device.h>
2524 #include <linux/dma-mapping.h>
25+#include <linux/amba/bus.h>
26+#include <linux/amba/pl330.h>
27+
28+#include <asm/irq.h>
2629
2730 #include <mach/map.h>
2831 #include <mach/irqs.h>
2932 #include <mach/regs-clock.h>
33+#include <mach/dma.h>
3034
3135 #include <plat/cpu.h>
3236 #include <plat/devs.h>
33−#include <plat/s3c-pl330-pdata.h>
37+#include <plat/irqs.h>
3438
3539 static u64 dma_dmamask = DMA_BIT_MASK(32);
3640
37−static struct resource s5p64x0_pdma_resource[] = {
38− [0] = {
39− .start = S5P64X0_PA_PDMA,
40− .end = S5P64X0_PA_PDMA + SZ_4K,
41− .flags = IORESOURCE_MEM,
42− },
43− [1] = {
44− .start = IRQ_DMA0,
45− .end = IRQ_DMA0,
46− .flags = IORESOURCE_IRQ,
41+struct dma_pl330_peri s5p6440_pdma_peri[22] = {
42+ {
43+ .peri_id = (u8)DMACH_UART0_RX,
44+ .rqtype = DEVTOMEM,
45+ }, {
46+ .peri_id = (u8)DMACH_UART0_TX,
47+ .rqtype = MEMTODEV,
48+ }, {
49+ .peri_id = (u8)DMACH_UART1_RX,
50+ .rqtype = DEVTOMEM,
51+ }, {
52+ .peri_id = (u8)DMACH_UART1_TX,
53+ .rqtype = MEMTODEV,
54+ }, {
55+ .peri_id = (u8)DMACH_UART2_RX,
56+ .rqtype = DEVTOMEM,
57+ }, {
58+ .peri_id = (u8)DMACH_UART2_TX,
59+ .rqtype = MEMTODEV,
60+ }, {
61+ .peri_id = (u8)DMACH_UART3_RX,
62+ .rqtype = DEVTOMEM,
63+ }, {
64+ .peri_id = (u8)DMACH_UART3_TX,
65+ .rqtype = MEMTODEV,
66+ }, {
67+ .peri_id = DMACH_MAX,
68+ }, {
69+ .peri_id = DMACH_MAX,
70+ }, {
71+ .peri_id = (u8)DMACH_PCM0_TX,
72+ .rqtype = MEMTODEV,
73+ }, {
74+ .peri_id = (u8)DMACH_PCM0_RX,
75+ .rqtype = DEVTOMEM,
76+ }, {
77+ .peri_id = (u8)DMACH_I2S0_TX,
78+ .rqtype = MEMTODEV,
79+ }, {
80+ .peri_id = (u8)DMACH_I2S0_RX,
81+ .rqtype = DEVTOMEM,
82+ }, {
83+ .peri_id = (u8)DMACH_SPI0_TX,
84+ .rqtype = MEMTODEV,
85+ }, {
86+ .peri_id = (u8)DMACH_SPI0_RX,
87+ .rqtype = DEVTOMEM,
88+ }, {
89+ .peri_id = (u8)DMACH_MAX,
90+ }, {
91+ .peri_id = (u8)DMACH_MAX,
92+ }, {
93+ .peri_id = (u8)DMACH_MAX,
94+ }, {
95+ .peri_id = (u8)DMACH_MAX,
96+ }, {
97+ .peri_id = (u8)DMACH_SPI1_TX,
98+ .rqtype = MEMTODEV,
99+ }, {
100+ .peri_id = (u8)DMACH_SPI1_RX,
101+ .rqtype = DEVTOMEM,
47102 },
48103 };
49104
50−static struct s3c_pl330_platdata s5p6440_pdma_pdata = {
51− .peri = {
52− [0] = DMACH_UART0_RX,
53− [1] = DMACH_UART0_TX,
54− [2] = DMACH_UART1_RX,
55− [3] = DMACH_UART1_TX,
56− [4] = DMACH_UART2_RX,
57− [5] = DMACH_UART2_TX,
58− [6] = DMACH_UART3_RX,
59− [7] = DMACH_UART3_TX,
60− [8] = DMACH_MAX,
61− [9] = DMACH_MAX,
62− [10] = DMACH_PCM0_TX,
63− [11] = DMACH_PCM0_RX,
64− [12] = DMACH_I2S0_TX,
65− [13] = DMACH_I2S0_RX,
66− [14] = DMACH_SPI0_TX,
67− [15] = DMACH_SPI0_RX,
68− [16] = DMACH_MAX,
69− [17] = DMACH_MAX,
70− [18] = DMACH_MAX,
71− [19] = DMACH_MAX,
72− [20] = DMACH_SPI1_TX,
73− [21] = DMACH_SPI1_RX,
74− [22] = DMACH_MAX,
75− [23] = DMACH_MAX,
76− [24] = DMACH_MAX,
77− [25] = DMACH_MAX,
78− [26] = DMACH_MAX,
79− [27] = DMACH_MAX,
80− [28] = DMACH_MAX,
81− [29] = DMACH_PWM,
82− [30] = DMACH_MAX,
83− [31] = DMACH_MAX,
84− },
105+struct dma_pl330_platdata s5p6440_pdma_pdata = {
106+ .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
107+ .peri = s5p6440_pdma_peri,
85108 };
86109
87−static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
88− .peri = {
89− [0] = DMACH_UART0_RX,
90− [1] = DMACH_UART0_TX,
91− [2] = DMACH_UART1_RX,
92− [3] = DMACH_UART1_TX,
93− [4] = DMACH_UART2_RX,
94− [5] = DMACH_UART2_TX,
95− [6] = DMACH_UART3_RX,
96− [7] = DMACH_UART3_TX,
97− [8] = DMACH_UART4_RX,
98− [9] = DMACH_UART4_TX,
99− [10] = DMACH_PCM0_TX,
100− [11] = DMACH_PCM0_RX,
101− [12] = DMACH_I2S0_TX,
102− [13] = DMACH_I2S0_RX,
103− [14] = DMACH_SPI0_TX,
104− [15] = DMACH_SPI0_RX,
105− [16] = DMACH_PCM1_TX,
106− [17] = DMACH_PCM1_RX,
107− [18] = DMACH_PCM2_TX,
108− [19] = DMACH_PCM2_RX,
109− [20] = DMACH_SPI1_TX,
110− [21] = DMACH_SPI1_RX,
111− [22] = DMACH_USI_TX,
112− [23] = DMACH_USI_RX,
113− [24] = DMACH_MAX,
114− [25] = DMACH_I2S1_TX,
115− [26] = DMACH_I2S1_RX,
116− [27] = DMACH_I2S2_TX,
117− [28] = DMACH_I2S2_RX,
118− [29] = DMACH_PWM,
119− [30] = DMACH_UART5_RX,
120− [31] = DMACH_UART5_TX,
110+struct dma_pl330_peri s5p6450_pdma_peri[32] = {
111+ {
112+ .peri_id = (u8)DMACH_UART0_RX,
113+ .rqtype = DEVTOMEM,
114+ }, {
115+ .peri_id = (u8)DMACH_UART0_TX,
116+ .rqtype = MEMTODEV,
117+ }, {
118+ .peri_id = (u8)DMACH_UART1_RX,
119+ .rqtype = DEVTOMEM,
120+ }, {
121+ .peri_id = (u8)DMACH_UART1_TX,
122+ .rqtype = MEMTODEV,
123+ }, {
124+ .peri_id = (u8)DMACH_UART2_RX,
125+ .rqtype = DEVTOMEM,
126+ }, {
127+ .peri_id = (u8)DMACH_UART2_TX,
128+ .rqtype = MEMTODEV,
129+ }, {
130+ .peri_id = (u8)DMACH_UART3_RX,
131+ .rqtype = DEVTOMEM,
132+ }, {
133+ .peri_id = (u8)DMACH_UART3_TX,
134+ .rqtype = MEMTODEV,
135+ }, {
136+ .peri_id = (u8)DMACH_UART4_RX,
137+ .rqtype = DEVTOMEM,
138+ }, {
139+ .peri_id = (u8)DMACH_UART4_TX,
140+ .rqtype = MEMTODEV,
141+ }, {
142+ .peri_id = (u8)DMACH_PCM0_TX,
143+ .rqtype = MEMTODEV,
144+ }, {
145+ .peri_id = (u8)DMACH_PCM0_RX,
146+ .rqtype = DEVTOMEM,
147+ }, {
148+ .peri_id = (u8)DMACH_I2S0_TX,
149+ .rqtype = MEMTODEV,
150+ }, {
151+ .peri_id = (u8)DMACH_I2S0_RX,
152+ .rqtype = DEVTOMEM,
153+ }, {
154+ .peri_id = (u8)DMACH_SPI0_TX,
155+ .rqtype = MEMTODEV,
156+ }, {
157+ .peri_id = (u8)DMACH_SPI0_RX,
158+ .rqtype = DEVTOMEM,
159+ }, {
160+ .peri_id = (u8)DMACH_PCM1_TX,
161+ .rqtype = MEMTODEV,
162+ }, {
163+ .peri_id = (u8)DMACH_PCM1_RX,
164+ .rqtype = DEVTOMEM,
165+ }, {
166+ .peri_id = (u8)DMACH_PCM2_TX,
167+ .rqtype = MEMTODEV,
168+ }, {
169+ .peri_id = (u8)DMACH_PCM2_RX,
170+ .rqtype = DEVTOMEM,
171+ }, {
172+ .peri_id = (u8)DMACH_SPI1_TX,
173+ .rqtype = MEMTODEV,
174+ }, {
175+ .peri_id = (u8)DMACH_SPI1_RX,
176+ .rqtype = DEVTOMEM,
177+ }, {
178+ .peri_id = (u8)DMACH_USI_TX,
179+ .rqtype = MEMTODEV,
180+ }, {
181+ .peri_id = (u8)DMACH_USI_RX,
182+ .rqtype = DEVTOMEM,
183+ }, {
184+ .peri_id = (u8)DMACH_MAX,
185+ }, {
186+ .peri_id = (u8)DMACH_I2S1_TX,
187+ .rqtype = MEMTODEV,
188+ }, {
189+ .peri_id = (u8)DMACH_I2S1_RX,
190+ .rqtype = DEVTOMEM,
191+ }, {
192+ .peri_id = (u8)DMACH_I2S2_TX,
193+ .rqtype = MEMTODEV,
194+ }, {
195+ .peri_id = (u8)DMACH_I2S2_RX,
196+ .rqtype = DEVTOMEM,
197+ }, {
198+ .peri_id = (u8)DMACH_PWM,
199+ }, {
200+ .peri_id = (u8)DMACH_UART5_RX,
201+ .rqtype = DEVTOMEM,
202+ }, {
203+ .peri_id = (u8)DMACH_UART5_TX,
204+ .rqtype = MEMTODEV,
121205 },
122206 };
123207
124−static struct platform_device s5p64x0_device_pdma = {
125− .name = "s3c-pl330",
126− .id = -1,
127− .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource),
128− .resource = s5p64x0_pdma_resource,
129− .dev = {
208+struct dma_pl330_platdata s5p6450_pdma_pdata = {
209+ .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
210+ .peri = s5p6450_pdma_peri,
211+};
212+
213+struct amba_device s5p64x0_device_pdma = {
214+ .dev = {
215+ .init_name = "dma-pl330",
130216 .dma_mask = &dma_dmamask,
131217 .coherent_dma_mask = DMA_BIT_MASK(32),
132218 },
219+ .res = {
220+ .start = S5P64X0_PA_PDMA,
221+ .end = S5P64X0_PA_PDMA + SZ_4K,
222+ .flags = IORESOURCE_MEM,
223+ },
224+ .irq = {IRQ_DMA0, NO_IRQ},
225+ .periphid = 0x00041330,
133226 };
134227
135228 static int __init s5p64x0_dma_init(void)
@@ -139,7 +232,7 @@ static int __init s5p64x0_dma_init(void) · 3 unmodified lines
139232 else
140233 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
141234
142− platform_device_register(&s5p64x0_device_pdma);
235+ amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
143236
144237 return 0;
145238 }
arch/arm/mach-s5p64x0/include/mach/dma.h+2−2
@@ -20,7 +20,7 @@ · 19 unmodified lines
2020 #ifndef __MACH_DMA_H
2121 #define __MACH_DMA_H
2222
23−/* This platform uses the common S3C DMA API driver for PL330 */
24−#include <plat/s3c-dma-pl330.h>
23+/* This platform uses the common common DMA API driver for PL330 */
24+#include <plat/dma-pl330.h>
2525
2626 #endif /* __MACH_DMA_H */
arch/arm/mach-s5pc100/Kconfig+1−1
@@ -10,7 +10,7 @@ if ARCH_S5PC100 · 9 unmodified lines
1010 config CPU_S5PC100
1111 bool
1212 select S5P_EXT_INT
13− select S3C_PL330_DMA
13+ select SAMSUNG_DMADEV
1414 help
1515 Enable S5PC100 CPU support
1616
arch/arm/mach-s5pc100/clock.c+9−2
@@ -33,6 +33,11 @@ static struct clk s5p_clk_otgphy = { · 32 unmodified lines
3333 .name = "otg_phy",
3434 };
3535
36+static struct clk dummy_apb_pclk = {
37+ .name = "apb_pclk",
38+ .id = -1,
39+};
40+
3641 static struct clk *clk_src_mout_href_list[] = {
3742 [0] = &s5p_clk_27m,
3843 [1] = &clk_fin_hpll,
@@ -454,13 +459,13 @@ static struct clk init_clocks_off[] = { · 415 unmodified lines
454459 .enable = s5pc100_d1_0_ctrl,
455460 .ctrlbit = (1 << 2),
456461 }, {
457− .name = "pdma",
462+ .name = "dma",
458463 .devname = "s3c-pl330.1",
459464 .parent = &clk_div_d1_bus.clk,
460465 .enable = s5pc100_d1_0_ctrl,
461466 .ctrlbit = (1 << 1),
462467 }, {
463− .name = "pdma",
468+ .name = "dma",
464469 .devname = "s3c-pl330.0",
465470 .parent = &clk_div_d1_bus.clk,
466471 .enable = s5pc100_d1_0_ctrl,
@@ -1276,5 +1281,7 @@ void __init s5pc100_register_clocks(void) · 809 unmodified lines
12761281 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
12771282 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
12781283
1284+ s3c24xx_register_clock(&dummy_apb_pclk);
1285+
12791286 s3c_pwmclk_init();
12801287 }
arch/arm/mach-s5pc100/dma.c+211−112
@@ -1,4 +1,8 @@
1−/*
1+/* linux/arch/arm/mach-s5pc100/dma.c
2+ *
3+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4+ * http://www.samsung.com
5+ *
26 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
37 * Jaswinder Singh <jassi.brar@samsung.com>
48 *
@@ -17,150 +21,245 @@ · 12 unmodified lines
1721 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1822 */
1923
20−#include <linux/platform_device.h>
2124 #include <linux/dma-mapping.h>
25+#include <linux/amba/bus.h>
26+#include <linux/amba/pl330.h>
2227
28+#include <asm/irq.h>
2329 #include <plat/devs.h>
30+#include <plat/irqs.h>
2431
2532 #include <mach/map.h>
2633 #include <mach/irqs.h>
27−
28−#include <plat/s3c-pl330-pdata.h>
34+#include <mach/dma.h>
2935
3036 static u64 dma_dmamask = DMA_BIT_MASK(32);
3137
32−static struct resource s5pc100_pdma0_resource[] = {
33− [0] = {
34− .start = S5PC100_PA_PDMA0,
35− .end = S5PC100_PA_PDMA0 + SZ_4K,
36− .flags = IORESOURCE_MEM,
37− },
38− [1] = {
39− .start = IRQ_PDMA0,
40− .end = IRQ_PDMA0,
41− .flags = IORESOURCE_IRQ,
38+struct dma_pl330_peri pdma0_peri[30] = {
39+ {
40+ .peri_id = (u8)DMACH_UART0_RX,
41+ .rqtype = DEVTOMEM,
42+ }, {
43+ .peri_id = (u8)DMACH_UART0_TX,
44+ .rqtype = MEMTODEV,
45+ }, {
46+ .peri_id = (u8)DMACH_UART1_RX,
47+ .rqtype = DEVTOMEM,
48+ }, {
49+ .peri_id = (u8)DMACH_UART1_TX,
50+ .rqtype = MEMTODEV,
51+ }, {
52+ .peri_id = (u8)DMACH_UART2_RX,
53+ .rqtype = DEVTOMEM,
54+ }, {
55+ .peri_id = (u8)DMACH_UART2_TX,
56+ .rqtype = MEMTODEV,
57+ }, {
58+ .peri_id = (u8)DMACH_UART3_RX,
59+ .rqtype = DEVTOMEM,
60+ }, {
61+ .peri_id = (u8)DMACH_UART3_TX,
62+ .rqtype = MEMTODEV,
63+ }, {
64+ .peri_id = DMACH_IRDA,
65+ }, {
66+ .peri_id = (u8)DMACH_I2S0_RX,
67+ .rqtype = DEVTOMEM,
68+ }, {
69+ .peri_id = (u8)DMACH_I2S0_TX,
70+ .rqtype = MEMTODEV,
71+ }, {
72+ .peri_id = (u8)DMACH_I2S0S_TX,
73+ .rqtype = MEMTODEV,
74+ }, {
75+ .peri_id = (u8)DMACH_I2S1_RX,
76+ .rqtype = DEVTOMEM,
77+ }, {
78+ .peri_id = (u8)DMACH_I2S1_TX,
79+ .rqtype = MEMTODEV,
80+ }, {
81+ .peri_id = (u8)DMACH_I2S2_RX,
82+ .rqtype = DEVTOMEM,
83+ }, {
84+ .peri_id = (u8)DMACH_I2S2_TX,
85+ .rqtype = MEMTODEV,
86+ }, {
87+ .peri_id = (u8)DMACH_SPI0_RX,
88+ .rqtype = DEVTOMEM,
89+ }, {
90+ .peri_id = (u8)DMACH_SPI0_TX,
91+ .rqtype = MEMTODEV,
92+ }, {
93+ .peri_id = (u8)DMACH_SPI1_RX,
94+ .rqtype = DEVTOMEM,
95+ }, {
96+ .peri_id = (u8)DMACH_SPI1_TX,
97+ .rqtype = MEMTODEV,
98+ }, {
99+ .peri_id = (u8)DMACH_SPI2_RX,
100+ .rqtype = DEVTOMEM,
101+ }, {
102+ .peri_id = (u8)DMACH_SPI2_TX,
103+ .rqtype = MEMTODEV,
104+ }, {
105+ .peri_id = (u8)DMACH_AC97_MICIN,
106+ .rqtype = DEVTOMEM,
107+ }, {
108+ .peri_id = (u8)DMACH_AC97_PCMIN,
109+ .rqtype = DEVTOMEM,
110+ }, {
111+ .peri_id = (u8)DMACH_AC97_PCMOUT,
112+ .rqtype = MEMTODEV,
113+ }, {
114+ .peri_id = (u8)DMACH_EXTERNAL,
115+ }, {
116+ .peri_id = (u8)DMACH_PWM,
117+ }, {
118+ .peri_id = (u8)DMACH_SPDIF,
119+ .rqtype = MEMTODEV,
120+ }, {
121+ .peri_id = (u8)DMACH_HSI_RX,
122+ .rqtype = DEVTOMEM,
123+ }, {
124+ .peri_id = (u8)DMACH_HSI_TX,
125+ .rqtype = MEMTODEV,
42126 },
43127 };
44128
45−static struct s3c_pl330_platdata s5pc100_pdma0_pdata = {
46− .peri = {
47− [0] = DMACH_UART0_RX,
48− [1] = DMACH_UART0_TX,
49− [2] = DMACH_UART1_RX,
50− [3] = DMACH_UART1_TX,
51− [4] = DMACH_UART2_RX,
52− [5] = DMACH_UART2_TX,
53− [6] = DMACH_UART3_RX,
54− [7] = DMACH_UART3_TX,
55− [8] = DMACH_IRDA,
56− [9] = DMACH_I2S0_RX,
57− [10] = DMACH_I2S0_TX,
58− [11] = DMACH_I2S0S_TX,
59− [12] = DMACH_I2S1_RX,
60− [13] = DMACH_I2S1_TX,
61− [14] = DMACH_I2S2_RX,
62− [15] = DMACH_I2S2_TX,
63− [16] = DMACH_SPI0_RX,
64− [17] = DMACH_SPI0_TX,
65− [18] = DMACH_SPI1_RX,
66− [19] = DMACH_SPI1_TX,
67− [20] = DMACH_SPI2_RX,
68− [21] = DMACH_SPI2_TX,
69− [22] = DMACH_AC97_MICIN,
70− [23] = DMACH_AC97_PCMIN,
71− [24] = DMACH_AC97_PCMOUT,
72− [25] = DMACH_EXTERNAL,
73− [26] = DMACH_PWM,
74− [27] = DMACH_SPDIF,
75− [28] = DMACH_HSI_RX,
76− [29] = DMACH_HSI_TX,
77− [30] = DMACH_MAX,
78− [31] = DMACH_MAX,
79− },
129+struct dma_pl330_platdata s5pc100_pdma0_pdata = {
130+ .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
131+ .peri = pdma0_peri,
80132 };
81133
82−static struct platform_device s5pc100_device_pdma0 = {
83− .name = "s3c-pl330",
84− .id = 0,
85− .num_resources = ARRAY_SIZE(s5pc100_pdma0_resource),
86− .resource = s5pc100_pdma0_resource,
87− .dev = {
134+struct amba_device s5pc100_device_pdma0 = {
135+ .dev = {
136+ .init_name = "dma-pl330.0",
88137 .dma_mask = &dma_dmamask,
89138 .coherent_dma_mask = DMA_BIT_MASK(32),
90139 .platform_data = &s5pc100_pdma0_pdata,
91140 },
92−};
93−
94−static struct resource s5pc100_pdma1_resource[] = {
95− [0] = {
96− .start = S5PC100_PA_PDMA1,
97− .end = S5PC100_PA_PDMA1 + SZ_4K,
141+ .res = {
142+ .start = S5PC100_PA_PDMA0,
143+ .end = S5PC100_PA_PDMA0 + SZ_4K,
98144 .flags = IORESOURCE_MEM,
99145 },
100− [1] = {
101− .start = IRQ_PDMA1,
102− .end = IRQ_PDMA1,
103− .flags = IORESOURCE_IRQ,
104− },
146+ .irq = {IRQ_PDMA0, NO_IRQ},
147+ .periphid = 0x00041330,
105148 };
106149
107−static struct s3c_pl330_platdata s5pc100_pdma1_pdata = {
108− .peri = {
109− [0] = DMACH_UART0_RX,
110− [1] = DMACH_UART0_TX,
111− [2] = DMACH_UART1_RX,
112− [3] = DMACH_UART1_TX,
113− [4] = DMACH_UART2_RX,
114− [5] = DMACH_UART2_TX,
115− [6] = DMACH_UART3_RX,
116− [7] = DMACH_UART3_TX,
117− [8] = DMACH_IRDA,
118− [9] = DMACH_I2S0_RX,
119− [10] = DMACH_I2S0_TX,
120− [11] = DMACH_I2S0S_TX,
121− [12] = DMACH_I2S1_RX,
122− [13] = DMACH_I2S1_TX,
123− [14] = DMACH_I2S2_RX,
124− [15] = DMACH_I2S2_TX,
125− [16] = DMACH_SPI0_RX,
126− [17] = DMACH_SPI0_TX,
127− [18] = DMACH_SPI1_RX,
128− [19] = DMACH_SPI1_TX,
129− [20] = DMACH_SPI2_RX,
130− [21] = DMACH_SPI2_TX,
131− [22] = DMACH_PCM0_RX,
132− [23] = DMACH_PCM0_TX,
133− [24] = DMACH_PCM1_RX,
134− [25] = DMACH_PCM1_TX,
135− [26] = DMACH_MSM_REQ0,
136− [27] = DMACH_MSM_REQ1,
137− [28] = DMACH_MSM_REQ2,
138− [29] = DMACH_MSM_REQ3,
139− [30] = DMACH_MAX,
140− [31] = DMACH_MAX,
150+struct dma_pl330_peri pdma1_peri[30] = {
151+ {
152+ .peri_id = (u8)DMACH_UART0_RX,
153+ .rqtype = DEVTOMEM,
154+ }, {
155+ .peri_id = (u8)DMACH_UART0_TX,
156+ .rqtype = MEMTODEV,
157+ }, {
158+ .peri_id = (u8)DMACH_UART1_RX,
159+ .rqtype = DEVTOMEM,
160+ }, {
161+ .peri_id = (u8)DMACH_UART1_TX,
162+ .rqtype = MEMTODEV,
163+ }, {
164+ .peri_id = (u8)DMACH_UART2_RX,
165+ .rqtype = DEVTOMEM,
166+ }, {
167+ .peri_id = (u8)DMACH_UART2_TX,
168+ .rqtype = MEMTODEV,
169+ }, {
170+ .peri_id = (u8)DMACH_UART3_RX,
171+ .rqtype = DEVTOMEM,
172+ }, {
173+ .peri_id = (u8)DMACH_UART3_TX,
174+ .rqtype = MEMTODEV,
175+ }, {
176+ .peri_id = DMACH_IRDA,
177+ }, {
178+ .peri_id = (u8)DMACH_I2S0_RX,
179+ .rqtype = DEVTOMEM,
180+ }, {
181+ .peri_id = (u8)DMACH_I2S0_TX,
182+ .rqtype = MEMTODEV,
183+ }, {
184+ .peri_id = (u8)DMACH_I2S0S_TX,
185+ .rqtype = MEMTODEV,
186+ }, {
187+ .peri_id = (u8)DMACH_I2S1_RX,
188+ .rqtype = DEVTOMEM,
189+ }, {
190+ .peri_id = (u8)DMACH_I2S1_TX,
191+ .rqtype = MEMTODEV,
192+ }, {
193+ .peri_id = (u8)DMACH_I2S2_RX,
194+ .rqtype = DEVTOMEM,
195+ }, {
196+ .peri_id = (u8)DMACH_I2S2_TX,
197+ .rqtype = MEMTODEV,
198+ }, {
199+ .peri_id = (u8)DMACH_SPI0_RX,
200+ .rqtype = DEVTOMEM,
201+ }, {
202+ .peri_id = (u8)DMACH_SPI0_TX,
203+ .rqtype = MEMTODEV,
204+ }, {
205+ .peri_id = (u8)DMACH_SPI1_RX,
206+ .rqtype = DEVTOMEM,
207+ }, {
208+ .peri_id = (u8)DMACH_SPI1_TX,
209+ .rqtype = MEMTODEV,
210+ }, {
211+ .peri_id = (u8)DMACH_SPI2_RX,
212+ .rqtype = DEVTOMEM,
213+ }, {
214+ .peri_id = (u8)DMACH_SPI2_TX,
215+ .rqtype = MEMTODEV,
216+ }, {
217+ .peri_id = (u8)DMACH_PCM0_RX,
218+ .rqtype = DEVTOMEM,
219+ }, {
220+ .peri_id = (u8)DMACH_PCM1_TX,
221+ .rqtype = MEMTODEV,
222+ }, {
223+ .peri_id = (u8)DMACH_PCM1_RX,
224+ .rqtype = DEVTOMEM,
225+ }, {
226+ .peri_id = (u8)DMACH_PCM1_TX,
227+ .rqtype = MEMTODEV,
228+ }, {
229+ .peri_id = (u8)DMACH_MSM_REQ0,
230+ }, {
231+ .peri_id = (u8)DMACH_MSM_REQ1,
232+ }, {
233+ .peri_id = (u8)DMACH_MSM_REQ2,
234+ }, {
235+ .peri_id = (u8)DMACH_MSM_REQ3,
141236 },
142237 };
143238
144−static struct platform_device s5pc100_device_pdma1 = {
145− .name = "s3c-pl330",
146− .id = 1,
147− .num_resources = ARRAY_SIZE(s5pc100_pdma1_resource),
148− .resource = s5pc100_pdma1_resource,
149− .dev = {
239+struct dma_pl330_platdata s5pc100_pdma1_pdata = {
240+ .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
241+ .peri = pdma1_peri,
242+};
243+
244+struct amba_device s5pc100_device_pdma1 = {
245+ .dev = {
246+ .init_name = "dma-pl330.1",
150247 .dma_mask = &dma_dmamask,
151248 .coherent_dma_mask = DMA_BIT_MASK(32),
152249 .platform_data = &s5pc100_pdma1_pdata,
153250 },
154−};
155−
156−static struct platform_device *s5pc100_dmacs[] __initdata = {
157− &s5pc100_device_pdma0,
158− &s5pc100_device_pdma1,
251+ .res = {
252+ .start = S5PC100_PA_PDMA1,
253+ .end = S5PC100_PA_PDMA1 + SZ_4K,
254+ .flags = IORESOURCE_MEM,
255+ },
256+ .irq = {IRQ_PDMA1, NO_IRQ},
257+ .periphid = 0x00041330,
159258 };
160259
161260 static int __init s5pc100_dma_init(void)
162261 {
163− platform_add_devices(s5pc100_dmacs, ARRAY_SIZE(s5pc100_dmacs));
262+ amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
164263
165264 return 0;
166265 }
arch/arm/mach-s5pc100/include/mach/dma.h+2−2
@@ -20,7 +20,7 @@ · 19 unmodified lines
2020 #ifndef __MACH_DMA_H
2121 #define __MACH_DMA_H
2222
23−/* This platform uses the common S3C DMA API driver for PL330 */
24−#include <plat/s3c-dma-pl330.h>
23+/* This platform uses the common DMA API driver for PL330 */
24+#include <plat/dma-pl330.h>
2525
2626 #endif /* __MACH_DMA_H */
arch/arm/mach-s5pv210/Kconfig+1−1
@@ -11,7 +11,7 @@ if ARCH_S5PV210 · 10 unmodified lines
1111
1212 config CPU_S5PV210
1313 bool
14− select S3C_PL330_DMA
14+ select SAMSUNG_DMADEV
1515 select S5P_EXT_INT
1616 select S5P_HRT
1717 help
arch/arm/mach-s5pv210/clock.c+8−2
@@ -203,6 +203,11 @@ static struct clk clk_pcmcdclk2 = { · 202 unmodified lines
203203 .name = "pcmcdclk",
204204 };
205205
206+static struct clk dummy_apb_pclk = {
207+ .name = "apb_pclk",
208+ .id = -1,
209+};
210+
206211 static struct clk *clkset_vpllsrc_list[] = {
207212 [0] = &clk_fin_vpll,
208213 [1] = &clk_sclk_hdmi27m,
@@ -289,13 +294,13 @@ static struct clk_ops clk_fout_apll_ops = { · 80 unmodified lines
289294
290295 static struct clk init_clocks_off[] = {
291296 {
292− .name = "pdma",
297+ .name = "dma",
293298 .devname = "s3c-pl330.0",
294299 .parent = &clk_hclk_psys.clk,
295300 .enable = s5pv210_clk_ip0_ctrl,
296301 .ctrlbit = (1 << 3),
297302 }, {
298− .name = "pdma",
303+ .name = "dma",
299304 .devname = "s3c-pl330.1",
300305 .parent = &clk_hclk_psys.clk,
301306 .enable = s5pv210_clk_ip0_ctrl,
@@ -1159,5 +1164,6 @@ void __init s5pv210_register_clocks(void) · 857 unmodified lines
11591164 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
11601165 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
11611166
1167+ s3c24xx_register_clock(&dummy_apb_pclk);
11621168 s3c_pwmclk_init();
11631169 }
arch/arm/mach-s5pv210/dma.c+204−112
@@ -1,4 +1,8 @@
1−/*
1+/* linux/arch/arm/mach-s5pv210/dma.c
2+ *
3+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4+ * http://www.samsung.com
5+ *
26 * Copyright (C) 2010 Samsung Electronics Co. Ltd.
37 * Jaswinder Singh <jassi.brar@samsung.com>
48 *
@@ -17,151 +21,239 @@ · 12 unmodified lines
1721 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1822 */
1923
20−#include <linux/platform_device.h>
2124 #include <linux/dma-mapping.h>
25+#include <linux/amba/bus.h>
26+#include <linux/amba/pl330.h>
2227
28+#include <asm/irq.h>
2329 #include <plat/devs.h>
2430 #include <plat/irqs.h>
2531
2632 #include <mach/map.h>
2733 #include <mach/irqs.h>
28−
29−#include <plat/s3c-pl330-pdata.h>
34+#include <mach/dma.h>
3035
3136 static u64 dma_dmamask = DMA_BIT_MASK(32);
3237
33−static struct resource s5pv210_pdma0_resource[] = {
34− [0] = {
35− .start = S5PV210_PA_PDMA0,
36− .end = S5PV210_PA_PDMA0 + SZ_4K,
37− .flags = IORESOURCE_MEM,
38− },
39− [1] = {
40− .start = IRQ_PDMA0,
41− .end = IRQ_PDMA0,
42− .flags = IORESOURCE_IRQ,
38+struct dma_pl330_peri pdma0_peri[28] = {
39+ {
40+ .peri_id = (u8)DMACH_UART0_RX,
41+ .rqtype = DEVTOMEM,
42+ }, {
43+ .peri_id = (u8)DMACH_UART0_TX,
44+ .rqtype = MEMTODEV,
45+ }, {
46+ .peri_id = (u8)DMACH_UART1_RX,
47+ .rqtype = DEVTOMEM,
48+ }, {
49+ .peri_id = (u8)DMACH_UART1_TX,
50+ .rqtype = MEMTODEV,
51+ }, {
52+ .peri_id = (u8)DMACH_UART2_RX,
53+ .rqtype = DEVTOMEM,
54+ }, {
55+ .peri_id = (u8)DMACH_UART2_TX,
56+ .rqtype = MEMTODEV,
57+ }, {
58+ .peri_id = (u8)DMACH_UART3_RX,
59+ .rqtype = DEVTOMEM,
60+ }, {
61+ .peri_id = (u8)DMACH_UART3_TX,
62+ .rqtype = MEMTODEV,
63+ }, {
64+ .peri_id = DMACH_MAX,
65+ }, {
66+ .peri_id = (u8)DMACH_I2S0_RX,
67+ .rqtype = DEVTOMEM,
68+ }, {
69+ .peri_id = (u8)DMACH_I2S0_TX,
70+ .rqtype = MEMTODEV,
71+ }, {
72+ .peri_id = (u8)DMACH_I2S0S_TX,
73+ .rqtype = MEMTODEV,
74+ }, {
75+ .peri_id = (u8)DMACH_I2S1_RX,
76+ .rqtype = DEVTOMEM,
77+ }, {
78+ .peri_id = (u8)DMACH_I2S1_TX,
79+ .rqtype = MEMTODEV,
80+ }, {
81+ .peri_id = (u8)DMACH_MAX,
82+ }, {
83+ .peri_id = (u8)DMACH_MAX,
84+ }, {
85+ .peri_id = (u8)DMACH_SPI0_RX,
86+ .rqtype = DEVTOMEM,
87+ }, {
88+ .peri_id = (u8)DMACH_SPI0_TX,
89+ .rqtype = MEMTODEV,
90+ }, {
91+ .peri_id = (u8)DMACH_SPI1_RX,
92+ .rqtype = DEVTOMEM,
93+ }, {
94+ .peri_id = (u8)DMACH_SPI1_TX,
95+ .rqtype = MEMTODEV,
96+ }, {
97+ .peri_id = (u8)DMACH_MAX,
98+ }, {
99+ .peri_id = (u8)DMACH_MAX,
100+ }, {
101+ .peri_id = (u8)DMACH_AC97_MICIN,
102+ .rqtype = DEVTOMEM,
103+ }, {
104+ .peri_id = (u8)DMACH_AC97_PCMIN,
105+ .rqtype = DEVTOMEM,
106+ }, {
107+ .peri_id = (u8)DMACH_AC97_PCMOUT,
108+ .rqtype = MEMTODEV,
109+ }, {
110+ .peri_id = (u8)DMACH_MAX,
111+ }, {
112+ .peri_id = (u8)DMACH_PWM,
113+ }, {
114+ .peri_id = (u8)DMACH_SPDIF,
115+ .rqtype = MEMTODEV,
43116 },
44117 };
45118
46−static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
47− .peri = {
48− [0] = DMACH_UART0_RX,
49− [1] = DMACH_UART0_TX,
50− [2] = DMACH_UART1_RX,
51− [3] = DMACH_UART1_TX,
52− [4] = DMACH_UART2_RX,
53− [5] = DMACH_UART2_TX,
54− [6] = DMACH_UART3_RX,
55− [7] = DMACH_UART3_TX,
56− [8] = DMACH_MAX,
57− [9] = DMACH_I2S0_RX,
58− [10] = DMACH_I2S0_TX,
59− [11] = DMACH_I2S0S_TX,
60− [12] = DMACH_I2S1_RX,
61− [13] = DMACH_I2S1_TX,
62− [14] = DMACH_MAX,
63− [15] = DMACH_MAX,
64− [16] = DMACH_SPI0_RX,
65− [17] = DMACH_SPI0_TX,
66− [18] = DMACH_SPI1_RX,
67− [19] = DMACH_SPI1_TX,
68− [20] = DMACH_MAX,
69− [21] = DMACH_MAX,
70− [22] = DMACH_AC97_MICIN,
71− [23] = DMACH_AC97_PCMIN,
72− [24] = DMACH_AC97_PCMOUT,
73− [25] = DMACH_MAX,
74− [26] = DMACH_PWM,
75− [27] = DMACH_SPDIF,
76− [28] = DMACH_MAX,
77− [29] = DMACH_MAX,
78− [30] = DMACH_MAX,
79− [31] = DMACH_MAX,
80− },
119+struct dma_pl330_platdata s5pv210_pdma0_pdata = {
120+ .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
121+ .peri = pdma0_peri,
81122 };
82123
83−static struct platform_device s5pv210_device_pdma0 = {
84− .name = "s3c-pl330",
85− .id = 0,
86− .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
87− .resource = s5pv210_pdma0_resource,
88− .dev = {
124+struct amba_device s5pv210_device_pdma0 = {
125+ .dev = {
126+ .init_name = "dma-pl330.0",
89127 .dma_mask = &dma_dmamask,
90128 .coherent_dma_mask = DMA_BIT_MASK(32),
91129 .platform_data = &s5pv210_pdma0_pdata,
92130 },
93−};
94−
95−static struct resource s5pv210_pdma1_resource[] = {
96− [0] = {
97− .start = S5PV210_PA_PDMA1,
98− .end = S5PV210_PA_PDMA1 + SZ_4K,
131+ .res = {
132+ .start = S5PV210_PA_PDMA0,
133+ .end = S5PV210_PA_PDMA0 + SZ_4K,
99134 .flags = IORESOURCE_MEM,
100135 },
101− [1] = {
102− .start = IRQ_PDMA1,
103− .end = IRQ_PDMA1,
104− .flags = IORESOURCE_IRQ,
105− },
136+ .irq = {IRQ_PDMA0, NO_IRQ},
137+ .periphid = 0x00041330,
106138 };
107139
108−static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
109− .peri = {
110− [0] = DMACH_UART0_RX,
111− [1] = DMACH_UART0_TX,
112− [2] = DMACH_UART1_RX,
113− [3] = DMACH_UART1_TX,
114− [4] = DMACH_UART2_RX,
115− [5] = DMACH_UART2_TX,
116− [6] = DMACH_UART3_RX,
117− [7] = DMACH_UART3_TX,
118− [8] = DMACH_MAX,
119− [9] = DMACH_I2S0_RX,
120− [10] = DMACH_I2S0_TX,
121− [11] = DMACH_I2S0S_TX,
122− [12] = DMACH_I2S1_RX,
123− [13] = DMACH_I2S1_TX,
124− [14] = DMACH_I2S2_RX,
125− [15] = DMACH_I2S2_TX,
126− [16] = DMACH_SPI0_RX,
127− [17] = DMACH_SPI0_TX,
128− [18] = DMACH_SPI1_RX,
129− [19] = DMACH_SPI1_TX,
130− [20] = DMACH_MAX,
131− [21] = DMACH_MAX,
132− [22] = DMACH_PCM0_RX,
133− [23] = DMACH_PCM0_TX,
134− [24] = DMACH_PCM1_RX,
135− [25] = DMACH_PCM1_TX,
136− [26] = DMACH_MSM_REQ0,
137− [27] = DMACH_MSM_REQ1,
138− [28] = DMACH_MSM_REQ2,
139− [29] = DMACH_MSM_REQ3,
140− [30] = DMACH_PCM2_RX,
141− [31] = DMACH_PCM2_TX,
140+struct dma_pl330_peri pdma1_peri[32] = {
141+ {
142+ .peri_id = (u8)DMACH_UART0_RX,
143+ .rqtype = DEVTOMEM,
144+ }, {
145+ .peri_id = (u8)DMACH_UART0_TX,
146+ .rqtype = MEMTODEV,
147+ }, {
148+ .peri_id = (u8)DMACH_UART1_RX,
149+ .rqtype = DEVTOMEM,
150+ }, {
151+ .peri_id = (u8)DMACH_UART1_TX,
152+ .rqtype = MEMTODEV,
153+ }, {
154+ .peri_id = (u8)DMACH_UART2_RX,
155+ .rqtype = DEVTOMEM,
156+ }, {
157+ .peri_id = (u8)DMACH_UART2_TX,
158+ .rqtype = MEMTODEV,
159+ }, {
160+ .peri_id = (u8)DMACH_UART3_RX,
161+ .rqtype = DEVTOMEM,
162+ }, {
163+ .peri_id = (u8)DMACH_UART3_TX,
164+ .rqtype = MEMTODEV,
165+ }, {
166+ .peri_id = DMACH_MAX,
167+ }, {
168+ .peri_id = (u8)DMACH_I2S0_RX,
169+ .rqtype = DEVTOMEM,
170+ }, {
171+ .peri_id = (u8)DMACH_I2S0_TX,
172+ .rqtype = MEMTODEV,
173+ }, {
174+ .peri_id = (u8)DMACH_I2S0S_TX,
175+ .rqtype = MEMTODEV,
176+ }, {
177+ .peri_id = (u8)DMACH_I2S1_RX,
178+ .rqtype = DEVTOMEM,
179+ }, {
180+ .peri_id = (u8)DMACH_I2S1_TX,
181+ .rqtype = MEMTODEV,
182+ }, {
183+ .peri_id = (u8)DMACH_I2S2_RX,
184+ .rqtype = DEVTOMEM,
185+ }, {
186+ .peri_id = (u8)DMACH_I2S2_TX,
187+ .rqtype = MEMTODEV,
188+ }, {
189+ .peri_id = (u8)DMACH_SPI0_RX,
190+ .rqtype = DEVTOMEM,
191+ }, {
192+ .peri_id = (u8)DMACH_SPI0_TX,
193+ .rqtype = MEMTODEV,
194+ }, {
195+ .peri_id = (u8)DMACH_SPI1_RX,
196+ .rqtype = DEVTOMEM,
197+ }, {
198+ .peri_id = (u8)DMACH_SPI1_TX,
199+ .rqtype = MEMTODEV,
200+ }, {
201+ .peri_id = (u8)DMACH_MAX,
202+ }, {
203+ .peri_id = (u8)DMACH_MAX,
204+ }, {
205+ .peri_id = (u8)DMACH_PCM0_RX,
206+ .rqtype = DEVTOMEM,
207+ }, {
208+ .peri_id = (u8)DMACH_PCM0_TX,
209+ .rqtype = MEMTODEV,
210+ }, {
211+ .peri_id = (u8)DMACH_PCM1_RX,
212+ .rqtype = DEVTOMEM,
213+ }, {
214+ .peri_id = (u8)DMACH_PCM1_TX,
215+ .rqtype = MEMTODEV,
216+ }, {
217+ .peri_id = (u8)DMACH_MSM_REQ0,
218+ }, {
219+ .peri_id = (u8)DMACH_MSM_REQ1,
220+ }, {
221+ .peri_id = (u8)DMACH_MSM_REQ2,
222+ }, {
223+ .peri_id = (u8)DMACH_MSM_REQ3,
224+ }, {
225+ .peri_id = (u8)DMACH_PCM2_RX,
226+ .rqtype = DEVTOMEM,
227+ }, {
228+ .peri_id = (u8)DMACH_PCM2_TX,
229+ .rqtype = MEMTODEV,
142230 },
143231 };
144232
145−static struct platform_device s5pv210_device_pdma1 = {
146− .name = "s3c-pl330",
147− .id = 1,
148− .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
149− .resource = s5pv210_pdma1_resource,
150− .dev = {
233+struct dma_pl330_platdata s5pv210_pdma1_pdata = {
234+ .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
235+ .peri = pdma1_peri,
236+};
237+
238+struct amba_device s5pv210_device_pdma1 = {
239+ .dev = {
240+ .init_name = "dma-pl330.1",
151241 .dma_mask = &dma_dmamask,
152242 .coherent_dma_mask = DMA_BIT_MASK(32),
153243 .platform_data = &s5pv210_pdma1_pdata,
154244 },
155−};
156−
157−static struct platform_device *s5pv210_dmacs[] __initdata = {
158− &s5pv210_device_pdma0,
159− &s5pv210_device_pdma1,
245+ .res = {
246+ .start = S5PV210_PA_PDMA1,
247+ .end = S5PV210_PA_PDMA1 + SZ_4K,
248+ .flags = IORESOURCE_MEM,
249+ },
250+ .irq = {IRQ_PDMA1, NO_IRQ},
251+ .periphid = 0x00041330,
160252 };
161253
162254 static int __init s5pv210_dma_init(void)
163255 {
164− platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs));
256+ amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
165257
166258 return 0;
167259 }
arch/arm/mach-s5pv210/include/mach/dma.h+2−2
@@ -20,7 +20,7 @@ · 19 unmodified lines
2020 #ifndef __MACH_DMA_H
2121 #define __MACH_DMA_H
2222
23−/* This platform uses the common S3C DMA API driver for PL330 */
24−#include <plat/s3c-dma-pl330.h>
23+/* This platform uses the common DMA API driver for PL330 */
24+#include <plat/dma-pl330.h>
2525
2626 #endif /* __MACH_DMA_H */
arch/arm/plat-s3c24xx/dma.c+5−5
@@ -1094,14 +1094,14 @@ EXPORT_SYMBOL(s3c2410_dma_config); · 1093 unmodified lines
10941094 *
10951095 * configure the dma source/destination hardware type and address
10961096 *
1097− * source: S3C2410_DMASRC_HW: source is hardware
1098− * S3C2410_DMASRC_MEM: source is memory
1097+ * source: DMA_FROM_DEVICE: source is hardware
1098+ * DMA_TO_DEVICE: source is memory
10991099 *
11001100 * devaddr: physical address of the source
11011101 */
11021102
11031103 int s3c2410_dma_devconfig(enum dma_ch channel,
1104− enum s3c2410_dmasrc source,
1104+ enum dma_data_direction source,
11051105 unsigned long devaddr)
11061106 {
11071107 struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
@@ -1131,7 +1131,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel, · 23 unmodified lines
11311131 hwcfg |= S3C2410_DISRCC_INC;
11321132
11331133 switch (source) {
1134− case S3C2410_DMASRC_HW:
1134+ case DMA_FROM_DEVICE:
11351135 /* source is hardware */
11361136 pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
11371137 __func__, devaddr, hwcfg);
@@ -1142,7 +1142,7 @@ int s3c2410_dma_devconfig(enum dma_ch channel, · 4 unmodified lines
11421142 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
11431143 break;
11441144
1145− case S3C2410_DMASRC_MEM:
1145+ case DMA_TO_DEVICE:
11461146 /* source is memory */
11471147 pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
11481148 __func__, devaddr, hwcfg);
arch/arm/plat-samsung/Kconfig+6−3
@@ -295,11 +295,14 @@ config S3C_DMA · 294 unmodified lines
295295 help
296296 Internal configuration for S3C DMA core
297297
298−config S3C_PL330_DMA
298+config SAMSUNG_DMADEV
299299 bool
300− select PL330
300+ select DMADEVICES
301+ select PL330_DMA if (CPU_EXYNOS4210 || CPU_S5PV210 || CPU_S5PC100 || \
302+ CPU_S5P6450 || CPU_S5P6440)
303+ select ARM_AMBA
301304 help
302− S3C DMA API Driver for PL330 DMAC.
305+ Use DMA device engine for PL330 DMAC.
303306
304307 comment "Power management"
305308
arch/arm/plat-samsung/Makefile+2−2
@@ -62,9 +62,9 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o · 61 unmodified lines
6262
6363 # DMA support
6464
65−obj-$(CONFIG_S3C_DMA) += dma.o
65+obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o
6666
67−obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o
67+obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o
6868
6969 # PM support
7070
arch/arm/plat-samsung/dma-ops.c+131−0
@@ -0,0 +1,131 @@
1+/* linux/arch/arm/plat-samsung/dma-ops.c
2+ *
3+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4+ * http://www.samsung.com
5+ *
6+ * Samsung DMA Operations
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License version 2 as
10+ * published by the Free Software Foundation.
11+ */
12+
13+#include <linux/kernel.h>
14+#include <linux/errno.h>
15+#include <linux/amba/pl330.h>
16+#include <linux/scatterlist.h>
17+
18+#include <mach/dma.h>
19+
20+static inline bool pl330_filter(struct dma_chan *chan, void *param)
21+{
22+ struct dma_pl330_peri *peri = chan->private;
23+ return peri->peri_id == (unsigned)param;
24+}
25+
26+static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
27+ struct samsung_dma_info *info)
28+{
29+ struct dma_chan *chan;
30+ dma_cap_mask_t mask;
31+ struct dma_slave_config slave_config;
32+
33+ dma_cap_zero(mask);
34+ dma_cap_set(info->cap, mask);
35+
36+ chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch);
37+
38+ if (info->direction == DMA_FROM_DEVICE) {
39+ memset(&slave_config, 0, sizeof(struct dma_slave_config));
40+ slave_config.direction = info->direction;
41+ slave_config.src_addr = info->fifo;
42+ slave_config.src_addr_width = info->width;
43+ slave_config.src_maxburst = 1;
44+ dmaengine_slave_config(chan, &slave_config);
45+ } else if (info->direction == DMA_TO_DEVICE) {
46+ memset(&slave_config, 0, sizeof(struct dma_slave_config));
47+ slave_config.direction = info->direction;
48+ slave_config.dst_addr = info->fifo;
49+ slave_config.dst_addr_width = info->width;
50+ slave_config.dst_maxburst = 1;
51+ dmaengine_slave_config(chan, &slave_config);
52+ }
53+
54+ return (unsigned)chan;
55+}
56+
57+static int samsung_dmadev_release(unsigned ch,
58+ struct s3c2410_dma_client *client)
59+{
60+ dma_release_channel((struct dma_chan *)ch);
61+
62+ return 0;
63+}
64+
65+static int samsung_dmadev_prepare(unsigned ch,
66+ struct samsung_dma_prep_info *info)
67+{
68+ struct scatterlist sg;
69+ struct dma_chan *chan = (struct dma_chan *)ch;
70+ struct dma_async_tx_descriptor *desc;
71+
72+ switch (info->cap) {
73+ case DMA_SLAVE:
74+ sg_init_table(&sg, 1);
75+ sg_dma_len(&sg) = info->len;
76+ sg_set_page(&sg, pfn_to_page(PFN_DOWN(info->buf)),
77+ info->len, offset_in_page(info->buf));
78+ sg_dma_address(&sg) = info->buf;
79+
80+ desc = chan->device->device_prep_slave_sg(chan,
81+ &sg, 1, info->direction, DMA_PREP_INTERRUPT);
82+ break;
83+ case DMA_CYCLIC:
84+ desc = chan->device->device_prep_dma_cyclic(chan,
85+ info->buf, info->len, info->period, info->direction);
86+ break;
87+ default:
88+ dev_err(&chan->dev->device, "unsupported format\n");
89+ return -EFAULT;
90+ }
91+
92+ if (!desc) {
93+ dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
94+ return -EFAULT;
95+ }
96+
97+ desc->callback = info->fp;
98+ desc->callback_param = info->fp_param;
99+
100+ dmaengine_submit((struct dma_async_tx_descriptor *)desc);
101+
102+ return 0;
103+}
104+
105+static inline int samsung_dmadev_trigger(unsigned ch)
106+{
107+ dma_async_issue_pending((struct dma_chan *)ch);
108+
109+ return 0;
110+}
111+
112+static inline int samsung_dmadev_flush(unsigned ch)
113+{
114+ return dmaengine_terminate_all((struct dma_chan *)ch);
115+}
116+
117+struct samsung_dma_ops dmadev_ops = {
118+ .request = samsung_dmadev_request,
119+ .release = samsung_dmadev_release,
120+ .prepare = samsung_dmadev_prepare,
121+ .trigger = samsung_dmadev_trigger,
122+ .started = NULL,
123+ .flush = samsung_dmadev_flush,
124+ .stop = samsung_dmadev_flush,
125+};
126+
127+void *samsung_dmadev_get_ops(void)
128+{
129+ return &dmadev_ops;
130+}
131+EXPORT_SYMBOL(samsung_dmadev_get_ops);
arch/arm/plat-samsung/include/plat/dma-ops.h+63−0
@@ -0,0 +1,63 @@
1+/* arch/arm/plat-samsung/include/plat/dma-ops.h
2+ *
3+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4+ * http://www.samsung.com
5+ *
6+ * Samsung DMA support
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License version 2 as
10+ * published by the Free Software Foundation.
11+ */
12+
13+#ifndef __SAMSUNG_DMA_OPS_H_
14+#define __SAMSUNG_DMA_OPS_H_ __FILE__
15+
16+#include <linux/dmaengine.h>
17+
18+struct samsung_dma_prep_info {
19+ enum dma_transaction_type cap;
20+ enum dma_data_direction direction;
21+ dma_addr_t buf;
22+ unsigned long period;
23+ unsigned long len;
24+ void (*fp)(void *data);
25+ void *fp_param;
26+};
27+
28+struct samsung_dma_info {
29+ enum dma_transaction_type cap;
30+ enum dma_data_direction direction;
31+ enum dma_slave_buswidth width;
32+ dma_addr_t fifo;
33+ struct s3c2410_dma_client *client;
34+};
35+
36+struct samsung_dma_ops {
37+ unsigned (*request)(enum dma_ch ch, struct samsung_dma_info *info);
38+ int (*release)(unsigned ch, struct s3c2410_dma_client *client);
39+ int (*prepare)(unsigned ch, struct samsung_dma_prep_info *info);
40+ int (*trigger)(unsigned ch);
41+ int (*started)(unsigned ch);
42+ int (*flush)(unsigned ch);
43+ int (*stop)(unsigned ch);
44+};
45+
46+extern void *samsung_dmadev_get_ops(void);
47+extern void *s3c_dma_get_ops(void);
48+
49+static inline void *__samsung_dma_get_ops(void)
50+{
51+ if (samsung_dma_is_dmadev())
52+ return samsung_dmadev_get_ops();
53+ else
54+ return s3c_dma_get_ops();
55+}
56+
57+/*
58+ * samsung_dma_get_ops
59+ * get the set of samsung dma operations
60+ */
61+#define samsung_dma_get_ops() __samsung_dma_get_ops()
62+
63+#endif /* __SAMSUNG_DMA_OPS_H_ */
arch/arm/plat-samsung/include/plat/dma-pl330.hrenamed from arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h+15−9
@@ -8,11 +8,8 @@ · 7 unmodified lines
88 * (at your option) any later version.
99 */
1010
11−#ifndef __S3C_DMA_PL330_H_
12−#define __S3C_DMA_PL330_H_
13−
14−#define S3C2410_DMAF_AUTOSTART (1 << 0)
15−#define S3C2410_DMAF_CIRCULAR (1 << 1)
11+#ifndef __DMA_PL330_H_
12+#define __DMA_PL330_H_ __FILE__
1613
1714 /*
1815 * PL330 can assign any channel to communicate with
@@ -20,7 +17,7 @@ · 1 unmodified line
2017 * For the sake of consistency across client drivers,
2118 * We keep the channel names unchanged and only add
2219 * missing peripherals are added.
23− * Order is not important since S3C PL330 API driver
20+ * Order is not important since DMA PL330 API driver
2421 * use these just as IDs.
2522 */
2623 enum dma_ch {
@@ -88,11 +85,20 @@ enum dma_ch { · 61 unmodified lines
8885 DMACH_MAX,
8986 };
9087
91−static inline bool s3c_dma_has_circular(void)
88+struct s3c2410_dma_client {
89+ char *name;
90+};
91+
92+static inline bool samsung_dma_has_circular(void)
93+{
94+ return true;
95+}
96+
97+static inline bool samsung_dma_is_dmadev(void)
9298 {
9399 return true;
94100 }
95101
96−#include <plat/dma.h>
102+#include <plat/dma-ops.h>
97103
98−#endif /* __S3C_DMA_PL330_H_ */
104+#endif /* __DMA_PL330_H_ */
arch/arm/plat-samsung/include/plat/dma-s3c24xx.h+1−1
@@ -41,7 +41,7 @@ struct s3c24xx_dma_selection { · 40 unmodified lines
4141
4242 void (*direction)(struct s3c2410_dma_chan *chan,
4343 struct s3c24xx_dma_map *map,
44− enum s3c2410_dmasrc dir);
44+ enum dma_data_direction dir);
4545 };
4646
4747 extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
arch/arm/plat-samsung/include/plat/dma.h+4−6
@@ -10,17 +10,14 @@ · 9 unmodified lines
1010 * published by the Free Software Foundation.
1111 */
1212
13+#include <linux/dma-mapping.h>
14+
1315 enum s3c2410_dma_buffresult {
1416 S3C2410_RES_OK,
1517 S3C2410_RES_ERR,
1618 S3C2410_RES_ABORT
1719 };
1820
19−enum s3c2410_dmasrc {
20− S3C2410_DMASRC_HW, /* source is memory */
21− S3C2410_DMASRC_MEM /* source is hardware */
22−};
23−
2421 /* enum s3c2410_chan_op
2522 *
2623 * operation codes passed to the DMA code by the user, and also used
@@ -112,7 +109,7 @@ extern int s3c2410_dma_config(enum dma_ch channel, int xferunit); · 85 unmodified lines
112109 */
113110
114111 extern int s3c2410_dma_devconfig(enum dma_ch channel,
115− enum s3c2410_dmasrc source, unsigned long devaddr);
112+ enum dma_data_direction source, unsigned long devaddr);
116113
117114 /* s3c2410_dma_getposition
118115 *
@@ -126,3 +123,4 @@ extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn); · 7 unmodified lines
126123 extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn);
127124
128125
126+#include <plat/dma-ops.h>
arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h+0−32
@@ -1,32 +0,0 @@
1−/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
2− *
3− * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4− * Jaswinder Singh <jassi.brar@samsung.com>
5− *
6− * This program is free software; you can redistribute it and/or modify
7− * it under the terms of the GNU General Public License as published by
8− * the Free Software Foundation; either version 2 of the License, or
9− * (at your option) any later version.
10− */
11−
12−#ifndef __S3C_PL330_PDATA_H
13−#define __S3C_PL330_PDATA_H
14−
15−#include <plat/s3c-dma-pl330.h>
16−
17−/*
18− * Every PL330 DMAC has max 32 peripheral interfaces,
19− * of which some may be not be really used in your
20− * DMAC's configuration.
21− * Populate this array of 32 peri i/fs with relevant
22− * channel IDs for used peri i/f and DMACH_MAX for
23− * those unused.
24− *
25− * The platforms just need to provide this info
26− * to the S3C DMA API driver for PL330.
27− */
28−struct s3c_pl330_platdata {
29− enum dma_ch peri[32];
30−};
31−
32−#endif /* __S3C_PL330_PDATA_H */
arch/arm/plat-samsung/s3c-dma-ops.c+130−0
@@ -0,0 +1,130 @@
1+/* linux/arch/arm/plat-samsung/s3c-dma-ops.c
2+ *
3+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4+ * http://www.samsung.com
5+ *
6+ * Samsung S3C-DMA Operations
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License version 2 as
10+ * published by the Free Software Foundation.
11+ */
12+
13+#include <linux/kernel.h>
14+#include <linux/errno.h>
15+#include <linux/slab.h>
16+#include <linux/types.h>
17+
18+#include <mach/dma.h>
19+
20+struct cb_data {
21+ void (*fp) (void *);
22+ void *fp_param;
23+ unsigned ch;
24+ struct list_head node;
25+};
26+
27+static LIST_HEAD(dma_list);
28+
29+static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param,
30+ int size, enum s3c2410_dma_buffresult res)
31+{
32+ struct cb_data *data = param;
33+
34+ data->fp(data->fp_param);
35+}
36+
37+static unsigned s3c_dma_request(enum dma_ch dma_ch,
38+ struct samsung_dma_info *info)
39+{
40+ struct cb_data *data;
41+
42+ if (s3c2410_dma_request(dma_ch, info->client, NULL) < 0) {
43+ s3c2410_dma_free(dma_ch, info->client);
44+ return 0;
45+ }
46+
47+ data = kzalloc(sizeof(struct cb_data), GFP_KERNEL);
48+ data->ch = dma_ch;
49+ list_add_tail(&data->node, &dma_list);
50+
51+ s3c2410_dma_devconfig(dma_ch, info->direction, info->fifo);
52+
53+ if (info->cap == DMA_CYCLIC)
54+ s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
55+
56+ s3c2410_dma_config(dma_ch, info->width);
57+
58+ return (unsigned)dma_ch;
59+}
60+
61+static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client)
62+{
63+ struct cb_data *data;
64+
65+ list_for_each_entry(data, &dma_list, node)
66+ if (data->ch == ch)
67+ break;
68+ list_del(&data->node);
69+
70+ s3c2410_dma_free(ch, client);
71+ kfree(data);
72+
73+ return 0;
74+}
75+
76+static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info)
77+{
78+ struct cb_data *data;
79+ int len = (info->cap == DMA_CYCLIC) ? info->period : info->len;
80+
81+ list_for_each_entry(data, &dma_list, node)
82+ if (data->ch == ch)
83+ break;
84+
85+ if (!data->fp) {
86+ s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb);
87+ data->fp = info->fp;
88+ data->fp_param = info->fp_param;
89+ }
90+
91+ s3c2410_dma_enqueue(ch, (void *)data, info->buf, len);
92+
93+ return 0;
94+}
95+
96+static inline int s3c_dma_trigger(unsigned ch)
97+{
98+ return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START);
99+}
100+
101+static inline int s3c_dma_started(unsigned ch)
102+{
103+ return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED);
104+}
105+
106+static inline int s3c_dma_flush(unsigned ch)
107+{
108+ return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH);
109+}
110+
111+static inline int s3c_dma_stop(unsigned ch)
112+{
113+ return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP);
114+}
115+
116+static struct samsung_dma_ops s3c_dma_ops = {
117+ .request = s3c_dma_request,
118+ .release = s3c_dma_release,
119+ .prepare = s3c_dma_prepare,
120+ .trigger = s3c_dma_trigger,
121+ .started = s3c_dma_started,
122+ .flush = s3c_dma_flush,
123+ .stop = s3c_dma_stop,
124+};
125+
126+void *s3c_dma_get_ops(void)
127+{
128+ return &s3c_dma_ops;
129+}
130+EXPORT_SYMBOL(s3c_dma_get_ops);
arch/arm/plat-samsung/s3c-pl330.c+0−1244
@@ -1,1244 +0,0 @@
1−/* linux/arch/arm/plat-samsung/s3c-pl330.c
2− *
3− * Copyright (C) 2010 Samsung Electronics Co. Ltd.
4− * Jaswinder Singh <jassi.brar@samsung.com>
5− *
6− * This program is free software; you can redistribute it and/or modify
7− * it under the terms of the GNU General Public License as published by
8− * the Free Software Foundation; either version 2 of the License, or
9− * (at your option) any later version.
10− */
11−
12−#include <linux/init.h>
13−#include <linux/module.h>
14−#include <linux/interrupt.h>
15−#include <linux/io.h>
16−#include <linux/slab.h>
17−#include <linux/platform_device.h>
18−#include <linux/clk.h>
19−#include <linux/err.h>
20−
21−#include <asm/hardware/pl330.h>
22−
23−#include <plat/s3c-pl330-pdata.h>
24−
25−/**
26− * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC.
27− * @busy_chan: Number of channels currently busy.
28− * @peri: List of IDs of peripherals this DMAC can work with.
29− * @node: To attach to the global list of DMACs.
30− * @pi: PL330 configuration info for the DMAC.
31− * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
32− * @clk: Pointer of DMAC operation clock.
33− */
34−struct s3c_pl330_dmac {
35− unsigned busy_chan;
36− enum dma_ch *peri;
37− struct list_head node;
38− struct pl330_info *pi;
39− struct kmem_cache *kmcache;
40− struct clk *clk;
41−};
42−
43−/**
44− * struct s3c_pl330_xfer - A request submitted by S3C DMA clients.
45− * @token: Xfer ID provided by the client.
46− * @node: To attach to the list of xfers on a channel.
47− * @px: Xfer for PL330 core.
48− * @chan: Owner channel of this xfer.
49− */
50−struct s3c_pl330_xfer {
51− void *token;
52− struct list_head node;
53− struct pl330_xfer px;
54− struct s3c_pl330_chan *chan;
55−};
56−
57−/**
58− * struct s3c_pl330_chan - Logical channel to communicate with
59− * a Physical peripheral.
60− * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC.
61− * NULL if the channel is available to be acquired.
62− * @id: ID of the peripheral that this channel can communicate with.
63− * @options: Options specified by the client.
64− * @sdaddr: Address provided via s3c2410_dma_devconfig.
65− * @node: To attach to the global list of channels.
66− * @lrq: Pointer to the last submitted pl330_req to PL330 core.
67− * @xfer_list: To manage list of xfers enqueued.
68− * @req: Two requests to communicate with the PL330 engine.
69− * @callback_fn: Callback function to the client.
70− * @rqcfg: Channel configuration for the xfers.
71− * @xfer_head: Pointer to the xfer to be next executed.
72− * @dmac: Pointer to the DMAC that manages this channel, NULL if the
73− * channel is available to be acquired.
74− * @client: Client of this channel. NULL if the
75− * channel is available to be acquired.
76− */
77−struct s3c_pl330_chan {
78− void *pl330_chan_id;
79− enum dma_ch id;
80− unsigned int options;
81− unsigned long sdaddr;
82− struct list_head node;
83− struct pl330_req *lrq;
84− struct list_head xfer_list;
85− struct pl330_req req[2];
86− s3c2410_dma_cbfn_t callback_fn;
87− struct pl330_reqcfg rqcfg;
88− struct s3c_pl330_xfer *xfer_head;
89− struct s3c_pl330_dmac *dmac;
90− struct s3c2410_dma_client *client;
91−};
92−
93−/* All DMACs in the platform */
94−static LIST_HEAD(dmac_list);
95−
96−/* All channels to peripherals in the platform */
97−static LIST_HEAD(chan_list);
98−
99−/*
100− * Since we add resources(DMACs and Channels) to the global pool,
101− * we need to guard access to the resources using a global lock
102− */
103−static DEFINE_SPINLOCK(res_lock);
104−
105−/* Returns the channel with ID 'id' in the chan_list */
106−static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id)
107−{
108− struct s3c_pl330_chan *ch;
109−
110− list_for_each_entry(ch, &chan_list, node)
111− if (ch->id == id)
112− return ch;
113−
114− return NULL;
115−}
116−
117−/* Allocate a new channel with ID 'id' and add to chan_list */
118−static void chan_add(const enum dma_ch id)
119−{
120− struct s3c_pl330_chan *ch = id_to_chan(id);
121−
122− /* Return if the channel already exists */
123− if (ch)
124− return;
125−
126− ch = kmalloc(sizeof(*ch), GFP_KERNEL);
127− /* Return silently to work with other channels */
128− if (!ch)
129− return;
130−
131− ch->id = id;
132− ch->dmac = NULL;
133−
134− list_add_tail(&ch->node, &chan_list);
135−}
136−
137−/* If the channel is not yet acquired by any client */
138−static bool chan_free(struct s3c_pl330_chan *ch)
139−{
140− if (!ch)
141− return false;
142−
143− /* Channel points to some DMAC only when it's acquired */
144− return ch->dmac ? false : true;
145−}
146−
147−/*
148− * Returns 0 is peripheral i/f is invalid or not present on the dmac.
149− * Index + 1, otherwise.
150− */
151−static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id)
152−{
153− enum dma_ch *id = dmac->peri;
154− int i;
155−
156− /* Discount invalid markers */
157− if (ch_id == DMACH_MAX)
158− return 0;
159−
160− for (i = 0; i < PL330_MAX_PERI; i++)
161− if (id[i] == ch_id)
162− return i + 1;
163−
164− return 0;
165−}
166−
167−/* If all channel threads of the DMAC are busy */
168−static inline bool dmac_busy(struct s3c_pl330_dmac *dmac)
169−{
170− struct pl330_info *pi = dmac->pi;
171−
172− return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true;
173−}
174−
175−/*
176− * Returns the number of free channels that
177− * can be handled by this dmac only.
178− */
179−static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac)
180−{
181− enum dma_ch *id = dmac->peri;
182− struct s3c_pl330_dmac *d;
183− struct s3c_pl330_chan *ch;
184− unsigned found, count = 0;
185− enum dma_ch p;
186− int i;
187−
188− for (i = 0; i < PL330_MAX_PERI; i++) {
189− p = id[i];
190− ch = id_to_chan(p);
191−
192− if (p == DMACH_MAX || !chan_free(ch))
193− continue;
194−
195− found = 0;
196− list_for_each_entry(d, &dmac_list, node) {
197− if (d != dmac && iface_of_dmac(d, ch->id)) {
198− found = 1;
199− break;
200− }
201− }
202− if (!found)
203− count++;
204− }
205−
206− return count;
207−}
208−
209−/*
210− * Measure of suitability of 'dmac' handling 'ch'
211− *
212− * 0 indicates 'dmac' can not handle 'ch' either
213− * because it is not supported by the hardware or
214− * because all dmac channels are currently busy.
215− *
216− * >0 vlaue indicates 'dmac' has the capability.
217− * The bigger the value the more suitable the dmac.
218− */
219−#define MAX_SUIT UINT_MAX
220−#define MIN_SUIT 0
221−
222−static unsigned suitablility(struct s3c_pl330_dmac *dmac,
223− struct s3c_pl330_chan *ch)
224−{
225− struct pl330_info *pi = dmac->pi;
226− enum dma_ch *id = dmac->peri;
227− struct s3c_pl330_dmac *d;
228− unsigned s;
229− int i;
230−
231− s = MIN_SUIT;
232− /* If all the DMAC channel threads are busy */
233− if (dmac_busy(dmac))
234− return s;
235−
236− for (i = 0; i < PL330_MAX_PERI; i++)
237− if (id[i] == ch->id)
238− break;
239−
240− /* If the 'dmac' can't talk to 'ch' */
241− if (i == PL330_MAX_PERI)
242− return s;
243−
244− s = MAX_SUIT;
245− list_for_each_entry(d, &dmac_list, node) {
246− /*
247− * If some other dmac can talk to this
248− * peri and has some channel free.
249− */
250− if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) {
251− s = 0;
252− break;
253− }
254− }
255− if (s)
256− return s;
257−
258− s = 100;
259−
260− /* Good if free chans are more, bad otherwise */
261− s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac);
262−
263− return s;
264−}
265−
266−/* More than one DMAC may have capability to transfer data with the
267− * peripheral. This function assigns most suitable DMAC to manage the
268− * channel and hence communicate with the peripheral.
269− */
270−static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch)
271−{
272− struct s3c_pl330_dmac *d, *dmac = NULL;
273− unsigned sn, sl = MIN_SUIT;
274−
275− list_for_each_entry(d, &dmac_list, node) {
276− sn = suitablility(d, ch);
277−
278− if (sn == MAX_SUIT)
279− return d;
280−
281− if (sn > sl)
282− dmac = d;
283− }
284−
285− return dmac;
286−}
287−
288−/* Acquire the channel for peripheral 'id' */
289−static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id)
290−{
291− struct s3c_pl330_chan *ch = id_to_chan(id);
292− struct s3c_pl330_dmac *dmac;
293−
294− /* If the channel doesn't exist or is already acquired */
295− if (!ch || !chan_free(ch)) {
296− ch = NULL;
297− goto acq_exit;
298− }
299−
300− dmac = map_chan_to_dmac(ch);
301− /* If couldn't map */
302− if (!dmac) {
303− ch = NULL;
304− goto acq_exit;
305− }
306−
307− dmac->busy_chan++;
308− ch->dmac = dmac;
309−
310−acq_exit:
311− return ch;
312−}
313−
314−/* Delete xfer from the queue */
315−static inline void del_from_queue(struct s3c_pl330_xfer *xfer)
316−{
317− struct s3c_pl330_xfer *t;
318− struct s3c_pl330_chan *ch;
319− int found;
320−
321− if (!xfer)
322− return;
323−
324− ch = xfer->chan;
325−
326− /* Make sure xfer is in the queue */
327− found = 0;
328− list_for_each_entry(t, &ch->xfer_list, node)
329− if (t == xfer) {
330− found = 1;
331− break;
332− }
333−
334− if (!found)
335− return;
336−
337− /* If xfer is last entry in the queue */
338− if (xfer->node.next == &ch->xfer_list)
339− t = list_entry(ch->xfer_list.next,
340− struct s3c_pl330_xfer, node);
341− else
342− t = list_entry(xfer->node.next,
343− struct s3c_pl330_xfer, node);
344−
345− /* If there was only one node left */
346− if (t == xfer)
347− ch->xfer_head = NULL;
348− else if (ch->xfer_head == xfer)
349− ch->xfer_head = t;
350−
351− list_del(&xfer->node);
352−}
353−
354−/* Provides pointer to the next xfer in the queue.
355− * If CIRCULAR option is set, the list is left intact,
356− * otherwise the xfer is removed from the list.
357− * Forced delete 'pluck' can be set to override the CIRCULAR option.
358− */
359−static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch,
360− int pluck)
361−{
362− struct s3c_pl330_xfer *xfer = ch->xfer_head;
363−
364− if (!xfer)
365− return NULL;
366−
367− /* If xfer is last entry in the queue */
368− if (xfer->node.next == &ch->xfer_list)
369− ch->xfer_head = list_entry(ch->xfer_list.next,
370− struct s3c_pl330_xfer, node);
371− else
372− ch->xfer_head = list_entry(xfer->node.next,
373− struct s3c_pl330_xfer, node);
374−
375− if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR))
376− del_from_queue(xfer);
377−
378− return xfer;
379−}
380−
381−static inline void add_to_queue(struct s3c_pl330_chan *ch,
382− struct s3c_pl330_xfer *xfer, int front)
383−{
384− struct pl330_xfer *xt;
385−
386− /* If queue empty */
387− if (ch->xfer_head == NULL)
388− ch->xfer_head = xfer;
389−
390− xt = &ch->xfer_head->px;
391− /* If the head already submitted (CIRCULAR head) */
392− if (ch->options & S3C2410_DMAF_CIRCULAR &&
393− (xt == ch->req[0].x || xt == ch->req[1].x))
394− ch->xfer_head = xfer;
395−
396− /* If this is a resubmission, it should go at the head */
397− if (front) {
398− ch->xfer_head = xfer;
399− list_add(&xfer->node, &ch->xfer_list);
400− } else {
401− list_add_tail(&xfer->node, &ch->xfer_list);
402− }
403−}
404−
405−static inline void _finish_off(struct s3c_pl330_xfer *xfer,
406− enum s3c2410_dma_buffresult res, int ffree)
407−{
408− struct s3c_pl330_chan *ch;
409−
410− if (!xfer)
411− return;
412−
413− ch = xfer->chan;
414−
415− /* Do callback */
416− if (ch->callback_fn)
417− ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
418−
419− /* Force Free or if buffer is not needed anymore */
420− if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR))
421− kmem_cache_free(ch->dmac->kmcache, xfer);
422−}
423−
424−static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch,
425− struct pl330_req *r)
426−{
427− struct s3c_pl330_xfer *xfer;
428− int ret = 0;
429−
430− /* If already submitted */
431− if (r->x)
432− return 0;
433−
434− xfer = get_from_queue(ch, 0);
435− if (xfer) {
436− r->x = &xfer->px;
437−
438− /* Use max bandwidth for M<->M xfers */
439− if (r->rqtype == MEMTOMEM) {
440− struct pl330_info *pi = xfer->chan->dmac->pi;
441− int burst = 1 << ch->rqcfg.brst_size;
442− u32 bytes = r->x->bytes;
443− int bl;
444−
445− bl = pi->pcfg.data_bus_width / 8;
446− bl *= pi->pcfg.data_buf_dep;
447− bl /= burst;
448−
449− /* src/dst_burst_len can't be more than 16 */
450− if (bl > 16)
451− bl = 16;
452−
453− while (bl > 1) {
454− if (!(bytes % (bl * burst)))
455− break;
456− bl--;
457− }
458−
459− ch->rqcfg.brst_len = bl;
460− } else {
461− ch->rqcfg.brst_len = 1;
462− }
463−
464− ret = pl330_submit_req(ch->pl330_chan_id, r);
465−
466− /* If submission was successful */
467− if (!ret) {
468− ch->lrq = r; /* latest submitted req */
469− return 0;
470− }
471−
472− r->x = NULL;
473−
474− /* If both of the PL330 ping-pong buffers filled */
475− if (ret == -EAGAIN) {
476− dev_err(ch->dmac->pi->dev, "%s:%d!\n",
477− __func__, __LINE__);
478− /* Queue back again */
479− add_to_queue(ch, xfer, 1);
480− ret = 0;
481− } else {
482− dev_err(ch->dmac->pi->dev, "%s:%d!\n",
483− __func__, __LINE__);
484− _finish_off(xfer, S3C2410_RES_ERR, 0);
485− }
486− }
487−
488− return ret;
489−}
490−
491−static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
492− struct pl330_req *r, enum pl330_op_err err)
493−{
494− unsigned long flags;
495− struct s3c_pl330_xfer *xfer;
496− struct pl330_xfer *xl = r->x;
497− enum s3c2410_dma_buffresult res;
498−
499− spin_lock_irqsave(&res_lock, flags);
500−
501− r->x = NULL;
502−
503− s3c_pl330_submit(ch, r);
504−
505− spin_unlock_irqrestore(&res_lock, flags);
506−
507− /* Map result to S3C DMA API */
508− if (err == PL330_ERR_NONE)
509− res = S3C2410_RES_OK;
510− else if (err == PL330_ERR_ABORT)
511− res = S3C2410_RES_ABORT;
512− else
513− res = S3C2410_RES_ERR;
514−
515− /* If last request had some xfer */
516− if (xl) {
517− xfer = container_of(xl, struct s3c_pl330_xfer, px);
518− _finish_off(xfer, res, 0);
519− } else {
520− dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
521− __func__, __LINE__);
522− }
523−}
524−
525−static void s3c_pl330_rq0(void *token, enum pl330_op_err err)
526−{
527− struct pl330_req *r = token;
528− struct s3c_pl330_chan *ch = container_of(r,
529− struct s3c_pl330_chan, req[0]);
530− s3c_pl330_rq(ch, r, err);
531−}
532−
533−static void s3c_pl330_rq1(void *token, enum pl330_op_err err)
534−{
535− struct pl330_req *r = token;
536− struct s3c_pl330_chan *ch = container_of(r,
537− struct s3c_pl330_chan, req[1]);
538− s3c_pl330_rq(ch, r, err);
539−}
540−
541−/* Release an acquired channel */
542−static void chan_release(struct s3c_pl330_chan *ch)
543−{
544− struct s3c_pl330_dmac *dmac;
545−
546− if (chan_free(ch))
547− return;
548−
549− dmac = ch->dmac;
550− ch->dmac = NULL;
551− dmac->busy_chan--;
552−}
553−
554−int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op)
555−{
556− struct s3c_pl330_xfer *xfer;
557− enum pl330_chan_op pl330op;
558− struct s3c_pl330_chan *ch;
559− unsigned long flags;
560− int idx, ret;
561−
562− spin_lock_irqsave(&res_lock, flags);
563−
564− ch = id_to_chan(id);
565−
566− if (!ch || chan_free(ch)) {
567− ret = -EINVAL;
568− goto ctrl_exit;
569− }
570−
571− switch (op) {
572− case S3C2410_DMAOP_START:
573− /* Make sure both reqs are enqueued */
574− idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
575− s3c_pl330_submit(ch, &ch->req[idx]);
576− s3c_pl330_submit(ch, &ch->req[1 - idx]);
577− pl330op = PL330_OP_START;
578− break;
579−
580− case S3C2410_DMAOP_STOP:
581− pl330op = PL330_OP_ABORT;
582− break;
583−
584− case S3C2410_DMAOP_FLUSH:
585− pl330op = PL330_OP_FLUSH;
586− break;
587−
588− case S3C2410_DMAOP_PAUSE:
589− case S3C2410_DMAOP_RESUME:
590− case S3C2410_DMAOP_TIMEOUT:
591− case S3C2410_DMAOP_STARTED:
592− spin_unlock_irqrestore(&res_lock, flags);
593− return 0;
594−
595− default:
596− spin_unlock_irqrestore(&res_lock, flags);
597− return -EINVAL;
598− }
599−
600− ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op);
601−
602− if (pl330op == PL330_OP_START) {
603− spin_unlock_irqrestore(&res_lock, flags);
604− return ret;
605− }
606−
607− idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
608−
609− /* Abort the current xfer */
610− if (ch->req[idx].x) {
611− xfer = container_of(ch->req[idx].x,
612− struct s3c_pl330_xfer, px);
613−
614− /* Drop xfer during FLUSH */
615− if (pl330op == PL330_OP_FLUSH)
616− del_from_queue(xfer);
617−
618− ch->req[idx].x = NULL;
619−
620− spin_unlock_irqrestore(&res_lock, flags);
621− _finish_off(xfer, S3C2410_RES_ABORT,
622− pl330op == PL330_OP_FLUSH ? 1 : 0);
623− spin_lock_irqsave(&res_lock, flags);
624− }
625−
626− /* Flush the whole queue */
627− if (pl330op == PL330_OP_FLUSH) {
628−
629− if (ch->req[1 - idx].x) {
630− xfer = container_of(ch->req[1 - idx].x,
631− struct s3c_pl330_xfer, px);
632−
633− del_from_queue(xfer);
634−
635− ch->req[1 - idx].x = NULL;
636−
637− spin_unlock_irqrestore(&res_lock, flags);
638− _finish_off(xfer, S3C2410_RES_ABORT, 1);
639− spin_lock_irqsave(&res_lock, flags);
640− }
641−
642− /* Finish off the remaining in the queue */
643− xfer = ch->xfer_head;
644− while (xfer) {
645−
646− del_from_queue(xfer);
647−
648− spin_unlock_irqrestore(&res_lock, flags);
649− _finish_off(xfer, S3C2410_RES_ABORT, 1);
650− spin_lock_irqsave(&res_lock, flags);
651−
652− xfer = ch->xfer_head;
653− }
654− }
655−
656−ctrl_exit:
657− spin_unlock_irqrestore(&res_lock, flags);
658−
659− return ret;
660−}
661−EXPORT_SYMBOL(s3c2410_dma_ctrl);
662−
663−int s3c2410_dma_enqueue(enum dma_ch id, void *token,
664− dma_addr_t addr, int size)
665−{
666− struct s3c_pl330_chan *ch;
667− struct s3c_pl330_xfer *xfer;
668− unsigned long flags;
669− int idx, ret = 0;
670−
671− spin_lock_irqsave(&res_lock, flags);
672−
673− ch = id_to_chan(id);
674−
675− /* Error if invalid or free channel */
676− if (!ch || chan_free(ch)) {
677− ret = -EINVAL;
678− goto enq_exit;
679− }
680−
681− /* Error if size is unaligned */
682− if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) {
683− ret = -EINVAL;
684− goto enq_exit;
685− }
686−
687− xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC);
688− if (!xfer) {
689− ret = -ENOMEM;
690− goto enq_exit;
691− }
692−
693− xfer->token = token;
694− xfer->chan = ch;
695− xfer->px.bytes = size;
696− xfer->px.next = NULL; /* Single request */
697−
698− /* For S3C DMA API, direction is always fixed for all xfers */
699− if (ch->req[0].rqtype == MEMTODEV) {
700− xfer->px.src_addr = addr;
701− xfer->px.dst_addr = ch->sdaddr;
702− } else {
703− xfer->px.src_addr = ch->sdaddr;
704− xfer->px.dst_addr = addr;
705− }
706−
707− add_to_queue(ch, xfer, 0);
708−
709− /* Try submitting on either request */
710− idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
711−
712− if (!ch->req[idx].x)
713− s3c_pl330_submit(ch, &ch->req[idx]);
714− else
715− s3c_pl330_submit(ch, &ch->req[1 - idx]);
716−
717− spin_unlock_irqrestore(&res_lock, flags);
718−
719− if (ch->options & S3C2410_DMAF_AUTOSTART)
720− s3c2410_dma_ctrl(id, S3C2410_DMAOP_START);
721−
722− return 0;
723−
724−enq_exit:
725− spin_unlock_irqrestore(&res_lock, flags);
726−
727− return ret;
728−}
729−EXPORT_SYMBOL(s3c2410_dma_enqueue);
730−
731−int s3c2410_dma_request(enum dma_ch id,
732− struct s3c2410_dma_client *client,
733− void *dev)
734−{
735− struct s3c_pl330_dmac *dmac;
736− struct s3c_pl330_chan *ch;
737− unsigned long flags;
738− int ret = 0;
739−
740− spin_lock_irqsave(&res_lock, flags);
741−
742− ch = chan_acquire(id);
743− if (!ch) {
744− ret = -EBUSY;
745− goto req_exit;
746− }
747−
748− dmac = ch->dmac;
749−
750− ch->pl330_chan_id = pl330_request_channel(dmac->pi);
751− if (!ch->pl330_chan_id) {
752− chan_release(ch);
753− ret = -EBUSY;
754− goto req_exit;
755− }
756−
757− ch->client = client;
758− ch->options = 0; /* Clear any option */
759− ch->callback_fn = NULL; /* Clear any callback */
760− ch->lrq = NULL;
761−
762− ch->rqcfg.brst_size = 2; /* Default word size */
763− ch->rqcfg.swap = SWAP_NO;
764− ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */
765− ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */
766− ch->rqcfg.privileged = 0;
767− ch->rqcfg.insnaccess = 0;
768−
769− /* Set invalid direction */
770− ch->req[0].rqtype = DEVTODEV;
771− ch->req[1].rqtype = ch->req[0].rqtype;
772−
773− ch->req[0].cfg = &ch->rqcfg;
774− ch->req[1].cfg = ch->req[0].cfg;
775−
776− ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */
777− ch->req[1].peri = ch->req[0].peri;
778−
779− ch->req[0].token = &ch->req[0];
780− ch->req[0].xfer_cb = s3c_pl330_rq0;
781− ch->req[1].token = &ch->req[1];
782− ch->req[1].xfer_cb = s3c_pl330_rq1;
783−
784− ch->req[0].x = NULL;
785− ch->req[1].x = NULL;
786−
787− /* Reset xfer list */
788− INIT_LIST_HEAD(&ch->xfer_list);
789− ch->xfer_head = NULL;
790−
791−req_exit:
792− spin_unlock_irqrestore(&res_lock, flags);
793−
794− return ret;
795−}
796−EXPORT_SYMBOL(s3c2410_dma_request);
797−
798−int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
799−{
800− struct s3c_pl330_chan *ch;
801− struct s3c_pl330_xfer *xfer;
802− unsigned long flags;
803− int ret = 0;
804− unsigned idx;
805−
806− spin_lock_irqsave(&res_lock, flags);
807−
808− ch = id_to_chan(id);
809−
810− if (!ch || chan_free(ch))
811− goto free_exit;
812−
813− /* Refuse if someone else wanted to free the channel */
814− if (ch->client != client) {
815− ret = -EBUSY;
816− goto free_exit;
817− }
818−
819− /* Stop any active xfer, Flushe the queue and do callbacks */
820− pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH);
821−
822− /* Abort the submitted requests */
823− idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
824−
825− if (ch->req[idx].x) {
826− xfer = container_of(ch->req[idx].x,
827− struct s3c_pl330_xfer, px);
828−
829− ch->req[idx].x = NULL;
830− del_from_queue(xfer);
831−
832− spin_unlock_irqrestore(&res_lock, flags);
833− _finish_off(xfer, S3C2410_RES_ABORT, 1);
834− spin_lock_irqsave(&res_lock, flags);
835− }
836−
837− if (ch->req[1 - idx].x) {
838− xfer = container_of(ch->req[1 - idx].x,
839− struct s3c_pl330_xfer, px);
840−
841− ch->req[1 - idx].x = NULL;
842− del_from_queue(xfer);
843−
844− spin_unlock_irqrestore(&res_lock, flags);
845− _finish_off(xfer, S3C2410_RES_ABORT, 1);
846− spin_lock_irqsave(&res_lock, flags);
847− }
848−
849− /* Pluck and Abort the queued requests in order */
850− do {
851− xfer = get_from_queue(ch, 1);
852−
853− spin_unlock_irqrestore(&res_lock, flags);
854− _finish_off(xfer, S3C2410_RES_ABORT, 1);
855− spin_lock_irqsave(&res_lock, flags);
856− } while (xfer);
857−
858− ch->client = NULL;
859−
860− pl330_release_channel(ch->pl330_chan_id);
861−
862− ch->pl330_chan_id = NULL;
863−
864− chan_release(ch);
865−
866−free_exit:
867− spin_unlock_irqrestore(&res_lock, flags);
868−
869− return ret;
870−}
871−EXPORT_SYMBOL(s3c2410_dma_free);
872−
873−int s3c2410_dma_config(enum dma_ch id, int xferunit)
874−{
875− struct s3c_pl330_chan *ch;
876− struct pl330_info *pi;
877− unsigned long flags;
878− int i, dbwidth, ret = 0;
879−
880− spin_lock_irqsave(&res_lock, flags);
881−
882− ch = id_to_chan(id);
883−
884− if (!ch || chan_free(ch)) {
885− ret = -EINVAL;
886− goto cfg_exit;
887− }
888−
889− pi = ch->dmac->pi;
890− dbwidth = pi->pcfg.data_bus_width / 8;
891−
892− /* Max size of xfer can be pcfg.data_bus_width */
893− if (xferunit > dbwidth) {
894− ret = -EINVAL;
895− goto cfg_exit;
896− }
897−
898− i = 0;
899− while (xferunit != (1 << i))
900− i++;
901−
902− /* If valid value */
903− if (xferunit == (1 << i))
904− ch->rqcfg.brst_size = i;
905− else
906− ret = -EINVAL;
907−
908−cfg_exit:
909− spin_unlock_irqrestore(&res_lock, flags);
910−
911− return ret;
912−}
913−EXPORT_SYMBOL(s3c2410_dma_config);
914−
915−/* Options that are supported by this driver */
916−#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART)
917−
918−int s3c2410_dma_setflags(enum dma_ch id, unsigned int options)
919−{
920− struct s3c_pl330_chan *ch;
921− unsigned long flags;
922− int ret = 0;
923−
924− spin_lock_irqsave(&res_lock, flags);
925−
926− ch = id_to_chan(id);
927−
928− if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS))
929− ret = -EINVAL;
930− else
931− ch->options = options;
932−
933− spin_unlock_irqrestore(&res_lock, flags);
934−
935− return 0;
936−}
937−EXPORT_SYMBOL(s3c2410_dma_setflags);
938−
939−int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn)
940−{
941− struct s3c_pl330_chan *ch;
942− unsigned long flags;
943− int ret = 0;
944−
945− spin_lock_irqsave(&res_lock, flags);
946−
947− ch = id_to_chan(id);
948−
949− if (!ch || chan_free(ch))
950− ret = -EINVAL;
951− else
952− ch->callback_fn = rtn;
953−
954− spin_unlock_irqrestore(&res_lock, flags);
955−
956− return ret;
957−}
958−EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
959−
960−int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
961− unsigned long address)
962−{
963− struct s3c_pl330_chan *ch;
964− unsigned long flags;
965− int ret = 0;
966−
967− spin_lock_irqsave(&res_lock, flags);
968−
969− ch = id_to_chan(id);
970−
971− if (!ch || chan_free(ch)) {
972− ret = -EINVAL;
973− goto devcfg_exit;
974− }
975−
976− switch (source) {
977− case S3C2410_DMASRC_HW: /* P->M */
978− ch->req[0].rqtype = DEVTOMEM;
979− ch->req[1].rqtype = DEVTOMEM;
980− ch->rqcfg.src_inc = 0;
981− ch->rqcfg.dst_inc = 1;
982− break;
983− case S3C2410_DMASRC_MEM: /* M->P */
984− ch->req[0].rqtype = MEMTODEV;
985− ch->req[1].rqtype = MEMTODEV;
986− ch->rqcfg.src_inc = 1;
987− ch->rqcfg.dst_inc = 0;
988− break;
989− default:
990− ret = -EINVAL;
991− goto devcfg_exit;
992− }
993−
994− ch->sdaddr = address;
995−
996−devcfg_exit:
997− spin_unlock_irqrestore(&res_lock, flags);
998−
999− return ret;
1000−}
1001−EXPORT_SYMBOL(s3c2410_dma_devconfig);
1002−
1003−int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst)
1004−{
1005− struct s3c_pl330_chan *ch = id_to_chan(id);
1006− struct pl330_chanstatus status;
1007− int ret;
1008−
1009− if (!ch || chan_free(ch))
1010− return -EINVAL;
1011−
1012− ret = pl330_chan_status(ch->pl330_chan_id, &status);
1013− if (ret < 0)
1014− return ret;
1015−
1016− *src = status.src_addr;
1017− *dst = status.dst_addr;
1018−
1019− return 0;
1020−}
1021−EXPORT_SYMBOL(s3c2410_dma_getposition);
1022−
1023−static irqreturn_t pl330_irq_handler(int irq, void *data)
1024−{
1025− if (pl330_update(data))
1026− return IRQ_HANDLED;
1027− else
1028− return IRQ_NONE;
1029−}
1030−
1031−static int pl330_probe(struct platform_device *pdev)
1032−{
1033− struct s3c_pl330_dmac *s3c_pl330_dmac;
1034− struct s3c_pl330_platdata *pl330pd;
1035− struct pl330_info *pl330_info;
1036− struct resource *res;
1037− int i, ret, irq;
1038−
1039− pl330pd = pdev->dev.platform_data;
1040−
1041− /* Can't do without the list of _32_ peripherals */
1042− if (!pl330pd || !pl330pd->peri) {
1043− dev_err(&pdev->dev, "platform data missing!\n");
1044− return -ENODEV;
1045− }
1046−
1047− pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL);
1048− if (!pl330_info)
1049− return -ENOMEM;
1050−
1051− pl330_info->pl330_data = NULL;
1052− pl330_info->dev = &pdev->dev;
1053−
1054− res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1055− if (!res) {
1056− ret = -ENODEV;
1057− goto probe_err1;
1058− }
1059−
1060− request_mem_region(res->start, resource_size(res), pdev->name);
1061−
1062− pl330_info->base = ioremap(res->start, resource_size(res));
1063− if (!pl330_info->base) {
1064− ret = -ENXIO;
1065− goto probe_err2;
1066− }
1067−
1068− irq = platform_get_irq(pdev, 0);
1069− if (irq < 0) {
1070− ret = irq;
1071− goto probe_err3;
1072− }
1073−
1074− ret = request_irq(irq, pl330_irq_handler, 0,
1075− dev_name(&pdev->dev), pl330_info);
1076− if (ret)
1077− goto probe_err4;
1078−
1079− /* Allocate a new DMAC */
1080− s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
1081− if (!s3c_pl330_dmac) {
1082− ret = -ENOMEM;
1083− goto probe_err5;
1084− }
1085−
1086− /* Get operation clock and enable it */
1087− s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
1088− if (IS_ERR(s3c_pl330_dmac->clk)) {
1089− dev_err(&pdev->dev, "Cannot get operation clock.\n");
1090− ret = -EINVAL;
1091− goto probe_err6;
1092− }
1093− clk_enable(s3c_pl330_dmac->clk);
1094−
1095− ret = pl330_add(pl330_info);
1096− if (ret)
1097− goto probe_err7;
1098−
1099− /* Hook the info */
1100− s3c_pl330_dmac->pi = pl330_info;
1101−
1102− /* No busy channels */
1103− s3c_pl330_dmac->busy_chan = 0;
1104−
1105− s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev),
1106− sizeof(struct s3c_pl330_xfer), 0, 0, NULL);
1107−
1108− if (!s3c_pl330_dmac->kmcache) {
1109− ret = -ENOMEM;
1110− goto probe_err8;
1111− }
1112−
1113− /* Get the list of peripherals */
1114− s3c_pl330_dmac->peri = pl330pd->peri;
1115−
1116− /* Attach to the list of DMACs */
1117− list_add_tail(&s3c_pl330_dmac->node, &dmac_list);
1118−
1119− /* Create a channel for each peripheral in the DMAC
1120− * that is, if it doesn't already exist
1121− */
1122− for (i = 0; i < PL330_MAX_PERI; i++)
1123− if (s3c_pl330_dmac->peri[i] != DMACH_MAX)
1124− chan_add(s3c_pl330_dmac->peri[i]);
1125−
1126− printk(KERN_INFO
1127− "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name);
1128− printk(KERN_INFO
1129− "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
1130− pl330_info->pcfg.data_buf_dep,
1131− pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
1132− pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
1133−
1134− return 0;
1135−
1136−probe_err8:
1137− pl330_del(pl330_info);
1138−probe_err7:
1139− clk_disable(s3c_pl330_dmac->clk);
1140− clk_put(s3c_pl330_dmac->clk);
1141−probe_err6:
1142− kfree(s3c_pl330_dmac);
1143−probe_err5:
1144− free_irq(irq, pl330_info);
1145−probe_err4:
1146−probe_err3:
1147− iounmap(pl330_info->base);
1148−probe_err2:
1149− release_mem_region(res->start, resource_size(res));
1150−probe_err1:
1151− kfree(pl330_info);
1152−
1153− return ret;
1154−}
1155−
1156−static int pl330_remove(struct platform_device *pdev)
1157−{
1158− struct s3c_pl330_dmac *dmac, *d;
1159− struct s3c_pl330_chan *ch;
1160− unsigned long flags;
1161− int del, found;
1162−
1163− if (!pdev->dev.platform_data)
1164− return -EINVAL;
1165−
1166− spin_lock_irqsave(&res_lock, flags);
1167−
1168− found = 0;
1169− list_for_each_entry(d, &dmac_list, node)
1170− if (d->pi->dev == &pdev->dev) {
1171− found = 1;
1172− break;
1173− }
1174−
1175− if (!found) {
1176− spin_unlock_irqrestore(&res_lock, flags);
1177− return 0;
1178− }
1179−
1180− dmac = d;
1181−
1182− /* Remove all Channels that are managed only by this DMAC */
1183− list_for_each_entry(ch, &chan_list, node) {
1184−
1185− /* Only channels that are handled by this DMAC */
1186− if (iface_of_dmac(dmac, ch->id))
1187− del = 1;
1188− else
1189− continue;
1190−
1191− /* Don't remove if some other DMAC has it too */
1192− list_for_each_entry(d, &dmac_list, node)
1193− if (d != dmac && iface_of_dmac(d, ch->id)) {
1194− del = 0;
1195− break;
1196− }
1197−
1198− if (del) {
1199− spin_unlock_irqrestore(&res_lock, flags);
1200− s3c2410_dma_free(ch->id, ch->client);
1201− spin_lock_irqsave(&res_lock, flags);
1202− list_del(&ch->node);
1203− kfree(ch);
1204− }
1205− }
1206−
1207− /* Disable operation clock */
1208− clk_disable(dmac->clk);
1209− clk_put(dmac->clk);
1210−
1211− /* Remove the DMAC */
1212− list_del(&dmac->node);
1213− kfree(dmac);
1214−
1215− spin_unlock_irqrestore(&res_lock, flags);
1216−
1217− return 0;
1218−}
1219−
1220−static struct platform_driver pl330_driver = {
1221− .driver = {
1222− .owner = THIS_MODULE,
1223− .name = "s3c-pl330",
1224− },
1225− .probe = pl330_probe,
1226− .remove = pl330_remove,
1227−};
1228−
1229−static int __init pl330_init(void)
1230−{
1231− return platform_driver_register(&pl330_driver);
1232−}
1233−module_init(pl330_init);
1234−
1235−static void __exit pl330_exit(void)
1236−{
1237− platform_driver_unregister(&pl330_driver);
1238− return;
1239−}
1240−module_exit(pl330_exit);
1241−
1242−MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
1243−MODULE_DESCRIPTION("Driver for PL330 DMA Controller");
1244−MODULE_LICENSE("GPL");
drivers/dma/Kconfig+2−1
@@ -193,7 +193,8 @@ config ARCH_HAS_ASYNC_TX_FIND_CHANNEL · 192 unmodified lines
193193 config PL330_DMA
194194 tristate "DMA API Driver for PL330"
195195 select DMA_ENGINE
196− depends on PL330
196+ depends on ARM_AMBA
197+ select PL330
197198 help
198199 Select if your platform has one or more PL330 DMACs.
199200 You need to provide platform specific settings via
drivers/dma/amba-pl08x.c+316−324
@@ -66,32 +66,29 @@ · 65 unmodified lines
6666 * after the final transfer signalled by LBREQ or LSREQ. The DMAC
6767 * will then move to the next LLI entry.
6868 *
69− * Only the former works sanely with scatter lists, so we only implement
70− * the DMAC flow control method. However, peripherals which use the LBREQ
71− * and LSREQ signals (eg, MMCI) are unable to use this mode, which through
72− * these hardware restrictions prevents them from using scatter DMA.
73− *
7469 * Global TODO:
7570 * - Break out common code from arch/arm/mach-s3c64xx and share
7671 */
77−#include <linux/device.h>
78−#include <linux/init.h>
79−#include <linux/module.h>
80−#include <linux/interrupt.h>
81−#include <linux/slab.h>
82−#include <linux/delay.h>
83−#include <linux/dma-mapping.h>
84−#include <linux/dmapool.h>
85−#include <linux/dmaengine.h>
8672 #include <linux/amba/bus.h>
8773 #include <linux/amba/pl08x.h>
8874 #include <linux/debugfs.h>
75+#include <linux/delay.h>
76+#include <linux/device.h>
77+#include <linux/dmaengine.h>
78+#include <linux/dmapool.h>
79+#include <linux/dma-mapping.h>
80+#include <linux/init.h>
81+#include <linux/interrupt.h>
82+#include <linux/module.h>
83+#include <linux/pm_runtime.h>
8984 #include <linux/seq_file.h>
90−
85+#include <linux/slab.h>
9186 #include <asm/hardware/pl080.h>
9287
9388 #define DRIVER_NAME "pl08xdmac"
9489
90+static struct amba_driver pl08x_amba_driver;
91+
9592 /**
9693 * struct vendor_data - vendor-specific config parameters for PL08x derivatives
9794 * @channels: the number of channels available in this variant
@@ -126,7 +123,8 @@ struct pl08x_lli { · 28 unmodified lines
126123 * @phy_chans: array of data for the physical channels
127124 * @pool: a pool for the LLI descriptors
128125 * @pool_ctr: counter of LLIs in the pool
129− * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI fetches
126+ * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI
127+ * fetches
130128 * @mem_buses: set to indicate memory transfers on AHB2.
131129 * @lock: a spinlock for this struct
132130 */
@@ -149,14 +147,6 @@ struct pl08x_driver_data { · 16 unmodified lines
149147 * PL08X specific defines
150148 */
151149
152−/*
153− * Memory boundaries: the manual for PL08x says that the controller
154− * cannot read past a 1KiB boundary, so these defines are used to
155− * create transfer LLIs that do not cross such boundaries.
156− */
157−#define PL08X_BOUNDARY_SHIFT (10) /* 1KB 0x400 */
158−#define PL08X_BOUNDARY_SIZE (1 << PL08X_BOUNDARY_SHIFT)
159−
160150 /* Size (bytes) of each LLI buffer allocated for one transfer */
161151 # define PL08X_LLI_TSFR_SIZE 0x2000
162152
@@ -272,7 +262,6 @@ static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) · 109 unmodified lines
272262 writel(val, ch->base + PL080_CH_CONFIG);
273263 }
274264
275−
276265 /*
277266 * pl08x_terminate_phy_chan() stops the channel, clears the FIFO and
278267 * clears any pending interrupt status. This should not be used for
@@ -363,7 +352,9 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan) · 84 unmodified lines
363352 if (!list_empty(&plchan->pend_list)) {
364353 struct pl08x_txd *txdi;
365354 list_for_each_entry(txdi, &plchan->pend_list, node) {
366− bytes += txdi->len;
355+ struct pl08x_sg *dsg;
356+ list_for_each_entry(dsg, &txd->dsg_list, node)
357+ bytes += dsg->len;
367358 }
368359 }
369360
@@ -407,6 +398,7 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x, · 37 unmodified lines
407398 return NULL;
408399 }
409400
401+ pm_runtime_get_sync(&pl08x->adev->dev);
410402 return ch;
411403 }
412404
@@ -420,6 +412,8 @@ static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x, · 7 unmodified lines
420412 /* Stop the channel and clear its interrupts */
421413 pl08x_terminate_phy_chan(pl08x, ch);
422414
415+ pm_runtime_put(&pl08x->adev->dev);
416+
423417 /* Mark it as free */
424418 ch->serving = NULL;
425419 spin_unlock_irqrestore(&ch->lock, flags);
@@ -499,36 +493,30 @@ struct pl08x_lli_build_data { · 73 unmodified lines
499493 };
500494
501495 /*
502− * Autoselect a master bus to use for the transfer this prefers the
503− * destination bus if both available if fixed address on one bus the
504− * other will be chosen
496+ * Autoselect a master bus to use for the transfer. Slave will be the chosen as
497+ * victim in case src & dest are not similarly aligned. i.e. If after aligning
498+ * masters address with width requirements of transfer (by sending few byte by
499+ * byte data), slave is still not aligned, then its width will be reduced to
500+ * BYTE.
501+ * - prefers the destination bus if both available
502+ * - prefers bus with fixed address (i.e. peripheral)
505503 */
506504 static void pl08x_choose_master_bus(struct pl08x_lli_build_data *bd,
507505 struct pl08x_bus_data **mbus, struct pl08x_bus_data **sbus, u32 cctl)
508506 {
509507 if (!(cctl & PL080_CONTROL_DST_INCR)) {
510− *mbus = &bd->srcbus;
511− *sbus = &bd->dstbus;
512− } else if (!(cctl & PL080_CONTROL_SRC_INCR)) {
513508 *mbus = &bd->dstbus;
514509 *sbus = &bd->srcbus;
510+ } else if (!(cctl & PL080_CONTROL_SRC_INCR)) {
511+ *mbus = &bd->srcbus;
512+ *sbus = &bd->dstbus;
515513 } else {
516− if (bd->dstbus.buswidth == 4) {
514+ if (bd->dstbus.buswidth >= bd->srcbus.buswidth) {
517515 *mbus = &bd->dstbus;
518516 *sbus = &bd->srcbus;
519− } else if (bd->srcbus.buswidth == 4) {
520− *mbus = &bd->srcbus;
521− *sbus = &bd->dstbus;
522− } else if (bd->dstbus.buswidth == 2) {
523− *mbus = &bd->dstbus;
524− *sbus = &bd->srcbus;
525− } else if (bd->srcbus.buswidth == 2) {
517+ } else {
526518 *mbus = &bd->srcbus;
527519 *sbus = &bd->dstbus;
528− } else {
529− /* bd->srcbus.buswidth == 1 */
530− *mbus = &bd->dstbus;
531− *sbus = &bd->srcbus;
532520 }
533521 }
534522 }
@@ -547,7 +535,8 @@ static void pl08x_fill_lli_for_desc(struct pl08x_lli_build_data *bd, · 12 unmodified lines
547535 llis_va[num_llis].cctl = cctl;
548536 llis_va[num_llis].src = bd->srcbus.addr;
549537 llis_va[num_llis].dst = bd->dstbus.addr;
550− llis_va[num_llis].lli = llis_bus + (num_llis + 1) * sizeof(struct pl08x_lli);
538+ llis_va[num_llis].lli = llis_bus + (num_llis + 1) *
539+ sizeof(struct pl08x_lli);
551540 llis_va[num_llis].lli |= bd->lli_bus;
552541
553542 if (cctl & PL080_CONTROL_SRC_INCR)
@@ -560,16 +549,12 @@ static void pl08x_fill_lli_for_desc(struct pl08x_lli_build_data *bd, · 6 unmodified lines
560549 bd->remainder -= len;
561550 }
562551
563−/*
564− * Return number of bytes to fill to boundary, or len.
565− * This calculation works for any value of addr.
566− */
567−static inline size_t pl08x_pre_boundary(u32 addr, size_t len)
552+static inline void prep_byte_width_lli(struct pl08x_lli_build_data *bd,
553+ u32 *cctl, u32 len, int num_llis, size_t *total_bytes)
568554 {
569− size_t boundary_len = PL08X_BOUNDARY_SIZE -
570− (addr & (PL08X_BOUNDARY_SIZE - 1));
571−
572− return min(boundary_len, len);
555+ *cctl = pl08x_cctl_bits(*cctl, 1, 1, len);
556+ pl08x_fill_lli_for_desc(bd, num_llis, len, *cctl);
557+ (*total_bytes) += len;
573558 }
574559
575560 /*
@@ -583,13 +568,12 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, · 7 unmodified lines
583568 struct pl08x_bus_data *mbus, *sbus;
584569 struct pl08x_lli_build_data bd;
585570 int num_llis = 0;
586− u32 cctl;
587− size_t max_bytes_per_lli;
588− size_t total_bytes = 0;
571+ u32 cctl, early_bytes = 0;
572+ size_t max_bytes_per_lli, total_bytes;
589573 struct pl08x_lli *llis_va;
574+ struct pl08x_sg *dsg;
590575
591− txd->llis_va = dma_pool_alloc(pl08x->pool, GFP_NOWAIT,
592− &txd->llis_bus);
576+ txd->llis_va = dma_pool_alloc(pl08x->pool, GFP_NOWAIT, &txd->llis_bus);
593577 if (!txd->llis_va) {
594578 dev_err(&pl08x->adev->dev, "%s no memory for llis\n", __func__);
595579 return 0;
@@ -597,13 +581,9 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, · 1 unmodified line
597581
598582 pl08x->pool_ctr++;
599583
600− /* Get the default CCTL */
601− cctl = txd->cctl;
602−
603584 bd.txd = txd;
604− bd.srcbus.addr = txd->src_addr;
605− bd.dstbus.addr = txd->dst_addr;
606585 bd.lli_bus = (pl08x->lli_buses & PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0;
586+ cctl = txd->cctl;
607587
608588 /* Find maximum width of the source bus */
609589 bd.srcbus.maxwidth =
@@ -615,215 +595,179 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, · 5 unmodified lines
615595 pl08x_get_bytes_for_cctl((cctl & PL080_CONTROL_DWIDTH_MASK) >>
616596 PL080_CONTROL_DWIDTH_SHIFT);
617597
618− /* Set up the bus widths to the maximum */
619− bd.srcbus.buswidth = bd.srcbus.maxwidth;
620− bd.dstbus.buswidth = bd.dstbus.maxwidth;
598+ list_for_each_entry(dsg, &txd->dsg_list, node) {
599+ total_bytes = 0;
600+ cctl = txd->cctl;
621601
622− /*
623− * Bytes transferred == tsize * MIN(buswidths), not max(buswidths)
624− */
625− max_bytes_per_lli = min(bd.srcbus.buswidth, bd.dstbus.buswidth) *
626− PL080_CONTROL_TRANSFER_SIZE_MASK;
602+ bd.srcbus.addr = dsg->src_addr;
603+ bd.dstbus.addr = dsg->dst_addr;
604+ bd.remainder = dsg->len;
605+ bd.srcbus.buswidth = bd.srcbus.maxwidth;
606+ bd.dstbus.buswidth = bd.dstbus.maxwidth;
627607
628− /* We need to count this down to zero */
629− bd.remainder = txd->len;
608+ pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl);
630609
631− /*
632− * Choose bus to align to
633− * - prefers destination bus if both available
634− * - if fixed address on one bus chooses other
635− */
636− pl08x_choose_master_bus(&bd, &mbus, &sbus, cctl);
637−
638− dev_vdbg(&pl08x->adev->dev, "src=0x%08x%s/%u dst=0x%08x%s/%u len=%zu llimax=%zu\n",
639− bd.srcbus.addr, cctl & PL080_CONTROL_SRC_INCR ? "+" : "",
640− bd.srcbus.buswidth,
641− bd.dstbus.addr, cctl & PL080_CONTROL_DST_INCR ? "+" : "",
642− bd.dstbus.buswidth,
643− bd.remainder, max_bytes_per_lli);
644− dev_vdbg(&pl08x->adev->dev, "mbus=%s sbus=%s\n",
645− mbus == &bd.srcbus ? "src" : "dst",
646− sbus == &bd.srcbus ? "src" : "dst");
647−
648− if (txd->len < mbus->buswidth) {
649− /* Less than a bus width available - send as single bytes */
650− while (bd.remainder) {
651− dev_vdbg(&pl08x->adev->dev,
652− "%s single byte LLIs for a transfer of "
653− "less than a bus width (remain 0x%08x)\n",
654− __func__, bd.remainder);
655− cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
656− pl08x_fill_lli_for_desc(&bd, num_llis++, 1, cctl);
657− total_bytes++;
658− }
659− } else {
660− /* Make one byte LLIs until master bus is aligned */
661− while ((mbus->addr) % (mbus->buswidth)) {
662− dev_vdbg(&pl08x->adev->dev,
663− "%s adjustment lli for less than bus width "
664− "(remain 0x%08x)\n",
665− __func__, bd.remainder);
666− cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
667− pl08x_fill_lli_for_desc(&bd, num_llis++, 1, cctl);
668− total_bytes++;
669− }
610+ dev_vdbg(&pl08x->adev->dev, "src=0x%08x%s/%u dst=0x%08x%s/%u len=%zu\n",
611+ bd.srcbus.addr, cctl & PL080_CONTROL_SRC_INCR ? "+" : "",
612+ bd.srcbus.buswidth,
613+ bd.dstbus.addr, cctl & PL080_CONTROL_DST_INCR ? "+" : "",
614+ bd.dstbus.buswidth,
615+ bd.remainder);
616+ dev_vdbg(&pl08x->adev->dev, "mbus=%s sbus=%s\n",
617+ mbus == &bd.srcbus ? "src" : "dst",
618+ sbus == &bd.srcbus ? "src" : "dst");
670619
671620 /*
672− * Master now aligned
673− * - if slave is not then we must set its width down
621+ * Zero length is only allowed if all these requirements are
622+ * met:
623+ * - flow controller is peripheral.
624+ * - src.addr is aligned to src.width
625+ * - dst.addr is aligned to dst.width
626+ *
627+ * sg_len == 1 should be true, as there can be two cases here:
628+ *
629+ * - Memory addresses are contiguous and are not scattered.
630+ * Here, Only one sg will be passed by user driver, with
631+ * memory address and zero length. We pass this to controller
632+ * and after the transfer it will receive the last burst
633+ * request from peripheral and so transfer finishes.
634+ *
635+ * - Memory addresses are scattered and are not contiguous.
636+ * Here, Obviously as DMA controller doesn't know when a lli's
637+ * transfer gets over, it can't load next lli. So in this
638+ * case, there has to be an assumption that only one lli is
639+ * supported. Thus, we can't have scattered addresses.
674640 */
675− if (sbus->addr % sbus->buswidth) {
676− dev_dbg(&pl08x->adev->dev,
677− "%s set down bus width to one byte\n",
678− __func__);
641+ if (!bd.remainder) {
642+ u32 fc = (txd->ccfg & PL080_CONFIG_FLOW_CONTROL_MASK) >>
643+ PL080_CONFIG_FLOW_CONTROL_SHIFT;
644+ if (!((fc >= PL080_FLOW_SRC2DST_DST) &&
645+ (fc <= PL080_FLOW_SRC2DST_SRC))) {
646+ dev_err(&pl08x->adev->dev, "%s sg len can't be zero",
647+ __func__);
648+ return 0;
649+ }
650+
651+ if ((bd.srcbus.addr % bd.srcbus.buswidth) ||
652+ (bd.srcbus.addr % bd.srcbus.buswidth)) {
653+ dev_err(&pl08x->adev->dev,
654+ "%s src & dst address must be aligned to src"
655+ " & dst width if peripheral is flow controller",
656+ __func__);
657+ return 0;
658+ }
679659
680− sbus->buswidth = 1;
660+ cctl = pl08x_cctl_bits(cctl, bd.srcbus.buswidth,
661+ bd.dstbus.buswidth, 0);
662+ pl08x_fill_lli_for_desc(&bd, num_llis++, 0, cctl);
663+ break;
681664 }
682665
683666 /*
684− * Make largest possible LLIs until less than one bus
685− * width left
667+ * Send byte by byte for following cases
668+ * - Less than a bus width available
669+ * - until master bus is aligned
686670 */
687− while (bd.remainder > (mbus->buswidth - 1)) {
688− size_t lli_len, target_len, tsize, odd_bytes;
671+ if (bd.remainder < mbus->buswidth)
672+ early_bytes = bd.remainder;
673+ else if ((mbus->addr) % (mbus->buswidth)) {
674+ early_bytes = mbus->buswidth - (mbus->addr) %
675+ (mbus->buswidth);
676+ if ((bd.remainder - early_bytes) < mbus->buswidth)
677+ early_bytes = bd.remainder;
678+ }
689679
680+ if (early_bytes) {
681+ dev_vdbg(&pl08x->adev->dev,
682+ "%s byte width LLIs (remain 0x%08x)\n",
683+ __func__, bd.remainder);
684+ prep_byte_width_lli(&bd, &cctl, early_bytes, num_llis++,
685+ &total_bytes);
686+ }
687+
688+ if (bd.remainder) {
690689 /*
691− * If enough left try to send max possible,
692− * otherwise try to send the remainder
690+ * Master now aligned
691+ * - if slave is not then we must set its width down
693692 */
694− target_len = min(bd.remainder, max_bytes_per_lli);
693+ if (sbus->addr % sbus->buswidth) {
694+ dev_dbg(&pl08x->adev->dev,
695+ "%s set down bus width to one byte\n",
696+ __func__);
697+
698+ sbus->buswidth = 1;
699+ }
695700
696701 /*
697− * Set bus lengths for incrementing buses to the
698− * number of bytes which fill to next memory boundary,
699− * limiting on the target length calculated above.
702+ * Bytes transferred = tsize * src width, not
703+ * MIN(buswidths)
700704 */
701− if (cctl & PL080_CONTROL_SRC_INCR)
702− bd.srcbus.fill_bytes =
703− pl08x_pre_boundary(bd.srcbus.addr,
704− target_len);
705− else
706− bd.srcbus.fill_bytes = target_len;
707−
708− if (cctl & PL080_CONTROL_DST_INCR)
709− bd.dstbus.fill_bytes =
710− pl08x_pre_boundary(bd.dstbus.addr,
711− target_len);
712− else
713− bd.dstbus.fill_bytes = target_len;
714−
715− /* Find the nearest */
716− lli_len = min(bd.srcbus.fill_bytes,
717− bd.dstbus.fill_bytes);
718−
719− BUG_ON(lli_len > bd.remainder);
720−
721− if (lli_len <= 0) {
722− dev_err(&pl08x->adev->dev,
723− "%s lli_len is %zu, <= 0\n",
724− __func__, lli_len);
725− return 0;
726− }
705+ max_bytes_per_lli = bd.srcbus.buswidth *
706+ PL080_CONTROL_TRANSFER_SIZE_MASK;
707+ dev_vdbg(&pl08x->adev->dev,
708+ "%s max bytes per lli = %zu\n",
709+ __func__, max_bytes_per_lli);
710+
711+ /*
712+ * Make largest possible LLIs until less than one bus
713+ * width left
714+ */
715+ while (bd.remainder > (mbus->buswidth - 1)) {
716+ size_t lli_len, tsize, width;
727717
728− if (lli_len == target_len) {
729− /*
730− * Can send what we wanted.
731− * Maintain alignment
732− */
733− lli_len = (lli_len/mbus->buswidth) *
734− mbus->buswidth;
735− odd_bytes = 0;
736− } else {
737718 /*
738− * So now we know how many bytes to transfer
739− * to get to the nearest boundary. The next
740− * LLI will past the boundary. However, we
741− * may be working to a boundary on the slave
742− * bus. We need to ensure the master stays
743− * aligned, and that we are working in
744− * multiples of the bus widths.
719+ * If enough left try to send max possible,
720+ * otherwise try to send the remainder
745721 */
746− odd_bytes = lli_len % mbus->buswidth;
747− lli_len -= odd_bytes;
748−
749− }
722+ lli_len = min(bd.remainder, max_bytes_per_lli);
750723
751− if (lli_len) {
752724 /*
753− * Check against minimum bus alignment:
754− * Calculate actual transfer size in relation
755− * to bus width an get a maximum remainder of
756− * the smallest bus width - 1
725+ * Check against maximum bus alignment:
726+ * Calculate actual transfer size in relation to
727+ * bus width an get a maximum remainder of the
728+ * highest bus width - 1
757729 */
758− /* FIXME: use round_down()? */
759− tsize = lli_len / min(mbus->buswidth,
760− sbus->buswidth);
761− lli_len = tsize * min(mbus->buswidth,
762− sbus->buswidth);
763−
764− if (target_len != lli_len) {
765− dev_vdbg(&pl08x->adev->dev,
766− "%s can't send what we want. Desired 0x%08zx, lli of 0x%08zx bytes in txd of 0x%08zx\n",
767− __func__, target_len, lli_len, txd->len);
768− }
769−
770− cctl = pl08x_cctl_bits(cctl,
771− bd.srcbus.buswidth,
772− bd.dstbus.buswidth,
773− tsize);
730+ width = max(mbus->buswidth, sbus->buswidth);
731+ lli_len = (lli_len / width) * width;
732+ tsize = lli_len / bd.srcbus.buswidth;
774733
775734 dev_vdbg(&pl08x->adev->dev,
776− "%s fill lli with single lli chunk of size 0x%08zx (remainder 0x%08zx)\n",
735+ "%s fill lli with single lli chunk of "
736+ "size 0x%08zx (remainder 0x%08zx)\n",
777737 __func__, lli_len, bd.remainder);
738+
739+ cctl = pl08x_cctl_bits(cctl, bd.srcbus.buswidth,
740+ bd.dstbus.buswidth, tsize);
778741 pl08x_fill_lli_for_desc(&bd, num_llis++,
779− lli_len, cctl);
742+ lli_len, cctl);
780743 total_bytes += lli_len;
781744 }
782745
783−
784− if (odd_bytes) {
785− /*
786− * Creep past the boundary, maintaining
787− * master alignment
788− */
789− int j;
790− for (j = 0; (j < mbus->buswidth)
791− && (bd.remainder); j++) {
792− cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
793− dev_vdbg(&pl08x->adev->dev,
794− "%s align with boundary, single byte (remain 0x%08zx)\n",
795− __func__, bd.remainder);
796− pl08x_fill_lli_for_desc(&bd,
797− num_llis++, 1, cctl);
798− total_bytes++;
799− }
746+ /*
747+ * Send any odd bytes
748+ */
749+ if (bd.remainder) {
750+ dev_vdbg(&pl08x->adev->dev,
751+ "%s align with boundary, send odd bytes (remain %zu)\n",
752+ __func__, bd.remainder);
753+ prep_byte_width_lli(&bd, &cctl, bd.remainder,
754+ num_llis++, &total_bytes);
800755 }
801756 }
802757
803− /*
804− * Send any odd bytes
805− */
806− while (bd.remainder) {
807− cctl = pl08x_cctl_bits(cctl, 1, 1, 1);
808− dev_vdbg(&pl08x->adev->dev,
809− "%s align with boundary, single odd byte (remain %zu)\n",
810− __func__, bd.remainder);
811− pl08x_fill_lli_for_desc(&bd, num_llis++, 1, cctl);
812− total_bytes++;
758+ if (total_bytes != dsg->len) {
759+ dev_err(&pl08x->adev->dev,
760+ "%s size of encoded lli:s don't match total txd, transferred 0x%08zx from size 0x%08zx\n",
761+ __func__, total_bytes, dsg->len);
762+ return 0;
813763 }
814− }
815− if (total_bytes != txd->len) {
816− dev_err(&pl08x->adev->dev,
817− "%s size of encoded lli:s don't match total txd, transferred 0x%08zx from size 0x%08zx\n",
818− __func__, total_bytes, txd->len);
819− return 0;
820− }
821764
822− if (num_llis >= MAX_NUM_TSFR_LLIS) {
823− dev_err(&pl08x->adev->dev,
824− "%s need to increase MAX_NUM_TSFR_LLIS from 0x%08x\n",
825− __func__, (u32) MAX_NUM_TSFR_LLIS);
826− return 0;
765+ if (num_llis >= MAX_NUM_TSFR_LLIS) {
766+ dev_err(&pl08x->adev->dev,
767+ "%s need to increase MAX_NUM_TSFR_LLIS from 0x%08x\n",
768+ __func__, (u32) MAX_NUM_TSFR_LLIS);
769+ return 0;
770+ }
827771 }
828772
829773 llis_va = txd->llis_va;
@@ -856,11 +800,19 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, · 26 unmodified lines
856800 static void pl08x_free_txd(struct pl08x_driver_data *pl08x,
857801 struct pl08x_txd *txd)
858802 {
803+ struct pl08x_sg *dsg, *_dsg;
804+
859805 /* Free the LLI */
860− dma_pool_free(pl08x->pool, txd->llis_va, txd->llis_bus);
806+ if (txd->llis_va)
807+ dma_pool_free(pl08x->pool, txd->llis_va, txd->llis_bus);
861808
862809 pl08x->pool_ctr--;
863810
811+ list_for_each_entry_safe(dsg, _dsg, &txd->dsg_list, node) {
812+ list_del(&dsg->node);
813+ kfree(dsg);
814+ }
815+
864816 kfree(txd);
865817 }
866818
@@ -917,9 +869,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan, · 50 unmodified lines
917869 * need, but for slaves the physical signals may be muxed!
918870 * Can the platform allow us to use this channel?
919871 */
920− if (plchan->slave &&
921− ch->signal < 0 &&
922− pl08x->pd->get_signal) {
872+ if (plchan->slave && pl08x->pd->get_signal) {
923873 ret = pl08x->pd->get_signal(plchan);
924874 if (ret < 0) {
925875 dev_dbg(&pl08x->adev->dev,
@@ -1008,10 +958,8 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt( · 82 unmodified lines
1008958 * If slaves are relying on interrupts to signal completion this function
1009959 * must not be called with interrupts disabled.
1010960 */
1011−static enum dma_status
1012−pl08x_dma_tx_status(struct dma_chan *chan,
1013− dma_cookie_t cookie,
1014− struct dma_tx_state *txstate)
961+static enum dma_status pl08x_dma_tx_status(struct dma_chan *chan,
962+ dma_cookie_t cookie, struct dma_tx_state *txstate)
1015963 {
1016964 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1017965 dma_cookie_t last_used;
@@ -1253,7 +1201,9 @@ static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan, · 235 unmodified lines
12531201
12541202 num_llis = pl08x_fill_llis_for_desc(pl08x, txd);
12551203 if (!num_llis) {
1256− kfree(txd);
1204+ spin_lock_irqsave(&plchan->lock, flags);
1205+ pl08x_free_txd(pl08x, txd);
1206+ spin_unlock_irqrestore(&plchan->lock, flags);
12571207 return -EINVAL;
12581208 }
12591209
@@ -1301,13 +1251,14 @@ static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan, · 41 unmodified lines
13011251 static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan,
13021252 unsigned long flags)
13031253 {
1304− struct pl08x_txd *txd = kzalloc(sizeof(struct pl08x_txd), GFP_NOWAIT);
1254+ struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT);
13051255
13061256 if (txd) {
13071257 dma_async_tx_descriptor_init(&txd->tx, &plchan->chan);
13081258 txd->tx.flags = flags;
13091259 txd->tx.tx_submit = pl08x_tx_submit;
13101260 INIT_LIST_HEAD(&txd->node);
1261+ INIT_LIST_HEAD(&txd->dsg_list);
13111262
13121263 /* Always enable error and terminal interrupts */
13131264 txd->ccfg = PL080_CONFIG_ERR_IRQ_MASK |
@@ -1326,6 +1277,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy( · 12 unmodified lines
13261277 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
13271278 struct pl08x_driver_data *pl08x = plchan->host;
13281279 struct pl08x_txd *txd;
1280+ struct pl08x_sg *dsg;
13291281 int ret;
13301282
13311283 txd = pl08x_get_txd(plchan, flags);
@@ -1335,10 +1287,19 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy( · 3 unmodified lines
13351287 return NULL;
13361288 }
13371289
1290+ dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT);
1291+ if (!dsg) {
1292+ pl08x_free_txd(pl08x, txd);
1293+ dev_err(&pl08x->adev->dev, "%s no memory for pl080 sg\n",
1294+ __func__);
1295+ return NULL;
1296+ }
1297+ list_add_tail(&dsg->node, &txd->dsg_list);
1298+
13381299 txd->direction = DMA_NONE;
1339− txd->src_addr = src;
1340− txd->dst_addr = dest;
1341− txd->len = len;
1300+ dsg->src_addr = src;
1301+ dsg->dst_addr = dest;
1302+ dsg->len = len;
13421303
13431304 /* Set platform data for m2m */
13441305 txd->ccfg |= PL080_FLOW_MEM2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
@@ -1367,19 +1328,13 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( · 22 unmodified lines
13671328 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
13681329 struct pl08x_driver_data *pl08x = plchan->host;
13691330 struct pl08x_txd *txd;
1370− int ret;
1371−
1372− /*
1373− * Current implementation ASSUMES only one sg
1374− */
1375− if (sg_len != 1) {
1376− dev_err(&pl08x->adev->dev, "%s prepared too long sglist\n",
1377− __func__);
1378− BUG();
1379− }
1331+ struct pl08x_sg *dsg;
1332+ struct scatterlist *sg;
1333+ dma_addr_t slave_addr;
1334+ int ret, tmp;
13801335
13811336 dev_dbg(&pl08x->adev->dev, "%s prepare transaction of %d bytes from %s\n",
1382− __func__, sgl->length, plchan->name);
1337+ __func__, sgl->length, plchan->name);
13831338
13841339 txd = pl08x_get_txd(plchan, flags);
13851340 if (!txd) {
@@ -1398,24 +1353,49 @@ static struct dma_async_tx_descriptor *pl08x_prep_slave_sg( · 12 unmodified lines
13981353 * channel target address dynamically at runtime.
13991354 */
14001355 txd->direction = direction;
1401− txd->len = sgl->length;
14021356
14031357 if (direction == DMA_TO_DEVICE) {
1404− txd->ccfg |= PL080_FLOW_MEM2PER << PL080_CONFIG_FLOW_CONTROL_SHIFT;
14051358 txd->cctl = plchan->dst_cctl;
1406− txd->src_addr = sgl->dma_address;
1407− txd->dst_addr = plchan->dst_addr;
1359+ slave_addr = plchan->dst_addr;
14081360 } else if (direction == DMA_FROM_DEVICE) {
1409− txd->ccfg |= PL080_FLOW_PER2MEM << PL080_CONFIG_FLOW_CONTROL_SHIFT;
14101361 txd->cctl = plchan->src_cctl;
1411− txd->src_addr = plchan->src_addr;
1412− txd->dst_addr = sgl->dma_address;
1362+ slave_addr = plchan->src_addr;
14131363 } else {
1364+ pl08x_free_txd(pl08x, txd);
14141365 dev_err(&pl08x->adev->dev,
14151366 "%s direction unsupported\n", __func__);
14161367 return NULL;
14171368 }
14181369
1370+ if (plchan->cd->device_fc)
1371+ tmp = (direction == DMA_TO_DEVICE) ? PL080_FLOW_MEM2PER_PER :
1372+ PL080_FLOW_PER2MEM_PER;
1373+ else
1374+ tmp = (direction == DMA_TO_DEVICE) ? PL080_FLOW_MEM2PER :
1375+ PL080_FLOW_PER2MEM;
1376+
1377+ txd->ccfg |= tmp << PL080_CONFIG_FLOW_CONTROL_SHIFT;
1378+
1379+ for_each_sg(sgl, sg, sg_len, tmp) {
1380+ dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT);
1381+ if (!dsg) {
1382+ pl08x_free_txd(pl08x, txd);
1383+ dev_err(&pl08x->adev->dev, "%s no mem for pl080 sg\n",
1384+ __func__);
1385+ return NULL;
1386+ }
1387+ list_add_tail(&dsg->node, &txd->dsg_list);
1388+
1389+ dsg->len = sg_dma_len(sg);
1390+ if (direction == DMA_TO_DEVICE) {
1391+ dsg->src_addr = sg_phys(sg);
1392+ dsg->dst_addr = slave_addr;
1393+ } else {
1394+ dsg->src_addr = slave_addr;
1395+ dsg->dst_addr = sg_phys(sg);
1396+ }
1397+ }
1398+
14191399 ret = pl08x_prep_channel_resources(plchan, txd);
14201400 if (ret)
14211401 return NULL;
@@ -1489,9 +1469,15 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, · 67 unmodified lines
14891469
14901470 bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
14911471 {
1492− struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1472+ struct pl08x_dma_chan *plchan;
14931473 char *name = chan_id;
14941474
1475+ /* Reject channels for devices not bound to this driver */
1476+ if (chan->device->dev->driver != &pl08x_amba_driver.drv)
1477+ return false;
1478+
1479+ plchan = to_pl08x_chan(chan);
1480+
14951481 /* Check that the channel is not taken! */
14961482 if (!strcmp(plchan->name, name))
14971483 return true;
@@ -1507,34 +1493,34 @@ bool pl08x_filter_id(struct dma_chan *chan, void *chan_id) · 9 unmodified lines
15071493 */
15081494 static void pl08x_ensure_on(struct pl08x_driver_data *pl08x)
15091495 {
1510− u32 val;
1511−
1512− val = readl(pl08x->base + PL080_CONFIG);
1513− val &= ~(PL080_CONFIG_M2_BE | PL080_CONFIG_M1_BE | PL080_CONFIG_ENABLE);
1514− /* We implicitly clear bit 1 and that means little-endian mode */
1515− val |= PL080_CONFIG_ENABLE;
1516− writel(val, pl08x->base + PL080_CONFIG);
1496+ writel(PL080_CONFIG_ENABLE, pl08x->base + PL080_CONFIG);
15171497 }
15181498
15191499 static void pl08x_unmap_buffers(struct pl08x_txd *txd)
15201500 {
15211501 struct device *dev = txd->tx.chan->device->dev;
1502+ struct pl08x_sg *dsg;
15221503
15231504 if (!(txd->tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
15241505 if (txd->tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
1525− dma_unmap_single(dev, txd->src_addr, txd->len,
1526− DMA_TO_DEVICE);
1527− else
1528− dma_unmap_page(dev, txd->src_addr, txd->len,
1529− DMA_TO_DEVICE);
1506+ list_for_each_entry(dsg, &txd->dsg_list, node)
1507+ dma_unmap_single(dev, dsg->src_addr, dsg->len,
1508+ DMA_TO_DEVICE);
1509+ else {
1510+ list_for_each_entry(dsg, &txd->dsg_list, node)
1511+ dma_unmap_page(dev, dsg->src_addr, dsg->len,
1512+ DMA_TO_DEVICE);
1513+ }
15301514 }
15311515 if (!(txd->tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
15321516 if (txd->tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
1533− dma_unmap_single(dev, txd->dst_addr, txd->len,
1534− DMA_FROM_DEVICE);
1517+ list_for_each_entry(dsg, &txd->dsg_list, node)
1518+ dma_unmap_single(dev, dsg->dst_addr, dsg->len,
1519+ DMA_FROM_DEVICE);
15351520 else
1536− dma_unmap_page(dev, txd->dst_addr, txd->len,
1537− DMA_FROM_DEVICE);
1521+ list_for_each_entry(dsg, &txd->dsg_list, node)
1522+ dma_unmap_page(dev, dsg->dst_addr, dsg->len,
1523+ DMA_FROM_DEVICE);
15381524 }
15391525 }
15401526
@@ -1589,8 +1575,8 @@ static void pl08x_tasklet(unsigned long data) · 48 unmodified lines
15891575 */
15901576 list_for_each_entry(waiting, &pl08x->memcpy.channels,
15911577 chan.device_node) {
1592− if (waiting->state == PL08X_CHAN_WAITING &&
1593− waiting->waiting != NULL) {
1578+ if (waiting->state == PL08X_CHAN_WAITING &&
1579+ waiting->waiting != NULL) {
15941580 int ret;
15951581
15961582 /* This should REALLY not fail now */
@@ -1630,38 +1616,40 @@ static void pl08x_tasklet(unsigned long data) · 33 unmodified lines
16301616 static irqreturn_t pl08x_irq(int irq, void *dev)
16311617 {
16321618 struct pl08x_driver_data *pl08x = dev;
1633− u32 mask = 0;
1634− u32 val;
1635− int i;
1636−
1637− val = readl(pl08x->base + PL080_ERR_STATUS);
1638− if (val) {
1639− /* An error interrupt (on one or more channels) */
1640− dev_err(&pl08x->adev->dev,
1641− "%s error interrupt, register value 0x%08x\n",
1642− __func__, val);
1643− /*
1644− * Simply clear ALL PL08X error interrupts,
1645− * regardless of channel and cause
1646− * FIXME: should be 0x00000003 on PL081 really.
1647− */
1648− writel(0x000000FF, pl08x->base + PL080_ERR_CLEAR);
1619+ u32 mask = 0, err, tc, i;
1620+
1621+ /* check & clear - ERR & TC interrupts */
1622+ err = readl(pl08x->base + PL080_ERR_STATUS);
1623+ if (err) {
1624+ dev_err(&pl08x->adev->dev, "%s error interrupt, register value 0x%08x\n",
1625+ __func__, err);
1626+ writel(err, pl08x->base + PL080_ERR_CLEAR);
16491627 }
1650− val = readl(pl08x->base + PL080_INT_STATUS);
1628+ tc = readl(pl08x->base + PL080_INT_STATUS);
1629+ if (tc)
1630+ writel(tc, pl08x->base + PL080_TC_CLEAR);
1631+
1632+ if (!err && !tc)
1633+ return IRQ_NONE;
1634+
16511635 for (i = 0; i < pl08x->vd->channels; i++) {
1652− if ((1 << i) & val) {
1636+ if (((1 << i) & err) || ((1 << i) & tc)) {
16531637 /* Locate physical channel */
16541638 struct pl08x_phy_chan *phychan = &pl08x->phy_chans[i];
16551639 struct pl08x_dma_chan *plchan = phychan->serving;
16561640
1641+ if (!plchan) {
1642+ dev_err(&pl08x->adev->dev,
1643+ "%s Error TC interrupt on unused channel: 0x%08x\n",
1644+ __func__, i);
1645+ continue;
1646+ }
1647+
16571648 /* Schedule tasklet on this channel */
16581649 tasklet_schedule(&plchan->tasklet);
1659−
16601650 mask |= (1 << i);
16611651 }
16621652 }
1663− /* Clear only the terminal interrupts on channels we processed */
1664− writel(mask, pl08x->base + PL080_TC_CLEAR);
16651653
16661654 return mask ? IRQ_HANDLED : IRQ_NONE;
16671655 }
@@ -1685,9 +1673,7 @@ static void pl08x_dma_slave_init(struct pl08x_dma_chan *chan) · 17 unmodified lines
16851673 * Make a local wrapper to hold required data
16861674 */
16871675 static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1688− struct dma_device *dmadev,
1689− unsigned int channels,
1690− bool slave)
1676+ struct dma_device *dmadev, unsigned int channels, bool slave)
16911677 {
16921678 struct pl08x_dma_chan *chan;
16931679 int i;
@@ -1700,7 +1686,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, · 6 unmodified lines
17001686 * to cope with that situation.
17011687 */
17021688 for (i = 0; i < channels; i++) {
1703− chan = kzalloc(sizeof(struct pl08x_dma_chan), GFP_KERNEL);
1689+ chan = kzalloc(sizeof(*chan), GFP_KERNEL);
17041690 if (!chan) {
17051691 dev_err(&pl08x->adev->dev,
17061692 "%s no memory for channel\n", __func__);
@@ -1728,7 +1714,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, · 21 unmodified lines
17281714 kfree(chan);
17291715 continue;
17301716 }
1731− dev_info(&pl08x->adev->dev,
1717+ dev_dbg(&pl08x->adev->dev,
17321718 "initialize virtual channel \"%s\"\n",
17331719 chan->name);
17341720
@@ -1837,9 +1823,9 @@ static const struct file_operations pl08x_debugfs_operations = { · 102 unmodified lines
18371823 static void init_pl08x_debugfs(struct pl08x_driver_data *pl08x)
18381824 {
18391825 /* Expose a simple debugfs interface to view all clocks */
1840− (void) debugfs_create_file(dev_name(&pl08x->adev->dev), S_IFREG | S_IRUGO,
1841− NULL, pl08x,
1842− &pl08x_debugfs_operations);
1826+ (void) debugfs_create_file(dev_name(&pl08x->adev->dev),
1827+ S_IFREG | S_IRUGO, NULL, pl08x,
1828+ &pl08x_debugfs_operations);
18431829 }
18441830
18451831 #else
@@ -1860,12 +1846,15 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) · 14 unmodified lines
18601846 return ret;
18611847
18621848 /* Create the driver state holder */
1863− pl08x = kzalloc(sizeof(struct pl08x_driver_data), GFP_KERNEL);
1849+ pl08x = kzalloc(sizeof(*pl08x), GFP_KERNEL);
18641850 if (!pl08x) {
18651851 ret = -ENOMEM;
18661852 goto out_no_pl08x;
18671853 }
18681854
1855+ pm_runtime_set_active(&adev->dev);
1856+ pm_runtime_enable(&adev->dev);
1857+
18691858 /* Initialize memcpy engine */
18701859 dma_cap_set(DMA_MEMCPY, pl08x->memcpy.cap_mask);
18711860 pl08x->memcpy.dev = &adev->dev;
@@ -1939,7 +1928,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) · 67 unmodified lines
19391928 }
19401929
19411930 /* Initialize physical channels */
1942− pl08x->phy_chans = kmalloc((vd->channels * sizeof(struct pl08x_phy_chan)),
1931+ pl08x->phy_chans = kmalloc((vd->channels * sizeof(*pl08x->phy_chans)),
19431932 GFP_KERNEL);
19441933 if (!pl08x->phy_chans) {
19451934 dev_err(&adev->dev, "%s failed to allocate "
@@ -1956,9 +1945,8 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) · 10 unmodified lines
19561945 spin_lock_init(&ch->lock);
19571946 ch->serving = NULL;
19581947 ch->signal = -1;
1959− dev_info(&adev->dev,
1960− "physical channel %d is %s\n", i,
1961− pl08x_phy_channel_busy(ch) ? "BUSY" : "FREE");
1948+ dev_dbg(&adev->dev, "physical channel %d is %s\n",
1949+ i, pl08x_phy_channel_busy(ch) ? "BUSY" : "FREE");
19621950 }
19631951
19641952 /* Register as many memcpy channels as there are physical channels */
@@ -1974,8 +1962,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) · 9 unmodified lines
19741962
19751963 /* Register slave channels */
19761964 ret = pl08x_dma_init_virtual_channels(pl08x, &pl08x->slave,
1977− pl08x->pd->num_slave_channels,
1978− true);
1965+ pl08x->pd->num_slave_channels, true);
19791966 if (ret <= 0) {
19801967 dev_warn(&pl08x->adev->dev,
19811968 "%s failed to enumerate slave channels - %d\n",
@@ -2005,6 +1992,8 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) · 23 unmodified lines
20051992 dev_info(&pl08x->adev->dev, "DMA: PL%03x rev%u at 0x%08llx irq %d\n",
20061993 amba_part(adev), amba_rev(adev),
20071994 (unsigned long long)adev->res.start, adev->irq[0]);
1995+
1996+ pm_runtime_put(&adev->dev);
20081997 return 0;
20091998
20101999 out_no_slave_reg:
@@ -2023,6 +2012,9 @@ out_no_ioremap: · 12 unmodified lines
20232012 dma_pool_destroy(pl08x->pool);
20242013 out_no_lli_pool:
20252014 out_no_platdata:
2015+ pm_runtime_put(&adev->dev);
2016+ pm_runtime_disable(&adev->dev);
2017+
20262018 kfree(pl08x);
20272019 out_no_pl08x:
20282020 amba_release_regions(adev);
drivers/dma/at_hdmac.c+127−37
@@ -107,10 +107,11 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan) · 106 unmodified lines
107107 {
108108 struct at_desc *desc, *_desc;
109109 struct at_desc *ret = NULL;
110+ unsigned long flags;
110111 unsigned int i = 0;
111112 LIST_HEAD(tmp_list);
112113
113− spin_lock_bh(&atchan->lock);
114+ spin_lock_irqsave(&atchan->lock, flags);
114115 list_for_each_entry_safe(desc, _desc, &atchan->free_list, desc_node) {
115116 i++;
116117 if (async_tx_test_ack(&desc->txd)) {
@@ -121,7 +122,7 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan) · 4 unmodified lines
121122 dev_dbg(chan2dev(&atchan->chan_common),
122123 "desc %p not ACKed\n", desc);
123124 }
124− spin_unlock_bh(&atchan->lock);
125+ spin_unlock_irqrestore(&atchan->lock, flags);
125126 dev_vdbg(chan2dev(&atchan->chan_common),
126127 "scanned %u descriptors on freelist\n", i);
127128
@@ -129,9 +130,9 @@ static struct at_desc *atc_desc_get(struct at_dma_chan *atchan) · 1 unmodified line
129130 if (!ret) {
130131 ret = atc_alloc_descriptor(&atchan->chan_common, GFP_ATOMIC);
131132 if (ret) {
132− spin_lock_bh(&atchan->lock);
133+ spin_lock_irqsave(&atchan->lock, flags);
133134 atchan->descs_allocated++;
134− spin_unlock_bh(&atchan->lock);
135+ spin_unlock_irqrestore(&atchan->lock, flags);
135136 } else {
136137 dev_err(chan2dev(&atchan->chan_common),
137138 "not enough descriptors available\n");
@@ -150,8 +151,9 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc) · 12 unmodified lines
150151 {
151152 if (desc) {
152153 struct at_desc *child;
154+ unsigned long flags;
153155
154− spin_lock_bh(&atchan->lock);
156+ spin_lock_irqsave(&atchan->lock, flags);
155157 list_for_each_entry(child, &desc->tx_list, desc_node)
156158 dev_vdbg(chan2dev(&atchan->chan_common),
157159 "moving child desc %p to freelist\n",
@@ -160,7 +162,7 @@ static void atc_desc_put(struct at_dma_chan *atchan, struct at_desc *desc) · 2 unmodified lines
160162 dev_vdbg(chan2dev(&atchan->chan_common),
161163 "moving desc %p to freelist\n", desc);
162164 list_add(&desc->desc_node, &atchan->free_list);
163− spin_unlock_bh(&atchan->lock);
165+ spin_unlock_irqrestore(&atchan->lock, flags);
164166 }
165167 }
166168
@@ -299,7 +301,7 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) · 132 unmodified lines
299301
300302 /* for cyclic transfers,
301303 * no need to replay callback function while stopping */
302− if (!test_bit(ATC_IS_CYCLIC, &atchan->status)) {
304+ if (!atc_chan_is_cyclic(atchan)) {
303305 dma_async_tx_callback callback = txd->callback;
304306 void *param = txd->callback_param;
305307
@@ -471,16 +473,17 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan) · 165 unmodified lines
471473 static void atc_tasklet(unsigned long data)
472474 {
473475 struct at_dma_chan *atchan = (struct at_dma_chan *)data;
476+ unsigned long flags;
474477
475− spin_lock(&atchan->lock);
478+ spin_lock_irqsave(&atchan->lock, flags);
476479 if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status))
477480 atc_handle_error(atchan);
478− else if (test_bit(ATC_IS_CYCLIC, &atchan->status))
481+ else if (atc_chan_is_cyclic(atchan))
479482 atc_handle_cyclic(atchan);
480483 else
481484 atc_advance_work(atchan);
482485
483− spin_unlock(&atchan->lock);
486+ spin_unlock_irqrestore(&atchan->lock, flags);
484487 }
485488
486489 static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
@@ -539,8 +542,9 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx) · 52 unmodified lines
539542 struct at_desc *desc = txd_to_at_desc(tx);
540543 struct at_dma_chan *atchan = to_at_dma_chan(tx->chan);
541544 dma_cookie_t cookie;
545+ unsigned long flags;
542546
543− spin_lock_bh(&atchan->lock);
547+ spin_lock_irqsave(&atchan->lock, flags);
544548 cookie = atc_assign_cookie(atchan, desc);
545549
546550 if (list_empty(&atchan->active_list)) {
@@ -554,7 +558,7 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx) · 7 unmodified lines
554558 list_add_tail(&desc->desc_node, &atchan->queue);
555559 }
556560
557− spin_unlock_bh(&atchan->lock);
561+ spin_unlock_irqrestore(&atchan->lock, flags);
558562
559563 return cookie;
560564 }
@@ -927,28 +931,29 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, · 366 unmodified lines
927931 struct at_dma_chan *atchan = to_at_dma_chan(chan);
928932 struct at_dma *atdma = to_at_dma(chan->device);
929933 int chan_id = atchan->chan_common.chan_id;
934+ unsigned long flags;
930935
931936 LIST_HEAD(list);
932937
933938 dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd);
934939
935940 if (cmd == DMA_PAUSE) {
936− spin_lock_bh(&atchan->lock);
941+ spin_lock_irqsave(&atchan->lock, flags);
937942
938943 dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id));
939944 set_bit(ATC_IS_PAUSED, &atchan->status);
940945
941− spin_unlock_bh(&atchan->lock);
946+ spin_unlock_irqrestore(&atchan->lock, flags);
942947 } else if (cmd == DMA_RESUME) {
943− if (!test_bit(ATC_IS_PAUSED, &atchan->status))
948+ if (!atc_chan_is_paused(atchan))
944949 return 0;
945950
946− spin_lock_bh(&atchan->lock);
951+ spin_lock_irqsave(&atchan->lock, flags);
947952
948953 dma_writel(atdma, CHDR, AT_DMA_RES(chan_id));
949954 clear_bit(ATC_IS_PAUSED, &atchan->status);
950955
951− spin_unlock_bh(&atchan->lock);
956+ spin_unlock_irqrestore(&atchan->lock, flags);
952957 } else if (cmd == DMA_TERMINATE_ALL) {
953958 struct at_desc *desc, *_desc;
954959 /*
@@ -957,7 +962,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, · 2 unmodified lines
957962 * channel. We still have to poll the channel enable bit due
958963 * to AHB/HSB limitations.
959964 */
960− spin_lock_bh(&atchan->lock);
965+ spin_lock_irqsave(&atchan->lock, flags);
961966
962967 /* disabling channel: must also remove suspend state */
963968 dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask);
@@ -978,7 +983,7 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, · 14 unmodified lines
978983 /* if channel dedicated to cyclic operations, free it */
979984 clear_bit(ATC_IS_CYCLIC, &atchan->status);
980985
981− spin_unlock_bh(&atchan->lock);
986+ spin_unlock_irqrestore(&atchan->lock, flags);
982987 } else {
983988 return -ENXIO;
984989 }
@@ -1004,9 +1009,10 @@ atc_tx_status(struct dma_chan *chan, · 19 unmodified lines
10041009 struct at_dma_chan *atchan = to_at_dma_chan(chan);
10051010 dma_cookie_t last_used;
10061011 dma_cookie_t last_complete;
1012+ unsigned long flags;
10071013 enum dma_status ret;
10081014
1009− spin_lock_bh(&atchan->lock);
1015+ spin_lock_irqsave(&atchan->lock, flags);
10101016
10111017 last_complete = atchan->completed_cookie;
10121018 last_used = chan->cookie;
@@ -1021,7 +1027,7 @@ atc_tx_status(struct dma_chan *chan, · 8 unmodified lines
10211027 ret = dma_async_is_complete(cookie, last_complete, last_used);
10221028 }
10231029
1024− spin_unlock_bh(&atchan->lock);
1030+ spin_unlock_irqrestore(&atchan->lock, flags);
10251031
10261032 if (ret != DMA_SUCCESS)
10271033 dma_set_tx_state(txstate, last_complete, last_used,
@@ -1029,7 +1035,7 @@ atc_tx_status(struct dma_chan *chan, · 1 unmodified line
10291035 else
10301036 dma_set_tx_state(txstate, last_complete, last_used, 0);
10311037
1032− if (test_bit(ATC_IS_PAUSED, &atchan->status))
1038+ if (atc_chan_is_paused(atchan))
10331039 ret = DMA_PAUSED;
10341040
10351041 dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n",
@@ -1046,18 +1052,19 @@ atc_tx_status(struct dma_chan *chan, · 10 unmodified lines
10461052 static void atc_issue_pending(struct dma_chan *chan)
10471053 {
10481054 struct at_dma_chan *atchan = to_at_dma_chan(chan);
1055+ unsigned long flags;
10491056
10501057 dev_vdbg(chan2dev(chan), "issue_pending\n");
10511058
10521059 /* Not needed for cyclic transfers */
1053− if (test_bit(ATC_IS_CYCLIC, &atchan->status))
1060+ if (atc_chan_is_cyclic(atchan))
10541061 return;
10551062
1056− spin_lock_bh(&atchan->lock);
1063+ spin_lock_irqsave(&atchan->lock, flags);
10571064 if (!atc_chan_is_enabled(atchan)) {
10581065 atc_advance_work(atchan);
10591066 }
1060− spin_unlock_bh(&atchan->lock);
1067+ spin_unlock_irqrestore(&atchan->lock, flags);
10611068 }
10621069
10631070 /**
@@ -1073,6 +1080,7 @@ static int atc_alloc_chan_resources(struct dma_chan *chan) · 9 unmodified lines
10731080 struct at_dma *atdma = to_at_dma(chan->device);
10741081 struct at_desc *desc;
10751082 struct at_dma_slave *atslave;
1083+ unsigned long flags;
10761084 int i;
10771085 u32 cfg;
10781086 LIST_HEAD(tmp_list);
@@ -1116,11 +1124,11 @@ static int atc_alloc_chan_resources(struct dma_chan *chan) · 37 unmodified lines
11161124 list_add_tail(&desc->desc_node, &tmp_list);
11171125 }
11181126
1119− spin_lock_bh(&atchan->lock);
1127+ spin_lock_irqsave(&atchan->lock, flags);
11201128 atchan->descs_allocated = i;
11211129 list_splice(&tmp_list, &atchan->free_list);
11221130 atchan->completed_cookie = chan->cookie = 1;
1123− spin_unlock_bh(&atchan->lock);
1131+ spin_unlock_irqrestore(&atchan->lock, flags);
11241132
11251133 /* channel parameters */
11261134 channel_writel(atchan, CFG, cfg);
@@ -1260,12 +1268,11 @@ static int __init at_dma_probe(struct platform_device *pdev) · 133 unmodified lines
12601268
12611269 /* initialize channels related values */
12621270 INIT_LIST_HEAD(&atdma->dma_common.channels);
1263− for (i = 0; i < pdata->nr_channels; i++, atdma->dma_common.chancnt++) {
1271+ for (i = 0; i < pdata->nr_channels; i++) {
12641272 struct at_dma_chan *atchan = &atdma->chan[i];
12651273
12661274 atchan->chan_common.device = &atdma->dma_common;
12671275 atchan->chan_common.cookie = atchan->completed_cookie = 1;
1268− atchan->chan_common.chan_id = i;
12691276 list_add_tail(&atchan->chan_common.device_node,
12701277 &atdma->dma_common.channels);
12711278
@@ -1293,22 +1300,20 @@ static int __init at_dma_probe(struct platform_device *pdev) · 21 unmodified lines
12931300 if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask))
12941301 atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy;
12951302
1296− if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask))
1303+ if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) {
12971304 atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg;
1298−
1299− if (dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask))
1305+ /* controller can do slave DMA: can trigger cyclic transfers */
1306+ dma_cap_set(DMA_CYCLIC, atdma->dma_common.cap_mask);
13001307 atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic;
1301−
1302− if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ||
1303− dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask))
13041308 atdma->dma_common.device_control = atc_control;
1309+ }
13051310
13061311 dma_writel(atdma, EN, AT_DMA_ENABLE);
13071312
13081313 dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n",
13091314 dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "",
13101315 dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "",
1311− atdma->dma_common.chancnt);
1316+ pdata->nr_channels);
13121317
13131318 dma_async_device_register(&atdma->dma_common);
13141319
@@ -1377,27 +1382,112 @@ static void at_dma_shutdown(struct platform_device *pdev) · 62 unmodified lines
13771382 clk_disable(atdma->clk);
13781383 }
13791384
1385+static int at_dma_prepare(struct device *dev)
1386+{
1387+ struct platform_device *pdev = to_platform_device(dev);
1388+ struct at_dma *atdma = platform_get_drvdata(pdev);
1389+ struct dma_chan *chan, *_chan;
1390+
1391+ list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
1392+ device_node) {
1393+ struct at_dma_chan *atchan = to_at_dma_chan(chan);
1394+ /* wait for transaction completion (except in cyclic case) */
1395+ if (atc_chan_is_enabled(atchan) && !atc_chan_is_cyclic(atchan))
1396+ return -EAGAIN;
1397+ }
1398+ return 0;
1399+}
1400+
1401+static void atc_suspend_cyclic(struct at_dma_chan *atchan)
1402+{
1403+ struct dma_chan *chan = &atchan->chan_common;
1404+
1405+ /* Channel should be paused by user
1406+ * do it anyway even if it is not done already */
1407+ if (!atc_chan_is_paused(atchan)) {
1408+ dev_warn(chan2dev(chan),
1409+ "cyclic channel not paused, should be done by channel user\n");
1410+ atc_control(chan, DMA_PAUSE, 0);
1411+ }
1412+
1413+ /* now preserve additional data for cyclic operations */
1414+ /* next descriptor address in the cyclic list */
1415+ atchan->save_dscr = channel_readl(atchan, DSCR);
1416+
1417+ vdbg_dump_regs(atchan);
1418+}
1419+
13801420 static int at_dma_suspend_noirq(struct device *dev)
13811421 {
13821422 struct platform_device *pdev = to_platform_device(dev);
13831423 struct at_dma *atdma = platform_get_drvdata(pdev);
1424+ struct dma_chan *chan, *_chan;
13841425
1385− at_dma_off(platform_get_drvdata(pdev));
1426+ /* preserve data */
1427+ list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
1428+ device_node) {
1429+ struct at_dma_chan *atchan = to_at_dma_chan(chan);
1430+
1431+ if (atc_chan_is_cyclic(atchan))
1432+ atc_suspend_cyclic(atchan);
1433+ atchan->save_cfg = channel_readl(atchan, CFG);
1434+ }
1435+ atdma->save_imr = dma_readl(atdma, EBCIMR);
1436+
1437+ /* disable DMA controller */
1438+ at_dma_off(atdma);
13861439 clk_disable(atdma->clk);
13871440 return 0;
13881441 }
13891442
1443+static void atc_resume_cyclic(struct at_dma_chan *atchan)
1444+{
1445+ struct at_dma *atdma = to_at_dma(atchan->chan_common.device);
1446+
1447+ /* restore channel status for cyclic descriptors list:
1448+ * next descriptor in the cyclic list at the time of suspend */
1449+ channel_writel(atchan, SADDR, 0);
1450+ channel_writel(atchan, DADDR, 0);
1451+ channel_writel(atchan, CTRLA, 0);
1452+ channel_writel(atchan, CTRLB, 0);
1453+ channel_writel(atchan, DSCR, atchan->save_dscr);
1454+ dma_writel(atdma, CHER, atchan->mask);
1455+
1456+ /* channel pause status should be removed by channel user
1457+ * We cannot take the initiative to do it here */
1458+
1459+ vdbg_dump_regs(atchan);
1460+}
1461+
13901462 static int at_dma_resume_noirq(struct device *dev)
13911463 {
13921464 struct platform_device *pdev = to_platform_device(dev);
13931465 struct at_dma *atdma = platform_get_drvdata(pdev);
1466+ struct dma_chan *chan, *_chan;
13941467
1468+ /* bring back DMA controller */
13951469 clk_enable(atdma->clk);
13961470 dma_writel(atdma, EN, AT_DMA_ENABLE);
1471+
1472+ /* clear any pending interrupt */
1473+ while (dma_readl(atdma, EBCISR))
1474+ cpu_relax();
1475+
1476+ /* restore saved data */
1477+ dma_writel(atdma, EBCIER, atdma->save_imr);
1478+ list_for_each_entry_safe(chan, _chan, &atdma->dma_common.channels,
1479+ device_node) {
1480+ struct at_dma_chan *atchan = to_at_dma_chan(chan);
1481+
1482+ channel_writel(atchan, CFG, atchan->save_cfg);
1483+ if (atc_chan_is_cyclic(atchan))
1484+ atc_resume_cyclic(atchan);
1485+ }
13971486 return 0;
13981487 }
13991488
14001489 static const struct dev_pm_ops at_dma_dev_pm_ops = {
1490+ .prepare = at_dma_prepare,
14011491 .suspend_noirq = at_dma_suspend_noirq,
14021492 .resume_noirq = at_dma_resume_noirq,
14031493 };
drivers/dma/at_hdmac_regs.h+24−0
@@ -204,6 +204,9 @@ enum atc_status { · 203 unmodified lines
204204 * @status: transmit status information from irq/prep* functions
205205 * to tasklet (use atomic operations)
206206 * @tasklet: bottom half to finish transaction work
207+ * @save_cfg: configuration register that is saved on suspend/resume cycle
208+ * @save_dscr: for cyclic operations, preserve next descriptor address in
209+ * the cyclic list on suspend/resume cycle
207210 * @lock: serializes enqueue/dequeue operations to descriptors lists
208211 * @completed_cookie: identifier for the most recently completed operation
209212 * @active_list: list of descriptors dmaengine is being running on
@@ -218,6 +221,8 @@ struct at_dma_chan { · 8 unmodified lines
218221 u8 mask;
219222 unsigned long status;
220223 struct tasklet_struct tasklet;
224+ u32 save_cfg;
225+ u32 save_dscr;
221226
222227 spinlock_t lock;
223228
@@ -248,6 +253,7 @@ static inline struct at_dma_chan *to_at_dma_chan(struct dma_chan *dchan) · 24 unmodified lines
248253 * @chan_common: common dmaengine dma_device object members
249254 * @ch_regs: memory mapped register base
250255 * @clk: dma controller clock
256+ * @save_imr: interrupt mask register that is saved on suspend/resume cycle
251257 * @all_chan_mask: all channels availlable in a mask
252258 * @dma_desc_pool: base of DMA descriptor region (DMA address)
253259 * @chan: channels table to store at_dma_chan structures
@@ -256,6 +262,7 @@ struct at_dma { · 2 unmodified lines
256262 struct dma_device dma_common;
257263 void __iomem *regs;
258264 struct clk *clk;
265+ u32 save_imr;
259266
260267 u8 all_chan_mask;
261268
@@ -355,6 +362,23 @@ static inline int atc_chan_is_enabled(struct at_dma_chan *atchan) · 93 unmodified lines
355362 return !!(dma_readl(atdma, CHSR) & atchan->mask);
356363 }
357364
365+/**
366+ * atc_chan_is_paused - test channel pause/resume status
367+ * @atchan: channel we want to test status
368+ */
369+static inline int atc_chan_is_paused(struct at_dma_chan *atchan)
370+{
371+ return test_bit(ATC_IS_PAUSED, &atchan->status);
372+}
373+
374+/**
375+ * atc_chan_is_cyclic - test if given channel has cyclic property set
376+ * @atchan: channel we want to test status
377+ */
378+static inline int atc_chan_is_cyclic(struct at_dma_chan *atchan)
379+{
380+ return test_bit(ATC_IS_CYCLIC, &atchan->status);
381+}
358382
359383 /**
360384 * set_desc_eol - set end-of-link to descriptor so it will end transfer
drivers/dma/dmatest.c+21−2
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/delay.h>
1111 #include <linux/dma-mapping.h>
1212 #include <linux/dmaengine.h>
13+#include <linux/freezer.h>
1314 #include <linux/init.h>
1415 #include <linux/kthread.h>
1516 #include <linux/module.h>
@@ -251,6 +252,7 @@ static int dmatest_func(void *data) · 235 unmodified lines
251252 int i;
252253
253254 thread_name = current->comm;
255+ set_freezable_with_signal();
254256
255257 ret = -ENOMEM;
256258
@@ -305,7 +307,8 @@ static int dmatest_func(void *data) · 48 unmodified lines
305307 dma_addr_t dma_srcs[src_cnt];
306308 dma_addr_t dma_dsts[dst_cnt];
307309 struct completion cmp;
308− unsigned long tmo = msecs_to_jiffies(timeout);
310+ unsigned long start, tmo, end = 0 /* compiler... */;
311+ bool reload = true;
309312 u8 align = 0;
310313
311314 total_tests++;
@@ -404,7 +407,17 @@ static int dmatest_func(void *data) · 92 unmodified lines
404407 }
405408 dma_async_issue_pending(chan);
406409
407− tmo = wait_for_completion_timeout(&cmp, tmo);
410+ do {
411+ start = jiffies;
412+ if (reload)
413+ end = start + msecs_to_jiffies(timeout);
414+ else if (end <= start)
415+ end = start + 1;
416+ tmo = wait_for_completion_interruptible_timeout(&cmp,
417+ end - start);
418+ reload = try_to_freeze();
419+ } while (tmo == -ERESTARTSYS);
420+
408421 status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
409422
410423 if (tmo == 0) {
@@ -477,6 +490,8 @@ err_srcs: · 66 unmodified lines
477490 pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
478491 thread_name, total_tests, failed_tests, ret);
479492
493+ /* terminate all transfers on specified channels */
494+ chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
480495 if (iterations > 0)
481496 while (!kthread_should_stop()) {
482497 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
@@ -499,6 +514,10 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc) · 16 unmodified lines
499514 list_del(&thread->node);
500515 kfree(thread);
501516 }
517+
518+ /* terminate all transfers on specified channels */
519+ dtc->chan->device->device_control(dtc->chan, DMA_TERMINATE_ALL, 0);
520+
502521 kfree(dtc);
503522 }
504523
drivers/dma/dw_dmac.c+2−3
@@ -1407,12 +1407,11 @@ static int __init dw_probe(struct platform_device *pdev) · 1406 unmodified lines
14071407 dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
14081408
14091409 INIT_LIST_HEAD(&dw->dma.channels);
1410− for (i = 0; i < pdata->nr_channels; i++, dw->dma.chancnt++) {
1410+ for (i = 0; i < pdata->nr_channels; i++) {
14111411 struct dw_dma_chan *dwc = &dw->chan[i];
14121412
14131413 dwc->chan.device = &dw->dma;
14141414 dwc->chan.cookie = dwc->completed = 1;
1415− dwc->chan.chan_id = i;
14161415 if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
14171416 list_add_tail(&dwc->chan.device_node,
14181417 &dw->dma.channels);
@@ -1468,7 +1467,7 @@ static int __init dw_probe(struct platform_device *pdev) · 49 unmodified lines
14681467 dma_writel(dw, CFG, DW_CFG_DMA_EN);
14691468
14701469 printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
1471− dev_name(&pdev->dev), dw->dma.chancnt);
1470+ dev_name(&pdev->dev), pdata->nr_channels);
14721471
14731472 dma_async_device_register(&dw->dma);
14741473
drivers/dma/ep93xx_dma.c+1−0
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222 #include <linux/init.h>
2323 #include <linux/interrupt.h>
2424 #include <linux/dmaengine.h>
25+#include <linux/module.h>
2526 #include <linux/platform_device.h>
2627 #include <linux/slab.h>
2728
drivers/dma/imx-dma.c+1−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 * http://www.gnu.org/copyleft/gpl.html
1515 */
1616 #include <linux/init.h>
17+#include <linux/module.h>
1718 #include <linux/types.h>
1819 #include <linux/mm.h>
1920 #include <linux/interrupt.h>
drivers/dma/imx-sdma.c+39−9
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 */
1919
2020 #include <linux/init.h>
21+#include <linux/module.h>
2122 #include <linux/types.h>
2223 #include <linux/mm.h>
2324 #include <linux/interrupt.h>
@@ -318,6 +319,7 @@ struct sdma_engine { · 294 unmodified lines
318319 dma_addr_t context_phys;
319320 struct dma_device dma_device;
320321 struct clk *clk;
322+ struct mutex channel_0_lock;
321323 struct sdma_script_start_addrs *script_addrs;
322324 };
323325
@@ -415,11 +417,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, · 91 unmodified lines
415417 dma_addr_t buf_phys;
416418 int ret;
417419
420+ mutex_lock(&sdma->channel_0_lock);
421+
418422 buf_virt = dma_alloc_coherent(NULL,
419423 size,
420424 &buf_phys, GFP_KERNEL);
421− if (!buf_virt)
422− return -ENOMEM;
425+ if (!buf_virt) {
426+ ret = -ENOMEM;
427+ goto err_out;
428+ }
423429
424430 bd0->mode.command = C0_SETPM;
425431 bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
@@ -433,6 +439,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, · 7 unmodified lines
433439
434440 dma_free_coherent(NULL, size, buf_virt, buf_phys);
435441
442+err_out:
443+ mutex_unlock(&sdma->channel_0_lock);
444+
436445 return ret;
437446 }
438447
@@ -656,6 +665,8 @@ static int sdma_load_context(struct sdma_channel *sdmac) · 217 unmodified lines
656665 dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0);
657666 dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1);
658667
668+ mutex_lock(&sdma->channel_0_lock);
669+
659670 memset(context, 0, sizeof(*context));
660671 context->channel_state.pc = load_address;
661672
@@ -676,6 +687,8 @@ static int sdma_load_context(struct sdma_channel *sdmac) · 14 unmodified lines
676687
677688 ret = sdma_run_channel(&sdma->channel[0]);
678689
690+ mutex_unlock(&sdma->channel_0_lock);
691+
679692 return ret;
680693 }
681694
@@ -1131,18 +1144,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma, · 449 unmodified lines
11311144 saddr_arr[i] = addr_arr[i];
11321145 }
11331146
1134−static int __init sdma_get_firmware(struct sdma_engine *sdma,
1135− const char *fw_name)
1147+static void sdma_load_firmware(const struct firmware *fw, void *context)
11361148 {
1137− const struct firmware *fw;
1149+ struct sdma_engine *sdma = context;
11381150 const struct sdma_firmware_header *header;
1139− int ret;
11401151 const struct sdma_script_start_addrs *addr;
11411152 unsigned short *ram_code;
11421153
1143− ret = request_firmware(&fw, fw_name, sdma->dev);
1144− if (ret)
1145− return ret;
1154+ if (!fw) {
1155+ dev_err(sdma->dev, "firmware not found\n");
1156+ return;
1157+ }
11461158
11471159 if (fw->size < sizeof(*header))
11481160 goto err_firmware;
@@ -1172,6 +1184,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma, · 23 unmodified lines
11721184
11731185 err_firmware:
11741186 release_firmware(fw);
1187+}
1188+
1189+static int __init sdma_get_firmware(struct sdma_engine *sdma,
1190+ const char *fw_name)
1191+{
1192+ int ret;
1193+
1194+ ret = request_firmware_nowait(THIS_MODULE,
1195+ FW_ACTION_HOTPLUG, fw_name, sdma->dev,
1196+ GFP_KERNEL, sdma, sdma_load_firmware);
11751197
11761198 return ret;
11771199 }
@@ -1269,11 +1291,14 @@ static int __init sdma_probe(struct platform_device *pdev) · 91 unmodified lines
12691291 struct sdma_platform_data *pdata = pdev->dev.platform_data;
12701292 int i;
12711293 struct sdma_engine *sdma;
1294+ s32 *saddr_arr;
12721295
12731296 sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
12741297 if (!sdma)
12751298 return -ENOMEM;
12761299
1300+ mutex_init(&sdma->channel_0_lock);
1301+
12771302 sdma->dev = &pdev->dev;
12781303
12791304 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1310,6 +1335,11 @@ static int __init sdma_probe(struct platform_device *pdev) · 30 unmodified lines
13101335 goto err_alloc;
13111336 }
13121337
1338+ /* initially no scripts available */
1339+ saddr_arr = (s32 *)sdma->script_addrs;
1340+ for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
1341+ saddr_arr[i] = -EINVAL;
1342+
13131343 if (of_id)
13141344 pdev->id_entry = of_id->data;
13151345 sdma->devtype = pdev->id_entry->driver_data;
drivers/dma/intel_mid_dma.c+3−6
@@ -115,16 +115,15 @@ DMAC1 interrupt Functions*/ · 114 unmodified lines
115115
116116 /**
117117 * dmac1_mask_periphral_intr - mask the periphral interrupt
118− * @midc: dma channel for which masking is required
118+ * @mid: dma device for which masking is required
119119 *
120120 * Masks the DMA periphral interrupt
121121 * this is valid for DMAC1 family controllers only
122122 * This controller should have periphral mask registers already mapped
123123 */
124−static void dmac1_mask_periphral_intr(struct intel_mid_dma_chan *midc)
124+static void dmac1_mask_periphral_intr(struct middma_device *mid)
125125 {
126126 u32 pimr;
127− struct middma_device *mid = to_middma_device(midc->chan.device);
128127
129128 if (mid->pimr_mask) {
130129 pimr = readl(mid->mask_reg + LNW_PERIPHRAL_MASK);
@@ -184,7 +183,6 @@ static void enable_dma_interrupt(struct intel_mid_dma_chan *midc) · 53 unmodified lines
184183 static void disable_dma_interrupt(struct intel_mid_dma_chan *midc)
185184 {
186185 /*Check LPE PISR, make sure fwd is disabled*/
187− dmac1_mask_periphral_intr(midc);
188186 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_BLOCK);
189187 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_TFR);
190188 iowrite32(MASK_INTR_REG(midc->ch_id), midc->dma_base + MASK_ERR);
@@ -1114,7 +1112,6 @@ static int mid_setup_dma(struct pci_dev *pdev) · 923 unmodified lines
11141112
11151113 midch->chan.device = &dma->common;
11161114 midch->chan.cookie = 1;
1117− midch->chan.chan_id = i;
11181115 midch->ch_id = dma->chan_base + i;
11191116 pr_debug("MDMA:Init CH %d, ID %d\n", i, midch->ch_id);
11201117
@@ -1150,7 +1147,6 @@ static int mid_setup_dma(struct pci_dev *pdev) · 29 unmodified lines
11501147 dma_cap_set(DMA_SLAVE, dma->common.cap_mask);
11511148 dma_cap_set(DMA_PRIVATE, dma->common.cap_mask);
11521149 dma->common.dev = &pdev->dev;
1153− dma->common.chancnt = dma->max_chan;
11541150
11551151 dma->common.device_alloc_chan_resources =
11561152 intel_mid_dma_alloc_chan_resources;
@@ -1350,6 +1346,7 @@ int dma_suspend(struct pci_dev *pci, pm_message_t state) · 193 unmodified lines
13501346 if (device->ch[i].in_use)
13511347 return -EAGAIN;
13521348 }
1349+ dmac1_mask_periphral_intr(device);
13531350 device->state = SUSPENDED;
13541351 pci_save_state(pci);
13551352 pci_disable_device(pci);
drivers/dma/mpc512x_dma.c+0−1
@@ -741,7 +741,6 @@ static int __devinit mpc_dma_probe(struct platform_device *op) · 740 unmodified lines
741741 mchan = &mdma->channels[i];
742742
743743 mchan->chan.device = dma;
744− mchan->chan.chan_id = i;
745744 mchan->chan.cookie = 1;
746745 mchan->completed_cookie = mchan->chan.cookie;
747746
drivers/dma/mxs-dma.c+24−21
@@ -130,6 +130,23 @@ struct mxs_dma_engine { · 129 unmodified lines
130130 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
131131 };
132132
133+static inline void mxs_dma_clkgate(struct mxs_dma_chan *mxs_chan, int enable)
134+{
135+ struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
136+ int chan_id = mxs_chan->chan.chan_id;
137+ int set_clr = enable ? MXS_CLR_ADDR : MXS_SET_ADDR;
138+
139+ /* enable apbh channel clock */
140+ if (dma_is_apbh()) {
141+ if (apbh_is_old())
142+ writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
143+ mxs_dma->base + HW_APBHX_CTRL0 + set_clr);
144+ else
145+ writel(1 << chan_id,
146+ mxs_dma->base + HW_APBHX_CTRL0 + set_clr);
147+ }
148+}
149+
133150 static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
134151 {
135152 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@ -148,38 +165,21 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan) · 12 unmodified lines
148165 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
149166 int chan_id = mxs_chan->chan.chan_id;
150167
168+ /* clkgate needs to be enabled before writing other registers */
169+ mxs_dma_clkgate(mxs_chan, 1);
170+
151171 /* set cmd_addr up */
152172 writel(mxs_chan->ccw_phys,
153173 mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id));
154174
155− /* enable apbh channel clock */
156− if (dma_is_apbh()) {
157− if (apbh_is_old())
158− writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
159− mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
160− else
161− writel(1 << chan_id,
162− mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
163− }
164−
165175 /* write 1 to SEMA to kick off the channel */
166176 writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id));
167177 }
168178
169179 static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
170180 {
171− struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
172− int chan_id = mxs_chan->chan.chan_id;
173−
174181 /* disable apbh channel clock */
175− if (dma_is_apbh()) {
176− if (apbh_is_old())
177− writel(1 << (chan_id + BP_APBH_CTRL0_CLKGATE_CHANNEL),
178− mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
179− else
180− writel(1 << chan_id,
181− mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
182− }
182+ mxs_dma_clkgate(mxs_chan, 0);
183183
184184 mxs_chan->status = DMA_SUCCESS;
185185 }
@@ -338,7 +338,10 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan) · 152 unmodified lines
338338 if (ret)
339339 goto err_clk;
340340
341+ /* clkgate needs to be enabled for reset to finish */
342+ mxs_dma_clkgate(mxs_chan, 1);
341343 mxs_dma_reset_chan(mxs_chan);
344+ mxs_dma_clkgate(mxs_chan, 0);
342345
343346 dma_async_tx_descriptor_init(&mxs_chan->desc, chan);
344347 mxs_chan->desc.tx_submit = mxs_dma_tx_submit;
drivers/dma/pch_dma.c+2−5
@@ -60,7 +60,7 @@ · 59 unmodified lines
6060 #define DMA_DESC_FOLLOW_WITHOUT_IRQ 0x2
6161 #define DMA_DESC_FOLLOW_WITH_IRQ 0x3
6262
63−#define MAX_CHAN_NR 8
63+#define MAX_CHAN_NR 12
6464
6565 #define DMA_MASK_CTL0_MODE 0x33333333
6666 #define DMA_MASK_CTL2_MODE 0x00003333
@@ -872,8 +872,7 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev, · 805 unmodified lines
872872 int i;
873873
874874 nr_channels = id->driver_data;
875− pd = kzalloc(sizeof(struct pch_dma)+
876− sizeof(struct pch_dma_chan) * nr_channels, GFP_KERNEL);
875+ pd = kzalloc(sizeof(*pd), GFP_KERNEL);
877876 if (!pd)
878877 return -ENOMEM;
879878
@@ -926,7 +925,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev, · 46 unmodified lines
926925 }
927926
928927 pd->dma.dev = &pdev->dev;
929− pd->dma.chancnt = nr_channels;
930928
931929 INIT_LIST_HEAD(&pd->dma.channels);
932930
@@ -935,7 +933,6 @@ static int __devinit pch_dma_probe(struct pci_dev *pdev, · 2 unmodified lines
935933
936934 pd_chan->chan.device = &pd->dma;
937935 pd_chan->chan.cookie = 1;
938− pd_chan->chan.chan_id = i;
939936
940937 pd_chan->membase = &regs->desc[i];
941938
drivers/dma/pl330.c+207−24
@@ -17,6 +17,8 @@ · 16 unmodified lines
1717 #include <linux/interrupt.h>
1818 #include <linux/amba/bus.h>
1919 #include <linux/amba/pl330.h>
20+#include <linux/pm_runtime.h>
21+#include <linux/scatterlist.h>
2022
2123 #define NR_DEFAULT_DESC 16
2224
@@ -68,6 +70,14 @@ struct dma_pl330_chan { · 45 unmodified lines
6870 * NULL if the channel is available to be acquired.
6971 */
7072 void *pl330_chid;
73+
74+ /* For D-to-M and M-to-D channels */
75+ int burst_sz; /* the peripheral fifo width */
76+ int burst_len; /* the number of burst */
77+ dma_addr_t fifo_addr;
78+
79+ /* for cyclic capability */
80+ bool cyclic;
7181 };
7282
7383 struct dma_pl330_dmac {
@@ -83,6 +93,8 @@ struct dma_pl330_dmac { · 9 unmodified lines
8393
8494 /* Peripheral channels connected to this DMAC */
8595 struct dma_pl330_chan *peripherals; /* keep at end */
96+
97+ struct clk *clk;
8698 };
8799
88100 struct dma_pl330_desc {
@@ -152,6 +164,31 @@ static inline void free_desc_list(struct list_head *list) · 63 unmodified lines
152164 spin_unlock_irqrestore(&pdmac->pool_lock, flags);
153165 }
154166
167+static inline void handle_cyclic_desc_list(struct list_head *list)
168+{
169+ struct dma_pl330_desc *desc;
170+ struct dma_pl330_chan *pch;
171+ unsigned long flags;
172+
173+ if (list_empty(list))
174+ return;
175+
176+ list_for_each_entry(desc, list, node) {
177+ dma_async_tx_callback callback;
178+
179+ /* Change status to reload it */
180+ desc->status = PREP;
181+ pch = desc->pchan;
182+ callback = desc->txd.callback;
183+ if (callback)
184+ callback(desc->txd.callback_param);
185+ }
186+
187+ spin_lock_irqsave(&pch->lock, flags);
188+ list_splice_tail_init(list, &pch->work_list);
189+ spin_unlock_irqrestore(&pch->lock, flags);
190+}
191+
155192 static inline void fill_queue(struct dma_pl330_chan *pch)
156193 {
157194 struct dma_pl330_desc *desc;
@@ -205,7 +242,10 @@ static void pl330_tasklet(unsigned long data) · 47 unmodified lines
205242
206243 spin_unlock_irqrestore(&pch->lock, flags);
207244
208− free_desc_list(&list);
245+ if (pch->cyclic)
246+ handle_cyclic_desc_list(&list);
247+ else
248+ free_desc_list(&list);
209249 }
210250
211251 static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
@@ -236,6 +276,7 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) · 24 unmodified lines
236276 spin_lock_irqsave(&pch->lock, flags);
237277
238278 pch->completed = chan->cookie = 1;
279+ pch->cyclic = false;
239280
240281 pch->pl330_chid = pl330_request_channel(&pdmac->pif);
241282 if (!pch->pl330_chid) {
@@ -253,25 +294,52 @@ static int pl330_alloc_chan_resources(struct dma_chan *chan) · 11 unmodified lines
253294 static int pl330_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, unsigned long arg)
254295 {
255296 struct dma_pl330_chan *pch = to_pchan(chan);
256− struct dma_pl330_desc *desc;
297+ struct dma_pl330_desc *desc, *_dt;
257298 unsigned long flags;
299+ struct dma_pl330_dmac *pdmac = pch->dmac;
300+ struct dma_slave_config *slave_config;
301+ LIST_HEAD(list);
258302
259− /* Only supports DMA_TERMINATE_ALL */
260− if (cmd != DMA_TERMINATE_ALL)
261− return -ENXIO;
262−
263− spin_lock_irqsave(&pch->lock, flags);
264−
265− /* FLUSH the PL330 Channel thread */
266− pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
303+ switch (cmd) {
304+ case DMA_TERMINATE_ALL:
305+ spin_lock_irqsave(&pch->lock, flags);
267306
268− /* Mark all desc done */
269− list_for_each_entry(desc, &pch->work_list, node)
270− desc->status = DONE;
307+ /* FLUSH the PL330 Channel thread */
308+ pl330_chan_ctrl(pch->pl330_chid, PL330_OP_FLUSH);
271309
272− spin_unlock_irqrestore(&pch->lock, flags);
310+ /* Mark all desc done */
311+ list_for_each_entry_safe(desc, _dt, &pch->work_list , node) {
312+ desc->status = DONE;
313+ pch->completed = desc->txd.cookie;
314+ list_move_tail(&desc->node, &list);
315+ }
273316
274− pl330_tasklet((unsigned long) pch);
317+ list_splice_tail_init(&list, &pdmac->desc_pool);
318+ spin_unlock_irqrestore(&pch->lock, flags);
319+ break;
320+ case DMA_SLAVE_CONFIG:
321+ slave_config = (struct dma_slave_config *)arg;
322+
323+ if (slave_config->direction == DMA_TO_DEVICE) {
324+ if (slave_config->dst_addr)
325+ pch->fifo_addr = slave_config->dst_addr;
326+ if (slave_config->dst_addr_width)
327+ pch->burst_sz = __ffs(slave_config->dst_addr_width);
328+ if (slave_config->dst_maxburst)
329+ pch->burst_len = slave_config->dst_maxburst;
330+ } else if (slave_config->direction == DMA_FROM_DEVICE) {
331+ if (slave_config->src_addr)
332+ pch->fifo_addr = slave_config->src_addr;
333+ if (slave_config->src_addr_width)
334+ pch->burst_sz = __ffs(slave_config->src_addr_width);
335+ if (slave_config->src_maxburst)
336+ pch->burst_len = slave_config->src_maxburst;
337+ }
338+ break;
339+ default:
340+ dev_err(pch->dmac->pif.dev, "Not supported command.\n");
341+ return -ENXIO;
342+ }
275343
276344 return 0;
277345 }
@@ -288,6 +356,9 @@ static void pl330_free_chan_resources(struct dma_chan *chan) · 10 unmodified lines
288356 pl330_release_channel(pch->pl330_chid);
289357 pch->pl330_chid = NULL;
290358
359+ if (pch->cyclic)
360+ list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool);
361+
291362 spin_unlock_irqrestore(&pch->lock, flags);
292363 }
293364
@@ -453,7 +524,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) · 159 unmodified lines
453524
454525 if (peri) {
455526 desc->req.rqtype = peri->rqtype;
456− desc->req.peri = peri->peri_id;
527+ desc->req.peri = pch->chan.chan_id;
457528 } else {
458529 desc->req.rqtype = MEMTOMEM;
459530 desc->req.peri = 0;
@@ -524,6 +595,51 @@ static inline int get_burst_len(struct dma_pl330_desc *desc, size_t len) · 64 unmodified lines
524595 return burst_len;
525596 }
526597
598+static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
599+ struct dma_chan *chan, dma_addr_t dma_addr, size_t len,
600+ size_t period_len, enum dma_data_direction direction)
601+{
602+ struct dma_pl330_desc *desc;
603+ struct dma_pl330_chan *pch = to_pchan(chan);
604+ dma_addr_t dst;
605+ dma_addr_t src;
606+
607+ desc = pl330_get_desc(pch);
608+ if (!desc) {
609+ dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
610+ __func__, __LINE__);
611+ return NULL;
612+ }
613+
614+ switch (direction) {
615+ case DMA_TO_DEVICE:
616+ desc->rqcfg.src_inc = 1;
617+ desc->rqcfg.dst_inc = 0;
618+ src = dma_addr;
619+ dst = pch->fifo_addr;
620+ break;
621+ case DMA_FROM_DEVICE:
622+ desc->rqcfg.src_inc = 0;
623+ desc->rqcfg.dst_inc = 1;
624+ src = pch->fifo_addr;
625+ dst = dma_addr;
626+ break;
627+ default:
628+ dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
629+ __func__, __LINE__);
630+ return NULL;
631+ }
632+
633+ desc->rqcfg.brst_size = pch->burst_sz;
634+ desc->rqcfg.brst_len = 1;
635+
636+ pch->cyclic = true;
637+
638+ fill_px(&desc->px, dst, src, period_len);
639+
640+ return &desc->txd;
641+}
642+
527643 static struct dma_async_tx_descriptor *
528644 pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
529645 dma_addr_t src, size_t len, unsigned long flags)
@@ -579,7 +695,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 49 unmodified lines
579695 struct dma_pl330_peri *peri = chan->private;
580696 struct scatterlist *sg;
581697 unsigned long flags;
582− int i, burst_size;
698+ int i;
583699 dma_addr_t addr;
584700
585701 if (unlikely(!pch || !sgl || !sg_len || !peri))
@@ -595,8 +711,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 9 unmodified lines
595711 return NULL;
596712 }
597713
598− addr = peri->fifo_addr;
599− burst_size = peri->burst_sz;
714+ addr = pch->fifo_addr;
600715
601716 first = NULL;
602717
@@ -644,7 +759,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 41 unmodified lines
644759 sg_dma_address(sg), addr, sg_dma_len(sg));
645760 }
646761
647− desc->rqcfg.brst_size = burst_size;
762+ desc->rqcfg.brst_size = pch->burst_sz;
648763 desc->rqcfg.brst_len = 1;
649764 }
650765
@@ -696,6 +811,30 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) · 45 unmodified lines
696811 goto probe_err1;
697812 }
698813
814+ pdmac->clk = clk_get(&adev->dev, "dma");
815+ if (IS_ERR(pdmac->clk)) {
816+ dev_err(&adev->dev, "Cannot get operation clock.\n");
817+ ret = -EINVAL;
818+ goto probe_err1;
819+ }
820+
821+ amba_set_drvdata(adev, pdmac);
822+
823+#ifdef CONFIG_PM_RUNTIME
824+ /* to use the runtime PM helper functions */
825+ pm_runtime_enable(&adev->dev);
826+
827+ /* enable the power domain */
828+ if (pm_runtime_get_sync(&adev->dev)) {
829+ dev_err(&adev->dev, "failed to get runtime pm\n");
830+ ret = -ENODEV;
831+ goto probe_err1;
832+ }
833+#else
834+ /* enable dma clk */
835+ clk_enable(pdmac->clk);
836+#endif
837+
699838 irq = adev->irq[0];
700839 ret = request_irq(irq, pl330_irq_handler, 0,
701840 dev_name(&adev->dev), pi);
@@ -732,6 +871,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) · 30 unmodified lines
732871 case MEMTODEV:
733872 case DEVTOMEM:
734873 dma_cap_set(DMA_SLAVE, pd->cap_mask);
874+ dma_cap_set(DMA_CYCLIC, pd->cap_mask);
735875 break;
736876 default:
737877 dev_err(&adev->dev, "DEVTODEV Not Supported\n");
@@ -747,11 +887,9 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) · 9 unmodified lines
747887 spin_lock_init(&pch->lock);
748888 pch->pl330_chid = NULL;
749889 pch->chan.device = pd;
750− pch->chan.chan_id = i;
751890 pch->dmac = pdmac;
752891
753892 /* Add the channel to the DMAC list */
754− pd->chancnt++;
755893 list_add_tail(&pch->chan.device_node, &pd->channels);
756894 }
757895
@@ -760,6 +898,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) · 2 unmodified lines
760898 pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
761899 pd->device_free_chan_resources = pl330_free_chan_resources;
762900 pd->device_prep_dma_memcpy = pl330_prep_dma_memcpy;
901+ pd->device_prep_dma_cyclic = pl330_prep_dma_cyclic;
763902 pd->device_tx_status = pl330_tx_status;
764903 pd->device_prep_slave_sg = pl330_prep_slave_sg;
765904 pd->device_control = pl330_control;
@@ -771,8 +910,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) · 5 unmodified lines
771910 goto probe_err4;
772911 }
773912
774− amba_set_drvdata(adev, pdmac);
775−
776913 dev_info(&adev->dev,
777914 "Loaded driver for PL330 DMAC-%d\n", adev->periphid);
778915 dev_info(&adev->dev,
@@ -833,6 +970,13 @@ static int __devexit pl330_remove(struct amba_device *adev) · 54 unmodified lines
833970 res = &adev->res;
834971 release_mem_region(res->start, resource_size(res));
835972
973+#ifdef CONFIG_PM_RUNTIME
974+ pm_runtime_put(&adev->dev);
975+ pm_runtime_disable(&adev->dev);
976+#else
977+ clk_disable(pdmac->clk);
978+#endif
979+
836980 kfree(pdmac);
837981
838982 return 0;
@@ -846,10 +990,49 @@ static struct amba_id pl330_ids[] = { · 7 unmodified lines
846990 { 0, 0 },
847991 };
848992
993+#ifdef CONFIG_PM_RUNTIME
994+static int pl330_runtime_suspend(struct device *dev)
995+{
996+ struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
997+
998+ if (!pdmac) {
999+ dev_err(dev, "failed to get dmac\n");
1000+ return -ENODEV;
1001+ }
1002+
1003+ clk_disable(pdmac->clk);
1004+
1005+ return 0;
1006+}
1007+
1008+static int pl330_runtime_resume(struct device *dev)
1009+{
1010+ struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
1011+
1012+ if (!pdmac) {
1013+ dev_err(dev, "failed to get dmac\n");
1014+ return -ENODEV;
1015+ }
1016+
1017+ clk_enable(pdmac->clk);
1018+
1019+ return 0;
1020+}
1021+#else
1022+#define pl330_runtime_suspend NULL
1023+#define pl330_runtime_resume NULL
1024+#endif /* CONFIG_PM_RUNTIME */
1025+
1026+static const struct dev_pm_ops pl330_pm_ops = {
1027+ .runtime_suspend = pl330_runtime_suspend,
1028+ .runtime_resume = pl330_runtime_resume,
1029+};
1030+
8491031 static struct amba_driver pl330_driver = {
8501032 .drv = {
8511033 .owner = THIS_MODULE,
8521034 .name = "dma-pl330",
1035+ .pm = &pl330_pm_ops,
8531036 },
8541037 .id_table = pl330_ids,
8551038 .probe = pl330_probe,
drivers/dma/shdma.c+86−43
@@ -259,14 +259,23 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) · 258 unmodified lines
259259 return 0;
260260 }
261261
262+static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan);
263+
262264 static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx)
263265 {
264266 struct sh_desc *desc = tx_to_sh_desc(tx), *chunk, *last = desc, *c;
265267 struct sh_dmae_chan *sh_chan = to_sh_chan(tx->chan);
268+ struct sh_dmae_slave *param = tx->chan->private;
266269 dma_async_tx_callback callback = tx->callback;
267270 dma_cookie_t cookie;
271+ bool power_up;
272+
273+ spin_lock_irq(&sh_chan->desc_lock);
268274
269− spin_lock_bh(&sh_chan->desc_lock);
275+ if (list_empty(&sh_chan->ld_queue))
276+ power_up = true;
277+ else
278+ power_up = false;
270279
271280 cookie = sh_chan->common.cookie;
272281 cookie++;
@@ -302,7 +311,38 @@ static dma_cookie_t sh_dmae_tx_submit(struct dma_async_tx_descriptor *tx) · 29 unmodified lines
302311 tx->cookie, &last->async_tx, sh_chan->id,
303312 desc->hw.sar, desc->hw.tcr, desc->hw.dar);
304313
305− spin_unlock_bh(&sh_chan->desc_lock);
314+ if (power_up) {
315+ sh_chan->pm_state = DMAE_PM_BUSY;
316+
317+ pm_runtime_get(sh_chan->dev);
318+
319+ spin_unlock_irq(&sh_chan->desc_lock);
320+
321+ pm_runtime_barrier(sh_chan->dev);
322+
323+ spin_lock_irq(&sh_chan->desc_lock);
324+
325+ /* Have we been reset, while waiting? */
326+ if (sh_chan->pm_state != DMAE_PM_ESTABLISHED) {
327+ dev_dbg(sh_chan->dev, "Bring up channel %d\n",
328+ sh_chan->id);
329+ if (param) {
330+ const struct sh_dmae_slave_config *cfg =
331+ param->config;
332+
333+ dmae_set_dmars(sh_chan, cfg->mid_rid);
334+ dmae_set_chcr(sh_chan, cfg->chcr);
335+ } else {
336+ dmae_init(sh_chan);
337+ }
338+
339+ if (sh_chan->pm_state == DMAE_PM_PENDING)
340+ sh_chan_xfer_ld_queue(sh_chan);
341+ sh_chan->pm_state = DMAE_PM_ESTABLISHED;
342+ }
343+ }
344+
345+ spin_unlock_irq(&sh_chan->desc_lock);
306346
307347 return cookie;
308348 }
@@ -346,8 +386,6 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) · 37 unmodified lines
346386 struct sh_dmae_slave *param = chan->private;
347387 int ret;
348388
349− pm_runtime_get_sync(sh_chan->dev);
350−
351389 /*
352390 * This relies on the guarantee from dmaengine that alloc_chan_resources
353391 * never runs concurrently with itself or free_chan_resources.
@@ -367,31 +405,20 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) · 13 unmodified lines
367405 }
368406
369407 param->config = cfg;
370−
371− dmae_set_dmars(sh_chan, cfg->mid_rid);
372− dmae_set_chcr(sh_chan, cfg->chcr);
373− } else {
374− dmae_init(sh_chan);
375408 }
376409
377− spin_lock_bh(&sh_chan->desc_lock);
378410 while (sh_chan->descs_allocated < NR_DESCS_PER_CHANNEL) {
379− spin_unlock_bh(&sh_chan->desc_lock);
380411 desc = kzalloc(sizeof(struct sh_desc), GFP_KERNEL);
381− if (!desc) {
382− spin_lock_bh(&sh_chan->desc_lock);
412+ if (!desc)
383413 break;
384− }
385414 dma_async_tx_descriptor_init(&desc->async_tx,
386415 &sh_chan->common);
387416 desc->async_tx.tx_submit = sh_dmae_tx_submit;
388417 desc->mark = DESC_IDLE;
389418
390− spin_lock_bh(&sh_chan->desc_lock);
391419 list_add(&desc->node, &sh_chan->ld_free);
392420 sh_chan->descs_allocated++;
393421 }
394− spin_unlock_bh(&sh_chan->desc_lock);
395422
396423 if (!sh_chan->descs_allocated) {
397424 ret = -ENOMEM;
@@ -405,7 +432,7 @@ edescalloc: · 7 unmodified lines
405432 clear_bit(param->slave_id, sh_dmae_slave_used);
406433 etestused:
407434 efindslave:
408− pm_runtime_put(sh_chan->dev);
435+ chan->private = NULL;
409436 return ret;
410437 }
411438
@@ -417,7 +444,6 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) · 5 unmodified lines
417444 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
418445 struct sh_desc *desc, *_desc;
419446 LIST_HEAD(list);
420− int descs = sh_chan->descs_allocated;
421447
422448 /* Protect against ISR */
423449 spin_lock_irq(&sh_chan->desc_lock);
@@ -437,15 +463,12 @@ static void sh_dmae_free_chan_resources(struct dma_chan *chan) · 13 unmodified lines
437463 chan->private = NULL;
438464 }
439465
440− spin_lock_bh(&sh_chan->desc_lock);
466+ spin_lock_irq(&sh_chan->desc_lock);
441467
442468 list_splice_init(&sh_chan->ld_free, &list);
443469 sh_chan->descs_allocated = 0;
444470
445− spin_unlock_bh(&sh_chan->desc_lock);
446−
447− if (descs > 0)
448− pm_runtime_put(sh_chan->dev);
471+ spin_unlock_irq(&sh_chan->desc_lock);
449472
450473 list_for_each_entry_safe(desc, _desc, &list, node)
451474 kfree(desc);
@@ -534,6 +557,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_c · 82 unmodified lines
534557 struct sh_desc *first = NULL, *new = NULL /* compiler... */;
535558 LIST_HEAD(tx_list);
536559 int chunks = 0;
560+ unsigned long irq_flags;
537561 int i;
538562
539563 if (!sg_len)
@@ -544,7 +568,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_c · 4 unmodified lines
544568 (SH_DMA_TCR_MAX + 1);
545569
546570 /* Have to lock the whole loop to protect against concurrent release */
547− spin_lock_bh(&sh_chan->desc_lock);
571+ spin_lock_irqsave(&sh_chan->desc_lock, irq_flags);
548572
549573 /*
550574 * Chaining:
@@ -590,7 +614,7 @@ static struct dma_async_tx_descriptor *sh_dmae_prep_sg(struct sh_dmae_chan *sh_c · 39 unmodified lines
590614 /* Put them back on the free list, so, they don't get lost */
591615 list_splice_tail(&tx_list, &sh_chan->ld_free);
592616
593− spin_unlock_bh(&sh_chan->desc_lock);
617+ spin_unlock_irqrestore(&sh_chan->desc_lock, irq_flags);
594618
595619 return &first->async_tx;
596620
@@ -599,7 +623,7 @@ err_get_desc: · 2 unmodified lines
599623 new->mark = DESC_IDLE;
600624 list_splice(&tx_list, &sh_chan->ld_free);
601625
602− spin_unlock_bh(&sh_chan->desc_lock);
626+ spin_unlock_irqrestore(&sh_chan->desc_lock, irq_flags);
603627
604628 return NULL;
605629 }
@@ -661,6 +685,7 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, · 55 unmodified lines
661685 unsigned long arg)
662686 {
663687 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
688+ unsigned long flags;
664689
665690 /* Only supports DMA_TERMINATE_ALL */
666691 if (cmd != DMA_TERMINATE_ALL)
@@ -669,7 +694,7 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, · 2 unmodified lines
669694 if (!chan)
670695 return -EINVAL;
671696
672− spin_lock_bh(&sh_chan->desc_lock);
697+ spin_lock_irqsave(&sh_chan->desc_lock, flags);
673698 dmae_halt(sh_chan);
674699
675700 if (!list_empty(&sh_chan->ld_queue)) {
@@ -678,9 +703,8 @@ static int sh_dmae_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, · 2 unmodified lines
678703 struct sh_desc, node);
679704 desc->partial = (desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) <<
680705 sh_chan->xmit_shift;
681−
682706 }
683− spin_unlock_bh(&sh_chan->desc_lock);
707+ spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
684708
685709 sh_dmae_chan_ld_cleanup(sh_chan, true);
686710
@@ -695,8 +719,9 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all · 8 unmodified lines
695719 dma_cookie_t cookie = 0;
696720 dma_async_tx_callback callback = NULL;
697721 void *param = NULL;
722+ unsigned long flags;
698723
699− spin_lock_bh(&sh_chan->desc_lock);
724+ spin_lock_irqsave(&sh_chan->desc_lock, flags);
700725 list_for_each_entry_safe(desc, _desc, &sh_chan->ld_queue, node) {
701726 struct dma_async_tx_descriptor *tx = &desc->async_tx;
702727
@@ -762,7 +787,13 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all · 59 unmodified lines
762787 async_tx_test_ack(&desc->async_tx)) || all) {
763788 /* Remove from ld_queue list */
764789 desc->mark = DESC_IDLE;
790+
765791 list_move(&desc->node, &sh_chan->ld_free);
792+
793+ if (list_empty(&sh_chan->ld_queue)) {
794+ dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
795+ pm_runtime_put(sh_chan->dev);
796+ }
766797 }
767798 }
768799
@@ -773,7 +804,7 @@ static dma_async_tx_callback __ld_cleanup(struct sh_dmae_chan *sh_chan, bool all · 4 unmodified lines
773804 */
774805 sh_chan->completed_cookie = sh_chan->common.cookie;
775806
776− spin_unlock_bh(&sh_chan->desc_lock);
807+ spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
777808
778809 if (callback)
779810 callback(param);
@@ -792,14 +823,14 @@ static void sh_dmae_chan_ld_cleanup(struct sh_dmae_chan *sh_chan, bool all) · 12 unmodified lines
792823 ;
793824 }
794825
826+/* Called under spin_lock_irq(&sh_chan->desc_lock) */
795827 static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
796828 {
797829 struct sh_desc *desc;
798830
799− spin_lock_bh(&sh_chan->desc_lock);
800831 /* DMA work check */
801832 if (dmae_is_busy(sh_chan))
802− goto sh_chan_xfer_ld_queue_end;
833+ return;
803834
804835 /* Find the first not transferred descriptor */
805836 list_for_each_entry(desc, &sh_chan->ld_queue, node)
@@ -812,15 +843,18 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) · 6 unmodified lines
812843 dmae_start(sh_chan);
813844 break;
814845 }
815−
816−sh_chan_xfer_ld_queue_end:
817− spin_unlock_bh(&sh_chan->desc_lock);
818846 }
819847
820848 static void sh_dmae_memcpy_issue_pending(struct dma_chan *chan)
821849 {
822850 struct sh_dmae_chan *sh_chan = to_sh_chan(chan);
823− sh_chan_xfer_ld_queue(sh_chan);
851+
852+ spin_lock_irq(&sh_chan->desc_lock);
853+ if (sh_chan->pm_state == DMAE_PM_ESTABLISHED)
854+ sh_chan_xfer_ld_queue(sh_chan);
855+ else
856+ sh_chan->pm_state = DMAE_PM_PENDING;
857+ spin_unlock_irq(&sh_chan->desc_lock);
824858 }
825859
826860 static enum dma_status sh_dmae_tx_status(struct dma_chan *chan,
@@ -831,6 +865,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, · 4 unmodified lines
831865 dma_cookie_t last_used;
832866 dma_cookie_t last_complete;
833867 enum dma_status status;
868+ unsigned long flags;
834869
835870 sh_dmae_chan_ld_cleanup(sh_chan, false);
836871
@@ -841,7 +876,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, · 4 unmodified lines
841876 BUG_ON(last_complete < 0);
842877 dma_set_tx_state(txstate, last_complete, last_used, 0);
843878
844− spin_lock_bh(&sh_chan->desc_lock);
879+ spin_lock_irqsave(&sh_chan->desc_lock, flags);
845880
846881 status = dma_async_is_complete(cookie, last_complete, last_used);
847882
@@ -859,7 +894,7 @@ static enum dma_status sh_dmae_tx_status(struct dma_chan *chan, · 11 unmodified lines
859894 }
860895 }
861896
862− spin_unlock_bh(&sh_chan->desc_lock);
897+ spin_unlock_irqrestore(&sh_chan->desc_lock, flags);
863898
864899 return status;
865900 }
@@ -912,6 +947,12 @@ static bool sh_dmae_reset(struct sh_dmae_device *shdev) · 46 unmodified lines
912947
913948 list_splice_init(&sh_chan->ld_queue, &dl);
914949
950+ if (!list_empty(&dl)) {
951+ dev_dbg(sh_chan->dev, "Bring down channel %d\n", sh_chan->id);
952+ pm_runtime_put(sh_chan->dev);
953+ }
954+ sh_chan->pm_state = DMAE_PM_ESTABLISHED;
955+
915956 spin_unlock(&sh_chan->desc_lock);
916957
917958 /* Complete all */
@@ -952,7 +993,7 @@ static void dmae_do_tasklet(unsigned long data) · 34 unmodified lines
952993 u32 sar_buf = sh_dmae_readl(sh_chan, SAR);
953994 u32 dar_buf = sh_dmae_readl(sh_chan, DAR);
954995
955− spin_lock(&sh_chan->desc_lock);
996+ spin_lock_irq(&sh_chan->desc_lock);
956997 list_for_each_entry(desc, &sh_chan->ld_queue, node) {
957998 if (desc->mark == DESC_SUBMITTED &&
958999 ((desc->direction == DMA_FROM_DEVICE &&
@@ -965,10 +1006,10 @@ static void dmae_do_tasklet(unsigned long data) · 6 unmodified lines
9651006 break;
9661007 }
9671008 }
968− spin_unlock(&sh_chan->desc_lock);
969−
9701009 /* Next desc */
9711010 sh_chan_xfer_ld_queue(sh_chan);
1011+ spin_unlock_irq(&sh_chan->desc_lock);
1012+
9721013 sh_dmae_chan_ld_cleanup(sh_chan, false);
9731014 }
9741015
@@ -1036,7 +1077,9 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, · 61 unmodified lines
10361077 return -ENOMEM;
10371078 }
10381079
1039− /* copy struct dma_device */
1080+ new_sh_chan->pm_state = DMAE_PM_ESTABLISHED;
1081+
1082+ /* reference struct dma_device */
10401083 new_sh_chan->common.device = &shdev->common;
10411084
10421085 new_sh_chan->dev = shdev->common.dev;
drivers/dma/shdma.h+7−0
@@ -23,6 +23,12 @@ · 22 unmodified lines
2323
2424 struct device;
2525
26+enum dmae_pm_state {
27+ DMAE_PM_ESTABLISHED,
28+ DMAE_PM_BUSY,
29+ DMAE_PM_PENDING,
30+};
31+
2632 struct sh_dmae_chan {
2733 dma_cookie_t completed_cookie; /* The maximum cookie completed */
2834 spinlock_t desc_lock; /* Descriptor operation lock */
@@ -38,6 +44,7 @@ struct sh_dmae_chan { · 9 unmodified lines
3844 u32 __iomem *base;
3945 char dev_id[16]; /* unique name per DMAC of channel */
4046 int pm_error;
47+ enum dmae_pm_state pm_state;
4148 };
4249
4350 struct sh_dmae_device {
drivers/dma/timb_dma.c+2−3
@@ -753,7 +753,7 @@ static int __devinit td_probe(struct platform_device *pdev) · 752 unmodified lines
753753
754754 INIT_LIST_HEAD(&td->dma.channels);
755755
756− for (i = 0; i < pdata->nr_channels; i++, td->dma.chancnt++) {
756+ for (i = 0; i < pdata->nr_channels; i++) {
757757 struct timb_dma_chan *td_chan = &td->channels[i];
758758 struct timb_dma_platform_data_channel *pchan =
759759 pdata->channels + i;
@@ -762,12 +762,11 @@ static int __devinit td_probe(struct platform_device *pdev) · 2 unmodified lines
762762 if ((i % 2) == pchan->rx) {
763763 dev_err(&pdev->dev, "Wrong channel configuration\n");
764764 err = -EINVAL;
765− goto err_tasklet_kill;
765+ goto err_free_irq;
766766 }
767767
768768 td_chan->chan.device = &td->dma;
769769 td_chan->chan.cookie = 1;
770− td_chan->chan.chan_id = i;
771770 spin_lock_init(&td_chan->lock);
772771 INIT_LIST_HEAD(&td_chan->active_list);
773772 INIT_LIST_HEAD(&td_chan->queue);
drivers/mmc/host/s3cmci.c+3−3
@@ -913,9 +913,9 @@ request_done: · 912 unmodified lines
913913 }
914914
915915 static void s3cmci_dma_setup(struct s3cmci_host *host,
916− enum s3c2410_dmasrc source)
916+ enum dma_data_direction source)
917917 {
918− static enum s3c2410_dmasrc last_source = -1;
918+ static enum dma_data_direction last_source = -1;
919919 static int setup_ok;
920920
921921 if (last_source == source)
@@ -1087,7 +1087,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data) · 165 unmodified lines
10871087
10881088 BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
10891089
1090− s3cmci_dma_setup(host, rw ? S3C2410_DMASRC_MEM : S3C2410_DMASRC_HW);
1090+ s3cmci_dma_setup(host, rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
10911091 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
10921092
10931093 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
drivers/spi/spi-s3c64xx.c+92−83
@@ -131,6 +131,12 @@ · 130 unmodified lines
131131 #define RXBUSY (1<<2)
132132 #define TXBUSY (1<<3)
133133
134+struct s3c64xx_spi_dma_data {
135+ unsigned ch;
136+ enum dma_data_direction direction;
137+ enum dma_ch dmach;
138+};
139+
134140 /**
135141 * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver.
136142 * @clk: Pointer to the spi clock.
@@ -164,13 +170,14 @@ struct s3c64xx_spi_driver_data { · 27 unmodified lines
164170 struct work_struct work;
165171 struct list_head queue;
166172 spinlock_t lock;
167− enum dma_ch rx_dmach;
168− enum dma_ch tx_dmach;
169173 unsigned long sfr_start;
170174 struct completion xfer_completion;
171175 unsigned state;
172176 unsigned cur_mode, cur_bpw;
173177 unsigned cur_speed;
178+ struct s3c64xx_spi_dma_data rx_dma;
179+ struct s3c64xx_spi_dma_data tx_dma;
180+ struct samsung_dma_ops *ops;
174181 };
175182
176183 static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
@@ -226,6 +233,78 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) · 49 unmodified lines
226233 writel(val, regs + S3C64XX_SPI_CH_CFG);
227234 }
228235
236+static void s3c64xx_spi_dmacb(void *data)
237+{
238+ struct s3c64xx_spi_driver_data *sdd;
239+ struct s3c64xx_spi_dma_data *dma = data;
240+ unsigned long flags;
241+
242+ if (dma->direction == DMA_FROM_DEVICE)
243+ sdd = container_of(data,
244+ struct s3c64xx_spi_driver_data, rx_dma);
245+ else
246+ sdd = container_of(data,
247+ struct s3c64xx_spi_driver_data, tx_dma);
248+
249+ spin_lock_irqsave(&sdd->lock, flags);
250+
251+ if (dma->direction == DMA_FROM_DEVICE) {
252+ sdd->state &= ~RXBUSY;
253+ if (!(sdd->state & TXBUSY))
254+ complete(&sdd->xfer_completion);
255+ } else {
256+ sdd->state &= ~TXBUSY;
257+ if (!(sdd->state & RXBUSY))
258+ complete(&sdd->xfer_completion);
259+ }
260+
261+ spin_unlock_irqrestore(&sdd->lock, flags);
262+}
263+
264+static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
265+ unsigned len, dma_addr_t buf)
266+{
267+ struct s3c64xx_spi_driver_data *sdd;
268+ struct samsung_dma_prep_info info;
269+
270+ if (dma->direction == DMA_FROM_DEVICE)
271+ sdd = container_of((void *)dma,
272+ struct s3c64xx_spi_driver_data, rx_dma);
273+ else
274+ sdd = container_of((void *)dma,
275+ struct s3c64xx_spi_driver_data, tx_dma);
276+
277+ info.cap = DMA_SLAVE;
278+ info.len = len;
279+ info.fp = s3c64xx_spi_dmacb;
280+ info.fp_param = dma;
281+ info.direction = dma->direction;
282+ info.buf = buf;
283+
284+ sdd->ops->prepare(dma->ch, &info);
285+ sdd->ops->trigger(dma->ch);
286+}
287+
288+static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
289+{
290+ struct samsung_dma_info info;
291+
292+ sdd->ops = samsung_dma_get_ops();
293+
294+ info.cap = DMA_SLAVE;
295+ info.client = &s3c64xx_spi_dma_client;
296+ info.width = sdd->cur_bpw / 8;
297+
298+ info.direction = sdd->rx_dma.direction;
299+ info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
300+ sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info);
301+ info.direction = sdd->tx_dma.direction;
302+ info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
303+ sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info);
304+
305+ return 1;
306+}
307+
229308 static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
230309 struct spi_device *spi,
231310 struct spi_transfer *xfer, int dma_mode)
@@ -258,10 +337,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, · 26 unmodified lines
258337 chcfg |= S3C64XX_SPI_CH_TXCH_ON;
259338 if (dma_mode) {
260339 modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
261− s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8);
262− s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd,
263− xfer->tx_dma, xfer->len);
264− s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START);
340+ prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma);
265341 } else {
266342 switch (sdd->cur_bpw) {
267343 case 32:
@@ -293,10 +369,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, · 25 unmodified lines
293369 writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff)
294370 | S3C64XX_SPI_PACKET_CNT_EN,
295371 regs + S3C64XX_SPI_PACKET_CNT);
296− s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8);
297− s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd,
298− xfer->rx_dma, xfer->len);
299− s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START);
372+ prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma);
300373 }
301374 }
302375
@@ -482,46 +555,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) · 179 unmodified lines
482555 }
483556 }
484557
485−static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id,
486− int size, enum s3c2410_dma_buffresult res)
487−{
488− struct s3c64xx_spi_driver_data *sdd = buf_id;
489− unsigned long flags;
490−
491− spin_lock_irqsave(&sdd->lock, flags);
492−
493− if (res == S3C2410_RES_OK)
494− sdd->state &= ~RXBUSY;
495− else
496− dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size);
497−
498− /* If the other done */
499− if (!(sdd->state & TXBUSY))
500− complete(&sdd->xfer_completion);
501−
502− spin_unlock_irqrestore(&sdd->lock, flags);
503−}
504−
505−static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id,
506− int size, enum s3c2410_dma_buffresult res)
507−{
508− struct s3c64xx_spi_driver_data *sdd = buf_id;
509− unsigned long flags;
510−
511− spin_lock_irqsave(&sdd->lock, flags);
512−
513− if (res == S3C2410_RES_OK)
514− sdd->state &= ~TXBUSY;
515− else
516− dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size);
517−
518− /* If the other done */
519− if (!(sdd->state & RXBUSY))
520− complete(&sdd->xfer_completion);
521−
522− spin_unlock_irqrestore(&sdd->lock, flags);
523−}
524−
525558 #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32)
526559
527560 static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
@@ -696,12 +729,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd, · 168 unmodified lines
696729 if (use_dma) {
697730 if (xfer->tx_buf != NULL
698731 && (sdd->state & TXBUSY))
699− s3c2410_dma_ctrl(sdd->tx_dmach,
700− S3C2410_DMAOP_FLUSH);
732+ sdd->ops->stop(sdd->tx_dma.ch);
701733 if (xfer->rx_buf != NULL
702734 && (sdd->state & RXBUSY))
703− s3c2410_dma_ctrl(sdd->rx_dmach,
704− S3C2410_DMAOP_FLUSH);
735+ sdd->ops->stop(sdd->rx_dma.ch);
705736 }
706737
707738 goto out;
@@ -739,30 +770,6 @@ out: · 31 unmodified lines
739770 msg->complete(msg->context);
740771 }
741772
742−static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
743−{
744− if (s3c2410_dma_request(sdd->rx_dmach,
745− &s3c64xx_spi_dma_client, NULL) < 0) {
746− dev_err(&sdd->pdev->dev, "cannot get RxDMA\n");
747− return 0;
748− }
749− s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb);
750− s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW,
751− sdd->sfr_start + S3C64XX_SPI_RX_DATA);
752−
753− if (s3c2410_dma_request(sdd->tx_dmach,
754− &s3c64xx_spi_dma_client, NULL) < 0) {
755− dev_err(&sdd->pdev->dev, "cannot get TxDMA\n");
756− s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
757− return 0;
758− }
759− s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb);
760− s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM,
761− sdd->sfr_start + S3C64XX_SPI_TX_DATA);
762−
763− return 1;
764−}
765−
766773 static void s3c64xx_spi_work(struct work_struct *work)
767774 {
768775 struct s3c64xx_spi_driver_data *sdd = container_of(work,
@@ -799,8 +806,8 @@ static void s3c64xx_spi_work(struct work_struct *work) · 30 unmodified lines
799806 spin_unlock_irqrestore(&sdd->lock, flags);
800807
801808 /* Free DMA channels */
802− s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client);
803− s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client);
809+ sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client);
810+ sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client);
804811 }
805812
806813 static int s3c64xx_spi_transfer(struct spi_device *spi,
@@ -1017,8 +1024,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) · 210 unmodified lines
10171024 sdd->cntrlr_info = sci;
10181025 sdd->pdev = pdev;
10191026 sdd->sfr_start = mem_res->start;
1020− sdd->tx_dmach = dmatx_res->start;
1021− sdd->rx_dmach = dmarx_res->start;
1027+ sdd->tx_dma.dmach = dmatx_res->start;
1028+ sdd->tx_dma.direction = DMA_TO_DEVICE;
1029+ sdd->rx_dma.dmach = dmarx_res->start;
1030+ sdd->rx_dma.direction = DMA_FROM_DEVICE;
10221031
10231032 sdd->cur_bpw = 8;
10241033
@@ -1106,7 +1115,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) · 81 unmodified lines
11061115 pdev->id, master->num_chipselect);
11071116 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n",
11081117 mem_res->end, mem_res->start,
1109− sdd->rx_dmach, sdd->tx_dmach);
1118+ sdd->rx_dma.dmach, sdd->tx_dma.dmach);
11101119
11111120 return 0;
11121121
drivers/tty/serial/sh-sci.c+8−17
@@ -1446,12 +1446,8 @@ static bool filter(struct dma_chan *chan, void *slave) · 1445 unmodified lines
14461446 dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__,
14471447 param->slave_id);
14481448
1449− if (param->dma_dev == chan->device->dev) {
1450− chan->private = param;
1451− return true;
1452− } else {
1453− return false;
1454− }
1449+ chan->private = param;
1450+ return true;
14551451 }
14561452
14571453 static void rx_timer_fn(unsigned long arg)
@@ -1477,10 +1473,10 @@ static void sci_request_dma(struct uart_port *port) · 19 unmodified lines
14771473 dma_cap_mask_t mask;
14781474 int nent;
14791475
1480− dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__,
1481− port->line, s->cfg->dma_dev);
1476+ dev_dbg(port->dev, "%s: port %d\n", __func__,
1477+ port->line);
14821478
1483− if (!s->cfg->dma_dev)
1479+ if (s->cfg->dma_slave_tx <= 0 || s->cfg->dma_slave_rx <= 0)
14841480 return;
14851481
14861482 dma_cap_zero(mask);
@@ -1490,7 +1486,6 @@ static void sci_request_dma(struct uart_port *port) · 3 unmodified lines
14901486
14911487 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
14921488 param->slave_id = s->cfg->dma_slave_tx;
1493− param->dma_dev = s->cfg->dma_dev;
14941489
14951490 s->cookie_tx = -EINVAL;
14961491 chan = dma_request_channel(mask, filter, param);
@@ -1519,7 +1514,6 @@ static void sci_request_dma(struct uart_port *port) · 22 unmodified lines
15191514
15201515 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
15211516 param->slave_id = s->cfg->dma_slave_rx;
1522− param->dma_dev = s->cfg->dma_dev;
15231517
15241518 chan = dma_request_channel(mask, filter, param);
15251519 dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
@@ -1564,9 +1558,6 @@ static void sci_free_dma(struct uart_port *port) · 38 unmodified lines
15641558 {
15651559 struct sci_port *s = to_sci_port(port);
15661560
1567− if (!s->cfg->dma_dev)
1568− return;
1569−
15701561 if (s->chan_tx)
15711562 sci_tx_dma_release(s, false);
15721563 if (s->chan_rx)
@@ -1981,9 +1972,9 @@ static int __devinit sci_init_single(struct platform_device *dev, · 408 unmodified lines
19811972 port->serial_in = sci_serial_in;
19821973 port->serial_out = sci_serial_out;
19831974
1984− if (p->dma_dev)
1985− dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n",
1986− p->dma_dev, p->dma_slave_tx, p->dma_slave_rx);
1975+ if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0)
1976+ dev_dbg(port->dev, "DMA tx %d, rx %d\n",
1977+ p->dma_slave_tx, p->dma_slave_rx);
19871978
19881979 return 0;
19891980 }
include/linux/amba/pl08x.h+25−5
@@ -47,6 +47,9 @@ enum { · 46 unmodified lines
4747 * @muxval: a number usually used to poke into some mux regiser to
4848 * mux in the signal to this channel
4949 * @cctl_opt: default options for the channel control register
50+ * @device_fc: Flow Controller Settings for ccfg register. Only valid for slave
51+ * channels. Fill with 'true' if peripheral should be flow controller. Direction
52+ * will be selected at Runtime.
5053 * @addr: source/target address in physical memory for this DMA channel,
5154 * can be the address of a FIFO register for burst requests for example.
5255 * This can be left undefined if the PrimeCell API is used for configuring
@@ -65,6 +68,7 @@ struct pl08x_channel_data { · 12 unmodified lines
6568 int max_signal;
6669 u32 muxval;
6770 u32 cctl;
71+ bool device_fc;
6872 dma_addr_t addr;
6973 bool circular_buffer;
7074 bool single;
@@ -77,13 +81,11 @@ struct pl08x_channel_data { · 6 unmodified lines
7781 * @addr: current address
7882 * @maxwidth: the maximum width of a transfer on this bus
7983 * @buswidth: the width of this bus in bytes: 1, 2 or 4
80− * @fill_bytes: bytes required to fill to the next bus memory boundary
8184 */
8285 struct pl08x_bus_data {
8386 dma_addr_t addr;
8487 u8 maxwidth;
8588 u8 buswidth;
86− size_t fill_bytes;
8789 };
8890
8991 /**
@@ -103,18 +105,36 @@ struct pl08x_phy_chan { · 13 unmodified lines
103105 struct pl08x_dma_chan *serving;
104106 };
105107
108+/**
109+ * struct pl08x_sg - structure containing data per sg
110+ * @src_addr: src address of sg
111+ * @dst_addr: dst address of sg
112+ * @len: transfer len in bytes
113+ * @node: node for txd's dsg_list
114+ */
115+struct pl08x_sg {
116+ dma_addr_t src_addr;
117+ dma_addr_t dst_addr;
118+ size_t len;
119+ struct list_head node;
120+};
121+
106122 /**
107123 * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
124+ * @tx: async tx descriptor
125+ * @node: node for txd list for channels
126+ * @dsg_list: list of children sg's
127+ * @direction: direction of transfer
108128 * @llis_bus: DMA memory address (physical) start for the LLIs
109129 * @llis_va: virtual memory address start for the LLIs
130+ * @cctl: control reg values for current txd
131+ * @ccfg: config reg values for current txd
110132 */
111133 struct pl08x_txd {
112134 struct dma_async_tx_descriptor tx;
113135 struct list_head node;
136+ struct list_head dsg_list;
114137 enum dma_data_direction direction;
115− dma_addr_t src_addr;
116− dma_addr_t dst_addr;
117− size_t len;
118138 dma_addr_t llis_bus;
119139 struct pl08x_lli *llis_va;
120140 /* Default cctl value for LLIs */
include/linux/amba/pl330.h+1−5
@@ -19,12 +19,8 @@ struct dma_pl330_peri { · 18 unmodified lines
1919 * Peri_Req i/f of the DMAC that is
2020 * peripheral could be reached from.
2121 */
22− u8 peri_id; /* {0, 31} */
22+ u8 peri_id; /* specific dma id */
2323 enum pl330_reqtype rqtype;
24−
25− /* For M->D and D->M Channels */
26− int burst_sz; /* in power of 2 */
27− dma_addr_t fifo_addr;
2824 };
2925
3026 struct dma_pl330_platdata {
include/linux/dmaengine.h+11−2
@@ -24,8 +24,7 @@ · 23 unmodified lines
2424 #include <linux/device.h>
2525 #include <linux/uio.h>
2626 #include <linux/dma-direction.h>
27−
28−struct scatterlist;
27+#include <linux/scatterlist.h>
2928
3029 /**
3130 * typedef dma_cookie_t - an opaque DMA cookie
@@ -519,6 +518,16 @@ static inline int dmaengine_slave_config(struct dma_chan *chan, · 487 unmodified lines
519518 (unsigned long)config);
520519 }
521520
521+static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single(
522+ struct dma_chan *chan, void *buf, size_t len,
523+ enum dma_data_direction dir, unsigned long flags)
524+{
525+ struct scatterlist sg;
526+ sg_init_one(&sg, buf, len);
527+
528+ return chan->device->device_prep_slave_sg(chan, &sg, 1, dir, flags);
529+}
530+
522531 static inline int dmaengine_terminate_all(struct dma_chan *chan)
523532 {
524533 return dmaengine_device_control(chan, DMA_TERMINATE_ALL, 0);
include/linux/serial_sci.h+0−2
@@ -131,8 +131,6 @@ struct plat_sci_port { · 130 unmodified lines
131131
132132 struct plat_sci_port_ops *ops;
133133
134− struct device *dma_dev;
135−
136134 unsigned int dma_slave_tx;
137135 unsigned int dma_slave_rx;
138136 };
sound/soc/samsung/ac97.c+8−2
@@ -271,7 +271,10 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, · 270 unmodified lines
271271
272272 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
273273
274− s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
274+ if (!dma_data->ops)
275+ dma_data->ops = samsung_dma_get_ops();
276+
277+ dma_data->ops->started(dma_data->channel);
275278
276279 return 0;
277280 }
@@ -317,7 +320,10 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, · 39 unmodified lines
317320
318321 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
319322
320− s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
323+ if (!dma_data->ops)
324+ dma_data->ops = samsung_dma_get_ops();
325+
326+ dma_data->ops->started(dma_data->channel);
321327
322328 return 0;
323329 }
sound/soc/samsung/dma.c+60−86
@@ -54,7 +54,6 @@ struct runtime_data { · 53 unmodified lines
5454 spinlock_t lock;
5555 int state;
5656 unsigned int dma_loaded;
57− unsigned int dma_limit;
5857 unsigned int dma_period;
5958 dma_addr_t dma_start;
6059 dma_addr_t dma_pos;
@@ -62,77 +61,79 @@ struct runtime_data { · 1 unmodified line
6261 struct s3c_dma_params *params;
6362 };
6463
64+static void audio_buffdone(void *data);
65+
6566 /* dma_enqueue
6667 *
6768 * place a dma buffer onto the queue for the dma system
6869 * to handle.
69−*/
70+ */
7071 static void dma_enqueue(struct snd_pcm_substream *substream)
7172 {
7273 struct runtime_data *prtd = substream->runtime->private_data;
7374 dma_addr_t pos = prtd->dma_pos;
7475 unsigned int limit;
75− int ret;
76+ struct samsung_dma_prep_info dma_info;
7677
7778 pr_debug("Entered %s\n", __func__);
7879
79− if (s3c_dma_has_circular())
80− limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
81− else
82− limit = prtd->dma_limit;
80+ limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
8381
8482 pr_debug("%s: loaded %d, limit %d\n",
8583 __func__, prtd->dma_loaded, limit);
8684
87− while (prtd->dma_loaded < limit) {
88− unsigned long len = prtd->dma_period;
85+ dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE);
86+ dma_info.direction =
87+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
88+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
89+ dma_info.fp = audio_buffdone;
90+ dma_info.fp_param = substream;
91+ dma_info.period = prtd->dma_period;
92+ dma_info.len = prtd->dma_period*limit;
8993
94+ while (prtd->dma_loaded < limit) {
9095 pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
9196
92− if ((pos + len) > prtd->dma_end) {
93− len = prtd->dma_end - pos;
94− pr_debug("%s: corrected dma len %ld\n", __func__, len);
97+ if ((pos + dma_info.period) > prtd->dma_end) {
98+ dma_info.period = prtd->dma_end - pos;
99+ pr_debug("%s: corrected dma len %ld\n",
100+ __func__, dma_info.period);
95101 }
96102
97− ret = s3c2410_dma_enqueue(prtd->params->channel,
98− substream, pos, len);
103+ dma_info.buf = pos;
104+ prtd->params->ops->prepare(prtd->params->ch, &dma_info);
99105
100− if (ret == 0) {
101− prtd->dma_loaded++;
102− pos += prtd->dma_period;
103− if (pos >= prtd->dma_end)
104− pos = prtd->dma_start;
105− } else
106− break;
106+ prtd->dma_loaded++;
107+ pos += prtd->dma_period;
108+ if (pos >= prtd->dma_end)
109+ pos = prtd->dma_start;
107110 }
108111
109112 prtd->dma_pos = pos;
110113 }
111114
112−static void audio_buffdone(struct s3c2410_dma_chan *channel,
113− void *dev_id, int size,
114− enum s3c2410_dma_buffresult result)
115+static void audio_buffdone(void *data)
115116 {
116− struct snd_pcm_substream *substream = dev_id;
117− struct runtime_data *prtd;
117+ struct snd_pcm_substream *substream = data;
118+ struct runtime_data *prtd = substream->runtime->private_data;
118119
119120 pr_debug("Entered %s\n", __func__);
120121
121− if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR)
122− return;
123−
124− prtd = substream->runtime->private_data;
122+ if (prtd->state & ST_RUNNING) {
123+ prtd->dma_pos += prtd->dma_period;
124+ if (prtd->dma_pos >= prtd->dma_end)
125+ prtd->dma_pos = prtd->dma_start;
125126
126− if (substream)
127− snd_pcm_period_elapsed(substream);
127+ if (substream)
128+ snd_pcm_period_elapsed(substream);
128129
129− spin_lock(&prtd->lock);
130− if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
131− prtd->dma_loaded--;
132− dma_enqueue(substream);
130+ spin_lock(&prtd->lock);
131+ if (!samsung_dma_has_circular()) {
132+ prtd->dma_loaded--;
133+ dma_enqueue(substream);
134+ }
135+ spin_unlock(&prtd->lock);
133136 }
134−
135− spin_unlock(&prtd->lock);
136137 }
137138
138139 static int dma_hw_params(struct snd_pcm_substream *substream,
@@ -144,8 +145,7 @@ static int dma_hw_params(struct snd_pcm_substream *substream, · 5 unmodified lines
144145 unsigned long totbytes = params_buffer_bytes(params);
145146 struct s3c_dma_params *dma =
146147 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
147− int ret = 0;
148−
148+ struct samsung_dma_info dma_info;
149149
150150 pr_debug("Entered %s\n", __func__);
151151
@@ -163,30 +163,26 @@ static int dma_hw_params(struct snd_pcm_substream *substream, · 11 unmodified lines
163163 pr_debug("params %p, client %p, channel %d\n", prtd->params,
164164 prtd->params->client, prtd->params->channel);
165165
166− ret = s3c2410_dma_request(prtd->params->channel,
167− prtd->params->client, NULL);
168−
169− if (ret < 0) {
170− printk(KERN_ERR "failed to get dma channel\n");
171− return ret;
172− }
173−
174− /* use the circular buffering if we have it available. */
175− if (s3c_dma_has_circular())
176− s3c2410_dma_setflags(prtd->params->channel,
177− S3C2410_DMAF_CIRCULAR);
166+ prtd->params->ops = samsung_dma_get_ops();
167+
168+ dma_info.cap = (samsung_dma_has_circular() ?
169+ DMA_CYCLIC : DMA_SLAVE);
170+ dma_info.client = prtd->params->client;
171+ dma_info.direction =
172+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
173+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
174+ dma_info.width = prtd->params->dma_size;
175+ dma_info.fifo = prtd->params->dma_addr;
176+ prtd->params->ch = prtd->params->ops->request(
177+ prtd->params->channel, &dma_info);
178178 }
179179
180− s3c2410_dma_set_buffdone_fn(prtd->params->channel,
181− audio_buffdone);
182−
183180 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
184181
185182 runtime->dma_bytes = totbytes;
186183
187184 spin_lock_irq(&prtd->lock);
188185 prtd->dma_loaded = 0;
189− prtd->dma_limit = runtime->hw.periods_min;
190186 prtd->dma_period = params_period_bytes(params);
191187 prtd->dma_start = runtime->dma_addr;
192188 prtd->dma_pos = prtd->dma_start;
@@ -206,7 +202,8 @@ static int dma_hw_free(struct snd_pcm_substream *substream) · 13 unmodified lines
206202 snd_pcm_set_runtime_buffer(substream, NULL);
207203
208204 if (prtd->params) {
209− s3c2410_dma_free(prtd->params->channel, prtd->params->client);
205+ prtd->params->ops->release(prtd->params->ch,
206+ prtd->params->client);
210207 prtd->params = NULL;
211208 }
212209
@@ -225,23 +222,9 @@ static int dma_prepare(struct snd_pcm_substream *substream) · 12 unmodified lines
225222 if (!prtd->params)
226223 return 0;
227224
228− /* channel needs configuring for mem=>device, increment memory addr,
229− * sync to pclk, half-word transfers to the IIS-FIFO. */
230− if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
231− s3c2410_dma_devconfig(prtd->params->channel,
232− S3C2410_DMASRC_MEM,
233− prtd->params->dma_addr);
234− } else {
235− s3c2410_dma_devconfig(prtd->params->channel,
236− S3C2410_DMASRC_HW,
237− prtd->params->dma_addr);
238− }
239−
240− s3c2410_dma_config(prtd->params->channel,
241− prtd->params->dma_size);
242−
243225 /* flush the DMA channel */
244− s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
226+ prtd->params->ops->flush(prtd->params->ch);
227+
245228 prtd->dma_loaded = 0;
246229 prtd->dma_pos = prtd->dma_start;
247230
@@ -265,14 +248,14 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd) · 17 unmodified lines
265248 case SNDRV_PCM_TRIGGER_RESUME:
266249 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
267250 prtd->state |= ST_RUNNING;
268− s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
251+ prtd->params->ops->trigger(prtd->params->ch);
269252 break;
270253
271254 case SNDRV_PCM_TRIGGER_STOP:
272255 case SNDRV_PCM_TRIGGER_SUSPEND:
273256 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
274257 prtd->state &= ~ST_RUNNING;
275− s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP);
258+ prtd->params->ops->stop(prtd->params->ch);
276259 break;
277260
278261 default:
@@ -291,21 +274,12 @@ dma_pointer(struct snd_pcm_substream *substream) · 12 unmodified lines
291274 struct snd_pcm_runtime *runtime = substream->runtime;
292275 struct runtime_data *prtd = runtime->private_data;
293276 unsigned long res;
294− dma_addr_t src, dst;
295277
296278 pr_debug("Entered %s\n", __func__);
297279
298− spin_lock(&prtd->lock);
299− s3c2410_dma_getposition(prtd->params->channel, &src, &dst);
300−
301− if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
302− res = dst - prtd->dma_start;
303− else
304− res = src - prtd->dma_start;
305−
306− spin_unlock(&prtd->lock);
280+ res = prtd->dma_pos - prtd->dma_start;
307281
308− pr_debug("Pointer %x %x\n", src, dst);
282+ pr_debug("Pointer offset: %lu\n", res);
309283
310284 /* we seem to be getting the odd error from the pcm library due
311285 * to out-of-bounds pointers. this is maybe due to the dma engine
sound/soc/samsung/dma.h+3−1
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 * Free Software Foundation; either version 2 of the License, or (at your
77 * option) any later version.
88 *
9− * ALSA PCM interface for the Samsung S3C24xx CPU
9+ * ALSA PCM interface for the Samsung SoC
1010 */
1111
1212 #ifndef _S3C_AUDIO_H
@@ -17,6 +17,8 @@ struct s3c_dma_params { · 4 unmodified lines
1717 int channel; /* Channel ID */
1818 dma_addr_t dma_addr;
1919 int dma_size; /* Size of the DMA transfer */
20+ unsigned ch;
21+ struct samsung_dma_ops *ops;
2022 };
2123
2224 #endif