aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2012-07-17 17:06:32 -0400
committerArnd Bergmann <arnd@arndb.de>2012-07-17 17:06:32 -0400
commitfeb7b8d6d2b2eedbca5a55b5dc74d9d967c91151 (patch)
treeed2bae5b1a496471924792608ddbaa2ff942812d
parent6a1d02d861a35295db8b57fe4cd400bde7c8bd92 (diff)
parent79989ba3e201f3bf992e600a0745ecaf256f08f5 (diff)
Merge branch 'next/dt-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/dt
From Kukjin Kim <kgene.kim@samsung.com>: It is for supporting spi dt for exynos4210 and exynos5250, and got the ack from Grant Likely for spi driver. Note: Since this is including spi driver changes, so it was made based on next/devel-dma-ops which touches same file, Samsung spi driver for avoiding bad conflicts. * 'next/dt-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung: ARM: dts: Add nodes for spi controllers for SAMSUNG EXYNOS5 platforms ARM: EXYNOS: Enable platform support for SPI controllers for EXYNOS5 ARM: EXYNOS: Add spi clock support for EXYNOS5 ARM: dts: Add nodes for spi controllers for SAMSUNG EXYNOS4 platforms ARM: EXYNOS: Enable platform support for SPI controllers for EXYNOX4 ARM: EXYNOS: Fix the incorrect hierarchy of spi controller bus clock ARM: EXYNOS: Add device tree node for EXYNOS4 interrupt combiner controller spi: s3c64xx: add device tree support spi: s3c64xx: Remove the 'set_level' callback from controller data ARM: SAMSUNG: Modify s3c64xx_spi{0|1|2}_set_platdata function ARM: SAMSUNG: Remove pdev pointer parameter from spi gpio setup functions spi: s3c64xx: move controller information into driver data spi: s3c64xx: remove unused S3C64XX_SPI_ST_TRLCNTZ macro ARM: S3C64XX: Add a new dma request id for device tree based dma channel lookup Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-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/include/plat/s3c64xx-spi.h39
-rw-r--r--drivers/spi/spi-s3c64xx.c481
31 files changed, 953 insertions, 326 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 1d214cb9d770..86d075870a52 100644
--- a/arch/arm/plat-samsung/devs.c
+++ b/arch/arm/plat-samsung/devs.c
@@ -1512,7 +1512,7 @@ static struct resource s3c64xx_spi0_resource[] = {
1512}; 1512};
1513 1513
1514struct platform_device s3c64xx_device_spi0 = { 1514struct platform_device s3c64xx_device_spi0 = {
1515 .name = "s3c64xx-spi", 1515 .name = "s3c6410-spi",
1516 .id = 0, 1516 .id = 0,
1517 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), 1517 .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
1518 .resource = s3c64xx_spi0_resource, 1518 .resource = s3c64xx_spi0_resource,
@@ -1522,13 +1522,10 @@ struct platform_device s3c64xx_device_spi0 = {
1522 }, 1522 },
1523}; 1523};
1524 1524
1525void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd, 1525void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1526 int src_clk_nr, int num_cs) 1526 int num_cs)
1527{ 1527{
1528 if (!pd) { 1528 struct s3c64xx_spi_info pd;
1529 pr_err("%s:Need to pass platform data\n", __func__);
1530 return;
1531 }
1532 1529
1533 /* Reject invalid configuration */ 1530 /* Reject invalid configuration */
1534 if (!num_cs || src_clk_nr < 0) { 1531 if (!num_cs || src_clk_nr < 0) {
@@ -1536,12 +1533,11 @@ void __init s3c64xx_spi0_set_platdata(struct s3c64xx_spi_info *pd,
1536 return; 1533 return;
1537 } 1534 }
1538 1535
1539 pd->num_cs = num_cs; 1536 pd.num_cs = num_cs;
1540 pd->src_clk_nr = src_clk_nr; 1537 pd.src_clk_nr = src_clk_nr;
1541 if (!pd->cfg_gpio) 1538 pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
1542 pd->cfg_gpio = s3c64xx_spi0_cfg_gpio;
1543 1539
1544 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi0); 1540 s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0);
1545} 1541}
1546#endif /* CONFIG_S3C64XX_DEV_SPI0 */ 1542#endif /* CONFIG_S3C64XX_DEV_SPI0 */
1547 1543
@@ -1554,7 +1550,7 @@ static struct resource s3c64xx_spi1_resource[] = {
1554}; 1550};
1555 1551
1556struct platform_device s3c64xx_device_spi1 = { 1552struct platform_device s3c64xx_device_spi1 = {
1557 .name = "s3c64xx-spi", 1553 .name = "s3c6410-spi",
1558 .id = 1, 1554 .id = 1,
1559 .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource), 1555 .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
1560 .resource = s3c64xx_spi1_resource, 1556 .resource = s3c64xx_spi1_resource,
@@ -1564,26 +1560,20 @@ struct platform_device s3c64xx_device_spi1 = {
1564 }, 1560 },
1565}; 1561};
1566 1562
1567void __init s3c64xx_spi1_set_platdata(struct s3c64xx_spi_info *pd, 1563void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1568 int src_clk_nr, int num_cs) 1564 int num_cs)
1569{ 1565{
1570 if (!pd) {
1571 pr_err("%s:Need to pass platform data\n", __func__);
1572 return;
1573 }
1574
1575 /* Reject invalid configuration */ 1566 /* Reject invalid configuration */
1576 if (!num_cs || src_clk_nr < 0) { 1567 if (!num_cs || src_clk_nr < 0) {
1577 pr_err("%s: Invalid SPI configuration\n", __func__); 1568 pr_err("%s: Invalid SPI configuration\n", __func__);
1578 return; 1569 return;
1579 } 1570 }
1580 1571
1581 pd->num_cs = num_cs; 1572 pd.num_cs = num_cs;
1582 pd->src_clk_nr = src_clk_nr; 1573 pd.src_clk_nr = src_clk_nr;
1583 if (!pd->cfg_gpio) 1574 pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
1584 pd->cfg_gpio = s3c64xx_spi1_cfg_gpio;
1585 1575
1586 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi1); 1576 s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
1587} 1577}
1588#endif /* CONFIG_S3C64XX_DEV_SPI1 */ 1578#endif /* CONFIG_S3C64XX_DEV_SPI1 */
1589 1579
@@ -1596,7 +1586,7 @@ static struct resource s3c64xx_spi2_resource[] = {
1596}; 1586};
1597 1587
1598struct platform_device s3c64xx_device_spi2 = { 1588struct platform_device s3c64xx_device_spi2 = {
1599 .name = "s3c64xx-spi", 1589 .name = "s3c6410-spi",
1600 .id = 2, 1590 .id = 2,
1601 .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource), 1591 .num_resources = ARRAY_SIZE(s3c64xx_spi2_resource),
1602 .resource = s3c64xx_spi2_resource, 1592 .resource = s3c64xx_spi2_resource,
@@ -1606,13 +1596,10 @@ struct platform_device s3c64xx_device_spi2 = {
1606 }, 1596 },
1607}; 1597};
1608 1598
1609void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd, 1599void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
1610 int src_clk_nr, int num_cs) 1600 int num_cs)
1611{ 1601{
1612 if (!pd) { 1602 struct s3c64xx_spi_info pd;
1613 pr_err("%s:Need to pass platform data\n", __func__);
1614 return;
1615 }
1616 1603
1617 /* Reject invalid configuration */ 1604 /* Reject invalid configuration */
1618 if (!num_cs || src_clk_nr < 0) { 1605 if (!num_cs || src_clk_nr < 0) {
@@ -1620,11 +1607,10 @@ void __init s3c64xx_spi2_set_platdata(struct s3c64xx_spi_info *pd,
1620 return; 1607 return;
1621 } 1608 }
1622 1609
1623 pd->num_cs = num_cs; 1610 pd.num_cs = num_cs;
1624 pd->src_clk_nr = src_clk_nr; 1611 pd.src_clk_nr = src_clk_nr;
1625 if (!pd->cfg_gpio) 1612 pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
1626 pd->cfg_gpio = s3c64xx_spi2_cfg_gpio;
1627 1613
1628 s3c_set_platdata(pd, sizeof(*pd), &s3c64xx_device_spi2); 1614 s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
1629} 1615}
1630#endif /* CONFIG_S3C64XX_DEV_SPI2 */ 1616#endif /* CONFIG_S3C64XX_DEV_SPI2 */
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/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 3c36cfaa1b93..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;
@@ -301,7 +330,9 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
301 req.cap = DMA_SLAVE; 330 req.cap = DMA_SLAVE;
302 req.client = &s3c64xx_spi_dma_client; 331 req.client = &s3c64xx_spi_dma_client;
303 332
333 req.dt_dmach_prop = sdd->rx_dma.dma_prop;
304 sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req); 334 sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req);
335 req.dt_dmach_prop = sdd->tx_dma.dma_prop;
305 sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req); 336 sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req);
306 337
307 return 1; 338 return 1;
@@ -311,7 +342,6 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
311 struct spi_device *spi, 342 struct spi_device *spi,
312 struct spi_transfer *xfer, int dma_mode) 343 struct spi_transfer *xfer, int dma_mode)
313{ 344{
314 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
315 void __iomem *regs = sdd->regs; 345 void __iomem *regs = sdd->regs;
316 u32 modecfg, chcfg; 346 u32 modecfg, chcfg;
317 347
@@ -361,7 +391,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd,
361 if (xfer->rx_buf != NULL) { 391 if (xfer->rx_buf != NULL) {
362 sdd->state |= RXBUSY; 392 sdd->state |= RXBUSY;
363 393
364 if (sci->high_speed && sdd->cur_speed >= 30000000UL 394 if (sdd->port_conf->high_speed && sdd->cur_speed >= 30000000UL
365 && !(sdd->cur_mode & SPI_CPHA)) 395 && !(sdd->cur_mode & SPI_CPHA))
366 chcfg |= S3C64XX_SPI_CH_HS_EN; 396 chcfg |= S3C64XX_SPI_CH_HS_EN;
367 397
@@ -388,20 +418,19 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd,
388 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ 418 if (sdd->tgl_spi != spi) { /* if last mssg on diff device */
389 /* Deselect the last toggled device */ 419 /* Deselect the last toggled device */
390 cs = sdd->tgl_spi->controller_data; 420 cs = sdd->tgl_spi->controller_data;
391 cs->set_level(cs->line, 421 gpio_set_value(cs->line,
392 spi->mode & SPI_CS_HIGH ? 0 : 1); 422 spi->mode & SPI_CS_HIGH ? 0 : 1);
393 } 423 }
394 sdd->tgl_spi = NULL; 424 sdd->tgl_spi = NULL;
395 } 425 }
396 426
397 cs = spi->controller_data; 427 cs = spi->controller_data;
398 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);
399} 429}
400 430
401static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, 431static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
402 struct spi_transfer *xfer, int dma_mode) 432 struct spi_transfer *xfer, int dma_mode)
403{ 433{
404 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
405 void __iomem *regs = sdd->regs; 434 void __iomem *regs = sdd->regs;
406 unsigned long val; 435 unsigned long val;
407 int ms; 436 int ms;
@@ -418,7 +447,7 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
418 val = msecs_to_loops(ms); 447 val = msecs_to_loops(ms);
419 do { 448 do {
420 status = readl(regs + S3C64XX_SPI_STATUS); 449 status = readl(regs + S3C64XX_SPI_STATUS);
421 } while (RX_FIFO_LVL(status, sci) < xfer->len && --val); 450 } while (RX_FIFO_LVL(status, sdd) < xfer->len && --val);
422 } 451 }
423 452
424 if (!val) 453 if (!val)
@@ -437,8 +466,8 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
437 if (xfer->rx_buf == NULL) { 466 if (xfer->rx_buf == NULL) {
438 val = msecs_to_loops(10); 467 val = msecs_to_loops(10);
439 status = readl(regs + S3C64XX_SPI_STATUS); 468 status = readl(regs + S3C64XX_SPI_STATUS);
440 while ((TX_FIFO_LVL(status, sci) 469 while ((TX_FIFO_LVL(status, sdd)
441 || !S3C64XX_SPI_ST_TX_DONE(status, sci)) 470 || !S3C64XX_SPI_ST_TX_DONE(status, sdd))
442 && --val) { 471 && --val) {
443 cpu_relax(); 472 cpu_relax();
444 status = readl(regs + S3C64XX_SPI_STATUS); 473 status = readl(regs + S3C64XX_SPI_STATUS);
@@ -482,17 +511,16 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd,
482 if (sdd->tgl_spi == spi) 511 if (sdd->tgl_spi == spi)
483 sdd->tgl_spi = NULL; 512 sdd->tgl_spi = NULL;
484 513
485 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);
486} 515}
487 516
488static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) 517static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
489{ 518{
490 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
491 void __iomem *regs = sdd->regs; 519 void __iomem *regs = sdd->regs;
492 u32 val; 520 u32 val;
493 521
494 /* Disable Clock */ 522 /* Disable Clock */
495 if (sci->clk_from_cmu) { 523 if (sdd->port_conf->clk_from_cmu) {
496 clk_disable(sdd->src_clk); 524 clk_disable(sdd->src_clk);
497 } else { 525 } else {
498 val = readl(regs + S3C64XX_SPI_CLK_CFG); 526 val = readl(regs + S3C64XX_SPI_CLK_CFG);
@@ -536,7 +564,7 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
536 564
537 writel(val, regs + S3C64XX_SPI_MODE_CFG); 565 writel(val, regs + S3C64XX_SPI_MODE_CFG);
538 566
539 if (sci->clk_from_cmu) { 567 if (sdd->port_conf->clk_from_cmu) {
540 /* Configure Clock */ 568 /* Configure Clock */
541 /* There is half-multiplier before the SPI */ 569 /* There is half-multiplier before the SPI */
542 clk_set_rate(sdd->src_clk, sdd->cur_speed * 2); 570 clk_set_rate(sdd->src_clk, sdd->cur_speed * 2);
@@ -562,7 +590,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd)
562static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, 590static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
563 struct spi_message *msg) 591 struct spi_message *msg)
564{ 592{
565 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
566 struct device *dev = &sdd->pdev->dev; 593 struct device *dev = &sdd->pdev->dev;
567 struct spi_transfer *xfer; 594 struct spi_transfer *xfer;
568 595
@@ -578,7 +605,7 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
578 /* Map until end or first fail */ 605 /* Map until end or first fail */
579 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 606 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
580 607
581 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) 608 if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
582 continue; 609 continue;
583 610
584 if (xfer->tx_buf != NULL) { 611 if (xfer->tx_buf != NULL) {
@@ -612,7 +639,6 @@ static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd,
612static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, 639static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
613 struct spi_message *msg) 640 struct spi_message *msg)
614{ 641{
615 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
616 struct device *dev = &sdd->pdev->dev; 642 struct device *dev = &sdd->pdev->dev;
617 struct spi_transfer *xfer; 643 struct spi_transfer *xfer;
618 644
@@ -621,7 +647,7 @@ static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd,
621 647
622 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 648 list_for_each_entry(xfer, &msg->transfers, transfer_list) {
623 649
624 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) 650 if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
625 continue; 651 continue;
626 652
627 if (xfer->rx_buf != NULL 653 if (xfer->rx_buf != NULL
@@ -640,7 +666,6 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
640 struct spi_message *msg) 666 struct spi_message *msg)
641{ 667{
642 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 668 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
643 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
644 struct spi_device *spi = msg->spi; 669 struct spi_device *spi = msg->spi;
645 struct s3c64xx_spi_csinfo *cs = spi->controller_data; 670 struct s3c64xx_spi_csinfo *cs = spi->controller_data;
646 struct spi_transfer *xfer; 671 struct spi_transfer *xfer;
@@ -695,7 +720,7 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master,
695 } 720 }
696 721
697 /* Polling method for xfers not bigger than FIFO capacity */ 722 /* Polling method for xfers not bigger than FIFO capacity */
698 if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) 723 if (xfer->len <= ((FIFO_LVL_MASK(sdd) >> 1) + 1))
699 use_dma = 0; 724 use_dma = 0;
700 else 725 else
701 use_dma = 1; 726 use_dma = 1;
@@ -800,6 +825,48 @@ static int s3c64xx_spi_unprepare_transfer(struct spi_master *spi)
800 return 0; 825 return 0;
801} 826}
802 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
803/* 870/*
804 * Here we only check the validity of requested configuration 871 * Here we only check the validity of requested configuration
805 * and save the configuration in a local data-structure. 872 * and save the configuration in a local data-structure.
@@ -813,14 +880,30 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
813 struct s3c64xx_spi_info *sci; 880 struct s3c64xx_spi_info *sci;
814 struct spi_message *msg; 881 struct spi_message *msg;
815 unsigned long flags; 882 unsigned long flags;
816 int err = 0; 883 int err;
817 884
818 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)) {
819 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);
820 return -ENODEV; 893 return -ENODEV;
821 } 894 }
822 895
823 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
824 sci = sdd->cntrlr_info; 907 sci = sdd->cntrlr_info;
825 908
826 spin_lock_irqsave(&sdd->lock, flags); 909 spin_lock_irqsave(&sdd->lock, flags);
@@ -831,7 +914,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
831 dev_err(&spi->dev, 914 dev_err(&spi->dev,
832 "setup: attempt while mssg in queue!\n"); 915 "setup: attempt while mssg in queue!\n");
833 spin_unlock_irqrestore(&sdd->lock, flags); 916 spin_unlock_irqrestore(&sdd->lock, flags);
834 return -EBUSY; 917 err = -EBUSY;
918 goto err_msgq;
835 } 919 }
836 } 920 }
837 921
@@ -849,7 +933,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
849 pm_runtime_get_sync(&sdd->pdev->dev); 933 pm_runtime_get_sync(&sdd->pdev->dev);
850 934
851 /* Check if we can provide the requested rate */ 935 /* Check if we can provide the requested rate */
852 if (!sci->clk_from_cmu) { 936 if (!sdd->port_conf->clk_from_cmu) {
853 u32 psr, speed; 937 u32 psr, speed;
854 938
855 /* Max possible */ 939 /* Max possible */
@@ -874,22 +958,44 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
874 } 958 }
875 959
876 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1); 960 speed = clk_get_rate(sdd->src_clk) / 2 / (psr + 1);
877 if (spi->max_speed_hz >= speed) 961 if (spi->max_speed_hz >= speed) {
878 spi->max_speed_hz = speed; 962 spi->max_speed_hz = speed;
879 else 963 } else {
880 err = -EINVAL; 964 err = -EINVAL;
965 goto setup_exit;
966 }
881 } 967 }
882 968
883 pm_runtime_put(&sdd->pdev->dev); 969 pm_runtime_put(&sdd->pdev->dev);
970 disable_cs(sdd, spi);
971 return 0;
884 972
885setup_exit: 973setup_exit:
886
887 /* setup() returns with device de-selected */ 974 /* setup() returns with device de-selected */
888 disable_cs(sdd, spi); 975 disable_cs(sdd, spi);
889 976
977err_msgq:
978 gpio_free(cs->line);
979 spi_set_ctldata(spi, NULL);
980
981err_gpio_req:
982 kfree(cs);
983
890 return err; 984 return err;
891} 985}
892 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
893static irqreturn_t s3c64xx_spi_irq(int irq, void *data) 999static irqreturn_t s3c64xx_spi_irq(int irq, void *data)
894{ 1000{
895 struct s3c64xx_spi_driver_data *sdd = data; 1001 struct s3c64xx_spi_driver_data *sdd = data;
@@ -930,7 +1036,7 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
930 /* Disable Interrupts - we use Polling if not DMA mode */ 1036 /* Disable Interrupts - we use Polling if not DMA mode */
931 writel(0, regs + S3C64XX_SPI_INT_EN); 1037 writel(0, regs + S3C64XX_SPI_INT_EN);
932 1038
933 if (!sci->clk_from_cmu) 1039 if (!sdd->port_conf->clk_from_cmu)
934 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, 1040 writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT,
935 regs + S3C64XX_SPI_CLK_CFG); 1041 regs + S3C64XX_SPI_CLK_CFG);
936 writel(0, regs + S3C64XX_SPI_MODE_CFG); 1042 writel(0, regs + S3C64XX_SPI_MODE_CFG);
@@ -951,40 +1057,164 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel)
951 flush_fifo(sdd); 1057 flush_fifo(sdd);
952} 1058}
953 1059
954static 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)
955{ 1140{
956 struct resource *mem_res, *dmatx_res, *dmarx_res;
957 struct s3c64xx_spi_driver_data *sdd;
958 struct s3c64xx_spi_info *sci; 1141 struct s3c64xx_spi_info *sci;
959 struct spi_master *master; 1142 u32 temp;
960 int ret, irq;
961 char clk_name[16];
962 1143
963 if (pdev->id < 0) { 1144 sci = devm_kzalloc(dev, sizeof(*sci), GFP_KERNEL);
964 dev_err(&pdev->dev, 1145 if (!sci) {
965 "Invalid platform device id-%d\n", pdev->id); 1146 dev_err(dev, "memory allocation for spi_info failed\n");
966 return -ENODEV; 1147 return ERR_PTR(-ENOMEM);
967 } 1148 }
968 1149
969 if (pdev->dev.platform_data == NULL) { 1150 if (of_property_read_u32(dev->of_node, "samsung,spi-src-clk", &temp)) {
970 dev_err(&pdev->dev, "platform_data missing!\n"); 1151 dev_warn(dev, "spi bus clock parent not specified, using "
971 return -ENODEV; 1152 "clock at index 0 as parent\n");
1153 sci->src_clk_nr = 0;
1154 } else {
1155 sci->src_clk_nr = temp;
972 } 1156 }
973 1157
974 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 }
1165
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}
1173
1174static int s3c64xx_spi_parse_dt_gpio(struct s3c64xx_spi_driver_data *sdd)
1175{
1176 return -EINVAL;
1177}
975 1178
976 /* Check for availability of necessary resource */ 1179static void s3c64xx_spi_dt_gpio_free(struct s3c64xx_spi_driver_data *sdd)
1180{
1181}
1182#endif
977 1183
978 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1184static const struct of_device_id s3c64xx_spi_dt_match[];
979 if (dmatx_res == NULL) { 1185
980 dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n"); 1186static inline struct s3c64xx_spi_port_config *s3c64xx_spi_get_port_config(
981 return -ENXIO; 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;
982 } 1194 }
1195#endif
1196 return (struct s3c64xx_spi_port_config *)
1197 platform_get_device_id(pdev)->driver_data;
1198}
983 1199
984 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 1200static int __init s3c64xx_spi_probe(struct platform_device *pdev)
985 if (dmarx_res == NULL) { 1201{
986 dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n"); 1202 struct resource *mem_res;
987 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;
988 } 1218 }
989 1219
990 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1220 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1009,19 +1239,37 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1009 platform_set_drvdata(pdev, master); 1239 platform_set_drvdata(pdev, master);
1010 1240
1011 sdd = spi_master_get_devdata(master); 1241 sdd = spi_master_get_devdata(master);
1242 sdd->port_conf = s3c64xx_spi_get_port_config(pdev);
1012 sdd->master = master; 1243 sdd->master = master;
1013 sdd->cntrlr_info = sci; 1244 sdd->cntrlr_info = sci;
1014 sdd->pdev = pdev; 1245 sdd->pdev = pdev;
1015 sdd->sfr_start = mem_res->start; 1246 sdd->sfr_start = mem_res->start;
1016 sdd->tx_dma.dmach = dmatx_res->start; 1247 if (pdev->dev.of_node) {
1017 sdd->tx_dma.direction = DMA_MEM_TO_DEV; 1248 ret = of_alias_get_id(pdev->dev.of_node, "spi");
1018 sdd->rx_dma.dmach = dmarx_res->start; 1249 if (ret < 0) {
1019 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 }
1020 1258
1021 sdd->cur_bpw = 8; 1259 sdd->cur_bpw = 8;
1022 1260
1023 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;
1024 master->setup = s3c64xx_spi_setup; 1271 master->setup = s3c64xx_spi_setup;
1272 master->cleanup = s3c64xx_spi_cleanup;
1025 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; 1273 master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer;
1026 master->transfer_one_message = s3c64xx_spi_transfer_one_message; 1274 master->transfer_one_message = s3c64xx_spi_transfer_one_message;
1027 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer; 1275 master->unprepare_transfer_hardware = s3c64xx_spi_unprepare_transfer;
@@ -1044,7 +1292,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1044 goto err1; 1292 goto err1;
1045 } 1293 }
1046 1294
1047 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()) {
1048 dev_err(&pdev->dev, "Unable to config gpio\n"); 1299 dev_err(&pdev->dev, "Unable to config gpio\n");
1049 ret = -EBUSY; 1300 ret = -EBUSY;
1050 goto err2; 1301 goto err2;
@@ -1080,7 +1331,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1080 } 1331 }
1081 1332
1082 /* Setup Deufult Mode */ 1333 /* Setup Deufult Mode */
1083 s3c64xx_spi_hwinit(sdd, pdev->id); 1334 s3c64xx_spi_hwinit(sdd, sdd->port_id);
1084 1335
1085 spin_lock_init(&sdd->lock); 1336 spin_lock_init(&sdd->lock);
1086 init_completion(&sdd->xfer_completion); 1337 init_completion(&sdd->xfer_completion);
@@ -1105,7 +1356,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
1105 1356
1106 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 "
1107 "with %d Slaves attached\n", 1358 "with %d Slaves attached\n",
1108 pdev->id, master->num_chipselect); 1359 sdd->port_id, master->num_chipselect);
1109 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",
1110 mem_res->end, mem_res->start, 1361 mem_res->end, mem_res->start,
1111 sdd->rx_dma.dmach, sdd->tx_dma.dmach); 1362 sdd->rx_dma.dmach, sdd->tx_dma.dmach);
@@ -1125,6 +1376,8 @@ err5:
1125err4: 1376err4:
1126 clk_put(sdd->clk); 1377 clk_put(sdd->clk);
1127err3: 1378err3:
1379 if (!sdd->cntrlr_info->cfg_gpio && pdev->dev.of_node)
1380 s3c64xx_spi_dt_gpio_free(sdd);
1128err2: 1381err2:
1129 iounmap((void *) sdd->regs); 1382 iounmap((void *) sdd->regs);
1130err1: 1383err1:
@@ -1156,6 +1409,9 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
1156 clk_disable(sdd->clk); 1409 clk_disable(sdd->clk);
1157 clk_put(sdd->clk); 1410 clk_put(sdd->clk);
1158 1411
1412 if (!sdd->cntrlr_info->cfg_gpio && pdev->dev.of_node)
1413 s3c64xx_spi_dt_gpio_free(sdd);
1414
1159 iounmap((void *) sdd->regs); 1415 iounmap((void *) sdd->regs);
1160 1416
1161 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1417 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1180,6 +1436,9 @@ static int s3c64xx_spi_suspend(struct device *dev)
1180 clk_disable(sdd->src_clk); 1436 clk_disable(sdd->src_clk);
1181 clk_disable(sdd->clk); 1437 clk_disable(sdd->clk);
1182 1438
1439 if (!sdd->cntrlr_info->cfg_gpio && dev->of_node)
1440 s3c64xx_spi_dt_gpio_free(sdd);
1441
1183 sdd->cur_speed = 0; /* Output Clock is stopped */ 1442 sdd->cur_speed = 0; /* Output Clock is stopped */
1184 1443
1185 return 0; 1444 return 0;
@@ -1187,18 +1446,20 @@ static int s3c64xx_spi_suspend(struct device *dev)
1187 1446
1188static int s3c64xx_spi_resume(struct device *dev) 1447static int s3c64xx_spi_resume(struct device *dev)
1189{ 1448{
1190 struct platform_device *pdev = to_platform_device(dev);
1191 struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); 1449 struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
1192 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1450 struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master);
1193 struct s3c64xx_spi_info *sci = sdd->cntrlr_info; 1451 struct s3c64xx_spi_info *sci = sdd->cntrlr_info;
1194 1452
1195 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();
1196 1457
1197 /* Enable the clock */ 1458 /* Enable the clock */
1198 clk_enable(sdd->src_clk); 1459 clk_enable(sdd->src_clk);
1199 clk_enable(sdd->clk); 1460 clk_enable(sdd->clk);
1200 1461
1201 s3c64xx_spi_hwinit(sdd, pdev->id); 1462 s3c64xx_spi_hwinit(sdd, sdd->port_id);
1202 1463
1203 spi_master_resume(master); 1464 spi_master_resume(master);
1204 1465
@@ -1236,13 +1497,89 @@ static const struct dev_pm_ops s3c64xx_spi_pm = {
1236 s3c64xx_spi_runtime_resume, NULL) 1497 s3c64xx_spi_runtime_resume, NULL)
1237}; 1498};
1238 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
1239static struct platform_driver s3c64xx_spi_driver = { 1574static struct platform_driver s3c64xx_spi_driver = {
1240 .driver = { 1575 .driver = {
1241 .name = "s3c64xx-spi", 1576 .name = "s3c64xx-spi",
1242 .owner = THIS_MODULE, 1577 .owner = THIS_MODULE,
1243 .pm = &s3c64xx_spi_pm, 1578 .pm = &s3c64xx_spi_pm,
1579 .of_match_table = of_match_ptr(s3c64xx_spi_dt_match),
1244 }, 1580 },
1245 .remove = s3c64xx_spi_remove, 1581 .remove = s3c64xx_spi_remove,
1582 .id_table = s3c64xx_spi_driver_ids,
1246}; 1583};
1247MODULE_ALIAS("platform:s3c64xx-spi"); 1584MODULE_ALIAS("platform:s3c64xx-spi");
1248 1585