aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKukjin Kim <kgene.kim@samsung.com>2012-07-19 01:20:32 -0400
committerKukjin Kim <kgene.kim@samsung.com>2012-07-19 01:20:32 -0400
commitf9ed561ebd71f7a9a3238507ef9082862e2cbc9a (patch)
tree7d3e22c4b7db44ab6621c6ec7094a0dc041287c9
parent84a1caf1453c3d44050bd22db958af4a7f99315c (diff)
parent79989ba3e201f3bf992e600a0745ecaf256f08f5 (diff)
Merge branch 'next/dt-samsung' into next/devel-samsung-spi
-rw-r--r--Documentation/devicetree/bindings/spi/spi-samsung.txt113
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts12
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts38
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi47
-rw-r--r--arch/arm/boot/dts/exynos5250-smdk5250.dts38
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi36
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.c67
-rw-r--r--arch/arm/mach-exynos/clock-exynos5.c95
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h3
-rw-r--r--arch/arm/mach-exynos/mach-exynos4-dt.c6
-rw-r--r--arch/arm/mach-exynos/mach-exynos5-dt.c6
-rw-r--r--arch/arm/mach-exynos/setup-spi.c33
-rw-r--r--arch/arm/mach-s3c24xx/clock-s3c2416.c3
-rw-r--r--arch/arm/mach-s3c24xx/clock-s3c2443.c2
-rw-r--r--arch/arm/mach-s3c24xx/common-s3c2443.c4
-rw-r--r--arch/arm/mach-s3c24xx/setup-spi.c10
-rw-r--r--arch/arm/mach-s3c64xx/clock.c20
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h1
-rw-r--r--arch/arm/mach-s3c64xx/mach-crag6410.c2
-rw-r--r--arch/arm/mach-s3c64xx/setup-spi.c19
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c12
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c12
-rw-r--r--arch/arm/mach-s5p64x0/setup-spi.c21
-rw-r--r--arch/arm/mach-s5pc100/clock.c30
-rw-r--r--arch/arm/mach-s5pc100/setup-spi.c30
-rw-r--r--arch/arm/mach-s5pv210/clock.c14
-rw-r--r--arch/arm/mach-s5pv210/setup-spi.c21
-rw-r--r--arch/arm/plat-samsung/devs.c60
-rw-r--r--arch/arm/plat-samsung/dma-ops.c76
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-ops.h20
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h39
-rw-r--r--arch/arm/plat-samsung/s3c-dma-ops.c39
-rw-r--r--drivers/spi/spi-s3c64xx.c512
-rw-r--r--sound/soc/samsung/dma.c18
35 files changed, 1057 insertions, 406 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
new file mode 100644
index 000000000000..59bfc4f9feb3
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt
@@ -0,0 +1,113 @@
1* Samsung SPI Controller
2
3The Samsung SPI controller is used to interface with various devices such as flash
4and display controllers using the SPI communication interface.
5
6Required SoC Specific Properties:
7
8- compatible: should be one of the following.
9 - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
10 - samsung,s3c6410-spi: for s3c6410 platforms
11 - samsung,s5p6440-spi: for s5p6440 and s5p6450 platforms
12 - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
13 - samsung,exynos4210-spi: for exynos4 and exynos5 platforms
14
15- reg: physical base address of the controller and length of memory mapped
16 region.
17
18- interrupts: The interrupt number to the cpu. The interrupt specifier format
19 depends on the interrupt controller.
20
21- tx-dma-channel: The dma channel specifier for tx operations. The format of
22 the dma specifier depends on the dma controller.
23
24- rx-dma-channel: The dma channel specifier for rx operations. The format of
25 the dma specifier depends on the dma controller.
26
27Required Board Specific Properties:
28
29- #address-cells: should be 1.
30- #size-cells: should be 0.
31- gpios: The gpio specifier for clock, mosi and miso interface lines (in the
32 order specified). The format of the gpio specifier depends on the gpio
33 controller.
34
35Optional Board Specific Properties:
36
37- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
38 select the clock source for the spi bus clock, this property can be used to
39 indicate the clock to be used for driving the spi bus clock. If not specified,
40 the clock number 0 is used as default.
41
42- num-cs: Specifies the number of chip select lines supported. If
43 not specified, the default number of chip select lines is set to 1.
44
45SPI Controller specific data in SPI slave nodes:
46
47- The spi slave nodes should provide the following information which is required
48 by the spi controller.
49
50 - cs-gpio: A gpio specifier that specifies the gpio line used as
51 the slave select line by the spi controller. The format of the gpio
52 specifier depends on the gpio controller.
53
54 - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
55 miso line (to account for any lag in the miso line). The following are the
56 valid values.
57
58 - 0: No phase shift.
59 - 1: 90 degree phase shift sampling.
60 - 2: 180 degree phase shift sampling.
61 - 3: 270 degree phase shift sampling.
62
63Aliases:
64
65- All the SPI controller nodes should be represented in the aliases node using
66 the following format 'spi{n}' where n is a unique number for the alias.
67
68
69Example:
70
71- SoC Specific Portion:
72
73 spi_0: spi@12d20000 {
74 compatible = "samsung,exynos4210-spi";
75 reg = <0x12d20000 0x100>;
76 interrupts = <0 66 0>;
77 tx-dma-channel = <&pdma0 5>;
78 rx-dma-channel = <&pdma0 4>;
79 };
80
81- Board Specific Portion:
82
83 spi_0: spi@12d20000 {
84 #address-cells = <1>;
85 #size-cells = <0>;
86 gpios = <&gpa2 4 2 3 0>,
87 <&gpa2 6 2 3 0>,
88 <&gpa2 7 2 3 0>;
89
90 w25q80bw@0 {
91 #address-cells = <1>;
92 #size-cells = <1>;
93 compatible = "w25x80";
94 reg = <0>;
95 spi-max-frequency = <10000>;
96
97 controller-data {
98 cs-gpio = <&gpa2 5 1 0 3>;
99 samsung,spi-feedback-delay = <0>;
100 };
101
102 partition@0 {
103 label = "U-Boot";
104 reg = <0x0 0x40000>;
105 read-only;
106 };
107
108 partition@40000 {
109 label = "Kernel";
110 reg = <0x40000 0xc0000>;
111 };
112 };
113 };
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index b8c476384eef..0c49caa09978 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -134,4 +134,16 @@
134 i2c@138D0000 { 134 i2c@138D0000 {
135 status = "disabled"; 135 status = "disabled";
136 }; 136 };
137
138 spi_0: spi@13920000 {
139 status = "disabled";
140 };
141
142 spi_1: spi@13930000 {
143 status = "disabled";
144 };
145
146 spi_2: spi@13940000 {
147 status = "disabled";
148 };
137}; 149};
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 27afc8e535ca..1beccc8f14ff 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -179,4 +179,42 @@
179 i2c@138D0000 { 179 i2c@138D0000 {
180 status = "disabled"; 180 status = "disabled";
181 }; 181 };
182
183 spi_0: spi@13920000 {
184 status = "disabled";
185 };
186
187 spi_1: spi@13930000 {
188 status = "disabled";
189 };
190
191 spi_2: spi@13940000 {
192 gpios = <&gpc1 1 5 3 0>,
193 <&gpc1 3 5 3 0>,
194 <&gpc1 4 5 3 0>;
195
196 w25x80@0 {
197 #address-cells = <1>;
198 #size-cells = <1>;
199 compatible = "w25x80";
200 reg = <0>;
201 spi-max-frequency = <1000000>;
202
203 controller-data {
204 cs-gpio = <&gpc1 2 1 0 3>;
205 samsung,spi-feedback-delay = <0>;
206 };
207
208 partition@0 {
209 label = "U-Boot";
210 reg = <0x0 0x40000>;
211 read-only;
212 };
213
214 partition@40000 {
215 label = "Kernel";
216 reg = <0x40000 0xc0000>;
217 };
218 };
219 };
182}; 220};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index a1dd2ee83753..6904d9dfbf28 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -25,6 +25,12 @@
25 compatible = "samsung,exynos4210"; 25 compatible = "samsung,exynos4210";
26 interrupt-parent = <&gic>; 26 interrupt-parent = <&gic>;
27 27
28 aliases {
29 spi0 = &spi_0;
30 spi1 = &spi_1;
31 spi2 = &spi_2;
32 };
33
28 gic:interrupt-controller@10490000 { 34 gic:interrupt-controller@10490000 {
29 compatible = "arm,cortex-a9-gic"; 35 compatible = "arm,cortex-a9-gic";
30 #interrupt-cells = <3>; 36 #interrupt-cells = <3>;
@@ -33,6 +39,17 @@
33 reg = <0x10490000 0x1000>, <0x10480000 0x100>; 39 reg = <0x10490000 0x1000>, <0x10480000 0x100>;
34 }; 40 };
35 41
42 combiner:interrupt-controller@10440000 {
43 compatible = "samsung,exynos4210-combiner";
44 #interrupt-cells = <2>;
45 interrupt-controller;
46 reg = <0x10440000 0x1000>;
47 interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
48 <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
49 <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
50 <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
51 };
52
36 watchdog@10060000 { 53 watchdog@10060000 {
37 compatible = "samsung,s3c2410-wdt"; 54 compatible = "samsung,s3c2410-wdt";
38 reg = <0x10060000 0x100>; 55 reg = <0x10060000 0x100>;
@@ -147,6 +164,36 @@
147 interrupts = <0 65 0>; 164 interrupts = <0 65 0>;
148 }; 165 };
149 166
167 spi_0: spi@13920000 {
168 compatible = "samsung,exynos4210-spi";
169 reg = <0x13920000 0x100>;
170 interrupts = <0 66 0>;
171 tx-dma-channel = <&pdma0 7>;
172 rx-dma-channel = <&pdma0 6>;
173 #address-cells = <1>;
174 #size-cells = <0>;
175 };
176
177 spi_1: spi@13930000 {
178 compatible = "samsung,exynos4210-spi";
179 reg = <0x13930000 0x100>;
180 interrupts = <0 67 0>;
181 tx-dma-channel = <&pdma1 7>;
182 rx-dma-channel = <&pdma1 6>;
183 #address-cells = <1>;
184 #size-cells = <0>;
185 };
186
187 spi_2: spi@13940000 {
188 compatible = "samsung,exynos4210-spi";
189 reg = <0x13940000 0x100>;
190 interrupts = <0 68 0>;
191 tx-dma-channel = <&pdma0 9>;
192 rx-dma-channel = <&pdma0 8>;
193 #address-cells = <1>;
194 #size-cells = <0>;
195 };
196
150 amba { 197 amba {
151 #address-cells = <1>; 198 #address-cells = <1>;
152 #size-cells = <1>; 199 #size-cells = <1>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 49945cc1bc7d..8a5e348793c7 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -71,4 +71,42 @@
71 i2c@12CD0000 { 71 i2c@12CD0000 {
72 status = "disabled"; 72 status = "disabled";
73 }; 73 };
74
75 spi_0: spi@12d20000 {
76 status = "disabled";
77 };
78
79 spi_1: spi@12d30000 {
80 gpios = <&gpa2 4 2 3 0>,
81 <&gpa2 6 2 3 0>,
82 <&gpa2 7 2 3 0>;
83
84 w25q80bw@0 {
85 #address-cells = <1>;
86 #size-cells = <1>;
87 compatible = "w25x80";
88 reg = <0>;
89 spi-max-frequency = <1000000>;
90
91 controller-data {
92 cs-gpio = <&gpa2 5 1 0 3>;
93 samsung,spi-feedback-delay = <0>;
94 };
95
96 partition@0 {
97 label = "U-Boot";
98 reg = <0x0 0x40000>;
99 read-only;
100 };
101
102 partition@40000 {
103 label = "Kernel";
104 reg = <0x40000 0xc0000>;
105 };
106 };
107 };
108
109 spi_2: spi@12d40000 {
110 status = "disabled";
111 };
74}; 112};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 4272b2949228..a3a2eb2598d7 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -23,6 +23,12 @@
23 compatible = "samsung,exynos5250"; 23 compatible = "samsung,exynos5250";
24 interrupt-parent = <&gic>; 24 interrupt-parent = <&gic>;
25 25
26 aliases {
27 spi0 = &spi_0;
28 spi1 = &spi_1;
29 spi2 = &spi_2;
30 };
31
26 gic:interrupt-controller@10481000 { 32 gic:interrupt-controller@10481000 {
27 compatible = "arm,cortex-a9-gic"; 33 compatible = "arm,cortex-a9-gic";
28 #interrupt-cells = <3>; 34 #interrupt-cells = <3>;
@@ -146,6 +152,36 @@
146 #size-cells = <0>; 152 #size-cells = <0>;
147 }; 153 };
148 154
155 spi_0: spi@12d20000 {
156 compatible = "samsung,exynos4210-spi";
157 reg = <0x12d20000 0x100>;
158 interrupts = <0 66 0>;
159 tx-dma-channel = <&pdma0 5>;
160 rx-dma-channel = <&pdma0 4>;
161 #address-cells = <1>;
162 #size-cells = <0>;
163 };
164
165 spi_1: spi@12d30000 {
166 compatible = "samsung,exynos4210-spi";
167 reg = <0x12d30000 0x100>;
168 interrupts = <0 67 0>;
169 tx-dma-channel = <&pdma1 5>;
170 rx-dma-channel = <&pdma1 4>;
171 #address-cells = <1>;
172 #size-cells = <0>;
173 };
174
175 spi_2: spi@12d40000 {
176 compatible = "samsung,exynos4210-spi";
177 reg = <0x12d40000 0x100>;
178 interrupts = <0 68 0>;
179 tx-dma-channel = <&pdma0 7>;
180 rx-dma-channel = <&pdma0 6>;
181 #address-cells = <1>;
182 #size-cells = <0>;
183 };
184
149 amba { 185 amba {
150 #address-cells = <1>; 186 #address-cells = <1>;
151 #size-cells = <1>; 187 #size-cells = <1>;
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index bcb7db453145..26fe9de35ecb 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -586,17 +586,17 @@ static struct clk exynos4_init_clocks_off[] = {
586 .ctrlbit = (1 << 13), 586 .ctrlbit = (1 << 13),
587 }, { 587 }, {
588 .name = "spi", 588 .name = "spi",
589 .devname = "s3c64xx-spi.0", 589 .devname = "exynos4210-spi.0",
590 .enable = exynos4_clk_ip_peril_ctrl, 590 .enable = exynos4_clk_ip_peril_ctrl,
591 .ctrlbit = (1 << 16), 591 .ctrlbit = (1 << 16),
592 }, { 592 }, {
593 .name = "spi", 593 .name = "spi",
594 .devname = "s3c64xx-spi.1", 594 .devname = "exynos4210-spi.1",
595 .enable = exynos4_clk_ip_peril_ctrl, 595 .enable = exynos4_clk_ip_peril_ctrl,
596 .ctrlbit = (1 << 17), 596 .ctrlbit = (1 << 17),
597 }, { 597 }, {
598 .name = "spi", 598 .name = "spi",
599 .devname = "s3c64xx-spi.2", 599 .devname = "exynos4210-spi.2",
600 .enable = exynos4_clk_ip_peril_ctrl, 600 .enable = exynos4_clk_ip_peril_ctrl,
601 .ctrlbit = (1 << 18), 601 .ctrlbit = (1 << 18),
602 }, { 602 }, {
@@ -1242,40 +1242,67 @@ static struct clksrc_clk exynos4_clk_sclk_mmc3 = {
1242 .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 }, 1242 .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1243}; 1243};
1244 1244
1245static struct clksrc_clk exynos4_clk_mdout_spi0 = {
1246 .clk = {
1247 .name = "mdout_spi",
1248 .devname = "exynos4210-spi.0",
1249 },
1250 .sources = &exynos4_clkset_group,
1251 .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1252 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1253};
1254
1255static struct clksrc_clk exynos4_clk_mdout_spi1 = {
1256 .clk = {
1257 .name = "mdout_spi",
1258 .devname = "exynos4210-spi.1",
1259 },
1260 .sources = &exynos4_clkset_group,
1261 .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1262 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1263};
1264
1265static struct clksrc_clk exynos4_clk_mdout_spi2 = {
1266 .clk = {
1267 .name = "mdout_spi",
1268 .devname = "exynos4210-spi.2",
1269 },
1270 .sources = &exynos4_clkset_group,
1271 .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1272 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1273};
1274
1245static struct clksrc_clk exynos4_clk_sclk_spi0 = { 1275static struct clksrc_clk exynos4_clk_sclk_spi0 = {
1246 .clk = { 1276 .clk = {
1247 .name = "sclk_spi", 1277 .name = "sclk_spi",
1248 .devname = "s3c64xx-spi.0", 1278 .devname = "exynos4210-spi.0",
1279 .parent = &exynos4_clk_mdout_spi0.clk,
1249 .enable = exynos4_clksrc_mask_peril1_ctrl, 1280 .enable = exynos4_clksrc_mask_peril1_ctrl,
1250 .ctrlbit = (1 << 16), 1281 .ctrlbit = (1 << 16),
1251 }, 1282 },
1252 .sources = &exynos4_clkset_group, 1283 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 8, .size = 8 },
1253 .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
1254 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
1255}; 1284};
1256 1285
1257static struct clksrc_clk exynos4_clk_sclk_spi1 = { 1286static struct clksrc_clk exynos4_clk_sclk_spi1 = {
1258 .clk = { 1287 .clk = {
1259 .name = "sclk_spi", 1288 .name = "sclk_spi",
1260 .devname = "s3c64xx-spi.1", 1289 .devname = "exynos4210-spi.1",
1290 .parent = &exynos4_clk_mdout_spi1.clk,
1261 .enable = exynos4_clksrc_mask_peril1_ctrl, 1291 .enable = exynos4_clksrc_mask_peril1_ctrl,
1262 .ctrlbit = (1 << 20), 1292 .ctrlbit = (1 << 20),
1263 }, 1293 },
1264 .sources = &exynos4_clkset_group, 1294 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 24, .size = 8 },
1265 .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
1266 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
1267}; 1295};
1268 1296
1269static struct clksrc_clk exynos4_clk_sclk_spi2 = { 1297static struct clksrc_clk exynos4_clk_sclk_spi2 = {
1270 .clk = { 1298 .clk = {
1271 .name = "sclk_spi", 1299 .name = "sclk_spi",
1272 .devname = "s3c64xx-spi.2", 1300 .devname = "exynos4210-spi.2",
1301 .parent = &exynos4_clk_mdout_spi2.clk,
1273 .enable = exynos4_clksrc_mask_peril1_ctrl, 1302 .enable = exynos4_clksrc_mask_peril1_ctrl,
1274 .ctrlbit = (1 << 24), 1303 .ctrlbit = (1 << 24),
1275 }, 1304 },
1276 .sources = &exynos4_clkset_group, 1305 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 },
1277 .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
1278 .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
1279}; 1306};
1280 1307
1281/* Clock initialization code */ 1308/* Clock initialization code */
@@ -1331,7 +1358,9 @@ static struct clksrc_clk *exynos4_clksrc_cdev[] = {
1331 &exynos4_clk_sclk_spi0, 1358 &exynos4_clk_sclk_spi0,
1332 &exynos4_clk_sclk_spi1, 1359 &exynos4_clk_sclk_spi1,
1333 &exynos4_clk_sclk_spi2, 1360 &exynos4_clk_sclk_spi2,
1334 1361 &exynos4_clk_mdout_spi0,
1362 &exynos4_clk_mdout_spi1,
1363 &exynos4_clk_mdout_spi2,
1335}; 1364};
1336 1365
1337static struct clk_lookup exynos4_clk_lookup[] = { 1366static struct clk_lookup exynos4_clk_lookup[] = {
@@ -1347,9 +1376,9 @@ static struct clk_lookup exynos4_clk_lookup[] = {
1347 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0), 1376 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0),
1348 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1), 1377 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1),
1349 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1), 1378 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1),
1350 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk), 1379 CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk),
1351 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk), 1380 CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk),
1352 CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk), 1381 CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk),
1353}; 1382};
1354 1383
1355static int xtal_rate; 1384static int xtal_rate;
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
index fefa336be2b4..774533c67066 100644
--- a/arch/arm/mach-exynos/clock-exynos5.c
+++ b/arch/arm/mach-exynos/clock-exynos5.c
@@ -131,6 +131,11 @@ static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable)
131 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable); 131 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
132} 132}
133 133
134static int exynos5_clksrc_mask_peric1_ctrl(struct clk *clk, int enable)
135{
136 return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC1, clk, enable);
137}
138
134static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable) 139static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable)
135{ 140{
136 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable); 141 return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable);
@@ -741,6 +746,24 @@ static struct clk exynos5_init_clocks_off[] = {
741 .enable = exynos5_clk_ip_peric_ctrl, 746 .enable = exynos5_clk_ip_peric_ctrl,
742 .ctrlbit = (1 << 14), 747 .ctrlbit = (1 << 14),
743 }, { 748 }, {
749 .name = "spi",
750 .devname = "exynos4210-spi.0",
751 .parent = &exynos5_clk_aclk_66.clk,
752 .enable = exynos5_clk_ip_peric_ctrl,
753 .ctrlbit = (1 << 16),
754 }, {
755 .name = "spi",
756 .devname = "exynos4210-spi.1",
757 .parent = &exynos5_clk_aclk_66.clk,
758 .enable = exynos5_clk_ip_peric_ctrl,
759 .ctrlbit = (1 << 17),
760 }, {
761 .name = "spi",
762 .devname = "exynos4210-spi.2",
763 .parent = &exynos5_clk_aclk_66.clk,
764 .enable = exynos5_clk_ip_peric_ctrl,
765 .ctrlbit = (1 << 18),
766 }, {
744 .name = SYSMMU_CLOCK_NAME, 767 .name = SYSMMU_CLOCK_NAME,
745 .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0), 768 .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0),
746 .enable = &exynos5_clk_ip_mfc_ctrl, 769 .enable = &exynos5_clk_ip_mfc_ctrl,
@@ -1034,6 +1057,69 @@ static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
1034 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 }, 1057 .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
1035}; 1058};
1036 1059
1060static struct clksrc_clk exynos5_clk_mdout_spi0 = {
1061 .clk = {
1062 .name = "mdout_spi",
1063 .devname = "exynos4210-spi.0",
1064 },
1065 .sources = &exynos5_clkset_group,
1066 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 16, .size = 4 },
1067 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 0, .size = 4 },
1068};
1069
1070static struct clksrc_clk exynos5_clk_mdout_spi1 = {
1071 .clk = {
1072 .name = "mdout_spi",
1073 .devname = "exynos4210-spi.1",
1074 },
1075 .sources = &exynos5_clkset_group,
1076 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 20, .size = 4 },
1077 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 16, .size = 4 },
1078};
1079
1080static struct clksrc_clk exynos5_clk_mdout_spi2 = {
1081 .clk = {
1082 .name = "mdout_spi",
1083 .devname = "exynos4210-spi.2",
1084 },
1085 .sources = &exynos5_clkset_group,
1086 .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 24, .size = 4 },
1087 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 0, .size = 4 },
1088};
1089
1090static struct clksrc_clk exynos5_clk_sclk_spi0 = {
1091 .clk = {
1092 .name = "sclk_spi",
1093 .devname = "exynos4210-spi.0",
1094 .parent = &exynos5_clk_mdout_spi0.clk,
1095 .enable = exynos5_clksrc_mask_peric1_ctrl,
1096 .ctrlbit = (1 << 16),
1097 },
1098 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 8, .size = 8 },
1099};
1100
1101static struct clksrc_clk exynos5_clk_sclk_spi1 = {
1102 .clk = {
1103 .name = "sclk_spi",
1104 .devname = "exynos4210-spi.1",
1105 .parent = &exynos5_clk_mdout_spi1.clk,
1106 .enable = exynos5_clksrc_mask_peric1_ctrl,
1107 .ctrlbit = (1 << 20),
1108 },
1109 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 24, .size = 8 },
1110};
1111
1112static struct clksrc_clk exynos5_clk_sclk_spi2 = {
1113 .clk = {
1114 .name = "sclk_spi",
1115 .devname = "exynos4210-spi.2",
1116 .parent = &exynos5_clk_mdout_spi2.clk,
1117 .enable = exynos5_clksrc_mask_peric1_ctrl,
1118 .ctrlbit = (1 << 24),
1119 },
1120 .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 8, .size = 8 },
1121};
1122
1037static struct clksrc_clk exynos5_clksrcs[] = { 1123static struct clksrc_clk exynos5_clksrcs[] = {
1038 { 1124 {
1039 .clk = { 1125 .clk = {
@@ -1148,6 +1234,12 @@ static struct clksrc_clk *exynos5_sysclks[] = {
1148 &exynos5_clk_dout_mmc4, 1234 &exynos5_clk_dout_mmc4,
1149 &exynos5_clk_aclk_acp, 1235 &exynos5_clk_aclk_acp,
1150 &exynos5_clk_pclk_acp, 1236 &exynos5_clk_pclk_acp,
1237 &exynos5_clk_sclk_spi0,
1238 &exynos5_clk_sclk_spi1,
1239 &exynos5_clk_sclk_spi2,
1240 &exynos5_clk_mdout_spi0,
1241 &exynos5_clk_mdout_spi1,
1242 &exynos5_clk_mdout_spi2,
1151}; 1243};
1152 1244
1153static struct clk *exynos5_clk_cdev[] = { 1245static struct clk *exynos5_clk_cdev[] = {
@@ -1176,6 +1268,9 @@ static struct clk_lookup exynos5_clk_lookup[] = {
1176 CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), 1268 CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk),
1177 CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), 1269 CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk),
1178 CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), 1270 CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),
1271 CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos5_clk_sclk_spi0.clk),
1272 CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos5_clk_sclk_spi1.clk),
1273 CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos5_clk_sclk_spi2.clk),
1179 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0), 1274 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),
1180 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1), 1275 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),
1181 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1), 1276 CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1),
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index 7a4b4789eb72..35bced6f9092 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -195,6 +195,10 @@
195#define IRQ_IIC6 EXYNOS4_IRQ_IIC6 195#define IRQ_IIC6 EXYNOS4_IRQ_IIC6
196#define IRQ_IIC7 EXYNOS4_IRQ_IIC7 196#define IRQ_IIC7 EXYNOS4_IRQ_IIC7
197 197
198#define IRQ_SPI0 EXYNOS4_IRQ_SPI0
199#define IRQ_SPI1 EXYNOS4_IRQ_SPI1
200#define IRQ_SPI2 EXYNOS4_IRQ_SPI2
201
198#define IRQ_USB_HOST EXYNOS4_IRQ_USB_HOST 202#define IRQ_USB_HOST EXYNOS4_IRQ_USB_HOST
199#define IRQ_OTG EXYNOS4_IRQ_USB_HSOTG 203#define IRQ_OTG EXYNOS4_IRQ_USB_HSOTG
200 204
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index ca4aa89aa46b..c72b675b3e4b 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -154,6 +154,9 @@
154#define EXYNOS4_PA_SPI0 0x13920000 154#define EXYNOS4_PA_SPI0 0x13920000
155#define EXYNOS4_PA_SPI1 0x13930000 155#define EXYNOS4_PA_SPI1 0x13930000
156#define EXYNOS4_PA_SPI2 0x13940000 156#define EXYNOS4_PA_SPI2 0x13940000
157#define EXYNOS5_PA_SPI0 0x12D20000
158#define EXYNOS5_PA_SPI1 0x12D30000
159#define EXYNOS5_PA_SPI2 0x12D40000
157 160
158#define EXYNOS4_PA_GPIO1 0x11400000 161#define EXYNOS4_PA_GPIO1 0x11400000
159#define EXYNOS4_PA_GPIO2 0x11000000 162#define EXYNOS4_PA_GPIO2 0x11000000
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
index e7e9743543ac..b2b5d5faa748 100644
--- a/arch/arm/mach-exynos/mach-exynos4-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -55,6 +55,12 @@ static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
55 "exynos4-sdhci.3", NULL), 55 "exynos4-sdhci.3", NULL),
56 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0), 56 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
57 "s3c2440-i2c.0", NULL), 57 "s3c2440-i2c.0", NULL),
58 OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI0,
59 "exynos4210-spi.0", NULL),
60 OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI1,
61 "exynos4210-spi.1", NULL),
62 OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI2,
63 "exynos4210-spi.2", NULL),
58 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL), 64 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
59 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL), 65 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
60 {}, 66 {},
diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c
index 7b1e11a228cc..ef770bc2318f 100644
--- a/arch/arm/mach-exynos/mach-exynos5-dt.c
+++ b/arch/arm/mach-exynos/mach-exynos5-dt.c
@@ -47,6 +47,12 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
47 "s3c2440-i2c.0", NULL), 47 "s3c2440-i2c.0", NULL),
48 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1), 48 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
49 "s3c2440-i2c.1", NULL), 49 "s3c2440-i2c.1", NULL),
50 OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI0,
51 "exynos4210-spi.0", NULL),
52 OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI1,
53 "exynos4210-spi.1", NULL),
54 OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI2,
55 "exynos4210-spi.2", NULL),
50 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL), 56 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
51 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL), 57 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
52 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL), 58 OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
diff --git a/arch/arm/mach-exynos/setup-spi.c b/arch/arm/mach-exynos/setup-spi.c
index 833ff40ee0e8..4999829d1c6e 100644
--- a/arch/arm/mach-exynos/setup-spi.c
+++ b/arch/arm/mach-exynos/setup-spi.c
@@ -9,21 +9,10 @@
9 */ 9 */
10 10
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h> 12#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16 13
17#ifdef CONFIG_S3C64XX_DEV_SPI0 14#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { 15int s3c64xx_spi0_cfg_gpio(void)
19 .fifo_lvl_mask = 0x1ff,
20 .rx_lvl_offset = 15,
21 .high_speed = 1,
22 .clk_from_cmu = true,
23 .tx_st_done = 25,
24};
25
26int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
27{ 16{
28 s3c_gpio_cfgpin(EXYNOS4_GPB(0), S3C_GPIO_SFN(2)); 17 s3c_gpio_cfgpin(EXYNOS4_GPB(0), S3C_GPIO_SFN(2));
29 s3c_gpio_setpull(EXYNOS4_GPB(0), S3C_GPIO_PULL_UP); 18 s3c_gpio_setpull(EXYNOS4_GPB(0), S3C_GPIO_PULL_UP);
@@ -34,15 +23,7 @@ int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
34#endif 23#endif
35 24
36#ifdef CONFIG_S3C64XX_DEV_SPI1 25#ifdef CONFIG_S3C64XX_DEV_SPI1
37struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { 26int s3c64xx_spi1_cfg_gpio(void)
38 .fifo_lvl_mask = 0x7f,
39 .rx_lvl_offset = 15,
40 .high_speed = 1,
41 .clk_from_cmu = true,
42 .tx_st_done = 25,
43};
44
45int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
46{ 27{
47 s3c_gpio_cfgpin(EXYNOS4_GPB(4), S3C_GPIO_SFN(2)); 28 s3c_gpio_cfgpin(EXYNOS4_GPB(4), S3C_GPIO_SFN(2));
48 s3c_gpio_setpull(EXYNOS4_GPB(4), S3C_GPIO_PULL_UP); 29 s3c_gpio_setpull(EXYNOS4_GPB(4), S3C_GPIO_PULL_UP);
@@ -53,15 +34,7 @@ int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
53#endif 34#endif
54 35
55#ifdef CONFIG_S3C64XX_DEV_SPI2 36#ifdef CONFIG_S3C64XX_DEV_SPI2
56struct s3c64xx_spi_info s3c64xx_spi2_pdata __initdata = { 37int s3c64xx_spi2_cfg_gpio(void)
57 .fifo_lvl_mask = 0x7f,
58 .rx_lvl_offset = 15,
59 .high_speed = 1,
60 .clk_from_cmu = true,
61 .tx_st_done = 25,
62};
63
64int s3c64xx_spi2_cfg_gpio(struct platform_device *dev)
65{ 38{
66 s3c_gpio_cfgpin(EXYNOS4_GPC1(1), S3C_GPIO_SFN(5)); 39 s3c_gpio_cfgpin(EXYNOS4_GPC1(1), S3C_GPIO_SFN(5));
67 s3c_gpio_setpull(EXYNOS4_GPC1(1), S3C_GPIO_PULL_UP); 40 s3c_gpio_setpull(EXYNOS4_GPC1(1), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2416.c b/arch/arm/mach-s3c24xx/clock-s3c2416.c
index 8702ecfaab30..14a81c2317a4 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2416.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2416.c
@@ -144,7 +144,8 @@ static struct clk_lookup s3c2416_clk_lookup[] = {
144 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk), 144 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &hsmmc0_clk),
145 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk), 145 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &hsmmc_mux0.clk),
146 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk), 146 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &hsmmc_mux1.clk),
147 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &hsspi_mux.clk), 147 /* s3c2443-spi.0 is used on s3c2416 and s3c2450 as well */
148 CLKDEV_INIT("s3c2443-spi.0", "spi_busclk2", &hsspi_mux.clk),
148}; 149};
149 150
150void __init s3c2416_init_clocks(int xtal) 151void __init s3c2416_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2443.c b/arch/arm/mach-s3c24xx/clock-s3c2443.c
index a4c5a520d994..7f689ce1be61 100644
--- a/arch/arm/mach-s3c24xx/clock-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/clock-s3c2443.c
@@ -181,7 +181,7 @@ static struct clk *clks[] __initdata = {
181 181
182static struct clk_lookup s3c2443_clk_lookup[] = { 182static struct clk_lookup s3c2443_clk_lookup[] = {
183 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_hsmmc), 183 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_hsmmc),
184 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_hsspi.clk), 184 CLKDEV_INIT("s3c2443-spi.0", "spi_busclk2", &clk_hsspi.clk),
185}; 185};
186 186
187void __init s3c2443_init_clocks(int xtal) 187void __init s3c2443_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c24xx/common-s3c2443.c b/arch/arm/mach-s3c24xx/common-s3c2443.c
index aeeb2be283fa..aeb4a24ff3ed 100644
--- a/arch/arm/mach-s3c24xx/common-s3c2443.c
+++ b/arch/arm/mach-s3c24xx/common-s3c2443.c
@@ -559,7 +559,7 @@ static struct clk hsmmc1_clk = {
559 559
560static struct clk hsspi_clk = { 560static struct clk hsspi_clk = {
561 .name = "spi", 561 .name = "spi",
562 .devname = "s3c64xx-spi.0", 562 .devname = "s3c2443-spi.0",
563 .parent = &clk_p, 563 .parent = &clk_p,
564 .enable = s3c2443_clkcon_enable_p, 564 .enable = s3c2443_clkcon_enable_p,
565 .ctrlbit = S3C2443_PCLKCON_HSSPI, 565 .ctrlbit = S3C2443_PCLKCON_HSSPI,
@@ -633,7 +633,7 @@ static struct clk_lookup s3c2443_clk_lookup[] = {
633 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), 633 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
634 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk), 634 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
635 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk), 635 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
636 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk0", &hsspi_clk), 636 CLKDEV_INIT("s3c2443-spi.0", "spi_busclk0", &hsspi_clk),
637}; 637};
638 638
639void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, 639void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
diff --git a/arch/arm/mach-s3c24xx/setup-spi.c b/arch/arm/mach-s3c24xx/setup-spi.c
index 5712c85f39b1..3d47e023ce94 100644
--- a/arch/arm/mach-s3c24xx/setup-spi.c
+++ b/arch/arm/mach-s3c24xx/setup-spi.c
@@ -13,20 +13,12 @@
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14 14
15#include <plat/gpio-cfg.h> 15#include <plat/gpio-cfg.h>
16#include <plat/s3c64xx-spi.h>
17 16
18#include <mach/hardware.h> 17#include <mach/hardware.h>
19#include <mach/regs-gpio.h> 18#include <mach/regs-gpio.h>
20 19
21#ifdef CONFIG_S3C64XX_DEV_SPI0 20#ifdef CONFIG_S3C64XX_DEV_SPI0
22struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { 21int s3c64xx_spi0_cfg_gpio(void)
23 .fifo_lvl_mask = 0x7f,
24 .rx_lvl_offset = 13,
25 .tx_st_done = 21,
26 .high_speed = 1,
27};
28
29int s3c64xx_spi0_cfg_gpio(struct platform_device *pdev)
30{ 22{
31 /* enable hsspi bit in misccr */ 23 /* enable hsspi bit in misccr */
32 s3c2410_modify_misccr(S3C2416_MISCCR_HSSPI_EN2, 1); 24 s3c2410_modify_misccr(S3C2416_MISCCR_HSSPI_EN2, 1);
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 52f079a691cb..28041e83dc82 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -178,13 +178,13 @@ static struct clk init_clocks_off[] = {
178 .ctrlbit = S3C_CLKCON_PCLK_KEYPAD, 178 .ctrlbit = S3C_CLKCON_PCLK_KEYPAD,
179 }, { 179 }, {
180 .name = "spi", 180 .name = "spi",
181 .devname = "s3c64xx-spi.0", 181 .devname = "s3c6410-spi.0",
182 .parent = &clk_p, 182 .parent = &clk_p,
183 .enable = s3c64xx_pclk_ctrl, 183 .enable = s3c64xx_pclk_ctrl,
184 .ctrlbit = S3C_CLKCON_PCLK_SPI0, 184 .ctrlbit = S3C_CLKCON_PCLK_SPI0,
185 }, { 185 }, {
186 .name = "spi", 186 .name = "spi",
187 .devname = "s3c64xx-spi.1", 187 .devname = "s3c6410-spi.1",
188 .parent = &clk_p, 188 .parent = &clk_p,
189 .enable = s3c64xx_pclk_ctrl, 189 .enable = s3c64xx_pclk_ctrl,
190 .ctrlbit = S3C_CLKCON_PCLK_SPI1, 190 .ctrlbit = S3C_CLKCON_PCLK_SPI1,
@@ -331,7 +331,7 @@ static struct clk init_clocks_off[] = {
331 331
332static struct clk clk_48m_spi0 = { 332static struct clk clk_48m_spi0 = {
333 .name = "spi_48m", 333 .name = "spi_48m",
334 .devname = "s3c64xx-spi.0", 334 .devname = "s3c6410-spi.0",
335 .parent = &clk_48m, 335 .parent = &clk_48m,
336 .enable = s3c64xx_sclk_ctrl, 336 .enable = s3c64xx_sclk_ctrl,
337 .ctrlbit = S3C_CLKCON_SCLK_SPI0_48, 337 .ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
@@ -339,7 +339,7 @@ static struct clk clk_48m_spi0 = {
339 339
340static struct clk clk_48m_spi1 = { 340static struct clk clk_48m_spi1 = {
341 .name = "spi_48m", 341 .name = "spi_48m",
342 .devname = "s3c64xx-spi.1", 342 .devname = "s3c6410-spi.1",
343 .parent = &clk_48m, 343 .parent = &clk_48m,
344 .enable = s3c64xx_sclk_ctrl, 344 .enable = s3c64xx_sclk_ctrl,
345 .ctrlbit = S3C_CLKCON_SCLK_SPI1_48, 345 .ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
@@ -802,7 +802,7 @@ static struct clksrc_clk clk_sclk_mmc2 = {
802static struct clksrc_clk clk_sclk_spi0 = { 802static struct clksrc_clk clk_sclk_spi0 = {
803 .clk = { 803 .clk = {
804 .name = "spi-bus", 804 .name = "spi-bus",
805 .devname = "s3c64xx-spi.0", 805 .devname = "s3c6410-spi.0",
806 .ctrlbit = S3C_CLKCON_SCLK_SPI0, 806 .ctrlbit = S3C_CLKCON_SCLK_SPI0,
807 .enable = s3c64xx_sclk_ctrl, 807 .enable = s3c64xx_sclk_ctrl,
808 }, 808 },
@@ -814,7 +814,7 @@ static struct clksrc_clk clk_sclk_spi0 = {
814static struct clksrc_clk clk_sclk_spi1 = { 814static struct clksrc_clk clk_sclk_spi1 = {
815 .clk = { 815 .clk = {
816 .name = "spi-bus", 816 .name = "spi-bus",
817 .devname = "s3c64xx-spi.1", 817 .devname = "s3c6410-spi.1",
818 .ctrlbit = S3C_CLKCON_SCLK_SPI1, 818 .ctrlbit = S3C_CLKCON_SCLK_SPI1,
819 .enable = s3c64xx_sclk_ctrl, 819 .enable = s3c64xx_sclk_ctrl,
820 }, 820 },
@@ -858,10 +858,10 @@ static struct clk_lookup s3c64xx_clk_lookup[] = {
858 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), 858 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
859 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), 859 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
860 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), 860 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
861 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), 861 CLKDEV_INIT("s3c6410-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
862 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_48m_spi0), 862 CLKDEV_INIT("s3c6410-spi.0", "spi_busclk2", &clk_48m_spi0),
863 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), 863 CLKDEV_INIT("s3c6410-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
864 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_48m_spi1), 864 CLKDEV_INIT("s3c6410-spi.1", "spi_busclk2", &clk_48m_spi1),
865}; 865};
866 866
867#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) 867#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index fe1a98cf0e4c..57b1ff4b2d7c 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -21,6 +21,7 @@
21 */ 21 */
22enum dma_ch { 22enum dma_ch {
23 /* DMA0/SDMA0 */ 23 /* DMA0/SDMA0 */
24 DMACH_DT_PROP = -1, /* not yet supported, do not use */
24 DMACH_UART0 = 0, 25 DMACH_UART0 = 0,
25 DMACH_UART0_SRC2, 26 DMACH_UART0_SRC2,
26 DMACH_UART1, 27 DMACH_UART1,
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index d0c352d861f8..6dd4fae33a82 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -799,7 +799,7 @@ static void __init crag6410_machine_init(void)
799 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); 799 i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
800 800
801 samsung_keypad_set_platdata(&crag6410_keypad_data); 801 samsung_keypad_set_platdata(&crag6410_keypad_data);
802 s3c64xx_spi0_set_platdata(&s3c64xx_spi0_pdata, 0, 1); 802 s3c64xx_spi0_set_platdata(NULL, 0, 1);
803 803
804 platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices)); 804 platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices));
805 805
diff --git a/arch/arm/mach-s3c64xx/setup-spi.c b/arch/arm/mach-s3c64xx/setup-spi.c
index d9592ad7a825..4dc53450d715 100644
--- a/arch/arm/mach-s3c64xx/setup-spi.c
+++ b/arch/arm/mach-s3c64xx/setup-spi.c
@@ -9,19 +9,10 @@
9 */ 9 */
10 10
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h> 12#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16 13
17#ifdef CONFIG_S3C64XX_DEV_SPI0 14#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { 15int s3c64xx_spi0_cfg_gpio(void)
19 .fifo_lvl_mask = 0x7f,
20 .rx_lvl_offset = 13,
21 .tx_st_done = 21,
22};
23
24int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
25{ 16{
26 s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3, 17 s3c_gpio_cfgall_range(S3C64XX_GPC(0), 3,
27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 18 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
@@ -30,13 +21,7 @@ int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
30#endif 21#endif
31 22
32#ifdef CONFIG_S3C64XX_DEV_SPI1 23#ifdef CONFIG_S3C64XX_DEV_SPI1
33struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { 24int s3c64xx_spi1_cfg_gpio(void)
34 .fifo_lvl_mask = 0x7f,
35 .rx_lvl_offset = 13,
36 .tx_st_done = 21,
37};
38
39int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
40{ 25{
41 s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3, 26 s3c_gpio_cfgall_range(S3C64XX_GPC(4), 3,
42 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index ee1e8e7f5631..000445596ec4 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -227,13 +227,13 @@ static struct clk init_clocks_off[] = {
227 .ctrlbit = (1 << 17), 227 .ctrlbit = (1 << 17),
228 }, { 228 }, {
229 .name = "spi", 229 .name = "spi",
230 .devname = "s3c64xx-spi.0", 230 .devname = "s5p64x0-spi.0",
231 .parent = &clk_pclk_low.clk, 231 .parent = &clk_pclk_low.clk,
232 .enable = s5p64x0_pclk_ctrl, 232 .enable = s5p64x0_pclk_ctrl,
233 .ctrlbit = (1 << 21), 233 .ctrlbit = (1 << 21),
234 }, { 234 }, {
235 .name = "spi", 235 .name = "spi",
236 .devname = "s3c64xx-spi.1", 236 .devname = "s5p64x0-spi.1",
237 .parent = &clk_pclk_low.clk, 237 .parent = &clk_pclk_low.clk,
238 .enable = s5p64x0_pclk_ctrl, 238 .enable = s5p64x0_pclk_ctrl,
239 .ctrlbit = (1 << 22), 239 .ctrlbit = (1 << 22),
@@ -467,7 +467,7 @@ static struct clksrc_clk clk_sclk_uclk = {
467static struct clksrc_clk clk_sclk_spi0 = { 467static struct clksrc_clk clk_sclk_spi0 = {
468 .clk = { 468 .clk = {
469 .name = "sclk_spi", 469 .name = "sclk_spi",
470 .devname = "s3c64xx-spi.0", 470 .devname = "s5p64x0-spi.0",
471 .ctrlbit = (1 << 20), 471 .ctrlbit = (1 << 20),
472 .enable = s5p64x0_sclk_ctrl, 472 .enable = s5p64x0_sclk_ctrl,
473 }, 473 },
@@ -479,7 +479,7 @@ static struct clksrc_clk clk_sclk_spi0 = {
479static struct clksrc_clk clk_sclk_spi1 = { 479static struct clksrc_clk clk_sclk_spi1 = {
480 .clk = { 480 .clk = {
481 .name = "sclk_spi", 481 .name = "sclk_spi",
482 .devname = "s3c64xx-spi.1", 482 .devname = "s5p64x0-spi.1",
483 .ctrlbit = (1 << 21), 483 .ctrlbit = (1 << 21),
484 .enable = s5p64x0_sclk_ctrl, 484 .enable = s5p64x0_sclk_ctrl,
485 }, 485 },
@@ -519,8 +519,8 @@ static struct clk_lookup s5p6440_clk_lookup[] = {
519 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk), 519 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
520 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), 520 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
521 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), 521 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
522 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), 522 CLKDEV_INIT("s5p64x0-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
523 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), 523 CLKDEV_INIT("s5p64x0-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
524 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), 524 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
525 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), 525 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
526 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), 526 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index dae6a13f43bb..f3e0ef3d27c9 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -236,13 +236,13 @@ static struct clk init_clocks_off[] = {
236 .ctrlbit = (1 << 17), 236 .ctrlbit = (1 << 17),
237 }, { 237 }, {
238 .name = "spi", 238 .name = "spi",
239 .devname = "s3c64xx-spi.0", 239 .devname = "s5p64x0-spi.0",
240 .parent = &clk_pclk_low.clk, 240 .parent = &clk_pclk_low.clk,
241 .enable = s5p64x0_pclk_ctrl, 241 .enable = s5p64x0_pclk_ctrl,
242 .ctrlbit = (1 << 21), 242 .ctrlbit = (1 << 21),
243 }, { 243 }, {
244 .name = "spi", 244 .name = "spi",
245 .devname = "s3c64xx-spi.1", 245 .devname = "s5p64x0-spi.1",
246 .parent = &clk_pclk_low.clk, 246 .parent = &clk_pclk_low.clk,
247 .enable = s5p64x0_pclk_ctrl, 247 .enable = s5p64x0_pclk_ctrl,
248 .ctrlbit = (1 << 22), 248 .ctrlbit = (1 << 22),
@@ -528,7 +528,7 @@ static struct clksrc_clk clk_sclk_uclk = {
528static struct clksrc_clk clk_sclk_spi0 = { 528static struct clksrc_clk clk_sclk_spi0 = {
529 .clk = { 529 .clk = {
530 .name = "sclk_spi", 530 .name = "sclk_spi",
531 .devname = "s3c64xx-spi.0", 531 .devname = "s5p64x0-spi.0",
532 .ctrlbit = (1 << 20), 532 .ctrlbit = (1 << 20),
533 .enable = s5p64x0_sclk_ctrl, 533 .enable = s5p64x0_sclk_ctrl,
534 }, 534 },
@@ -540,7 +540,7 @@ static struct clksrc_clk clk_sclk_spi0 = {
540static struct clksrc_clk clk_sclk_spi1 = { 540static struct clksrc_clk clk_sclk_spi1 = {
541 .clk = { 541 .clk = {
542 .name = "sclk_spi", 542 .name = "sclk_spi",
543 .devname = "s3c64xx-spi.1", 543 .devname = "s5p64x0-spi.1",
544 .ctrlbit = (1 << 21), 544 .ctrlbit = (1 << 21),
545 .enable = s5p64x0_sclk_ctrl, 545 .enable = s5p64x0_sclk_ctrl,
546 }, 546 },
@@ -562,8 +562,8 @@ static struct clk_lookup s5p6450_clk_lookup[] = {
562 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk), 562 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
563 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), 563 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
564 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), 564 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
565 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), 565 CLKDEV_INIT("s5p64x0-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
566 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), 566 CLKDEV_INIT("s5p64x0-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
567 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), 567 CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
568 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), 568 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
569 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), 569 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
diff --git a/arch/arm/mach-s5p64x0/setup-spi.c b/arch/arm/mach-s5p64x0/setup-spi.c
index e9b841240352..7664356720ca 100644
--- a/arch/arm/mach-s5p64x0/setup-spi.c
+++ b/arch/arm/mach-s5p64x0/setup-spi.c
@@ -9,21 +9,10 @@
9 */ 9 */
10 10
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13#include <linux/io.h>
14
15#include <plat/gpio-cfg.h> 12#include <plat/gpio-cfg.h>
16#include <plat/cpu.h>
17#include <plat/s3c64xx-spi.h>
18 13
19#ifdef CONFIG_S3C64XX_DEV_SPI0 14#ifdef CONFIG_S3C64XX_DEV_SPI0
20struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { 15int s3c64xx_spi0_cfg_gpio(void)
21 .fifo_lvl_mask = 0x1ff,
22 .rx_lvl_offset = 15,
23 .tx_st_done = 25,
24};
25
26int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
27{ 16{
28 if (soc_is_s5p6450()) 17 if (soc_is_s5p6450())
29 s3c_gpio_cfgall_range(S5P6450_GPC(0), 3, 18 s3c_gpio_cfgall_range(S5P6450_GPC(0), 3,
@@ -36,13 +25,7 @@ int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
36#endif 25#endif
37 26
38#ifdef CONFIG_S3C64XX_DEV_SPI1 27#ifdef CONFIG_S3C64XX_DEV_SPI1
39struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { 28int s3c64xx_spi1_cfg_gpio(void)
40 .fifo_lvl_mask = 0x7f,
41 .rx_lvl_offset = 15,
42 .tx_st_done = 25,
43};
44
45int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
46{ 29{
47 if (soc_is_s5p6450()) 30 if (soc_is_s5p6450())
48 s3c_gpio_cfgall_range(S5P6450_GPC(4), 3, 31 s3c_gpio_cfgall_range(S5P6450_GPC(4), 3,
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 16eca4ea2010..926219791f0d 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -564,19 +564,19 @@ static struct clk init_clocks_off[] = {
564 .ctrlbit = (1 << 5), 564 .ctrlbit = (1 << 5),
565 }, { 565 }, {
566 .name = "spi", 566 .name = "spi",
567 .devname = "s3c64xx-spi.0", 567 .devname = "s5pc100-spi.0",
568 .parent = &clk_div_d1_bus.clk, 568 .parent = &clk_div_d1_bus.clk,
569 .enable = s5pc100_d1_4_ctrl, 569 .enable = s5pc100_d1_4_ctrl,
570 .ctrlbit = (1 << 6), 570 .ctrlbit = (1 << 6),
571 }, { 571 }, {
572 .name = "spi", 572 .name = "spi",
573 .devname = "s3c64xx-spi.1", 573 .devname = "s5pc100-spi.1",
574 .parent = &clk_div_d1_bus.clk, 574 .parent = &clk_div_d1_bus.clk,
575 .enable = s5pc100_d1_4_ctrl, 575 .enable = s5pc100_d1_4_ctrl,
576 .ctrlbit = (1 << 7), 576 .ctrlbit = (1 << 7),
577 }, { 577 }, {
578 .name = "spi", 578 .name = "spi",
579 .devname = "s3c64xx-spi.2", 579 .devname = "s5pc100-spi.2",
580 .parent = &clk_div_d1_bus.clk, 580 .parent = &clk_div_d1_bus.clk,
581 .enable = s5pc100_d1_4_ctrl, 581 .enable = s5pc100_d1_4_ctrl,
582 .ctrlbit = (1 << 8), 582 .ctrlbit = (1 << 8),
@@ -702,7 +702,7 @@ static struct clk clk_hsmmc0 = {
702 702
703static struct clk clk_48m_spi0 = { 703static struct clk clk_48m_spi0 = {
704 .name = "spi_48m", 704 .name = "spi_48m",
705 .devname = "s3c64xx-spi.0", 705 .devname = "s5pc100-spi.0",
706 .parent = &clk_mout_48m.clk, 706 .parent = &clk_mout_48m.clk,
707 .enable = s5pc100_sclk0_ctrl, 707 .enable = s5pc100_sclk0_ctrl,
708 .ctrlbit = (1 << 7), 708 .ctrlbit = (1 << 7),
@@ -710,7 +710,7 @@ static struct clk clk_48m_spi0 = {
710 710
711static struct clk clk_48m_spi1 = { 711static struct clk clk_48m_spi1 = {
712 .name = "spi_48m", 712 .name = "spi_48m",
713 .devname = "s3c64xx-spi.1", 713 .devname = "s5pc100-spi.1",
714 .parent = &clk_mout_48m.clk, 714 .parent = &clk_mout_48m.clk,
715 .enable = s5pc100_sclk0_ctrl, 715 .enable = s5pc100_sclk0_ctrl,
716 .ctrlbit = (1 << 8), 716 .ctrlbit = (1 << 8),
@@ -718,7 +718,7 @@ static struct clk clk_48m_spi1 = {
718 718
719static struct clk clk_48m_spi2 = { 719static struct clk clk_48m_spi2 = {
720 .name = "spi_48m", 720 .name = "spi_48m",
721 .devname = "s3c64xx-spi.2", 721 .devname = "s5pc100-spi.2",
722 .parent = &clk_mout_48m.clk, 722 .parent = &clk_mout_48m.clk,
723 .enable = s5pc100_sclk0_ctrl, 723 .enable = s5pc100_sclk0_ctrl,
724 .ctrlbit = (1 << 9), 724 .ctrlbit = (1 << 9),
@@ -1085,7 +1085,7 @@ static struct clksrc_clk clk_sclk_mmc2 = {
1085static struct clksrc_clk clk_sclk_spi0 = { 1085static struct clksrc_clk clk_sclk_spi0 = {
1086 .clk = { 1086 .clk = {
1087 .name = "sclk_spi", 1087 .name = "sclk_spi",
1088 .devname = "s3c64xx-spi.0", 1088 .devname = "s5pc100-spi.0",
1089 .ctrlbit = (1 << 4), 1089 .ctrlbit = (1 << 4),
1090 .enable = s5pc100_sclk0_ctrl, 1090 .enable = s5pc100_sclk0_ctrl,
1091 }, 1091 },
@@ -1097,7 +1097,7 @@ static struct clksrc_clk clk_sclk_spi0 = {
1097static struct clksrc_clk clk_sclk_spi1 = { 1097static struct clksrc_clk clk_sclk_spi1 = {
1098 .clk = { 1098 .clk = {
1099 .name = "sclk_spi", 1099 .name = "sclk_spi",
1100 .devname = "s3c64xx-spi.1", 1100 .devname = "s5pc100-spi.1",
1101 .ctrlbit = (1 << 5), 1101 .ctrlbit = (1 << 5),
1102 .enable = s5pc100_sclk0_ctrl, 1102 .enable = s5pc100_sclk0_ctrl,
1103 }, 1103 },
@@ -1109,7 +1109,7 @@ static struct clksrc_clk clk_sclk_spi1 = {
1109static struct clksrc_clk clk_sclk_spi2 = { 1109static struct clksrc_clk clk_sclk_spi2 = {
1110 .clk = { 1110 .clk = {
1111 .name = "sclk_spi", 1111 .name = "sclk_spi",
1112 .devname = "s3c64xx-spi.2", 1112 .devname = "s5pc100-spi.2",
1113 .ctrlbit = (1 << 6), 1113 .ctrlbit = (1 << 6),
1114 .enable = s5pc100_sclk0_ctrl, 1114 .enable = s5pc100_sclk0_ctrl,
1115 }, 1115 },
@@ -1315,12 +1315,12 @@ static struct clk_lookup s5pc100_clk_lookup[] = {
1315 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), 1315 CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
1316 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), 1316 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1317 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), 1317 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
1318 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_48m_spi0), 1318 CLKDEV_INIT("s5pc100-spi.0", "spi_busclk1", &clk_48m_spi0),
1319 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk2", &clk_sclk_spi0.clk), 1319 CLKDEV_INIT("s5pc100-spi.0", "spi_busclk2", &clk_sclk_spi0.clk),
1320 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_48m_spi1), 1320 CLKDEV_INIT("s5pc100-spi.1", "spi_busclk1", &clk_48m_spi1),
1321 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk2", &clk_sclk_spi1.clk), 1321 CLKDEV_INIT("s5pc100-spi.1", "spi_busclk2", &clk_sclk_spi1.clk),
1322 CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk1", &clk_48m_spi2), 1322 CLKDEV_INIT("s5pc100-spi.2", "spi_busclk1", &clk_48m_spi2),
1323 CLKDEV_INIT("s3c64xx-spi.2", "spi_busclk2", &clk_sclk_spi2.clk), 1323 CLKDEV_INIT("s5pc100-spi.2", "spi_busclk2", &clk_sclk_spi2.clk),
1324}; 1324};
1325 1325
1326void __init s5pc100_register_clocks(void) 1326void __init s5pc100_register_clocks(void)
diff --git a/arch/arm/mach-s5pc100/setup-spi.c b/arch/arm/mach-s5pc100/setup-spi.c
index 431a6f747caa..183567961de1 100644
--- a/arch/arm/mach-s5pc100/setup-spi.c
+++ b/arch/arm/mach-s5pc100/setup-spi.c
@@ -9,20 +9,10 @@
9 */ 9 */
10 10
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h> 12#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16 13
17#ifdef CONFIG_S3C64XX_DEV_SPI0 14#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata __initdata = { 15int s3c64xx_spi0_cfg_gpio(void)
19 .fifo_lvl_mask = 0x7f,
20 .rx_lvl_offset = 13,
21 .high_speed = 1,
22 .tx_st_done = 21,
23};
24
25int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
26{ 16{
27 s3c_gpio_cfgall_range(S5PC100_GPB(0), 3, 17 s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
28 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 18 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
@@ -31,14 +21,7 @@ int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
31#endif 21#endif
32 22
33#ifdef CONFIG_S3C64XX_DEV_SPI1 23#ifdef CONFIG_S3C64XX_DEV_SPI1
34struct s3c64xx_spi_info s3c64xx_spi1_pdata __initdata = { 24int s3c64xx_spi1_cfg_gpio(void)
35 .fifo_lvl_mask = 0x7f,
36 .rx_lvl_offset = 13,
37 .high_speed = 1,
38 .tx_st_done = 21,
39};
40
41int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
42{ 25{
43 s3c_gpio_cfgall_range(S5PC100_GPB(4), 3, 26 s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
44 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); 27 S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
@@ -47,14 +30,7 @@ int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
47#endif 30#endif
48 31
49#ifdef CONFIG_S3C64XX_DEV_SPI2 32#ifdef CONFIG_S3C64XX_DEV_SPI2
50struct s3c64xx_spi_info s3c64xx_spi2_pdata __initdata = { 33int s3c64xx_spi2_cfg_gpio(void)
51 .fifo_lvl_mask = 0x7f,
52 .rx_lvl_offset = 13,
53 .high_speed = 1,
54 .tx_st_done = 21,
55};
56
57int s3c64xx_spi2_cfg_gpio(struct platform_device *dev)
58{ 34{
59 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3)); 35 s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
60 s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP); 36 s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 09609d50961d..fcdf52dbcc49 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -445,19 +445,19 @@ static struct clk init_clocks_off[] = {
445 .ctrlbit = (1 << 11), 445 .ctrlbit = (1 << 11),
446 }, { 446 }, {
447 .name = "spi", 447 .name = "spi",
448 .devname = "s3c64xx-spi.0", 448 .devname = "s5pv210-spi.0",
449 .parent = &clk_pclk_psys.clk, 449 .parent = &clk_pclk_psys.clk,
450 .enable = s5pv210_clk_ip3_ctrl, 450 .enable = s5pv210_clk_ip3_ctrl,
451 .ctrlbit = (1<<12), 451 .ctrlbit = (1<<12),
452 }, { 452 }, {
453 .name = "spi", 453 .name = "spi",
454 .devname = "s3c64xx-spi.1", 454 .devname = "s5pv210-spi.1",
455 .parent = &clk_pclk_psys.clk, 455 .parent = &clk_pclk_psys.clk,
456 .enable = s5pv210_clk_ip3_ctrl, 456 .enable = s5pv210_clk_ip3_ctrl,
457 .ctrlbit = (1<<13), 457 .ctrlbit = (1<<13),
458 }, { 458 }, {
459 .name = "spi", 459 .name = "spi",
460 .devname = "s3c64xx-spi.2", 460 .devname = "s5pv210-spi.2",
461 .parent = &clk_pclk_psys.clk, 461 .parent = &clk_pclk_psys.clk,
462 .enable = s5pv210_clk_ip3_ctrl, 462 .enable = s5pv210_clk_ip3_ctrl,
463 .ctrlbit = (1<<14), 463 .ctrlbit = (1<<14),
@@ -1035,7 +1035,7 @@ static struct clksrc_clk clk_sclk_mmc3 = {
1035static struct clksrc_clk clk_sclk_spi0 = { 1035static struct clksrc_clk clk_sclk_spi0 = {
1036 .clk = { 1036 .clk = {
1037 .name = "sclk_spi", 1037 .name = "sclk_spi",
1038 .devname = "s3c64xx-spi.0", 1038 .devname = "s5pv210-spi.0",
1039 .enable = s5pv210_clk_mask0_ctrl, 1039 .enable = s5pv210_clk_mask0_ctrl,
1040 .ctrlbit = (1 << 16), 1040 .ctrlbit = (1 << 16),
1041 }, 1041 },
@@ -1047,7 +1047,7 @@ static struct clksrc_clk clk_sclk_spi0 = {
1047static struct clksrc_clk clk_sclk_spi1 = { 1047static struct clksrc_clk clk_sclk_spi1 = {
1048 .clk = { 1048 .clk = {
1049 .name = "sclk_spi", 1049 .name = "sclk_spi",
1050 .devname = "s3c64xx-spi.1", 1050 .devname = "s5pv210-spi.1",
1051 .enable = s5pv210_clk_mask0_ctrl, 1051 .enable = s5pv210_clk_mask0_ctrl,
1052 .ctrlbit = (1 << 17), 1052 .ctrlbit = (1 << 17),
1053 }, 1053 },
@@ -1331,8 +1331,8 @@ static struct clk_lookup s5pv210_clk_lookup[] = {
1331 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), 1331 CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1332 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk), 1332 CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
1333 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), 1333 CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
1334 CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), 1334 CLKDEV_INIT("s5pv210-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
1335 CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), 1335 CLKDEV_INIT("s5pv210-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
1336}; 1336};
1337 1337
1338void __init s5pv210_register_clocks(void) 1338void __init s5pv210_register_clocks(void)
diff --git a/arch/arm/mach-s5pv210/setup-spi.c b/arch/arm/mach-s5pv210/setup-spi.c
index f43c5048a37d..81aecc162f82 100644
--- a/arch/arm/mach-s5pv210/setup-spi.c
+++ b/arch/arm/mach-s5pv210/setup-spi.c
@@ -9,20 +9,10 @@
9 */ 9 */
10 10
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/platform_device.h>
13
14#include <plat/gpio-cfg.h> 12#include <plat/gpio-cfg.h>
15#include <plat/s3c64xx-spi.h>
16 13
17#ifdef CONFIG_S3C64XX_DEV_SPI0 14#ifdef CONFIG_S3C64XX_DEV_SPI0
18struct s3c64xx_spi_info s3c64xx_spi0_pdata = { 15int s3c64xx_spi0_cfg_gpio(void)
19 .fifo_lvl_mask = 0x1ff,
20 .rx_lvl_offset = 15,
21 .high_speed = 1,
22 .tx_st_done = 25,
23};
24
25int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
26{ 16{
27 s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2)); 17 s3c_gpio_cfgpin(S5PV210_GPB(0), S3C_GPIO_SFN(2));
28 s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP); 18 s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP);
@@ -33,14 +23,7 @@ int s3c64xx_spi0_cfg_gpio(struct platform_device *dev)
33#endif 23#endif
34 24
35#ifdef CONFIG_S3C64XX_DEV_SPI1 25#ifdef CONFIG_S3C64XX_DEV_SPI1
36struct s3c64xx_spi_info s3c64xx_spi1_pdata = { 26int s3c64xx_spi1_cfg_gpio(void)
37 .fifo_lvl_mask = 0x7f,
38 .rx_lvl_offset = 15,
39 .high_speed = 1,
40 .tx_st_done = 25,
41};
42
43int s3c64xx_spi1_cfg_gpio(struct platform_device *dev)
44{ 27{
45 s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2)); 28 s3c_gpio_cfgpin(S5PV210_GPB(4), S3C_GPIO_SFN(2));
46 s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP); 29 s3c_gpio_setpull(S5PV210_GPB(4), S3C_GPIO_PULL_UP);
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c
index 6303974c2ee0..74e31ce35538 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1513,7 +1513,7 @@ static struct resource s3c64xx_spi0_resource[] = {
1513}; 1513};
1514 1514
1515struct platform_device s3c64xx_device_spi0 = { 1515struct platform_device s3c64xx_device_spi0 = {
1516 .name = "s3c64xx-spi", 1516 .name = "s3c6410-spi",
1517 .id = 0, 1517 .id = 0,
1518 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), 1518 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
1519 .resource = s3c64xx_spi0_resource, 1519 .resource = s3c64xx_spi0_resource,
@@ -1523,13 +1523,10 @@ struct platform_device s3c64xx_device_spi0 = {
1523 }, 1523 },
1524}; 1524};
1525 1525
1526void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd, 1526void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1527 int src_clk_nr, int num_cs) 1527 int num_cs)
1528{ 1528{
1529 if (!pd) { 1529 struct s3c64xx_spi_info pd;
1530 pr_err("%s:Need to pass platform data\n", __func__);
1531 return;
1532 }
1533 1530
1534 /* Reject invalid configuration */ 1531 /* Reject invalid configuration */
1535 if (!num_cs || src_clk_nr < 0) { 1532 if (!num_cs || src_clk_nr < 0) {
@@ -1537,12 +1534,11 @@ void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd,
1537 return; 1534 return;
1538 } 1535 }
1539 1536
1540 pd->num_cs = num_cs; 1537 pd.num_cs = num_cs;
1541 pd->src_clk_nr = src_clk_nr; 1538 pd.src_clk_nr = src_clk_nr;
1542 if (!pd->cfg_gpio) 1539 pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
1543 pd->cfg_gpio = s3c64xx_spi0_cfg_gpio;
1544 1540
1545 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi0); 1541 s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
1546} 1542}
1547#endif /* CONFIG_S3C64XX_DEV_SPI0 */ 1543#endif /* CONFIG_S3C64XX_DEV_SPI0 */
1548 1544
@@ -1555,7 +1551,7 @@ static struct resource s3c64xx_spi1_resource[] = {
1555}; 1551};
1556 1552
1557struct platform_device s3c64xx_device_spi1 = { 1553struct platform_device s3c64xx_device_spi1 = {
1558 .name = "s3c64xx-spi", 1554 .name = "s3c6410-spi",
1559 .id = 1, 1555 .id = 1,
1560 .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource), 1556 .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
1561 .resource = s3c64xx_spi1_resource, 1557 .resource = s3c64xx_spi1_resource,
@@ -1565,26 +1561,20 @@ struct platform_device s3c64xx_device_spi1 = {
1565 }, 1561 },
1566}; 1562};
1567 1563
1568void __init s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd, 1564void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1569 int src_clk_nr, int num_cs) 1565 int num_cs)
1570{ 1566{
1571 if (!pd) {
1572 pr_err("%s:Need to pass platform data\n", __func__);
1573 return;
1574 }
1575
1576 /* Reject invalid configuration */ 1567 /* Reject invalid configuration */
1577 if (!num_cs || src_clk_nr < 0) { 1568 if (!num_cs || src_clk_nr < 0) {
1578 pr_err("%s: Invalid SPI configuration\n", __func__); 1569 pr_err("%s: Invalid SPI configuration\n", __func__);
1579 return; 1570 return;
1580 } 1571 }
1581 1572
1582 pd->num_cs = num_cs; 1573 pd.num_cs = num_cs;
1583 pd->src_clk_nr = src_clk_nr; 1574 pd.src_clk_nr = src_clk_nr;
1584 if (!pd->cfg_gpio) 1575 pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
1585 pd->cfg_gpio = s3c64xx_spi1_cfg_gpio;
1586 1576
1587 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi1); 1577 s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
1588} 1578}
1589#endif /* CONFIG_S3C64XX_DEV_SPI1 */ 1579#endif /* CONFIG_S3C64XX_DEV_SPI1 */
1590 1580
@@ -1597,7 +1587,7 @@ static struct resource s3c64xx_spi2_resource[] = {
1597}; 1587};
1598 1588
1599struct platform_device s3c64xx_device_spi2 = { 1589struct platform_device s3c64xx_device_spi2 = {
1600 .name = "s3c64xx-spi", 1590 .name = "s3c6410-spi",
1601 .id = 2, 1591 .id = 2,
1602 .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource), 1592 .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource),
1603 .resource = s3c64xx_spi2_resource, 1593 .resource = s3c64xx_spi2_resource,
@@ -1607,13 +1597,10 @@ struct platform_device s3c64xx_device_spi2 = {
1607 }, 1597 },
1608}; 1598};
1609 1599
1610void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, 1600void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1611 int src_clk_nr, int num_cs) 1601 int num_cs)
1612{ 1602{
1613 if (!pd) { 1603 struct s3c64xx_spi_info pd;
1614 pr_err("%s:Need to pass platform data\n", __func__);
1615 return;
1616 }
1617 1604
1618 /* Reject invalid configuration */ 1605 /* Reject invalid configuration */
1619 if (!num_cs || src_clk_nr < 0) { 1606 if (!num_cs || src_clk_nr < 0) {
@@ -1621,11 +1608,10 @@ void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd,
1621 return; 1608 return;
1622 } 1609 }
1623 1610
1624 pd->num_cs = num_cs; 1611 pd.num_cs = num_cs;
1625 pd->src_clk_nr = src_clk_nr; 1612 pd.src_clk_nr = src_clk_nr;
1626 if (!pd->cfg_gpio) 1613 pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
1627 pd->cfg_gpio = s3c64xx_spi2_cfg_gpio;
1628 1614
1629 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi2); 1615 s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
1630} 1616}
1631#endif /* CONFIG_S3C64XX_DEV_SPI2 */ 1617#endif /* CONFIG_S3C64XX_DEV_SPI2 */
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index eb9f4f534006..c38d75489240 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -19,72 +19,79 @@
19#include <mach/dma.h> 19#include <mach/dma.h>
20 20
21static unsigned samsung_dmadev_request(enum dma_ch dma_ch, 21static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
22 struct samsung_dma_info *info) 22 struct samsung_dma_req *param)
23{ 23{
24 struct dma_chan *chan;
25 dma_cap_mask_t mask; 24 dma_cap_mask_t mask;
26 struct dma_slave_config slave_config;
27 void *filter_param; 25 void *filter_param;
28 26
29 dma_cap_zero(mask); 27 dma_cap_zero(mask);
30 dma_cap_set(info->cap, mask); 28 dma_cap_set(param->cap, mask);
31 29
32 /* 30 /*
33 * If a dma channel property of a device node from device tree is 31 * If a dma channel property of a device node from device tree is
34 * specified, use that as the fliter parameter. 32 * specified, use that as the fliter parameter.
35 */ 33 */
36 filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop : 34 filter_param = (dma_ch == DMACH_DT_PROP) ?
37 (void *)dma_ch; 35 (void *)param->dt_dmach_prop : (void *)dma_ch;
38 chan = dma_request_channel(mask, pl330_filter, filter_param); 36 return (unsigned)dma_request_channel(mask, pl330_filter, filter_param);
37}
38
39static int samsung_dmadev_release(unsigned ch, void *param)
40{
41 dma_release_channel((struct dma_chan *)ch);
39 42
40 if (info->direction == DMA_DEV_TO_MEM) { 43 return 0;
44}
45
46static int samsung_dmadev_config(unsigned ch,
47 struct samsung_dma_config *param)
48{
49 struct dma_chan *chan = (struct dma_chan *)ch;
50 struct dma_slave_config slave_config;
51
52 if (param->direction == DMA_DEV_TO_MEM) {
41 memset(&slave_config, 0, sizeof(struct dma_slave_config)); 53 memset(&slave_config, 0, sizeof(struct dma_slave_config));
42 slave_config.direction = info->direction; 54 slave_config.direction = param->direction;
43 slave_config.src_addr = info->fifo; 55 slave_config.src_addr = param->fifo;
44 slave_config.src_addr_width = info->width; 56 slave_config.src_addr_width = param->width;
45 slave_config.src_maxburst = 1; 57 slave_config.src_maxburst = 1;
46 dmaengine_slave_config(chan, &slave_config); 58 dmaengine_slave_config(chan, &slave_config);
47 } else if (info->direction == DMA_MEM_TO_DEV) { 59 } else if (param->direction == DMA_MEM_TO_DEV) {
48 memset(&slave_config, 0, sizeof(struct dma_slave_config)); 60 memset(&slave_config, 0, sizeof(struct dma_slave_config));
49 slave_config.direction = info->direction; 61 slave_config.direction = param->direction;
50 slave_config.dst_addr = info->fifo; 62 slave_config.dst_addr = param->fifo;
51 slave_config.dst_addr_width = info->width; 63 slave_config.dst_addr_width = param->width;
52 slave_config.dst_maxburst = 1; 64 slave_config.dst_maxburst = 1;
53 dmaengine_slave_config(chan, &slave_config); 65 dmaengine_slave_config(chan, &slave_config);
66 } else {
67 pr_warn("unsupported direction\n");
68 return -EINVAL;
54 } 69 }
55 70
56 return (unsigned)chan;
57}
58
59static int samsung_dmadev_release(unsigned ch,
60 struct s3c2410_dma_client *client)
61{
62 dma_release_channel((struct dma_chan *)ch);
63
64 return 0; 71 return 0;
65} 72}
66 73
67static int samsung_dmadev_prepare(unsigned ch, 74static int samsung_dmadev_prepare(unsigned ch,
68 struct samsung_dma_prep_info *info) 75 struct samsung_dma_prep *param)
69{ 76{
70 struct scatterlist sg; 77 struct scatterlist sg;
71 struct dma_chan *chan = (struct dma_chan *)ch; 78 struct dma_chan *chan = (struct dma_chan *)ch;
72 struct dma_async_tx_descriptor *desc; 79 struct dma_async_tx_descriptor *desc;
73 80
74 switch (info->cap) { 81 switch (param->cap) {
75 case DMA_SLAVE: 82 case DMA_SLAVE:
76 sg_init_table(&sg, 1); 83 sg_init_table(&sg, 1);
77 sg_dma_len(&sg) = info->len; 84 sg_dma_len(&sg) = param->len;
78 sg_set_page(&sg, pfn_to_page(PFN_DOWN(info->buf)), 85 sg_set_page(&sg, pfn_to_page(PFN_DOWN(param->buf)),
79 info->len, offset_in_page(info->buf)); 86 param->len, offset_in_page(param->buf));
80 sg_dma_address(&sg) = info->buf; 87 sg_dma_address(&sg) = param->buf;
81 88
82 desc = dmaengine_prep_slave_sg(chan, 89 desc = dmaengine_prep_slave_sg(chan,
83 &sg, 1, info->direction, DMA_PREP_INTERRUPT); 90 &sg, 1, param->direction, DMA_PREP_INTERRUPT);
84 break; 91 break;
85 case DMA_CYCLIC: 92 case DMA_CYCLIC:
86 desc = dmaengine_prep_dma_cyclic(chan, 93 desc = dmaengine_prep_dma_cyclic(chan, param->buf,
87 info->buf, info->len, info->period, info->direction); 94 param->len, param->period, param->direction);
88 break; 95 break;
89 default: 96 default:
90 dev_err(&chan->dev->device, "unsupported format\n"); 97 dev_err(&chan->dev->device, "unsupported format\n");
@@ -96,8 +103,8 @@ static int samsung_dmadev_prepare(unsigned ch,
96 return -EFAULT; 103 return -EFAULT;
97 } 104 }
98 105
99 desc->callback = info->fp; 106 desc->callback = param->fp;
100 desc->callback_param = info->fp_param; 107 desc->callback_param = param->fp_param;
101 108
102 dmaengine_submit((struct dma_async_tx_descriptor *)desc); 109 dmaengine_submit((struct dma_async_tx_descriptor *)desc);
103 110
@@ -119,6 +126,7 @@ static inline int samsung_dmadev_flush(unsigned ch)
119static struct samsung_dma_ops dmadev_ops = { 126static struct samsung_dma_ops dmadev_ops = {
120 .request = samsung_dmadev_request, 127 .request = samsung_dmadev_request,
121 .release = samsung_dmadev_release, 128 .release = samsung_dmadev_release,
129 .config = samsung_dmadev_config,
122 .prepare = samsung_dmadev_prepare, 130 .prepare = samsung_dmadev_prepare,
123 .trigger = samsung_dmadev_trigger, 131 .trigger = samsung_dmadev_trigger,
124 .started = NULL, 132 .started = NULL,
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
index 71a6827c7706..f5144cdd3001 100644
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -16,7 +16,13 @@
16#include <linux/dmaengine.h> 16#include <linux/dmaengine.h>
17#include <mach/dma.h> 17#include <mach/dma.h>
18 18
19struct samsung_dma_prep_info { 19struct samsung_dma_req {
20 enum dma_transaction_type cap;
21 struct property *dt_dmach_prop;
22 struct s3c2410_dma_client *client;
23};
24
25struct samsung_dma_prep {
20 enum dma_transaction_type cap; 26 enum dma_transaction_type cap;
21 enum dma_transfer_direction direction; 27 enum dma_transfer_direction direction;
22 dma_addr_t buf; 28 dma_addr_t buf;
@@ -26,19 +32,17 @@ struct samsung_dma_prep_info {
26 void *fp_param; 32 void *fp_param;
27}; 33};
28 34
29struct samsung_dma_info { 35struct samsung_dma_config {
30 enum dma_transaction_type cap;
31 enum dma_transfer_direction direction; 36 enum dma_transfer_direction direction;
32 enum dma_slave_buswidth width; 37 enum dma_slave_buswidth width;
33 dma_addr_t fifo; 38 dma_addr_t fifo;
34 struct s3c2410_dma_client *client;
35 struct property *dt_dmach_prop;
36}; 39};
37 40
38struct samsung_dma_ops { 41struct samsung_dma_ops {
39 unsigned (*request)(enum dma_ch ch, struct samsung_dma_info *info); 42 unsigned (*request)(enum dma_ch ch, struct samsung_dma_req *param);
40 int (*release)(unsigned ch, struct s3c2410_dma_client *client); 43 int (*release)(unsigned ch, void *param);
41 int (*prepare)(unsigned ch, struct samsung_dma_prep_info *info); 44 int (*config)(unsigned ch, struct samsung_dma_config *param);
45 int (*prepare)(unsigned ch, struct samsung_dma_prep *param);
42 int (*trigger)(unsigned ch); 46 int (*trigger)(unsigned ch);
43 int (*started)(unsigned ch); 47 int (*started)(unsigned ch);
44 int (*flush)(unsigned ch); 48 int (*flush)(unsigned ch);
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
index fa95e9a00972..ceba18d23a5a 100644
--- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -18,7 +18,6 @@ struct platform_device;
18 * @fb_delay: Slave specific feedback delay. 18 * @fb_delay: Slave specific feedback delay.
19 * Refer to FB_CLK_SEL register definition in SPI chapter. 19 * Refer to FB_CLK_SEL register definition in SPI chapter.
20 * @line: Custom 'identity' of the CS line. 20 * @line: Custom 'identity' of the CS line.
21 * @set_level: CS line control.
22 * 21 *
23 * This is per SPI-Slave Chipselect information. 22 * This is per SPI-Slave Chipselect information.
24 * Allocate and initialize one in machine init code and make the 23 * Allocate and initialize one in machine init code and make the
@@ -27,57 +26,41 @@ struct platform_device;
27struct s3c64xx_spi_csinfo { 26struct s3c64xx_spi_csinfo {
28 u8 fb_delay; 27 u8 fb_delay;
29 unsigned line; 28 unsigned line;
30 void (*set_level)(unsigned line_id, int lvl);
31}; 29};
32 30
33/** 31/**
34 * struct s3c64xx_spi_info - SPI Controller defining structure 32 * struct s3c64xx_spi_info - SPI Controller defining structure
35 * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field. 33 * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
36 * @clk_from_cmu: If the SPI clock/prescalar control block is present
37 * by the platform's clock-management-unit and not in SPI controller.
38 * @num_cs: Number of CS this controller emulates. 34 * @num_cs: Number of CS this controller emulates.
39 * @cfg_gpio: Configure pins for this SPI controller. 35 * @cfg_gpio: Configure pins for this SPI controller.
40 * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
41 * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number
42 * @high_speed: If the controller supports HIGH_SPEED_EN bit
43 * @tx_st_done: Depends on tx fifo_lvl field
44 */ 36 */
45struct s3c64xx_spi_info { 37struct s3c64xx_spi_info {
46 int src_clk_nr; 38 int src_clk_nr;
47 bool clk_from_cmu;
48
49 int num_cs; 39 int num_cs;
50 40 int (*cfg_gpio)(void);
51 int (*cfg_gpio)(struct platform_device *pdev);
52
53 /* Following two fields are for future compatibility */
54 int fifo_lvl_mask;
55 int rx_lvl_offset;
56 int high_speed;
57 int tx_st_done;
58}; 41};
59 42
60/** 43/**
61 * s3c64xx_spi_set_platdata - SPI Controller configure callback by the board 44 * s3c64xx_spi_set_platdata - SPI Controller configure callback by the board
62 * initialization code. 45 * initialization code.
63 * @pd: SPI platform data to set. 46 * @cfg_gpio: Pointer to gpio setup function.
64 * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks. 47 * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
65 * @num_cs: Number of elements in the 'cs' array. 48 * @num_cs: Number of elements in the 'cs' array.
66 * 49 *
67 * Call this from machine init code for each SPI Controller that 50 * Call this from machine init code for each SPI Controller that
68 * has some chips attached to it. 51 * has some chips attached to it.
69 */ 52 */
70extern void s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd, 53extern void s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
71 int src_clk_nr, int num_cs); 54 int num_cs);
72extern void s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd, 55extern void s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
73 int src_clk_nr, int num_cs); 56 int num_cs);
74extern void s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, 57extern void s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
75 int src_clk_nr, int num_cs); 58 int num_cs);
76 59
77/* defined by architecture to configure gpio */ 60/* defined by architecture to configure gpio */
78extern int s3c64xx_spi0_cfg_gpio(struct platform_device *dev); 61extern int s3c64xx_spi0_cfg_gpio(void);
79extern int s3c64xx_spi1_cfg_gpio(struct platform_device *dev); 62extern int s3c64xx_spi1_cfg_gpio(void);
80extern int s3c64xx_spi2_cfg_gpio(struct platform_device *dev); 63extern int s3c64xx_spi2_cfg_gpio(void);
81 64
82extern struct s3c64xx_spi_info s3c64xx_spi0_pdata; 65extern struct s3c64xx_spi_info s3c64xx_spi0_pdata;
83extern struct s3c64xx_spi_info s3c64xx_spi1_pdata; 66extern struct s3c64xx_spi_info s3c64xx_spi1_pdata;
diff --git a/arch/arm/plat-samsung/s3c-dma-ops.c b/arch/arm/plat-samsung/s3c-dma-ops.c
index 781494912827..f99448c48d30 100644
--- a/arch/arm/plat-samsung/s3c-dma-ops.c
+++ b/arch/arm/plat-samsung/s3c-dma-ops.c
@@ -36,30 +36,26 @@ static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param,
36} 36}
37 37
38static unsigned s3c_dma_request(enum dma_ch dma_ch, 38static unsigned s3c_dma_request(enum dma_ch dma_ch,
39 struct samsung_dma_info *info) 39 struct samsung_dma_req *param)
40{ 40{
41 struct cb_data *data; 41 struct cb_data *data;
42 42
43 if (s3c2410_dma_request(dma_ch, info->client, NULL) < 0) { 43 if (s3c2410_dma_request(dma_ch, param->client, NULL) < 0) {
44 s3c2410_dma_free(dma_ch, info->client); 44 s3c2410_dma_free(dma_ch, param->client);
45 return 0; 45 return 0;
46 } 46 }
47 47
48 if (param->cap == DMA_CYCLIC)
49 s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
50
48 data = kzalloc(sizeof(struct cb_data), GFP_KERNEL); 51 data = kzalloc(sizeof(struct cb_data), GFP_KERNEL);
49 data->ch = dma_ch; 52 data->ch = dma_ch;
50 list_add_tail(&data->node, &dma_list); 53 list_add_tail(&data->node, &dma_list);
51 54
52 s3c2410_dma_devconfig(dma_ch, info->direction, info->fifo);
53
54 if (info->cap == DMA_CYCLIC)
55 s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
56
57 s3c2410_dma_config(dma_ch, info->width);
58
59 return (unsigned)dma_ch; 55 return (unsigned)dma_ch;
60} 56}
61 57
62static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client) 58static int s3c_dma_release(unsigned ch, void *param)
63{ 59{
64 struct cb_data *data; 60 struct cb_data *data;
65 61
@@ -68,16 +64,24 @@ static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client)
68 break; 64 break;
69 list_del(&data->node); 65 list_del(&data->node);
70 66
71 s3c2410_dma_free(ch, client); 67 s3c2410_dma_free(ch, param);
72 kfree(data); 68 kfree(data);
73 69
74 return 0; 70 return 0;
75} 71}
76 72
77static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info) 73static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param)
74{
75 s3c2410_dma_devconfig(ch, param->direction, param->fifo);
76 s3c2410_dma_config(ch, param->width);
77
78 return 0;
79}
80
81static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param)
78{ 82{
79 struct cb_data *data; 83 struct cb_data *data;
80 int len = (info->cap == DMA_CYCLIC) ? info->period : info->len; 84 int len = (param->cap == DMA_CYCLIC) ? param->period : param->len;
81 85
82 list_for_each_entry(data, &dma_list, node) 86 list_for_each_entry(data, &dma_list, node)
83 if (data->ch == ch) 87 if (data->ch == ch)
@@ -85,11 +89,11 @@ static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info)
85 89
86 if (!data->fp) { 90 if (!data->fp) {
87 s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb); 91 s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb);
88 data->fp = info->fp; 92 data->fp = param->fp;
89 data->fp_param = info->fp_param; 93 data->fp_param = param->fp_param;
90 } 94 }
91 95
92 s3c2410_dma_enqueue(ch, (void *)data, info->buf, len); 96 s3c2410_dma_enqueue(ch, (void *)data, param->buf, len);
93 97
94 return 0; 98 return 0;
95} 99}
@@ -117,6 +121,7 @@ static inline int s3c_dma_stop(unsigned ch)
117static struct samsung_dma_ops s3c_dma_ops = { 121static struct samsung_dma_ops s3c_dma_ops = {
118 .request = s3c_dma_request, 122 .request = s3c_dma_request,
119 .release = s3c_dma_release, 123 .release = s3c_dma_release,
124 .config = s3c_dma_config,
120 .prepare = s3c_dma_prepare, 125 .prepare = s3c_dma_prepare,
121 .trigger = s3c_dma_trigger, 126 .trigger = s3c_dma_trigger,
122 .started = s3c_dma_started, 127 .started = s3c_dma_started,
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 972a94c58be3..0dedbbdb153a 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -27,10 +27,15 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/gpio.h>
31#include <linux/of.h>
32#include <linux/of_gpio.h>
30 33
31#include <mach/dma.h> 34#include <mach/dma.h>
32#include <plat/s3c64xx-spi.h> 35#include <plat/s3c64xx-spi.h>
33 36
37#define MAX_SPI_PORTS 3
38
34/* Registers and bit-fields */ 39/* Registers and bit-fields */
35 40
36#define S3C64XX_SPI_CH_CFG 0x00 41#define S3C64XX_SPI_CH_CFG 0x00
@@ -113,13 +118,12 @@
113 118
114#define S3C64XX_SPI_FBCLK_MSK (3<<0) 119#define S3C64XX_SPI_FBCLK_MSK (3<<0)
115 120
116#define S3C64XX_SPI_ST_TRLCNTZ(v, i) ((((v) >> (i)->rx_lvl_offset) & \ 121#define FIFO_LVL_MASK(i) ((i)->port_conf->fifo_lvl_mask[i->port_id])
117 (((i)->fifo_lvl_mask + 1))) \ 122#define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & \
118 ? 1 : 0) 123 (1 << (i)->port_conf->tx_st_done)) ? 1 : 0)
119 124#define TX_FIFO_LVL(v, i) (((v) >> 6) & FIFO_LVL_MASK(i))
120#define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & (1 << (i)->tx_st_done)) ? 1 : 0) 125#define RX_FIFO_LVL(v, i) (((v) >> (i)->port_conf->rx_lvl_offset) & \
121#define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask) 126 FIFO_LVL_MASK(i))
122#define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask)
123 127
124#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff 128#define S3C64XX_SPI_MAX_TRAILCNT 0x3ff
125#define S3C64XX_SPI_TRAILCNT_OFF 19 129#define S3C64XX_SPI_TRAILCNT_OFF 19
@@ -135,6 +139,29 @@ struct s3c64xx_spi_dma_data {
135 unsigned ch; 139 unsigned ch;
136 enum dma_data_direction direction; 140 enum dma_data_direction direction;
137 enum dma_ch dmach; 141 enum dma_ch dmach;
142 struct property *dma_prop;
143};
144
145/**
146 * struct s3c64xx_spi_info - SPI Controller hardware info
147 * @fifo_lvl_mask: Bit-mask for {TX|RX}_FIFO_LVL bits in SPI_STATUS register.
148 * @rx_lvl_offset: Bit offset of RX_FIFO_LVL bits in SPI_STATUS regiter.
149 * @tx_st_done: Bit offset of TX_DONE bit in SPI_STATUS regiter.
150 * @high_speed: True, if the controller supports HIGH_SPEED_EN bit.
151 * @clk_from_cmu: True, if the controller does not include a clock mux and
152 * prescaler unit.
153 *
154 * The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
155 * differ in some aspects such as the size of the fifo and spi bus clock
156 * setup. Such differences are specified to the driver using this structure
157 * which is provided as driver data to the driver.
158 */
159struct s3c64xx_spi_port_config {
160 int fifo_lvl_mask[MAX_SPI_PORTS];
161 int rx_lvl_offset;
162 int tx_st_done;
163 bool high_speed;
164 bool clk_from_cmu;
138}; 165};
139 166
140/** 167/**
@@ -175,6 +202,9 @@ struct s3c64xx_spi_driver_data {
175 struct s3c64xx_spi_dma_data rx_dma; 202 struct s3c64xx_spi_dma_data rx_dma;
176 struct s3c64xx_spi_dma_data tx_dma; 203 struct s3c64xx_spi_dma_data tx_dma;
177 struct samsung_dma_ops *ops; 204 struct samsung_dma_ops *ops;
205 struct s3c64xx_spi_port_config *port_conf;
206 unsigned int port_id;
207 unsigned long gpios[4];
178}; 208};
179 209
180static struct s3c2410_dma_client s3c64xx_spi_dma_client = { 210static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
@@ -183,7 +213,6 @@ static struct s3c2410_dma_client s3c64xx_spi_dma_client = {
183 213
184static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) 214static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
185{ 215{
186 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
187 void __iomem *regs = sdd->regs; 216 void __iomem *regs = sdd->regs;
188 unsigned long loops; 217 unsigned long loops;
189 u32 val; 218 u32 val;
@@ -199,7 +228,7 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
199 loops = msecs_to_loops(1); 228 loops = msecs_to_loops(1);
200 do { 229 do {
201 val = readl(regs + S3C64XX_SPI_STATUS); 230 val = readl(regs + S3C64XX_SPI_STATUS);
202 } while (TX_FIFO_LVL(val, sci) && loops--); 231 } while (TX_FIFO_LVL(val, sdd) && loops--);
203 232
204 if (loops == 0) 233 if (loops == 0)
205 dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); 234 dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n");
@@ -208,7 +237,7 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd)
208 loops = msecs_to_loops(1); 237 loops = msecs_to_loops(1);
209 do { 238 do {
210 val = readl(regs + S3C64XX_SPI_STATUS); 239 val = readl(regs + S3C64XX_SPI_STATUS);
211 if (RX_FIFO_LVL(val, sci)) 240 if (RX_FIFO_LVL(val, sdd))
212 readl(regs + S3C64XX_SPI_RX_DATA); 241 readl(regs + S3C64XX_SPI_RX_DATA);
213 else 242 else
214 break; 243 break;
@@ -262,14 +291,24 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
262 unsigned len, dma_addr_t buf) 291 unsigned len, dma_addr_t buf)
263{ 292{
264 struct s3c64xx_spi_driver_data *sdd; 293 struct s3c64xx_spi_driver_data *sdd;
265 struct samsung_dma_prep_info info; 294 struct samsung_dma_prep info;
295 struct samsung_dma_config config;
266 296
267 if (dma->direction == DMA_DEV_TO_MEM) 297 if (dma->direction == DMA_DEV_TO_MEM) {
268 sdd = container_of((void *)dma, 298 sdd = container_of((void *)dma,
269 struct s3c64xx_spi_driver_data, rx_dma); 299 struct s3c64xx_spi_driver_data, rx_dma);
270 else 300 config.direction = sdd->rx_dma.direction;
301 config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA;
302 config.width = sdd->cur_bpw / 8;
303 sdd->ops->config(sdd->rx_dma.ch, &config);
304 } else {
271 sdd = container_of((void *)dma, 305 sdd = container_of((void *)dma,
272 struct s3c64xx_spi_driver_data, tx_dma); 306 struct s3c64xx_spi_driver_data, tx_dma);
307 config.direction = sdd->tx_dma.direction;
308 config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
309 config.width = sdd->cur_bpw / 8;
310 sdd->ops->config(sdd->tx_dma.ch, &config);
311 }
273 312
274 info.cap = DMA_SLAVE; 313 info.cap = DMA_SLAVE;
275 info.len = len; 314 info.len = len;
@@ -284,20 +323,17 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
284 323
285static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) 324static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
286{ 325{
287 struct samsung_dma_info info; 326 struct samsung_dma_req req;
288 327
289 sdd->ops = samsung_dma_get_ops(); 328 sdd->ops = samsung_dma_get_ops();
290 329
291 info.cap = DMA_SLAVE; 330 req.cap = DMA_SLAVE;
292 info.client = &s3c64xx_spi_dma_client; 331 req.client = &s3c64xx_spi_dma_client;
293 info.width = sdd->cur_bpw / 8;
294 332
295 info.direction = sdd->rx_dma.direction; 333 req.dt_dmach_prop = sdd->rx_dma.dma_prop;
296 info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; 334 sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req);
297 sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info); 335 req.dt_dmach_prop = sdd->tx_dma.dma_prop;
298 info.direction = sdd->tx_dma.direction; 336 sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req);
299 info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA;
300 sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info);
301 337
302 return 1; 338 return 1;
303} 339}
@@ -306,7 +342,6 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
306 struct spi_device *spi, 342 struct spi_device *spi,
307 struct spi_transfer *xfer, int dma_mode) 343 struct spi_transfer *xfer, int dma_mode)
308{ 344{
309 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
310 void __iomem *regs = sdd->regs; 345 void __iomem *regs = sdd->regs;
311 u32 modecfg, chcfg; 346 u32 modecfg, chcfg;
312 347
@@ -356,7 +391,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
356 if (xfer->rx_buf != NULL) { 391 if (xfer->rx_buf != NULL) {
357 sdd->state |= RXBUSY; 392 sdd->state |= RXBUSY;
358 393
359 if (sci->high_speed && sdd->cur_speed >= 30000000UL 394 if (sdd->port_conf->high_speed && sdd->cur_speed >= 30000000UL
360 && !(sdd->cur_mode & SPI_CPHA)) 395 && !(sdd->cur_mode & SPI_CPHA))
361 chcfg |= S3C64XX_SPI_CH_HS_EN; 396 chcfg |= S3C64XX_SPI_CH_HS_EN;
362 397
@@ -383,20 +418,19 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
383 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ 418 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
384 /* Deselect the last toggled device */ 419 /* Deselect the last toggled device */
385 cs = sdd->tgl_spi->controller_data; 420 cs = sdd->tgl_spi->controller_data;
386 cs->set_level(cs->line, 421 gpio_set_value(cs->line,
387 spi->mode & SPI_CS_HIGH ? 0 : 1); 422 spi->mode & SPI_CS_HIGH ? 0 : 1);
388 } 423 }
389 sdd->tgl_spi = NULL; 424 sdd->tgl_spi = NULL;
390 } 425 }
391 426
392 cs = spi->controller_data; 427 cs = spi->controller_data;
393 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); 428 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0);
394} 429}
395 430
396static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, 431static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
397 struct spi_transfer *xfer, int dma_mode) 432 struct spi_transfer *xfer, int dma_mode)
398{ 433{
399 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
400 void __iomem *regs = sdd->regs; 434 void __iomem *regs = sdd->regs;
401 unsigned long val; 435 unsigned long val;
402 int ms; 436 int ms;
@@ -413,7 +447,7 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
413 val = msecs_to_loops(ms); 447 val = msecs_to_loops(ms);
414 do { 448 do {
415 status = readl(regs + S3C64XX_SPI_STATUS); 449 status = readl(regs + S3C64XX_SPI_STATUS);
416 } while (RX_FIFO_LVL(status, sci) < xfer->len && --val); 450 } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val);
417 } 451 }
418 452
419 if (!val) 453 if (!val)
@@ -432,8 +466,8 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
432 if (xfer->rx_buf == NULL) { 466 if (xfer->rx_buf == NULL) {
433 val = msecs_to_loops(10); 467 val = msecs_to_loops(10);
434 status = readl(regs + S3C64XX_SPI_STATUS); 468 status = readl(regs + S3C64XX_SPI_STATUS);
435 while ((TX_FIFO_LVL(status, sci) 469 while ((TX_FIFO_LVL(status, sdd)
436 || !S3C64XX_SPI_ST_TX_DONE(status, sci)) 470 || !S3C64XX_SPI_ST_TX_DONE(status, sdd))
437 && --val) { 471 && --val) {
438 cpu_relax(); 472 cpu_relax();
439 status = readl(regs + S3C64XX_SPI_STATUS); 473 status = readl(regs + S3C64XX_SPI_STATUS);
@@ -477,17 +511,16 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
477 if (sdd->tgl_spi == spi) 511 if (sdd->tgl_spi == spi)
478 sdd->tgl_spi = NULL; 512 sdd->tgl_spi = NULL;
479 513
480 cs->set_level(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); 514 gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1);
481} 515}
482 516
483static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) 517static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
484{ 518{
485 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
486 void __iomem *regs = sdd->regs; 519 void __iomem *regs = sdd->regs;
487 u32 val; 520 u32 val;
488 521
489 /* Disable Clock */ 522 /* Disable Clock */
490 if (sci->clk_from_cmu) { 523 if (sdd->port_conf->clk_from_cmu) {
491 clk_disable(sdd->src_clk); 524 clk_disable(sdd->src_clk);
492 } else { 525 } else {
493 val = readl(regs + S3C64XX_SPI_CLK_CFG); 526 val = readl(regs + S3C64XX_SPI_CLK_CFG);
@@ -531,7 +564,7 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
531 564
532 writel(val, regs + S3C64XX_SPI_MODE_CFG); 565 writel(val, regs + S3C64XX_SPI_MODE_CFG);
533 566
534 if (sci->clk_from_cmu) { 567 if (sdd->port_conf->clk_from_cmu) {
535 /* Configure Clock */ 568 /* Configure Clock */
536 /* There is half-multiplier before the SPI */ 569 /* There is half-multiplier before the SPI */
537 clk_set_rate(sdd->src_clk, sdd->cur_speed * 2); 570 clk_set_rate(sdd->src_clk, sdd->cur_speed * 2);
@@ -557,7 +590,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
557static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, 590static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
558 struct spi_message *msg) 591 struct spi_message *msg)
559{ 592{
560 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
561 struct device *dev = &sdd->pdev->dev; 593 struct device *dev = &sdd->pdev->dev;
562 struct spi_transfer *xfer; 594 struct spi_transfer *xfer;
563 595
@@ -573,7 +605,7 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
573 /* Map until end or first fail */ 605 /* Map until end or first fail */
574 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 606 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
575 607
576 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) 608 if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
577 continue; 609 continue;
578 610
579 if (xfer->tx_buf != NULL) { 611 if (xfer->tx_buf != NULL) {
@@ -607,7 +639,6 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
607static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, 639static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
608 struct spi_message *msg) 640 struct spi_message *msg)
609{ 641{
610 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
611 struct device *dev = &sdd->pdev->dev; 642 struct device *dev = &sdd->pdev->dev;
612 struct spi_transfer *xfer; 643 struct spi_transfer *xfer;
613 644
@@ -616,7 +647,7 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
616 647
617 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 648 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
618 649
619 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) 650 if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
620 continue; 651 continue;
621 652
622 if (xfer->rx_buf != NULL 653 if (xfer->rx_buf != NULL
@@ -635,7 +666,6 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
635 struct spi_message *msg) 666 struct spi_message *msg)
636{ 667{
637 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 668 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
638 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
639 struct spi_device *spi = msg->spi; 669 struct spi_device *spi = msg->spi;
640 struct s3c64xx_spi_csinfo *cs = spi->controller_data; 670 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
641 struct spi_transfer *xfer; 671 struct spi_transfer *xfer;
@@ -690,7 +720,7 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
690 } 720 }
691 721
692 /* Polling method for xfers not bigger than FIFO capacity */ 722 /* Polling method for xfers not bigger than FIFO capacity */
693 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) 723 if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
694 use_dma = 0; 724 use_dma = 0;
695 else 725 else
696 use_dma = 1; 726 use_dma = 1;
@@ -795,6 +825,48 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
795 return 0; 825 return 0;
796} 826}
797 827
828static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
829 struct s3c64xx_spi_driver_data *sdd,
830 struct spi_device *spi)
831{
832 struct s3c64xx_spi_csinfo *cs;
833 struct device_node *slave_np, *data_np;
834 u32 fb_delay = 0;
835
836 slave_np = spi->dev.of_node;
837 if (!slave_np) {
838 dev_err(&spi->dev, "device node not found\n");
839 return ERR_PTR(-EINVAL);
840 }
841
842 for_each_child_of_node(slave_np, data_np)
843 if (!strcmp(data_np->name, "controller-data"))
844 break;
845 if (!data_np) {
846 dev_err(&spi->dev, "child node 'controller-data' not found\n");
847 return ERR_PTR(-EINVAL);
848 }
849
850 cs = kzalloc(sizeof(*cs), GFP_KERNEL);
851 if (!cs) {
852 dev_err(&spi->dev, "could not allocate memory for controller"
853 " data\n");
854 return ERR_PTR(-ENOMEM);
855 }
856
857 cs->line = of_get_named_gpio(data_np, "cs-gpio", 0);
858 if (!gpio_is_valid(cs->line)) {
859 dev_err(&spi->dev, "chip select gpio is not specified or "
860 "invalid\n");
861 kfree(cs);
862 return ERR_PTR(-EINVAL);
863 }
864
865 of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
866 cs->fb_delay = fb_delay;
867 return cs;
868}
869
798/* 870/*
799 * Here we only check the validity of requested configuration 871 * Here we only check the validity of requested configuration
800 * and save the configuration in a local data-structure. 872 * and save the configuration in a local data-structure.
@@ -808,14 +880,30 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
808 struct s3c64xx_spi_info *sci; 880 struct s3c64xx_spi_info *sci;
809 struct spi_message *msg; 881 struct spi_message *msg;
810 unsigned long flags; 882 unsigned long flags;
811 int err = 0; 883 int err;
812 884
813 if (cs == NULL || cs->set_level == NULL) { 885 sdd = spi_master_get_devdata(spi->master);
886 if (!cs && spi->dev.of_node) {
887 cs = s3c64xx_get_slave_ctrldata(sdd, spi);
888 spi->controller_data = cs;
889 }
890
891 if (IS_ERR_OR_NULL(cs)) {
814 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); 892 dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select);
815 return -ENODEV; 893 return -ENODEV;
816 } 894 }
817 895
818 sdd = spi_master_get_devdata(spi->master); 896 if (!spi_get_ctldata(spi)) {
897 err = gpio_request(cs->line, dev_name(&spi->dev));
898 if (err) {
899 dev_err(&spi->dev, "request for slave select gpio "
900 "line [%d] failed\n", cs->line);
901 err = -EBUSY;
902 goto err_gpio_req;
903 }
904 spi_set_ctldata(spi, cs);
905 }
906
819 sci = sdd->cntrlr_info; 907 sci = sdd->cntrlr_info;
820 908
821 spin_lock_irqsave(&sdd->lock, flags); 909 spin_lock_irqsave(&sdd->lock, flags);
@@ -826,7 +914,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
826 dev_err(&spi->dev, 914 dev_err(&spi->dev,
827 "setup: attempt while mssg in queue!\n"); 915 "setup: attempt while mssg in queue!\n");
828 spin_unlock_irqrestore(&sdd->lock, flags); 916 spin_unlock_irqrestore(&sdd->lock, flags);
829 return -EBUSY; 917 err = -EBUSY;
918 goto err_msgq;
830 } 919 }
831 } 920 }
832 921
@@ -844,7 +933,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
844 pm_runtime_get_sync(&sdd->pdev->dev); 933 pm_runtime_get_sync(&sdd->pdev->dev);
845 934
846 /* Check if we can provide the requested rate */ 935 /* Check if we can provide the requested rate */
847 if (!sci->clk_from_cmu) { 936 if (!sdd->port_conf->clk_from_cmu) {
848 u32 psr, speed; 937 u32 psr, speed;
849 938
850 /* Max possible */ 939 /* Max possible */
@@ -869,22 +958,44 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
869 } 958 }
870 959
871 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1); 960 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
872 if (spi->max_speed_hz >= speed) 961 if (spi->max_speed_hz >= speed) {
873 spi->max_speed_hz = speed; 962 spi->max_speed_hz = speed;
874 else 963 } else {
875 err = -EINVAL; 964 err = -EINVAL;
965 goto setup_exit;
966 }
876 } 967 }
877 968
878 pm_runtime_put(&sdd->pdev->dev); 969 pm_runtime_put(&sdd->pdev->dev);
970 disable_cs(sdd, spi);
971 return 0;
879 972
880setup_exit: 973setup_exit:
881
882 /* setup() returns with device de-selected */ 974 /* setup() returns with device de-selected */
883 disable_cs(sdd, spi); 975 disable_cs(sdd, spi);
884 976
977err_msgq:
978 gpio_free(cs->line);
979 spi_set_ctldata(spi, NULL);
980
981err_gpio_req:
982 kfree(cs);
983
885 return err; 984 return err;
886} 985}
887 986
987static void s3c64xx_spi_cleanup(struct spi_device *spi)
988{
989 struct s3c64xx_spi_csinfo *cs = spi_get_ctldata(spi);
990
991 if (cs) {
992 gpio_free(cs->line);
993 if (spi->dev.of_node)
994 kfree(cs);
995 }
996 spi_set_ctldata(spi, NULL);
997}
998
888static irqreturn_t s3c64xx_spi_irq(int irq, void *data) 999static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
889{ 1000{
890 struct s3c64xx_spi_driver_data *sdd = data; 1001 struct s3c64xx_spi_driver_data *sdd = data;
@@ -925,7 +1036,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
925 /* Disable Interrupts - we use Polling if not DMA mode */ 1036 /* Disable Interrupts - we use Polling if not DMA mode */
926 writel(0, regs + S3C64XX_SPI_INT_EN); 1037 writel(0, regs + S3C64XX_SPI_INT_EN);
927 1038
928 if (!sci->clk_from_cmu) 1039 if (!sdd->port_conf->clk_from_cmu)
929 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, 1040 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT,
930 regs + S3C64XX_SPI_CLK_CFG); 1041 regs + S3C64XX_SPI_CLK_CFG);
931 writel(0, regs + S3C64XX_SPI_MODE_CFG); 1042 writel(0, regs + S3C64XX_SPI_MODE_CFG);
@@ -946,40 +1057,164 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
946 flush_fifo(sdd); 1057 flush_fifo(sdd);
947} 1058}
948 1059
949static int __init s3c64xx_spi_probe(struct platform_device *pdev) 1060static int __devinit s3c64xx_spi_get_dmares(
1061 struct s3c64xx_spi_driver_data *sdd, bool tx)
1062{
1063 struct platform_device *pdev = sdd->pdev;
1064 struct s3c64xx_spi_dma_data *dma_data;
1065 struct property *prop;
1066 struct resource *res;
1067 char prop_name[15], *chan_str;
1068
1069 if (tx) {
1070 dma_data = &sdd->tx_dma;
1071 dma_data->direction = DMA_TO_DEVICE;
1072 chan_str = "tx";
1073 } else {
1074 dma_data = &sdd->rx_dma;
1075 dma_data->direction = DMA_FROM_DEVICE;
1076 chan_str = "rx";
1077 }
1078
1079 if (!sdd->pdev->dev.of_node) {
1080 res = platform_get_resource(pdev, IORESOURCE_DMA, tx ? 0 : 1);
1081 if (!res) {
1082 dev_err(&pdev->dev, "Unable to get SPI-%s dma "
1083 "resource\n", chan_str);
1084 return -ENXIO;
1085 }
1086 dma_data->dmach = res->start;
1087 return 0;
1088 }
1089
1090 sprintf(prop_name, "%s-dma-channel", chan_str);
1091 prop = of_find_property(pdev->dev.of_node, prop_name, NULL);
1092 if (!prop) {
1093 dev_err(&pdev->dev, "%s dma channel property not specified\n",
1094 chan_str);
1095 return -ENXIO;
1096 }
1097
1098 dma_data->dmach = DMACH_DT_PROP;
1099 dma_data->dma_prop = prop;
1100 return 0;
1101}
1102
1103#ifdef CONFIG_OF
1104static int s3c64xx_spi_parse_dt_gpio(struct s3c64xx_spi_driver_data *sdd)
1105{
1106 struct device *dev = &sdd->pdev->dev;
1107 int idx, gpio, ret;
1108
1109 /* find gpios for mosi, miso and clock lines */
1110 for (idx = 0; idx < 3; idx++) {
1111 gpio = of_get_gpio(dev->of_node, idx);
1112 if (!gpio_is_valid(gpio)) {
1113 dev_err(dev, "invalid gpio[%d]: %d\n", idx, gpio);
1114 goto free_gpio;
1115 }
1116
1117 ret = gpio_request(gpio, "spi-bus");
1118 if (ret) {
1119 dev_err(dev, "gpio [%d] request failed\n", gpio);
1120 goto free_gpio;
1121 }
1122 }
1123 return 0;
1124
1125free_gpio:
1126 while (--idx >= 0)
1127 gpio_free(sdd->gpios[idx]);
1128 return -EINVAL;
1129}
1130
1131static void s3c64xx_spi_dt_gpio_free(struct s3c64xx_spi_driver_data *sdd)
1132{
1133 unsigned int idx;
1134 for (idx = 0; idx < 3; idx++)
1135 gpio_free(sdd->gpios[idx]);
1136}
1137
1138static struct __devinit s3c64xx_spi_info * s3c64xx_spi_parse_dt(
1139 struct device *dev)
950{ 1140{
951 struct resource *mem_res, *dmatx_res, *dmarx_res;
952 struct s3c64xx_spi_driver_data *sdd;
953 struct s3c64xx_spi_info *sci; 1141 struct s3c64xx_spi_info *sci;
954 struct spi_master *master; 1142 u32 temp;
955 int ret, irq;
956 char clk_name[16];
957 1143
958 if (pdev->id < 0) { 1144 sci = devm_kzalloc(dev, sizeof(*sci), GFP_KERNEL);
959 dev_err(&pdev->dev, 1145 if (!sci) {
960 "Invalid platform device id-%d\n", pdev->id); 1146 dev_err(dev, "memory allocation for spi_info failed\n");
961 return -ENODEV; 1147 return ERR_PTR(-ENOMEM);
962 } 1148 }
963 1149
964 if (pdev->dev.platform_data == NULL) { 1150 if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) {
965 dev_err(&pdev->dev, "platform_data missing!\n"); 1151 dev_warn(dev, "spi bus clock parent not specified, using "
966 return -ENODEV; 1152 "clock at index 0 as parent\n");
1153 sci->src_clk_nr = 0;
1154 } else {
1155 sci->src_clk_nr = temp;
967 } 1156 }
968 1157
969 sci = pdev->dev.platform_data; 1158 if (of_property_read_u32(dev->of_node, "num-cs", &temp)) {
1159 dev_warn(dev, "number of chip select lines not specified, "
1160 "assuming 1 chip select line\n");
1161 sci->num_cs = 1;
1162 } else {
1163 sci->num_cs = temp;
1164 }
970 1165
971 /* Check for availability of necessary resource */ 1166 return sci;
1167}
1168#else
1169static struct s3c64xx_spi_info *s3c64xx_spi_parse_dt(struct device *dev)
1170{
1171 return dev->platform_data;
1172}
972 1173
973 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1174static int s3c64xx_spi_parse_dt_gpio(struct s3c64xx_spi_driver_data *sdd)
974 if (dmatx_res == NULL) { 1175{
975 dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n"); 1176 return -EINVAL;
976 return -ENXIO; 1177}
1178
1179static void s3c64xx_spi_dt_gpio_free(struct s3c64xx_spi_driver_data *sdd)
1180{
1181}
1182#endif
1183
1184static const struct of_device_id s3c64xx_spi_dt_match[];
1185
1186static inline struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
1187 struct platform_device *pdev)
1188{
1189#ifdef CONFIG_OF
1190 if (pdev->dev.of_node) {
1191 const struct of_device_id *match;
1192 match = of_match_node(s3c64xx_spi_dt_match, pdev->dev.of_node);
1193 return (struct s3c64xx_spi_port_config *)match->data;
977 } 1194 }
1195#endif
1196 return (struct s3c64xx_spi_port_config *)
1197 platform_get_device_id(pdev)->driver_data;
1198}
978 1199
979 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 1200static int __init s3c64xx_spi_probe(struct platform_device *pdev)
980 if (dmarx_res == NULL) { 1201{
981 dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n"); 1202 struct resource *mem_res;
982 return -ENXIO; 1203 struct s3c64xx_spi_driver_data *sdd;
1204 struct s3c64xx_spi_info *sci = pdev->dev.platform_data;
1205 struct spi_master *master;
1206 int ret, irq;
1207 char clk_name[16];
1208
1209 if (!sci && pdev->dev.of_node) {
1210 sci = s3c64xx_spi_parse_dt(&pdev->dev);
1211 if (IS_ERR(sci))
1212 return PTR_ERR(sci);
1213 }
1214
1215 if (!sci) {
1216 dev_err(&pdev->dev, "platform_data missing!\n");
1217 return -ENODEV;
983 } 1218 }
984 1219
985 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1220 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1004,19 +1239,37 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1004 platform_set_drvdata(pdev, master); 1239 platform_set_drvdata(pdev, master);
1005 1240
1006 sdd = spi_master_get_devdata(master); 1241 sdd = spi_master_get_devdata(master);
1242 sdd->port_conf = s3c64xx_spi_get_port_config(pdev);
1007 sdd->master = master; 1243 sdd->master = master;
1008 sdd->cntrlr_info = sci; 1244 sdd->cntrlr_info = sci;
1009 sdd->pdev = pdev; 1245 sdd->pdev = pdev;
1010 sdd->sfr_start = mem_res->start; 1246 sdd->sfr_start = mem_res->start;
1011 sdd->tx_dma.dmach = dmatx_res->start; 1247 if (pdev->dev.of_node) {
1012 sdd->tx_dma.direction = DMA_MEM_TO_DEV; 1248 ret = of_alias_get_id(pdev->dev.of_node, "spi");
1013 sdd->rx_dma.dmach = dmarx_res->start; 1249 if (ret < 0) {
1014 sdd->rx_dma.direction = DMA_DEV_TO_MEM; 1250 dev_err(&pdev->dev, "failed to get alias id, "
1251 "errno %d\n", ret);
1252 goto err0;
1253 }
1254 sdd->port_id = ret;
1255 } else {
1256 sdd->port_id = pdev->id;
1257 }
1015 1258
1016 sdd->cur_bpw = 8; 1259 sdd->cur_bpw = 8;
1017 1260
1018 master->bus_num = pdev->id; 1261 ret = s3c64xx_spi_get_dmares(sdd, true);
1262 if (ret)
1263 goto err0;
1264
1265 ret = s3c64xx_spi_get_dmares(sdd, false);
1266 if (ret)
1267 goto err0;
1268
1269 master->dev.of_node = pdev->dev.of_node;
1270 master->bus_num = sdd->port_id;
1019 master->setup = s3c64xx_spi_setup; 1271 master->setup = s3c64xx_spi_setup;
1272 master->cleanup = s3c64xx_spi_cleanup;
1020 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; 1273 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
1021 master->transfer_one_message = s3c64xx_spi_transfer_one_message; 1274 master->transfer_one_message = s3c64xx_spi_transfer_one_message;
1022 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; 1275 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
@@ -1039,7 +1292,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1039 goto err1; 1292 goto err1;
1040 } 1293 }
1041 1294
1042 if (sci->cfg_gpio == NULL || sci->cfg_gpio(pdev)) { 1295 if (!sci->cfg_gpio && pdev->dev.of_node) {
1296 if (s3c64xx_spi_parse_dt_gpio(sdd))
1297 return -EBUSY;
1298 } else if (sci->cfg_gpio == NULL || sci->cfg_gpio()) {
1043 dev_err(&pdev->dev, "Unable to config gpio\n"); 1299 dev_err(&pdev->dev, "Unable to config gpio\n");
1044 ret = -EBUSY; 1300 ret = -EBUSY;
1045 goto err2; 1301 goto err2;
@@ -1075,7 +1331,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1075 } 1331 }
1076 1332
1077 /* Setup Deufult Mode */ 1333 /* Setup Deufult Mode */
1078 s3c64xx_spi_hwinit(sdd, pdev->id); 1334 s3c64xx_spi_hwinit(sdd, sdd->port_id);
1079 1335
1080 spin_lock_init(&sdd->lock); 1336 spin_lock_init(&sdd->lock);
1081 init_completion(&sdd->xfer_completion); 1337 init_completion(&sdd->xfer_completion);
@@ -1100,7 +1356,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1100 1356
1101 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d " 1357 dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d "
1102 "with %d Slaves attached\n", 1358 "with %d Slaves attached\n",
1103 pdev->id, master->num_chipselect); 1359 sdd->port_id, master->num_chipselect);
1104 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", 1360 dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n",
1105 mem_res->end, mem_res->start, 1361 mem_res->end, mem_res->start,
1106 sdd->rx_dma.dmach, sdd->tx_dma.dmach); 1362 sdd->rx_dma.dmach, sdd->tx_dma.dmach);
@@ -1120,6 +1376,8 @@ err5:
1120err4: 1376err4:
1121 clk_put(sdd->clk); 1377 clk_put(sdd->clk);
1122err3: 1378err3:
1379 if (!sdd->cntrlr_info->cfg_gpio && pdev->dev.of_node)
1380 s3c64xx_spi_dt_gpio_free(sdd);
1123err2: 1381err2:
1124 iounmap((void *) sdd->regs); 1382 iounmap((void *) sdd->regs);
1125err1: 1383err1:
@@ -1151,6 +1409,9 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1151 clk_disable(sdd->clk); 1409 clk_disable(sdd->clk);
1152 clk_put(sdd->clk); 1410 clk_put(sdd->clk);
1153 1411
1412 if (!sdd->cntrlr_info->cfg_gpio && pdev->dev.of_node)
1413 s3c64xx_spi_dt_gpio_free(sdd);
1414
1154 iounmap((void *) sdd->regs); 1415 iounmap((void *) sdd->regs);
1155 1416
1156 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1417 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1175,6 +1436,9 @@ static int s3c64xx_spi_suspend(struct device *dev)
1175 clk_disable(sdd->src_clk); 1436 clk_disable(sdd->src_clk);
1176 clk_disable(sdd->clk); 1437 clk_disable(sdd->clk);
1177 1438
1439 if (!sdd->cntrlr_info->cfg_gpio && dev->of_node)
1440 s3c64xx_spi_dt_gpio_free(sdd);
1441
1178 sdd->cur_speed = 0; /* Output Clock is stopped */ 1442 sdd->cur_speed = 0; /* Output Clock is stopped */
1179 1443
1180 return 0; 1444 return 0;
@@ -1182,18 +1446,20 @@ static int s3c64xx_spi_suspend(struct device *dev)
1182 1446
1183static int s3c64xx_spi_resume(struct device *dev) 1447static int s3c64xx_spi_resume(struct device *dev)
1184{ 1448{
1185 struct platform_device *pdev = to_platform_device(dev);
1186 struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); 1449 struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
1187 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1450 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1188 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; 1451 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
1189 1452
1190 sci->cfg_gpio(pdev); 1453 if (!sci->cfg_gpio && dev->of_node)
1454 s3c64xx_spi_parse_dt_gpio(sdd);
1455 else
1456 sci->cfg_gpio();
1191 1457
1192 /* Enable the clock */ 1458 /* Enable the clock */
1193 clk_enable(sdd->src_clk); 1459 clk_enable(sdd->src_clk);
1194 clk_enable(sdd->clk); 1460 clk_enable(sdd->clk);
1195 1461
1196 s3c64xx_spi_hwinit(sdd, pdev->id); 1462 s3c64xx_spi_hwinit(sdd, sdd->port_id);
1197 1463
1198 spi_master_resume(master); 1464 spi_master_resume(master);
1199 1465
@@ -1231,13 +1497,89 @@ static const struct dev_pm_ops s3c64xx_spi_pm = {
1231 s3c64xx_spi_runtime_resume, NULL) 1497 s3c64xx_spi_runtime_resume, NULL)
1232}; 1498};
1233 1499
1500struct s3c64xx_spi_port_config s3c2443_spi_port_config = {
1501 .fifo_lvl_mask = { 0x7f },
1502 .rx_lvl_offset = 13,
1503 .tx_st_done = 21,
1504 .high_speed = true,
1505};
1506
1507struct s3c64xx_spi_port_config s3c6410_spi_port_config = {
1508 .fifo_lvl_mask = { 0x7f, 0x7F },
1509 .rx_lvl_offset = 13,
1510 .tx_st_done = 21,
1511};
1512
1513struct s3c64xx_spi_port_config s5p64x0_spi_port_config = {
1514 .fifo_lvl_mask = { 0x1ff, 0x7F },
1515 .rx_lvl_offset = 15,
1516 .tx_st_done = 25,
1517};
1518
1519struct s3c64xx_spi_port_config s5pc100_spi_port_config = {
1520 .fifo_lvl_mask = { 0x7f, 0x7F },
1521 .rx_lvl_offset = 13,
1522 .tx_st_done = 21,
1523 .high_speed = true,
1524};
1525
1526struct s3c64xx_spi_port_config s5pv210_spi_port_config = {
1527 .fifo_lvl_mask = { 0x1ff, 0x7F },
1528 .rx_lvl_offset = 15,
1529 .tx_st_done = 25,
1530 .high_speed = true,
1531};
1532
1533struct s3c64xx_spi_port_config exynos4_spi_port_config = {
1534 .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F },
1535 .rx_lvl_offset = 15,
1536 .tx_st_done = 25,
1537 .high_speed = true,
1538 .clk_from_cmu = true,
1539};
1540
1541static struct platform_device_id s3c64xx_spi_driver_ids[] = {
1542 {
1543 .name = "s3c2443-spi",
1544 .driver_data = (kernel_ulong_t)&s3c2443_spi_port_config,
1545 }, {
1546 .name = "s3c6410-spi",
1547 .driver_data = (kernel_ulong_t)&s3c6410_spi_port_config,
1548 }, {
1549 .name = "s5p64x0-spi",
1550 .driver_data = (kernel_ulong_t)&s5p64x0_spi_port_config,
1551 }, {
1552 .name = "s5pc100-spi",
1553 .driver_data = (kernel_ulong_t)&s5pc100_spi_port_config,
1554 }, {
1555 .name = "s5pv210-spi",
1556 .driver_data = (kernel_ulong_t)&s5pv210_spi_port_config,
1557 }, {
1558 .name = "exynos4210-spi",
1559 .driver_data = (kernel_ulong_t)&exynos4_spi_port_config,
1560 },
1561 { },
1562};
1563
1564#ifdef CONFIG_OF
1565static const struct of_device_id s3c64xx_spi_dt_match[] = {
1566 { .compatible = "samsung,exynos4210-spi",
1567 .data = (void *)&exynos4_spi_port_config,
1568 },
1569 { },
1570};
1571MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
1572#endif /* CONFIG_OF */
1573
1234static struct platform_driver s3c64xx_spi_driver = { 1574static struct platform_driver s3c64xx_spi_driver = {
1235 .driver = { 1575 .driver = {
1236 .name = "s3c64xx-spi", 1576 .name = "s3c64xx-spi",
1237 .owner = THIS_MODULE, 1577 .owner = THIS_MODULE,
1238 .pm = &s3c64xx_spi_pm, 1578 .pm = &s3c64xx_spi_pm,
1579 .of_match_table = of_match_ptr(s3c64xx_spi_dt_match),
1239 }, 1580 },
1240 .remove = s3c64xx_spi_remove, 1581 .remove = s3c64xx_spi_remove,
1582 .id_table = s3c64xx_spi_driver_ids,
1241}; 1583};
1242MODULE_ALIAS("platform:s3c64xx-spi"); 1584MODULE_ALIAS("platform:s3c64xx-spi");
1243 1585
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index ddc6cde14e2a..f3ebc38c10fe 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -74,7 +74,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
74 struct runtime_data *prtd = substream->runtime->private_data; 74 struct runtime_data *prtd = substream->runtime->private_data;
75 dma_addr_t pos = prtd->dma_pos; 75 dma_addr_t pos = prtd->dma_pos;
76 unsigned int limit; 76 unsigned int limit;
77 struct samsung_dma_prep_info dma_info; 77 struct samsung_dma_prep dma_info;
78 78
79 pr_debug("Entered %s\n", __func__); 79 pr_debug("Entered %s\n", __func__);
80 80
@@ -146,7 +146,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
146 unsigned long totbytes = params_buffer_bytes(params); 146 unsigned long totbytes = params_buffer_bytes(params);
147 struct s3c_dma_params *dma = 147 struct s3c_dma_params *dma =
148 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 148 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
149 struct samsung_dma_info dma_info; 149 struct samsung_dma_req req;
150 struct samsung_dma_config config;
150 151
151 pr_debug("Entered %s\n", __func__); 152 pr_debug("Entered %s\n", __func__);
152 153
@@ -166,16 +167,17 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
166 167
167 prtd->params->ops = samsung_dma_get_ops(); 168 prtd->params->ops = samsung_dma_get_ops();
168 169
169 dma_info.cap = (samsung_dma_has_circular() ? 170 req.cap = (samsung_dma_has_circular() ?
170 DMA_CYCLIC : DMA_SLAVE); 171 DMA_CYCLIC : DMA_SLAVE);
171 dma_info.client = prtd->params->client; 172 req.client = prtd->params->client;
172 dma_info.direction = 173 config.direction =
173 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK 174 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
174 ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); 175 ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
175 dma_info.width = prtd->params->dma_size; 176 config.width = prtd->params->dma_size;
176 dma_info.fifo = prtd->params->dma_addr; 177 config.fifo = prtd->params->dma_addr;
177 prtd->params->ch = prtd->params->ops->request( 178 prtd->params->ch = prtd->params->ops->request(
178 prtd->params->channel, &dma_info); 179 prtd->params->channel, &req);
180 prtd->params->ops->config(prtd->params->ch, &config);
179 } 181 }
180 182
181 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 183 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);