aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-05-13 01:33:24 -0400
committerOlof Johansson <olof@lixom.net>2012-05-13 01:33:24 -0400
commite29402edf848359d619ce06af86d61e62c292c87 (patch)
tree94451c1d400d478654e0d0e78564e882081b806c
parentbf98a6eaa9964fef49f186834713bfc57d16ede1 (diff)
parent530f1d416091212243b341e0022b2967886b30e4 (diff)
Merge branch 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt2
* 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6: (51 commits) ARM: dts: enable audio support for imx28-evk ARM: dts: enable i2c device for imx28-evk i2c: mxs: add device tree probe support ARM: dts: enable mmc for imx28-evk ARM: dts: enable mmc for imx23-evk mmc: mxs-mmc: add device tree support mmc: mxs-mmc: copy wp_gpio in struct mxs_mmc_host mmc: mxs-mmc: have dma_channel than dma_res in mxs_mmc_host mmc: mxs-mmc: use devm_* helper to make cleanup simpler mmc: mxs-mmc: move header from mach into linux folder mmc: mxs-mmc: get rid of the use of cpu_is_xxx mmc: mxs-mmc: let ssp_is_old take host as parameter mmc: mxs-mmc: use global stmp_device functionality ARM: mxs: add gpio support for device tree boot gpio/mxs: add device tree probe gpio/mxs: get rid of the use of cpu_is_xxx gpio/mxs: use devm_* helpers to make error handling simple ARM: mxs: add mxs-dma dt support ARM: mxs: do not add dma device by default dma: mxs-dma: add device tree probe support ...
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.txt8
-rw-r--r--Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt19
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-mxs.txt87
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-mxs.txt16
-rw-r--r--Documentation/devicetree/bindings/mmc/mxs-mmc.txt25
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/boot/dts/imx23-evk.dts43
-rw-r--r--arch/arm/boot/dts/imx23.dtsi295
-rw-r--r--arch/arm/boot/dts/imx28-evk.dts114
-rw-r--r--arch/arm/boot/dts/imx28.dtsi497
-rw-r--r--arch/arm/configs/mxs_defconfig1
-rw-r--r--arch/arm/mach-imx/Kconfig2
-rw-r--r--arch/arm/mach-imx/imx51-dt.c3
-rw-r--r--arch/arm/mach-imx/imx53-dt.c3
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c7
-rw-r--r--arch/arm/mach-imx/mm-imx1.c2
-rw-r--r--arch/arm/mach-imx/mm-imx21.c2
-rw-r--r--arch/arm/mach-imx/mm-imx25.c2
-rw-r--r--arch/arm/mach-imx/mm-imx27.c2
-rw-r--r--arch/arm/mach-imx/mm-imx3.c2
-rw-r--r--arch/arm/mach-imx/mm-imx5.c2
-rw-r--r--arch/arm/mach-mxs/Kconfig12
-rw-r--r--arch/arm/mach-mxs/Makefile6
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c536
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c803
-rw-r--r--arch/arm/mach-mxs/clock.c211
-rw-r--r--arch/arm/mach-mxs/devices/Kconfig1
-rw-r--r--arch/arm/mach-mxs/devices/platform-dma.c21
-rw-r--r--arch/arm/mach-mxs/devices/platform-gpio-mxs.c24
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-mmc.c21
-rw-r--r--arch/arm/mach-mxs/include/mach/clock.h62
-rw-r--r--arch/arm/mach-mxs/include/mach/common.h13
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h3
-rw-r--r--arch/arm/mach-mxs/mach-apx4devkit.c2
-rw-r--r--arch/arm/mach-mxs/mach-m28evk.c2
-rw-r--r--arch/arm/mach-mxs/mach-mx23evk.c2
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c4
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c121
-rw-r--r--arch/arm/mach-mxs/mach-stmp378x_devb.c2
-rw-r--r--arch/arm/mach-mxs/mach-tx28.c2
-rw-r--r--arch/arm/mach-mxs/mm.c27
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx23.h331
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx28.h486
-rw-r--r--arch/arm/mach-mxs/system.c16
-rw-r--r--arch/arm/mach-mxs/timer.c11
-rw-r--r--drivers/clk/Makefile2
-rw-r--r--drivers/clk/mxs/Makefile8
-rw-r--r--drivers/clk/mxs/clk-div.c110
-rw-r--r--drivers/clk/mxs/clk-frac.c139
-rw-r--r--drivers/clk/mxs/clk-imx23.c205
-rw-r--r--drivers/clk/mxs/clk-imx28.c338
-rw-r--r--drivers/clk/mxs/clk-pll.c116
-rw-r--r--drivers/clk/mxs/clk-ref.c154
-rw-r--r--drivers/clk/mxs/clk.c28
-rw-r--r--drivers/clk/mxs/clk.h66
-rw-r--r--drivers/dma/Kconfig1
-rw-r--r--drivers/dma/mxs-dma.c188
-rw-r--r--drivers/gpio/gpio-mxs.c156
-rw-r--r--drivers/i2c/busses/i2c-imx.c8
-rw-r--r--drivers/i2c/busses/i2c-mxs.c19
-rw-r--r--drivers/mmc/host/mxs-mmc.c203
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c9
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c9
-rw-r--r--drivers/net/can/flexcan.c6
-rw-r--r--drivers/net/ethernet/freescale/fec.c9
-rw-r--r--drivers/spi/spi-imx.c8
-rw-r--r--drivers/tty/serial/amba-pl011.c8
-rw-r--r--drivers/tty/serial/imx.c8
-rw-r--r--drivers/tty/serial/mxs-auart.c8
-rw-r--r--drivers/video/mxsfb.c9
-rw-r--r--include/linux/fsl/mxs-dma.h12
-rw-r--r--include/linux/mmc/mxs-mmc.h (renamed from arch/arm/mach-mxs/include/mach/mmc.h)7
-rw-r--r--sound/soc/mxs/mxs-saif.c8
73 files changed, 2964 insertions, 2732 deletions
diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
index bfbc771a65f8..1708df5a8737 100644
--- a/Documentation/devicetree/bindings/arm/fsl.txt
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -1,6 +1,14 @@
1Freescale i.MX Platforms Device Tree Bindings 1Freescale i.MX Platforms Device Tree Bindings
2----------------------------------------------- 2-----------------------------------------------
3 3
4i.MX23 Evaluation Kit
5Required root node properties:
6 - compatible = "fsl,imx23-evk", "fsl,imx23";
7
8i.MX28 Evaluation Kit
9Required root node properties:
10 - compatible = "fsl,imx28-evk", "fsl,imx28";
11
4i.MX51 Babbage Board 12i.MX51 Babbage Board
5Required root node properties: 13Required root node properties:
6 - compatible = "fsl,imx51-babbage", "fsl,imx51"; 14 - compatible = "fsl,imx51-babbage", "fsl,imx51";
diff --git a/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt b/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt
new file mode 100644
index 000000000000..ded0398d3bdc
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt
@@ -0,0 +1,19 @@
1* Freescale MXS DMA
2
3Required properties:
4- compatible : Should be "fsl,<chip>-dma-apbh" or "fsl,<chip>-dma-apbx"
5- reg : Should contain registers location and length
6
7Supported chips:
8imx23, imx28.
9
10Examples:
11dma-apbh@80004000 {
12 compatible = "fsl,imx28-dma-apbh";
13 reg = <0x80004000 2000>;
14};
15
16dma-apbx@80024000 {
17 compatible = "fsl,imx28-dma-apbx";
18 reg = <0x80024000 2000>;
19};
diff --git a/Documentation/devicetree/bindings/gpio/gpio-mxs.txt b/Documentation/devicetree/bindings/gpio/gpio-mxs.txt
new file mode 100644
index 000000000000..0c35673f7a3e
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-mxs.txt
@@ -0,0 +1,87 @@
1* Freescale MXS GPIO controller
2
3The Freescale MXS GPIO controller is part of MXS PIN controller. The
4GPIOs are organized in port/bank. Each port consists of 32 GPIOs.
5
6As the GPIO controller is embedded in the PIN controller and all the
7GPIO ports share the same IO space with PIN controller, the GPIO node
8will be represented as sub-nodes of MXS pinctrl node.
9
10Required properties for GPIO node:
11- compatible : Should be "fsl,<soc>-gpio". The supported SoCs include
12 imx23 and imx28.
13- interrupts : Should be the port interrupt shared by all 32 pins.
14- gpio-controller : Marks the device node as a gpio controller.
15- #gpio-cells : Should be two. The first cell is the pin number and
16 the second cell is used to specify optional parameters (currently
17 unused).
18- interrupt-controller: Marks the device node as an interrupt controller.
19- #interrupt-cells : Should be 2. The first cell is the GPIO number.
20 The second cell bits[3:0] is used to specify trigger type and level flags:
21 1 = low-to-high edge triggered.
22 2 = high-to-low edge triggered.
23 4 = active high level-sensitive.
24 8 = active low level-sensitive.
25
26Note: Each GPIO port should have an alias correctly numbered in "aliases"
27node.
28
29Examples:
30
31aliases {
32 gpio0 = &gpio0;
33 gpio1 = &gpio1;
34 gpio2 = &gpio2;
35 gpio3 = &gpio3;
36 gpio4 = &gpio4;
37};
38
39pinctrl@80018000 {
40 compatible = "fsl,imx28-pinctrl", "simple-bus";
41 reg = <0x80018000 2000>;
42
43 gpio0: gpio@0 {
44 compatible = "fsl,imx28-gpio";
45 interrupts = <127>;
46 gpio-controller;
47 #gpio-cells = <2>;
48 interrupt-controller;
49 #interrupt-cells = <2>;
50 };
51
52 gpio1: gpio@1 {
53 compatible = "fsl,imx28-gpio";
54 interrupts = <126>;
55 gpio-controller;
56 #gpio-cells = <2>;
57 interrupt-controller;
58 #interrupt-cells = <2>;
59 };
60
61 gpio2: gpio@2 {
62 compatible = "fsl,imx28-gpio";
63 interrupts = <125>;
64 gpio-controller;
65 #gpio-cells = <2>;
66 interrupt-controller;
67 #interrupt-cells = <2>;
68 };
69
70 gpio3: gpio@3 {
71 compatible = "fsl,imx28-gpio";
72 interrupts = <124>;
73 gpio-controller;
74 #gpio-cells = <2>;
75 interrupt-controller;
76 #interrupt-cells = <2>;
77 };
78
79 gpio4: gpio@4 {
80 compatible = "fsl,imx28-gpio";
81 interrupts = <123>;
82 gpio-controller;
83 #gpio-cells = <2>;
84 interrupt-controller;
85 #interrupt-cells = <2>;
86 };
87};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mxs.txt b/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
new file mode 100644
index 000000000000..1bfc02de1b0c
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
@@ -0,0 +1,16 @@
1* Freescale MXS Inter IC (I2C) Controller
2
3Required properties:
4- compatible: Should be "fsl,<chip>-i2c"
5- reg: Should contain registers location and length
6- interrupts: Should contain ERROR and DMA interrupts
7
8Examples:
9
10i2c0: i2c@80058000 {
11 #address-cells = <1>;
12 #size-cells = <0>;
13 compatible = "fsl,imx28-i2c";
14 reg = <0x80058000 2000>;
15 interrupts = <111 68>;
16};
diff --git a/Documentation/devicetree/bindings/mmc/mxs-mmc.txt b/Documentation/devicetree/bindings/mmc/mxs-mmc.txt
new file mode 100644
index 000000000000..14d870a9e3db
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/mxs-mmc.txt
@@ -0,0 +1,25 @@
1* Freescale MXS MMC controller
2
3The Freescale MXS Synchronous Serial Ports (SSP) can act as a MMC controller
4to support MMC, SD, and SDIO types of memory cards.
5
6Required properties:
7- compatible: Should be "fsl,<chip>-mmc". The supported chips include
8 imx23 and imx28.
9- reg: Should contain registers location and length
10- interrupts: Should contain ERROR and DMA interrupts
11- fsl,ssp-dma-channel: APBH DMA channel for the SSP
12- bus-width: Number of data lines, can be <1>, <4>, or <8>
13
14Optional properties:
15- wp-gpios: Specify GPIOs for write protection
16
17Examples:
18
19ssp0: ssp@80010000 {
20 compatible = "fsl,imx28-mmc";
21 reg = <0x80010000 2000>;
22 interrupts = <96 82>;
23 fsl,ssp-dma-channel = <0>;
24 bus-width = <8>;
25};
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 36586dba6fa6..1f1a4fa6db58 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -468,7 +468,10 @@ config ARCH_MXS
468 select ARCH_REQUIRE_GPIOLIB 468 select ARCH_REQUIRE_GPIOLIB
469 select CLKDEV_LOOKUP 469 select CLKDEV_LOOKUP
470 select CLKSRC_MMIO 470 select CLKSRC_MMIO
471 select COMMON_CLK
471 select HAVE_CLK_PREPARE 472 select HAVE_CLK_PREPARE
473 select PINCTRL
474 select USE_OF
472 help 475 help
473 Support for Freescale MXS-based family of processors 476 Support for Freescale MXS-based family of processors
474 477
diff --git a/arch/arm/boot/dts/imx23-evk.dts b/arch/arm/boot/dts/imx23-evk.dts
new file mode 100644
index 000000000000..70bffa929b65
--- /dev/null
+++ b/arch/arm/boot/dts/imx23-evk.dts
@@ -0,0 +1,43 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/dts-v1/;
13/include/ "imx23.dtsi"
14
15/ {
16 model = "Freescale i.MX23 Evaluation Kit";
17 compatible = "fsl,imx23-evk", "fsl,imx23";
18
19 memory {
20 reg = <0x40000000 0x08000000>;
21 };
22
23 apb@80000000 {
24 apbh@80000000 {
25 ssp0: ssp@80010000 {
26 compatible = "fsl,imx23-mmc";
27 pinctrl-names = "default";
28 pinctrl-0 = <&mmc0_8bit_pins_a &mmc0_pins_fixup>;
29 bus-width = <8>;
30 wp-gpios = <&gpio1 30 0>;
31 status = "okay";
32 };
33 };
34
35 apbx@80040000 {
36 duart: serial@80070000 {
37 pinctrl-names = "default";
38 pinctrl-0 = <&duart_pins_a>;
39 status = "okay";
40 };
41 };
42 };
43};
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi
new file mode 100644
index 000000000000..8c5f9994f3fc
--- /dev/null
+++ b/arch/arm/boot/dts/imx23.dtsi
@@ -0,0 +1,295 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/include/ "skeleton.dtsi"
13
14/ {
15 interrupt-parent = <&icoll>;
16
17 aliases {
18 gpio0 = &gpio0;
19 gpio1 = &gpio1;
20 gpio2 = &gpio2;
21 };
22
23 cpus {
24 cpu@0 {
25 compatible = "arm,arm926ejs";
26 };
27 };
28
29 apb@80000000 {
30 compatible = "simple-bus";
31 #address-cells = <1>;
32 #size-cells = <1>;
33 reg = <0x80000000 0x80000>;
34 ranges;
35
36 apbh@80000000 {
37 compatible = "simple-bus";
38 #address-cells = <1>;
39 #size-cells = <1>;
40 reg = <0x80000000 0x40000>;
41 ranges;
42
43 icoll: interrupt-controller@80000000 {
44 compatible = "fsl,imx23-icoll", "fsl,mxs-icoll";
45 interrupt-controller;
46 #interrupt-cells = <1>;
47 reg = <0x80000000 0x2000>;
48 };
49
50 dma-apbh@80004000 {
51 compatible = "fsl,imx23-dma-apbh";
52 reg = <0x80004000 2000>;
53 };
54
55 ecc@80008000 {
56 reg = <0x80008000 2000>;
57 status = "disabled";
58 };
59
60 bch@8000a000 {
61 reg = <0x8000a000 2000>;
62 status = "disabled";
63 };
64
65 gpmi@8000c000 {
66 reg = <0x8000c000 2000>;
67 status = "disabled";
68 };
69
70 ssp0: ssp@80010000 {
71 reg = <0x80010000 2000>;
72 interrupts = <15 14>;
73 fsl,ssp-dma-channel = <1>;
74 status = "disabled";
75 };
76
77 etm@80014000 {
78 reg = <0x80014000 2000>;
79 status = "disabled";
80 };
81
82 pinctrl@80018000 {
83 #address-cells = <1>;
84 #size-cells = <0>;
85 compatible = "fsl,imx23-pinctrl", "simple-bus";
86 reg = <0x80018000 2000>;
87
88 gpio0: gpio@0 {
89 compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
90 interrupts = <16>;
91 gpio-controller;
92 #gpio-cells = <2>;
93 interrupt-controller;
94 #interrupt-cells = <2>;
95 };
96
97 gpio1: gpio@1 {
98 compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
99 interrupts = <17>;
100 gpio-controller;
101 #gpio-cells = <2>;
102 interrupt-controller;
103 #interrupt-cells = <2>;
104 };
105
106 gpio2: gpio@2 {
107 compatible = "fsl,imx23-gpio", "fsl,mxs-gpio";
108 interrupts = <18>;
109 gpio-controller;
110 #gpio-cells = <2>;
111 interrupt-controller;
112 #interrupt-cells = <2>;
113 };
114
115 duart_pins_a: duart@0 {
116 reg = <0>;
117 fsl,pinmux-ids = <0x11a2 0x11b2>;
118 fsl,drive-strength = <0>;
119 fsl,voltage = <1>;
120 fsl,pull-up = <0>;
121 };
122
123 mmc0_8bit_pins_a: mmc0-8bit@0 {
124 reg = <0>;
125 fsl,pinmux-ids = <0x2020 0x2030 0x2040
126 0x2050 0x0082 0x0092 0x00a2
127 0x00b2 0x2000 0x2010 0x2060>;
128 fsl,drive-strength = <1>;
129 fsl,voltage = <1>;
130 fsl,pull-up = <1>;
131 };
132
133 mmc0_pins_fixup: mmc0-pins-fixup {
134 fsl,pinmux-ids = <0x2010 0x2060>;
135 fsl,pull-up = <0>;
136 };
137 };
138
139 digctl@8001c000 {
140 reg = <0x8001c000 2000>;
141 status = "disabled";
142 };
143
144 emi@80020000 {
145 reg = <0x80020000 2000>;
146 status = "disabled";
147 };
148
149 dma-apbx@80024000 {
150 compatible = "fsl,imx23-dma-apbx";
151 reg = <0x80024000 2000>;
152 };
153
154 dcp@80028000 {
155 reg = <0x80028000 2000>;
156 status = "disabled";
157 };
158
159 pxp@8002a000 {
160 reg = <0x8002a000 2000>;
161 status = "disabled";
162 };
163
164 ocotp@8002c000 {
165 reg = <0x8002c000 2000>;
166 status = "disabled";
167 };
168
169 axi-ahb@8002e000 {
170 reg = <0x8002e000 2000>;
171 status = "disabled";
172 };
173
174 lcdif@80030000 {
175 reg = <0x80030000 2000>;
176 status = "disabled";
177 };
178
179 ssp1: ssp@80034000 {
180 reg = <0x80034000 2000>;
181 interrupts = <2 20>;
182 fsl,ssp-dma-channel = <2>;
183 status = "disabled";
184 };
185
186 tvenc@80038000 {
187 reg = <0x80038000 2000>;
188 status = "disabled";
189 };
190 };
191
192 apbx@80040000 {
193 compatible = "simple-bus";
194 #address-cells = <1>;
195 #size-cells = <1>;
196 reg = <0x80040000 0x40000>;
197 ranges;
198
199 clkctl@80040000 {
200 reg = <0x80040000 2000>;
201 status = "disabled";
202 };
203
204 saif0: saif@80042000 {
205 reg = <0x80042000 2000>;
206 status = "disabled";
207 };
208
209 power@80044000 {
210 reg = <0x80044000 2000>;
211 status = "disabled";
212 };
213
214 saif1: saif@80046000 {
215 reg = <0x80046000 2000>;
216 status = "disabled";
217 };
218
219 audio-out@80048000 {
220 reg = <0x80048000 2000>;
221 status = "disabled";
222 };
223
224 audio-in@8004c000 {
225 reg = <0x8004c000 2000>;
226 status = "disabled";
227 };
228
229 lradc@80050000 {
230 reg = <0x80050000 2000>;
231 status = "disabled";
232 };
233
234 spdif@80054000 {
235 reg = <0x80054000 2000>;
236 status = "disabled";
237 };
238
239 i2c@80058000 {
240 reg = <0x80058000 2000>;
241 status = "disabled";
242 };
243
244 rtc@8005c000 {
245 reg = <0x8005c000 2000>;
246 status = "disabled";
247 };
248
249 pwm@80064000 {
250 reg = <0x80064000 2000>;
251 status = "disabled";
252 };
253
254 timrot@80068000 {
255 reg = <0x80068000 2000>;
256 status = "disabled";
257 };
258
259 auart0: serial@8006c000 {
260 reg = <0x8006c000 0x2000>;
261 status = "disabled";
262 };
263
264 auart1: serial@8006e000 {
265 reg = <0x8006e000 0x2000>;
266 status = "disabled";
267 };
268
269 duart: serial@80070000 {
270 compatible = "arm,pl011", "arm,primecell";
271 reg = <0x80070000 0x2000>;
272 interrupts = <0>;
273 status = "disabled";
274 };
275
276 usbphy@8007c000 {
277 reg = <0x8007c000 0x2000>;
278 status = "disabled";
279 };
280 };
281 };
282
283 ahb@80080000 {
284 compatible = "simple-bus";
285 #address-cells = <1>;
286 #size-cells = <1>;
287 reg = <0x80080000 0x80000>;
288 ranges;
289
290 usbctrl@80080000 {
291 reg = <0x80080000 0x10000>;
292 status = "disabled";
293 };
294 };
295};
diff --git a/arch/arm/boot/dts/imx28-evk.dts b/arch/arm/boot/dts/imx28-evk.dts
new file mode 100644
index 000000000000..ee520a529cb4
--- /dev/null
+++ b/arch/arm/boot/dts/imx28-evk.dts
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/dts-v1/;
13/include/ "imx28.dtsi"
14
15/ {
16 model = "Freescale i.MX28 Evaluation Kit";
17 compatible = "fsl,imx28-evk", "fsl,imx28";
18
19 memory {
20 reg = <0x40000000 0x08000000>;
21 };
22
23 apb@80000000 {
24 apbh@80000000 {
25 ssp0: ssp@80010000 {
26 compatible = "fsl,imx28-mmc";
27 pinctrl-names = "default";
28 pinctrl-0 = <&mmc0_8bit_pins_a
29 &mmc0_cd_cfg &mmc0_sck_cfg>;
30 bus-width = <8>;
31 wp-gpios = <&gpio2 12 0>;
32 status = "okay";
33 };
34
35 ssp1: ssp@80012000 {
36 compatible = "fsl,imx28-mmc";
37 bus-width = <8>;
38 wp-gpios = <&gpio0 28 0>;
39 status = "okay";
40 };
41 };
42
43 apbx@80040000 {
44 saif0: saif@80042000 {
45 pinctrl-names = "default";
46 pinctrl-0 = <&saif0_pins_a>;
47 status = "okay";
48 };
49
50 saif1: saif@80046000 {
51 pinctrl-names = "default";
52 pinctrl-0 = <&saif1_pins_a>;
53 fsl,saif-master = <&saif0>;
54 status = "okay";
55 };
56
57 i2c0: i2c@80058000 {
58 pinctrl-names = "default";
59 pinctrl-0 = <&i2c0_pins_a>;
60 status = "okay";
61
62 sgtl5000: codec@0a {
63 compatible = "fsl,sgtl5000";
64 reg = <0x0a>;
65 VDDA-supply = <&reg_3p3v>;
66 VDDIO-supply = <&reg_3p3v>;
67
68 };
69 };
70
71 duart: serial@80074000 {
72 pinctrl-names = "default";
73 pinctrl-0 = <&duart_pins_a>;
74 status = "okay";
75 };
76 };
77 };
78
79 ahb@80080000 {
80 mac0: ethernet@800f0000 {
81 phy-mode = "rmii";
82 pinctrl-names = "default";
83 pinctrl-0 = <&mac0_pins_a>;
84 status = "okay";
85 };
86
87 mac1: ethernet@800f4000 {
88 phy-mode = "rmii";
89 pinctrl-names = "default";
90 pinctrl-0 = <&mac1_pins_a>;
91 status = "okay";
92 };
93 };
94
95 regulators {
96 compatible = "simple-bus";
97
98 reg_3p3v: 3p3v {
99 compatible = "regulator-fixed";
100 regulator-name = "3P3V";
101 regulator-min-microvolt = <3300000>;
102 regulator-max-microvolt = <3300000>;
103 regulator-always-on;
104 };
105 };
106
107 sound {
108 compatible = "fsl,imx28-evk-sgtl5000",
109 "fsl,mxs-audio-sgtl5000";
110 model = "imx28-evk-sgtl5000";
111 saif-controllers = <&saif0 &saif1>;
112 audio-codec = <&sgtl5000>;
113 };
114};
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
new file mode 100644
index 000000000000..4634cb861a59
--- /dev/null
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -0,0 +1,497 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12/include/ "skeleton.dtsi"
13
14/ {
15 interrupt-parent = <&icoll>;
16
17 aliases {
18 gpio0 = &gpio0;
19 gpio1 = &gpio1;
20 gpio2 = &gpio2;
21 gpio3 = &gpio3;
22 gpio4 = &gpio4;
23 saif0 = &saif0;
24 saif1 = &saif1;
25 };
26
27 cpus {
28 cpu@0 {
29 compatible = "arm,arm926ejs";
30 };
31 };
32
33 apb@80000000 {
34 compatible = "simple-bus";
35 #address-cells = <1>;
36 #size-cells = <1>;
37 reg = <0x80000000 0x80000>;
38 ranges;
39
40 apbh@80000000 {
41 compatible = "simple-bus";
42 #address-cells = <1>;
43 #size-cells = <1>;
44 reg = <0x80000000 0x3c900>;
45 ranges;
46
47 icoll: interrupt-controller@80000000 {
48 compatible = "fsl,imx28-icoll", "fsl,mxs-icoll";
49 interrupt-controller;
50 #interrupt-cells = <1>;
51 reg = <0x80000000 0x2000>;
52 };
53
54 hsadc@80002000 {
55 reg = <0x80002000 2000>;
56 interrupts = <13 87>;
57 status = "disabled";
58 };
59
60 dma-apbh@80004000 {
61 compatible = "fsl,imx28-dma-apbh";
62 reg = <0x80004000 2000>;
63 };
64
65 perfmon@80006000 {
66 reg = <0x80006000 800>;
67 interrupts = <27>;
68 status = "disabled";
69 };
70
71 bch@8000a000 {
72 reg = <0x8000a000 2000>;
73 interrupts = <41>;
74 status = "disabled";
75 };
76
77 gpmi@8000c000 {
78 reg = <0x8000c000 2000>;
79 interrupts = <42 88>;
80 status = "disabled";
81 };
82
83 ssp0: ssp@80010000 {
84 reg = <0x80010000 2000>;
85 interrupts = <96 82>;
86 fsl,ssp-dma-channel = <0>;
87 status = "disabled";
88 };
89
90 ssp1: ssp@80012000 {
91 reg = <0x80012000 2000>;
92 interrupts = <97 83>;
93 fsl,ssp-dma-channel = <1>;
94 status = "disabled";
95 };
96
97 ssp2: ssp@80014000 {
98 reg = <0x80014000 2000>;
99 interrupts = <98 84>;
100 fsl,ssp-dma-channel = <2>;
101 status = "disabled";
102 };
103
104 ssp3: ssp@80016000 {
105 reg = <0x80016000 2000>;
106 interrupts = <99 85>;
107 fsl,ssp-dma-channel = <3>;
108 status = "disabled";
109 };
110
111 pinctrl@80018000 {
112 #address-cells = <1>;
113 #size-cells = <0>;
114 compatible = "fsl,imx28-pinctrl", "simple-bus";
115 reg = <0x80018000 2000>;
116
117 gpio0: gpio@0 {
118 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
119 interrupts = <127>;
120 gpio-controller;
121 #gpio-cells = <2>;
122 interrupt-controller;
123 #interrupt-cells = <2>;
124 };
125
126 gpio1: gpio@1 {
127 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
128 interrupts = <126>;
129 gpio-controller;
130 #gpio-cells = <2>;
131 interrupt-controller;
132 #interrupt-cells = <2>;
133 };
134
135 gpio2: gpio@2 {
136 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
137 interrupts = <125>;
138 gpio-controller;
139 #gpio-cells = <2>;
140 interrupt-controller;
141 #interrupt-cells = <2>;
142 };
143
144 gpio3: gpio@3 {
145 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
146 interrupts = <124>;
147 gpio-controller;
148 #gpio-cells = <2>;
149 interrupt-controller;
150 #interrupt-cells = <2>;
151 };
152
153 gpio4: gpio@4 {
154 compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
155 interrupts = <123>;
156 gpio-controller;
157 #gpio-cells = <2>;
158 interrupt-controller;
159 #interrupt-cells = <2>;
160 };
161
162 duart_pins_a: duart@0 {
163 reg = <0>;
164 fsl,pinmux-ids = <0x3102 0x3112>;
165 fsl,drive-strength = <0>;
166 fsl,voltage = <1>;
167 fsl,pull-up = <0>;
168 };
169
170 mac0_pins_a: mac0@0 {
171 reg = <0>;
172 fsl,pinmux-ids = <0x4000 0x4010 0x4020
173 0x4030 0x4040 0x4060 0x4070
174 0x4080 0x4100>;
175 fsl,drive-strength = <1>;
176 fsl,voltage = <1>;
177 fsl,pull-up = <1>;
178 };
179
180 mac1_pins_a: mac1@0 {
181 reg = <0>;
182 fsl,pinmux-ids = <0x40f1 0x4091 0x40a1
183 0x40e1 0x40b1 0x40c1>;
184 fsl,drive-strength = <1>;
185 fsl,voltage = <1>;
186 fsl,pull-up = <1>;
187 };
188
189 mmc0_8bit_pins_a: mmc0-8bit@0 {
190 reg = <0>;
191 fsl,pinmux-ids = <0x2000 0x2010 0x2020
192 0x2030 0x2040 0x2050 0x2060
193 0x2070 0x2080 0x2090 0x20a0>;
194 fsl,drive-strength = <1>;
195 fsl,voltage = <1>;
196 fsl,pull-up = <1>;
197 };
198
199 mmc0_cd_cfg: mmc0-cd-cfg {
200 fsl,pinmux-ids = <0x2090>;
201 fsl,pull-up = <0>;
202 };
203
204 mmc0_sck_cfg: mmc0-sck-cfg {
205 fsl,pinmux-ids = <0x20a0>;
206 fsl,drive-strength = <2>;
207 fsl,pull-up = <0>;
208 };
209
210 i2c0_pins_a: i2c0@0 {
211 reg = <0>;
212 fsl,pinmux-ids = <0x3180 0x3190>;
213 fsl,drive-strength = <1>;
214 fsl,voltage = <1>;
215 fsl,pull-up = <1>;
216 };
217
218 saif0_pins_a: saif0@0 {
219 reg = <0>;
220 fsl,pinmux-ids =
221 <0x3140 0x3150 0x3160 0x3170>;
222 fsl,drive-strength = <2>;
223 fsl,voltage = <1>;
224 fsl,pull-up = <1>;
225 };
226
227 saif1_pins_a: saif1@0 {
228 reg = <0>;
229 fsl,pinmux-ids = <0x31a0>;
230 fsl,drive-strength = <2>;
231 fsl,voltage = <1>;
232 fsl,pull-up = <1>;
233 };
234 };
235
236 digctl@8001c000 {
237 reg = <0x8001c000 2000>;
238 interrupts = <89>;
239 status = "disabled";
240 };
241
242 etm@80022000 {
243 reg = <0x80022000 2000>;
244 status = "disabled";
245 };
246
247 dma-apbx@80024000 {
248 compatible = "fsl,imx28-dma-apbx";
249 reg = <0x80024000 2000>;
250 };
251
252 dcp@80028000 {
253 reg = <0x80028000 2000>;
254 interrupts = <52 53 54>;
255 status = "disabled";
256 };
257
258 pxp@8002a000 {
259 reg = <0x8002a000 2000>;
260 interrupts = <39>;
261 status = "disabled";
262 };
263
264 ocotp@8002c000 {
265 reg = <0x8002c000 2000>;
266 status = "disabled";
267 };
268
269 axi-ahb@8002e000 {
270 reg = <0x8002e000 2000>;
271 status = "disabled";
272 };
273
274 lcdif@80030000 {
275 reg = <0x80030000 2000>;
276 interrupts = <38 86>;
277 status = "disabled";
278 };
279
280 can0: can@80032000 {
281 reg = <0x80032000 2000>;
282 interrupts = <8>;
283 status = "disabled";
284 };
285
286 can1: can@80034000 {
287 reg = <0x80034000 2000>;
288 interrupts = <9>;
289 status = "disabled";
290 };
291
292 simdbg@8003c000 {
293 reg = <0x8003c000 200>;
294 status = "disabled";
295 };
296
297 simgpmisel@8003c200 {
298 reg = <0x8003c200 100>;
299 status = "disabled";
300 };
301
302 simsspsel@8003c300 {
303 reg = <0x8003c300 100>;
304 status = "disabled";
305 };
306
307 simmemsel@8003c400 {
308 reg = <0x8003c400 100>;
309 status = "disabled";
310 };
311
312 gpiomon@8003c500 {
313 reg = <0x8003c500 100>;
314 status = "disabled";
315 };
316
317 simenet@8003c700 {
318 reg = <0x8003c700 100>;
319 status = "disabled";
320 };
321
322 armjtag@8003c800 {
323 reg = <0x8003c800 100>;
324 status = "disabled";
325 };
326 };
327
328 apbx@80040000 {
329 compatible = "simple-bus";
330 #address-cells = <1>;
331 #size-cells = <1>;
332 reg = <0x80040000 0x40000>;
333 ranges;
334
335 clkctl@80040000 {
336 reg = <0x80040000 2000>;
337 status = "disabled";
338 };
339
340 saif0: saif@80042000 {
341 compatible = "fsl,imx28-saif";
342 reg = <0x80042000 2000>;
343 interrupts = <59 80>;
344 fsl,saif-dma-channel = <4>;
345 status = "disabled";
346 };
347
348 power@80044000 {
349 reg = <0x80044000 2000>;
350 status = "disabled";
351 };
352
353 saif1: saif@80046000 {
354 compatible = "fsl,imx28-saif";
355 reg = <0x80046000 2000>;
356 interrupts = <58 81>;
357 fsl,saif-dma-channel = <5>;
358 status = "disabled";
359 };
360
361 lradc@80050000 {
362 reg = <0x80050000 2000>;
363 status = "disabled";
364 };
365
366 spdif@80054000 {
367 reg = <0x80054000 2000>;
368 interrupts = <45 66>;
369 status = "disabled";
370 };
371
372 rtc@80056000 {
373 reg = <0x80056000 2000>;
374 interrupts = <28 29>;
375 status = "disabled";
376 };
377
378 i2c0: i2c@80058000 {
379 #address-cells = <1>;
380 #size-cells = <0>;
381 compatible = "fsl,imx28-i2c";
382 reg = <0x80058000 2000>;
383 interrupts = <111 68>;
384 status = "disabled";
385 };
386
387 i2c1: i2c@8005a000 {
388 #address-cells = <1>;
389 #size-cells = <0>;
390 compatible = "fsl,imx28-i2c";
391 reg = <0x8005a000 2000>;
392 interrupts = <110 69>;
393 status = "disabled";
394 };
395
396 pwm@80064000 {
397 reg = <0x80064000 2000>;
398 status = "disabled";
399 };
400
401 timrot@80068000 {
402 reg = <0x80068000 2000>;
403 status = "disabled";
404 };
405
406 auart0: serial@8006a000 {
407 reg = <0x8006a000 0x2000>;
408 interrupts = <112 70 71>;
409 status = "disabled";
410 };
411
412 auart1: serial@8006c000 {
413 reg = <0x8006c000 0x2000>;
414 interrupts = <113 72 73>;
415 status = "disabled";
416 };
417
418 auart2: serial@8006e000 {
419 reg = <0x8006e000 0x2000>;
420 interrupts = <114 74 75>;
421 status = "disabled";
422 };
423
424 auart3: serial@80070000 {
425 reg = <0x80070000 0x2000>;
426 interrupts = <115 76 77>;
427 status = "disabled";
428 };
429
430 auart4: serial@80072000 {
431 reg = <0x80072000 0x2000>;
432 interrupts = <116 78 79>;
433 status = "disabled";
434 };
435
436 duart: serial@80074000 {
437 compatible = "arm,pl011", "arm,primecell";
438 reg = <0x80074000 0x1000>;
439 interrupts = <47>;
440 status = "disabled";
441 };
442
443 usbphy0: usbphy@8007c000 {
444 reg = <0x8007c000 0x2000>;
445 status = "disabled";
446 };
447
448 usbphy1: usbphy@8007e000 {
449 reg = <0x8007e000 0x2000>;
450 status = "disabled";
451 };
452 };
453 };
454
455 ahb@80080000 {
456 compatible = "simple-bus";
457 #address-cells = <1>;
458 #size-cells = <1>;
459 reg = <0x80080000 0x80000>;
460 ranges;
461
462 usbctrl0: usbctrl@80080000 {
463 reg = <0x80080000 0x10000>;
464 status = "disabled";
465 };
466
467 usbctrl1: usbctrl@80090000 {
468 reg = <0x80090000 0x10000>;
469 status = "disabled";
470 };
471
472 dflpt@800c0000 {
473 reg = <0x800c0000 0x10000>;
474 status = "disabled";
475 };
476
477 mac0: ethernet@800f0000 {
478 compatible = "fsl,imx28-fec";
479 reg = <0x800f0000 0x4000>;
480 interrupts = <101>;
481 status = "disabled";
482 };
483
484 mac1: ethernet@800f4000 {
485 compatible = "fsl,imx28-fec";
486 reg = <0x800f4000 0x4000>;
487 interrupts = <102>;
488 status = "disabled";
489 };
490
491 switch@800f8000 {
492 reg = <0x800f8000 0x8000>;
493 status = "disabled";
494 };
495
496 };
497};
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
index 1ebbf451c48d..5406c23a02e3 100644
--- a/arch/arm/configs/mxs_defconfig
+++ b/arch/arm/configs/mxs_defconfig
@@ -22,6 +22,7 @@ CONFIG_BLK_DEV_INTEGRITY=y
22# CONFIG_IOSCHED_DEADLINE is not set 22# CONFIG_IOSCHED_DEADLINE is not set
23# CONFIG_IOSCHED_CFQ is not set 23# CONFIG_IOSCHED_CFQ is not set
24CONFIG_ARCH_MXS=y 24CONFIG_ARCH_MXS=y
25CONFIG_MACH_MXS_DT=y
25CONFIG_MACH_MX23EVK=y 26CONFIG_MACH_MX23EVK=y
26CONFIG_MACH_MX28EVK=y 27CONFIG_MACH_MX28EVK=y
27CONFIG_MACH_STMP378X_DEVB=y 28CONFIG_MACH_STMP378X_DEVB=y
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 7561eca131b0..e0fc67cf659b 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -842,6 +842,8 @@ config SOC_IMX6Q
842 select HAVE_IMX_MMDC 842 select HAVE_IMX_MMDC
843 select HAVE_IMX_SRC 843 select HAVE_IMX_SRC
844 select HAVE_SMP 844 select HAVE_SMP
845 select PINCTRL
846 select PINCTRL_IMX6Q
845 select USE_OF 847 select USE_OF
846 848
847 help 849 help
diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c
index 5cca573964f0..5f577fbda2c8 100644
--- a/arch/arm/mach-imx/imx51-dt.c
+++ b/arch/arm/mach-imx/imx51-dt.c
@@ -14,6 +14,7 @@
14#include <linux/irqdomain.h> 14#include <linux/irqdomain.h>
15#include <linux/of_irq.h> 15#include <linux/of_irq.h>
16#include <linux/of_platform.h> 16#include <linux/of_platform.h>
17#include <linux/pinctrl/machine.h>
17#include <asm/mach/arch.h> 18#include <asm/mach/arch.h>
18#include <asm/mach/time.h> 19#include <asm/mach/time.h>
19#include <mach/common.h> 20#include <mach/common.h>
@@ -81,6 +82,8 @@ static void __init imx51_dt_init(void)
81 82
82 of_irq_init(imx51_irq_match); 83 of_irq_init(imx51_irq_match);
83 84
85 pinctrl_provide_dummies();
86
84 node = of_find_matching_node(NULL, imx51_iomuxc_of_match); 87 node = of_find_matching_node(NULL, imx51_iomuxc_of_match);
85 if (node) { 88 if (node) {
86 of_id = of_match_node(imx51_iomuxc_of_match, node); 89 of_id = of_match_node(imx51_iomuxc_of_match, node);
diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c
index 4172279b3900..574eca4b89a5 100644
--- a/arch/arm/mach-imx/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
@@ -15,6 +15,7 @@
15#include <linux/irqdomain.h> 15#include <linux/irqdomain.h>
16#include <linux/of_irq.h> 16#include <linux/of_irq.h>
17#include <linux/of_platform.h> 17#include <linux/of_platform.h>
18#include <linux/pinctrl/machine.h>
18#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
19#include <asm/mach/time.h> 20#include <asm/mach/time.h>
20#include <mach/common.h> 21#include <mach/common.h>
@@ -88,6 +89,8 @@ static void __init imx53_dt_init(void)
88 89
89 of_irq_init(imx53_irq_match); 90 of_irq_init(imx53_irq_match);
90 91
92 pinctrl_provide_dummies();
93
91 node = of_find_matching_node(NULL, imx53_iomuxc_of_match); 94 node = of_find_matching_node(NULL, imx53_iomuxc_of_match);
92 if (node) { 95 if (node) {
93 of_id = of_match_node(imx53_iomuxc_of_match, node); 96 of_id = of_match_node(imx53_iomuxc_of_match, node);
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index da6c1d9af768..3df360a52c17 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -19,6 +19,7 @@
19#include <linux/of_address.h> 19#include <linux/of_address.h>
20#include <linux/of_irq.h> 20#include <linux/of_irq.h>
21#include <linux/of_platform.h> 21#include <linux/of_platform.h>
22#include <linux/pinctrl/machine.h>
22#include <linux/phy.h> 23#include <linux/phy.h>
23#include <linux/micrel_phy.h> 24#include <linux/micrel_phy.h>
24#include <asm/smp_twd.h> 25#include <asm/smp_twd.h>
@@ -77,6 +78,12 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
77 78
78static void __init imx6q_init_machine(void) 79static void __init imx6q_init_machine(void)
79{ 80{
81 /*
82 * This should be removed when all imx6q boards have pinctrl
83 * states for devices defined in device tree.
84 */
85 pinctrl_provide_dummies();
86
80 if (of_machine_is_compatible("fsl,imx6q-sabrelite")) 87 if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
81 phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, 88 phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
82 ksz9021rn_phy_fixup); 89 ksz9021rn_phy_fixup);
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index 2bded591d5c2..fcafd3dafb8c 100644
--- a/arch/arm/mach-imx/mm-imx1.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -18,6 +18,7 @@
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/pinctrl/machine.h>
21 22
22#include <asm/mach/map.h> 23#include <asm/mach/map.h>
23 24
@@ -58,4 +59,5 @@ void __init imx1_soc_init(void)
58 MX1_GPIO_INT_PORTC, 0); 59 MX1_GPIO_INT_PORTC, 0);
59 mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256, 60 mxc_register_gpio("imx1-gpio", 3, MX1_GPIO4_BASE_ADDR, SZ_256,
60 MX1_GPIO_INT_PORTD, 0); 61 MX1_GPIO_INT_PORTD, 0);
62 pinctrl_provide_dummies();
61} 63}
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index 14d540edfd1e..5f43905e5290 100644
--- a/arch/arm/mach-imx/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/pinctrl/machine.h>
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24#include <mach/common.h> 25#include <mach/common.h>
25#include <mach/devices-common.h> 26#include <mach/devices-common.h>
@@ -88,6 +89,7 @@ void __init imx21_soc_init(void)
88 mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); 89 mxc_register_gpio("imx21-gpio", 4, MX21_GPIO5_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
89 mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0); 90 mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
90 91
92 pinctrl_provide_dummies();
91 imx_add_imx_dma(); 93 imx_add_imx_dma();
92 platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res, 94 platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
93 ARRAY_SIZE(imx21_audmux_res)); 95 ARRAY_SIZE(imx21_audmux_res));
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c
index 153b457acdc0..6ff37140a4f8 100644
--- a/arch/arm/mach-imx/mm-imx25.c
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -19,6 +19,7 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/pinctrl/machine.h>
22 23
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
24#include <asm/mach/map.h> 25#include <asm/mach/map.h>
@@ -95,6 +96,7 @@ void __init imx25_soc_init(void)
95 mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0); 96 mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
96 mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0); 97 mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
97 98
99 pinctrl_provide_dummies();
98 /* i.mx25 has the i.mx35 type sdma */ 100 /* i.mx25 has the i.mx35 type sdma */
99 imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata); 101 imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
100 /* i.mx25 has the i.mx31 type audmux */ 102 /* i.mx25 has the i.mx31 type audmux */
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index 8cb3f5e3e569..25662558e018 100644
--- a/arch/arm/mach-imx/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/pinctrl/machine.h>
23#include <mach/hardware.h> 24#include <mach/hardware.h>
24#include <mach/common.h> 25#include <mach/common.h>
25#include <mach/devices-common.h> 26#include <mach/devices-common.h>
@@ -89,6 +90,7 @@ void __init imx27_soc_init(void)
89 mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); 90 mxc_register_gpio("imx21-gpio", 4, MX27_GPIO5_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
90 mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0); 91 mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
91 92
93 pinctrl_provide_dummies();
92 imx_add_imx_dma(); 94 imx_add_imx_dma();
93 /* imx27 has the imx21 type audmux */ 95 /* imx27 has the imx21 type audmux */
94 platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res, 96 platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 74127389e7ab..9128d15b1eb7 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -19,6 +19,7 @@
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/pinctrl/machine.h>
22 23
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
24#include <asm/system_misc.h> 25#include <asm/system_misc.h>
@@ -267,6 +268,7 @@ void __init imx35_soc_init(void)
267 mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0); 268 mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
268 mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0); 269 mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
269 270
271 pinctrl_provide_dummies();
270 if (to_version == 1) { 272 if (to_version == 1) {
271 strncpy(imx35_sdma_pdata.fw_name, "sdma-imx35-to1.bin", 273 strncpy(imx35_sdma_pdata.fw_name, "sdma-imx35-to1.bin",
272 strlen(imx35_sdma_pdata.fw_name)); 274 strlen(imx35_sdma_pdata.fw_name));
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index e10f3914fcfe..ba91e6b31cf4 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -14,6 +14,7 @@
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/clk.h> 16#include <linux/clk.h>
17#include <linux/pinctrl/machine.h>
17 18
18#include <asm/system_misc.h> 19#include <asm/system_misc.h>
19#include <asm/mach/map.h> 20#include <asm/mach/map.h>
@@ -223,6 +224,7 @@ void __init imx53_soc_init(void)
223 mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH); 224 mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
224 mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH); 225 mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
225 226
227 pinctrl_provide_dummies();
226 /* i.mx53 has the i.mx35 type sdma */ 228 /* i.mx53 has the i.mx35 type sdma */
227 imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata); 229 imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
228 230
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index c57f9964a713..91cf0625819c 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -7,16 +7,28 @@ config MXS_OCOTP
7 7
8config SOC_IMX23 8config SOC_IMX23
9 bool 9 bool
10 select ARM_AMBA
10 select CPU_ARM926T 11 select CPU_ARM926T
11 select HAVE_PWM 12 select HAVE_PWM
13 select PINCTRL_IMX23
12 14
13config SOC_IMX28 15config SOC_IMX28
14 bool 16 bool
17 select ARM_AMBA
15 select CPU_ARM926T 18 select CPU_ARM926T
16 select HAVE_PWM 19 select HAVE_PWM
20 select PINCTRL_IMX28
17 21
18comment "MXS platforms:" 22comment "MXS platforms:"
19 23
24config MACH_MXS_DT
25 bool "Support MXS platforms from device tree"
26 select SOC_IMX23
27 select SOC_IMX28
28 help
29 Include support for Freescale MXS platforms(i.MX23 and i.MX28)
30 using the device tree for discovery
31
20config MACH_STMP378X_DEVB 32config MACH_STMP378X_DEVB
21 bool "Support STMP378x_devb Platform" 33 bool "Support STMP378x_devb Platform"
22 select SOC_IMX23 34 select SOC_IMX23
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 908bf9a567f1..e41590ccb437 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,12 +1,10 @@
1# Common support 1# Common support
2obj-y := clock.o devices.o icoll.o iomux.o system.o timer.o mm.o 2obj-y := devices.o icoll.o iomux.o system.o timer.o mm.o
3 3
4obj-$(CONFIG_MXS_OCOTP) += ocotp.o 4obj-$(CONFIG_MXS_OCOTP) += ocotp.o
5obj-$(CONFIG_PM) += pm.o 5obj-$(CONFIG_PM) += pm.o
6 6
7obj-$(CONFIG_SOC_IMX23) += clock-mx23.o 7obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o
8obj-$(CONFIG_SOC_IMX28) += clock-mx28.o
9
10obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o 8obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
11obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o 9obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
12obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o 10obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
deleted file mode 100644
index e3ac52c34019..000000000000
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ /dev/null
@@ -1,536 +0,0 @@
1/*
2 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/mm.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/jiffies.h>
24#include <linux/clkdev.h>
25
26#include <asm/clkdev.h>
27#include <asm/div64.h>
28
29#include <mach/mx23.h>
30#include <mach/common.h>
31#include <mach/clock.h>
32
33#include "regs-clkctrl-mx23.h"
34
35#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
36#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
37
38#define PARENT_RATE_SHIFT 8
39
40static int _raw_clk_enable(struct clk *clk)
41{
42 u32 reg;
43
44 if (clk->enable_reg) {
45 reg = __raw_readl(clk->enable_reg);
46 reg &= ~(1 << clk->enable_shift);
47 __raw_writel(reg, clk->enable_reg);
48 }
49
50 return 0;
51}
52
53static void _raw_clk_disable(struct clk *clk)
54{
55 u32 reg;
56
57 if (clk->enable_reg) {
58 reg = __raw_readl(clk->enable_reg);
59 reg |= 1 << clk->enable_shift;
60 __raw_writel(reg, clk->enable_reg);
61 }
62}
63
64/*
65 * ref_xtal_clk
66 */
67static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
68{
69 return 24000000;
70}
71
72static struct clk ref_xtal_clk = {
73 .get_rate = ref_xtal_clk_get_rate,
74};
75
76/*
77 * pll_clk
78 */
79static unsigned long pll_clk_get_rate(struct clk *clk)
80{
81 return 480000000;
82}
83
84static int pll_clk_enable(struct clk *clk)
85{
86 __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
87 BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
88 CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
89
90 /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
91 * and is incorrect (excessive). Per definition of the PLLCTRL0
92 * POWER field, waiting at least 10us.
93 */
94 udelay(10);
95
96 return 0;
97}
98
99static void pll_clk_disable(struct clk *clk)
100{
101 __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
102 BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
103 CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
104}
105
106static struct clk pll_clk = {
107 .get_rate = pll_clk_get_rate,
108 .enable = pll_clk_enable,
109 .disable = pll_clk_disable,
110 .parent = &ref_xtal_clk,
111};
112
113/*
114 * ref_clk
115 */
116#define _CLK_GET_RATE_REF(name, sr, ss) \
117static unsigned long name##_get_rate(struct clk *clk) \
118{ \
119 unsigned long parent_rate; \
120 u32 reg, div; \
121 \
122 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
123 div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
124 parent_rate = clk_get_rate(clk->parent); \
125 \
126 return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
127 div, PARENT_RATE_SHIFT); \
128}
129
130_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
131_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
132_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
133_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
134
135#define _DEFINE_CLOCK_REF(name, er, es) \
136 static struct clk name = { \
137 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
138 .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
139 .get_rate = name##_get_rate, \
140 .enable = _raw_clk_enable, \
141 .disable = _raw_clk_disable, \
142 .parent = &pll_clk, \
143 }
144
145_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
146_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
147_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
148_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
149
150/*
151 * General clocks
152 *
153 * clk_get_rate
154 */
155static unsigned long rtc_clk_get_rate(struct clk *clk)
156{
157 /* ref_xtal_clk is implemented as the only parent */
158 return clk_get_rate(clk->parent) / 768;
159}
160
161static unsigned long clk32k_clk_get_rate(struct clk *clk)
162{
163 return clk->parent->get_rate(clk->parent) / 750;
164}
165
166#define _CLK_GET_RATE(name, rs) \
167static unsigned long name##_get_rate(struct clk *clk) \
168{ \
169 u32 reg, div; \
170 \
171 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
172 \
173 if (clk->parent == &ref_xtal_clk) \
174 div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
175 BP_CLKCTRL_##rs##_DIV_XTAL; \
176 else \
177 div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
178 BP_CLKCTRL_##rs##_DIV_##rs; \
179 \
180 if (!div) \
181 return -EINVAL; \
182 \
183 return clk_get_rate(clk->parent) / div; \
184}
185
186_CLK_GET_RATE(cpu_clk, CPU)
187_CLK_GET_RATE(emi_clk, EMI)
188
189#define _CLK_GET_RATE1(name, rs) \
190static unsigned long name##_get_rate(struct clk *clk) \
191{ \
192 u32 reg, div; \
193 \
194 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
195 div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
196 \
197 if (!div) \
198 return -EINVAL; \
199 \
200 return clk_get_rate(clk->parent) / div; \
201}
202
203_CLK_GET_RATE1(hbus_clk, HBUS)
204_CLK_GET_RATE1(xbus_clk, XBUS)
205_CLK_GET_RATE1(ssp_clk, SSP)
206_CLK_GET_RATE1(gpmi_clk, GPMI)
207_CLK_GET_RATE1(lcdif_clk, PIX)
208
209#define _CLK_GET_RATE_STUB(name) \
210static unsigned long name##_get_rate(struct clk *clk) \
211{ \
212 return clk_get_rate(clk->parent); \
213}
214
215_CLK_GET_RATE_STUB(uart_clk)
216_CLK_GET_RATE_STUB(audio_clk)
217_CLK_GET_RATE_STUB(pwm_clk)
218
219/*
220 * clk_set_rate
221 */
222static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
223{
224 u32 reg, bm_busy, div_max, d, f, div, frac;
225 unsigned long diff, parent_rate, calc_rate;
226
227 parent_rate = clk_get_rate(clk->parent);
228
229 if (clk->parent == &ref_xtal_clk) {
230 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
231 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
232 div = DIV_ROUND_UP(parent_rate, rate);
233 if (div == 0 || div > div_max)
234 return -EINVAL;
235 } else {
236 div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
237 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
238 rate >>= PARENT_RATE_SHIFT;
239 parent_rate >>= PARENT_RATE_SHIFT;
240 diff = parent_rate;
241 div = frac = 1;
242 for (d = 1; d <= div_max; d++) {
243 f = parent_rate * 18 / d / rate;
244 if ((parent_rate * 18 / d) % rate)
245 f++;
246 if (f < 18 || f > 35)
247 continue;
248
249 calc_rate = parent_rate * 18 / f / d;
250 if (calc_rate > rate)
251 continue;
252
253 if (rate - calc_rate < diff) {
254 frac = f;
255 div = d;
256 diff = rate - calc_rate;
257 }
258
259 if (diff == 0)
260 break;
261 }
262
263 if (diff == parent_rate)
264 return -EINVAL;
265
266 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
267 reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
268 reg |= frac;
269 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
270 }
271
272 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
273 reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
274 reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
275 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
276
277 mxs_clkctrl_timeout(HW_CLKCTRL_CPU, bm_busy);
278
279 return 0;
280}
281
282#define _CLK_SET_RATE(name, dr) \
283static int name##_set_rate(struct clk *clk, unsigned long rate) \
284{ \
285 u32 reg, div_max, div; \
286 unsigned long parent_rate; \
287 \
288 parent_rate = clk_get_rate(clk->parent); \
289 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
290 \
291 div = DIV_ROUND_UP(parent_rate, rate); \
292 if (div == 0 || div > div_max) \
293 return -EINVAL; \
294 \
295 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
296 reg &= ~BM_CLKCTRL_##dr##_DIV; \
297 reg |= div << BP_CLKCTRL_##dr##_DIV; \
298 if (reg & (1 << clk->enable_shift)) { \
299 pr_err("%s: clock is gated\n", __func__); \
300 return -EINVAL; \
301 } \
302 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
303 \
304 mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY); \
305 return 0; \
306}
307
308_CLK_SET_RATE(xbus_clk, XBUS)
309_CLK_SET_RATE(ssp_clk, SSP)
310_CLK_SET_RATE(gpmi_clk, GPMI)
311_CLK_SET_RATE(lcdif_clk, PIX)
312
313#define _CLK_SET_RATE_STUB(name) \
314static int name##_set_rate(struct clk *clk, unsigned long rate) \
315{ \
316 return -EINVAL; \
317}
318
319_CLK_SET_RATE_STUB(emi_clk)
320_CLK_SET_RATE_STUB(uart_clk)
321_CLK_SET_RATE_STUB(audio_clk)
322_CLK_SET_RATE_STUB(pwm_clk)
323_CLK_SET_RATE_STUB(clk32k_clk)
324
325/*
326 * clk_set_parent
327 */
328#define _CLK_SET_PARENT(name, bit) \
329static int name##_set_parent(struct clk *clk, struct clk *parent) \
330{ \
331 if (parent != clk->parent) { \
332 __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
333 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
334 clk->parent = parent; \
335 } \
336 \
337 return 0; \
338}
339
340_CLK_SET_PARENT(cpu_clk, CPU)
341_CLK_SET_PARENT(emi_clk, EMI)
342_CLK_SET_PARENT(ssp_clk, SSP)
343_CLK_SET_PARENT(gpmi_clk, GPMI)
344_CLK_SET_PARENT(lcdif_clk, PIX)
345
346#define _CLK_SET_PARENT_STUB(name) \
347static int name##_set_parent(struct clk *clk, struct clk *parent) \
348{ \
349 if (parent != clk->parent) \
350 return -EINVAL; \
351 else \
352 return 0; \
353}
354
355_CLK_SET_PARENT_STUB(uart_clk)
356_CLK_SET_PARENT_STUB(audio_clk)
357_CLK_SET_PARENT_STUB(pwm_clk)
358_CLK_SET_PARENT_STUB(clk32k_clk)
359
360/*
361 * clk definition
362 */
363static struct clk cpu_clk = {
364 .get_rate = cpu_clk_get_rate,
365 .set_rate = cpu_clk_set_rate,
366 .set_parent = cpu_clk_set_parent,
367 .parent = &ref_cpu_clk,
368};
369
370static struct clk hbus_clk = {
371 .get_rate = hbus_clk_get_rate,
372 .parent = &cpu_clk,
373};
374
375static struct clk xbus_clk = {
376 .get_rate = xbus_clk_get_rate,
377 .set_rate = xbus_clk_set_rate,
378 .parent = &ref_xtal_clk,
379};
380
381static struct clk rtc_clk = {
382 .get_rate = rtc_clk_get_rate,
383 .parent = &ref_xtal_clk,
384};
385
386/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
387static struct clk usb_clk = {
388 .enable_reg = DIGCTRL_BASE_ADDR,
389 .enable_shift = 2,
390 .enable = _raw_clk_enable,
391 .disable = _raw_clk_disable,
392 .parent = &pll_clk,
393};
394
395#define _DEFINE_CLOCK(name, er, es, p) \
396 static struct clk name = { \
397 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
398 .enable_shift = BP_CLKCTRL_##er##_##es, \
399 .get_rate = name##_get_rate, \
400 .set_rate = name##_set_rate, \
401 .set_parent = name##_set_parent, \
402 .enable = _raw_clk_enable, \
403 .disable = _raw_clk_disable, \
404 .parent = p, \
405 }
406
407_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
408_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
409_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
410_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
411_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
412_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
413_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
414_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
415
416#define _REGISTER_CLOCK(d, n, c) \
417 { \
418 .dev_id = d, \
419 .con_id = n, \
420 .clk = &c, \
421 },
422
423static struct clk_lookup lookups[] = {
424 /* for amba bus driver */
425 _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
426 /* for amba-pl011 driver */
427 _REGISTER_CLOCK("duart", NULL, uart_clk)
428 _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
429 _REGISTER_CLOCK("rtc", NULL, rtc_clk)
430 _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
431 _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
432 _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
433 _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp_clk)
434 _REGISTER_CLOCK(NULL, "usb", usb_clk)
435 _REGISTER_CLOCK(NULL, "audio", audio_clk)
436 _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
437 _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
438 _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
439 _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
440 _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
441 _REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk)
442 _REGISTER_CLOCK("imx23-gpmi-nand", NULL, gpmi_clk)
443};
444
445static int clk_misc_init(void)
446{
447 u32 reg;
448 int ret;
449
450 /* Fix up parent per register setting */
451 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
452 cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
453 &ref_xtal_clk : &ref_cpu_clk;
454 emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
455 &ref_xtal_clk : &ref_emi_clk;
456 ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
457 &ref_xtal_clk : &ref_io_clk;
458 gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
459 &ref_xtal_clk : &ref_io_clk;
460 lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
461 &ref_xtal_clk : &ref_pix_clk;
462
463 /* Use int div over frac when both are available */
464 __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
465 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
466 __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
467 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
468 __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
469 CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
470
471 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
472 reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
473 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
474
475 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
476 reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
477 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
478
479 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
480 reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
481 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
482
483 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
484 reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
485 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
486
487 /*
488 * Set safe hbus clock divider. A divider of 3 ensure that
489 * the Vddd voltage required for the cpu clock is sufficiently
490 * high for the hbus clock.
491 */
492 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
493 reg &= BM_CLKCTRL_HBUS_DIV;
494 reg |= 3 << BP_CLKCTRL_HBUS_DIV;
495 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
496
497 ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_BUSY);
498
499 /* Gate off cpu clock in WFI for power saving */
500 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
501 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
502
503 /*
504 * 480 MHz seems too high to be ssp clock source directly,
505 * so set frac to get a 288 MHz ref_io.
506 */
507 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
508 reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
509 reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
510 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
511
512 return ret;
513}
514
515int __init mx23_clocks_init(void)
516{
517 clk_misc_init();
518
519 /*
520 * source ssp clock from ref_io than ref_xtal,
521 * as ref_xtal only provides 24 MHz as maximum.
522 */
523 clk_set_parent(&ssp_clk, &ref_io_clk);
524
525 clk_prepare_enable(&cpu_clk);
526 clk_prepare_enable(&hbus_clk);
527 clk_prepare_enable(&xbus_clk);
528 clk_prepare_enable(&emi_clk);
529 clk_prepare_enable(&uart_clk);
530
531 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
532
533 mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
534
535 return 0;
536}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
deleted file mode 100644
index cea29c99e214..000000000000
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ /dev/null
@@ -1,803 +0,0 @@
1/*
2 * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <linux/mm.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/jiffies.h>
24#include <linux/clkdev.h>
25#include <linux/spinlock.h>
26
27#include <asm/clkdev.h>
28#include <asm/div64.h>
29
30#include <mach/mx28.h>
31#include <mach/common.h>
32#include <mach/clock.h>
33#include <mach/digctl.h>
34
35#include "regs-clkctrl-mx28.h"
36
37#define CLKCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
38#define DIGCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
39
40#define PARENT_RATE_SHIFT 8
41
42static struct clk pll2_clk;
43static struct clk cpu_clk;
44static struct clk emi_clk;
45static struct clk saif0_clk;
46static struct clk saif1_clk;
47static struct clk clk32k_clk;
48static DEFINE_SPINLOCK(clkmux_lock);
49
50/*
51 * HW_SAIF_CLKMUX_SEL:
52 * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
53 * clock pins selected for SAIF1 input clocks.
54 * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
55 * SAIF0 clock inputs selected for SAIF1 input clocks.
56 * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
57 * clocks.
58 * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
59 * clocks.
60 */
61int mxs_saif_clkmux_select(unsigned int clkmux)
62{
63 if (clkmux > 0x3)
64 return -EINVAL;
65
66 spin_lock(&clkmux_lock);
67 __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
68 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
69 __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
70 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
71 spin_unlock(&clkmux_lock);
72
73 return 0;
74}
75
76static int _raw_clk_enable(struct clk *clk)
77{
78 u32 reg;
79
80 if (clk->enable_reg) {
81 reg = __raw_readl(clk->enable_reg);
82 reg &= ~(1 << clk->enable_shift);
83 __raw_writel(reg, clk->enable_reg);
84 }
85
86 return 0;
87}
88
89static void _raw_clk_disable(struct clk *clk)
90{
91 u32 reg;
92
93 if (clk->enable_reg) {
94 reg = __raw_readl(clk->enable_reg);
95 reg |= 1 << clk->enable_shift;
96 __raw_writel(reg, clk->enable_reg);
97 }
98}
99
100/*
101 * ref_xtal_clk
102 */
103static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
104{
105 return 24000000;
106}
107
108static struct clk ref_xtal_clk = {
109 .get_rate = ref_xtal_clk_get_rate,
110};
111
112/*
113 * pll_clk
114 */
115static unsigned long pll0_clk_get_rate(struct clk *clk)
116{
117 return 480000000;
118}
119
120static unsigned long pll1_clk_get_rate(struct clk *clk)
121{
122 return 480000000;
123}
124
125static unsigned long pll2_clk_get_rate(struct clk *clk)
126{
127 return 50000000;
128}
129
130#define _CLK_ENABLE_PLL(name, r, g) \
131static int name##_enable(struct clk *clk) \
132{ \
133 __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
134 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
135 udelay(10); \
136 \
137 if (clk == &pll2_clk) \
138 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
139 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
140 else \
141 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
142 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
143 \
144 return 0; \
145}
146
147_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
148_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
149_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
150
151#define _CLK_DISABLE_PLL(name, r, g) \
152static void name##_disable(struct clk *clk) \
153{ \
154 __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
155 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
156 \
157 if (clk == &pll2_clk) \
158 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
159 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
160 else \
161 __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
162 CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
163 \
164}
165
166_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
167_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
168_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
169
170#define _DEFINE_CLOCK_PLL(name) \
171 static struct clk name = { \
172 .get_rate = name##_get_rate, \
173 .enable = name##_enable, \
174 .disable = name##_disable, \
175 .parent = &ref_xtal_clk, \
176 }
177
178_DEFINE_CLOCK_PLL(pll0_clk);
179_DEFINE_CLOCK_PLL(pll1_clk);
180_DEFINE_CLOCK_PLL(pll2_clk);
181
182/*
183 * ref_clk
184 */
185#define _CLK_GET_RATE_REF(name, sr, ss) \
186static unsigned long name##_get_rate(struct clk *clk) \
187{ \
188 unsigned long parent_rate; \
189 u32 reg, div; \
190 \
191 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
192 div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
193 parent_rate = clk_get_rate(clk->parent); \
194 \
195 return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
196 div, PARENT_RATE_SHIFT); \
197}
198
199_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
200_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
201_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
202_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
203_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
204_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
205
206#define _DEFINE_CLOCK_REF(name, er, es) \
207 static struct clk name = { \
208 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
209 .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
210 .get_rate = name##_get_rate, \
211 .enable = _raw_clk_enable, \
212 .disable = _raw_clk_disable, \
213 .parent = &pll0_clk, \
214 }
215
216_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
217_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
218_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
219_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
220_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
221_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
222
223/*
224 * General clocks
225 *
226 * clk_get_rate
227 */
228static unsigned long lradc_clk_get_rate(struct clk *clk)
229{
230 return clk_get_rate(clk->parent) / 16;
231}
232
233static unsigned long rtc_clk_get_rate(struct clk *clk)
234{
235 /* ref_xtal_clk is implemented as the only parent */
236 return clk_get_rate(clk->parent) / 768;
237}
238
239static unsigned long clk32k_clk_get_rate(struct clk *clk)
240{
241 return clk->parent->get_rate(clk->parent) / 750;
242}
243
244static unsigned long spdif_clk_get_rate(struct clk *clk)
245{
246 return clk_get_rate(clk->parent) / 4;
247}
248
249#define _CLK_GET_RATE(name, rs) \
250static unsigned long name##_get_rate(struct clk *clk) \
251{ \
252 u32 reg, div; \
253 \
254 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
255 \
256 if (clk->parent == &ref_xtal_clk) \
257 div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
258 BP_CLKCTRL_##rs##_DIV_XTAL; \
259 else \
260 div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
261 BP_CLKCTRL_##rs##_DIV_##rs; \
262 \
263 if (!div) \
264 return -EINVAL; \
265 \
266 return clk_get_rate(clk->parent) / div; \
267}
268
269_CLK_GET_RATE(cpu_clk, CPU)
270_CLK_GET_RATE(emi_clk, EMI)
271
272#define _CLK_GET_RATE1(name, rs) \
273static unsigned long name##_get_rate(struct clk *clk) \
274{ \
275 u32 reg, div; \
276 \
277 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
278 div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
279 \
280 if (!div) \
281 return -EINVAL; \
282 \
283 if (clk == &saif0_clk || clk == &saif1_clk) \
284 return clk_get_rate(clk->parent) >> 16 * div; \
285 else \
286 return clk_get_rate(clk->parent) / div; \
287}
288
289_CLK_GET_RATE1(hbus_clk, HBUS)
290_CLK_GET_RATE1(xbus_clk, XBUS)
291_CLK_GET_RATE1(ssp0_clk, SSP0)
292_CLK_GET_RATE1(ssp1_clk, SSP1)
293_CLK_GET_RATE1(ssp2_clk, SSP2)
294_CLK_GET_RATE1(ssp3_clk, SSP3)
295_CLK_GET_RATE1(gpmi_clk, GPMI)
296_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
297_CLK_GET_RATE1(saif0_clk, SAIF0)
298_CLK_GET_RATE1(saif1_clk, SAIF1)
299
300#define _CLK_GET_RATE_STUB(name) \
301static unsigned long name##_get_rate(struct clk *clk) \
302{ \
303 return clk_get_rate(clk->parent); \
304}
305
306_CLK_GET_RATE_STUB(uart_clk)
307_CLK_GET_RATE_STUB(pwm_clk)
308_CLK_GET_RATE_STUB(can0_clk)
309_CLK_GET_RATE_STUB(can1_clk)
310_CLK_GET_RATE_STUB(fec_clk)
311
312/*
313 * clk_set_rate
314 */
315/* fool compiler */
316#define BM_CLKCTRL_CPU_DIV 0
317#define BP_CLKCTRL_CPU_DIV 0
318#define BM_CLKCTRL_CPU_BUSY 0
319
320#define _CLK_SET_RATE(name, dr, fr, fs) \
321static int name##_set_rate(struct clk *clk, unsigned long rate) \
322{ \
323 u32 reg, bm_busy, div_max, d, f, div, frac; \
324 unsigned long diff, parent_rate, calc_rate; \
325 \
326 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
327 bm_busy = BM_CLKCTRL_##dr##_BUSY; \
328 \
329 if (clk->parent == &ref_xtal_clk) { \
330 parent_rate = clk_get_rate(clk->parent); \
331 div = DIV_ROUND_UP(parent_rate, rate); \
332 if (clk == &cpu_clk) { \
333 div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
334 BP_CLKCTRL_CPU_DIV_XTAL; \
335 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL; \
336 } \
337 if (div == 0 || div > div_max) \
338 return -EINVAL; \
339 } else { \
340 /* \
341 * hack alert: this block modifies clk->parent, too, \
342 * so the base to use it the grand parent. \
343 */ \
344 parent_rate = clk_get_rate(clk->parent->parent); \
345 rate >>= PARENT_RATE_SHIFT; \
346 parent_rate >>= PARENT_RATE_SHIFT; \
347 diff = parent_rate; \
348 div = frac = 1; \
349 if (clk == &cpu_clk) { \
350 div_max = BM_CLKCTRL_CPU_DIV_CPU >> \
351 BP_CLKCTRL_CPU_DIV_CPU; \
352 bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU; \
353 } \
354 for (d = 1; d <= div_max; d++) { \
355 f = parent_rate * 18 / d / rate; \
356 if ((parent_rate * 18 / d) % rate) \
357 f++; \
358 if (f < 18 || f > 35) \
359 continue; \
360 \
361 calc_rate = parent_rate * 18 / f / d; \
362 if (calc_rate > rate) \
363 continue; \
364 \
365 if (rate - calc_rate < diff) { \
366 frac = f; \
367 div = d; \
368 diff = rate - calc_rate; \
369 } \
370 \
371 if (diff == 0) \
372 break; \
373 } \
374 \
375 if (diff == parent_rate) \
376 return -EINVAL; \
377 \
378 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
379 reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
380 reg |= frac << BP_CLKCTRL_##fr##_##fs##FRAC; \
381 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
382 } \
383 \
384 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
385 if (clk == &cpu_clk) { \
386 reg &= ~BM_CLKCTRL_CPU_DIV_CPU; \
387 reg |= div << BP_CLKCTRL_CPU_DIV_CPU; \
388 } else { \
389 reg &= ~BM_CLKCTRL_##dr##_DIV; \
390 reg |= div << BP_CLKCTRL_##dr##_DIV; \
391 if (reg & (1 << clk->enable_shift)) { \
392 pr_err("%s: clock is gated\n", __func__); \
393 return -EINVAL; \
394 } \
395 } \
396 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
397 \
398 return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, bm_busy); \
399}
400
401_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
402_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
403_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
404_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
405_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
406_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
407_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
408
409#define _CLK_SET_RATE1(name, dr) \
410static int name##_set_rate(struct clk *clk, unsigned long rate) \
411{ \
412 u32 reg, div_max, div; \
413 unsigned long parent_rate; \
414 \
415 parent_rate = clk_get_rate(clk->parent); \
416 div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
417 \
418 div = DIV_ROUND_UP(parent_rate, rate); \
419 if (div == 0 || div > div_max) \
420 return -EINVAL; \
421 \
422 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
423 reg &= ~BM_CLKCTRL_##dr##_DIV; \
424 reg |= div << BP_CLKCTRL_##dr##_DIV; \
425 if (reg & (1 << clk->enable_shift)) { \
426 pr_err("%s: clock is gated\n", __func__); \
427 return -EINVAL; \
428 } \
429 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
430 \
431 return mxs_clkctrl_timeout(HW_CLKCTRL_##dr, BM_CLKCTRL_##dr##_BUSY);\
432}
433
434_CLK_SET_RATE1(xbus_clk, XBUS)
435
436/* saif clock uses 16 bits frac div */
437#define _CLK_SET_RATE_SAIF(name, rs) \
438static int name##_set_rate(struct clk *clk, unsigned long rate) \
439{ \
440 u16 div; \
441 u32 reg; \
442 u64 lrate; \
443 unsigned long parent_rate; \
444 \
445 parent_rate = clk_get_rate(clk->parent); \
446 if (rate > parent_rate) \
447 return -EINVAL; \
448 \
449 lrate = (u64)rate << 16; \
450 do_div(lrate, parent_rate); \
451 div = (u16)lrate; \
452 \
453 if (!div) \
454 return -EINVAL; \
455 \
456 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
457 reg &= ~BM_CLKCTRL_##rs##_DIV; \
458 reg |= div << BP_CLKCTRL_##rs##_DIV; \
459 if (reg & (1 << clk->enable_shift)) { \
460 pr_err("%s: clock is gated\n", __func__); \
461 return -EINVAL; \
462 } \
463 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
464 \
465 return mxs_clkctrl_timeout(HW_CLKCTRL_##rs, BM_CLKCTRL_##rs##_BUSY);\
466}
467
468_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
469_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
470
471#define _CLK_SET_RATE_STUB(name) \
472static int name##_set_rate(struct clk *clk, unsigned long rate) \
473{ \
474 return -EINVAL; \
475}
476
477_CLK_SET_RATE_STUB(emi_clk)
478_CLK_SET_RATE_STUB(uart_clk)
479_CLK_SET_RATE_STUB(pwm_clk)
480_CLK_SET_RATE_STUB(spdif_clk)
481_CLK_SET_RATE_STUB(clk32k_clk)
482_CLK_SET_RATE_STUB(can0_clk)
483_CLK_SET_RATE_STUB(can1_clk)
484_CLK_SET_RATE_STUB(fec_clk)
485
486/*
487 * clk_set_parent
488 */
489#define _CLK_SET_PARENT(name, bit) \
490static int name##_set_parent(struct clk *clk, struct clk *parent) \
491{ \
492 if (parent != clk->parent) { \
493 __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
494 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
495 clk->parent = parent; \
496 } \
497 \
498 return 0; \
499}
500
501_CLK_SET_PARENT(cpu_clk, CPU)
502_CLK_SET_PARENT(emi_clk, EMI)
503_CLK_SET_PARENT(ssp0_clk, SSP0)
504_CLK_SET_PARENT(ssp1_clk, SSP1)
505_CLK_SET_PARENT(ssp2_clk, SSP2)
506_CLK_SET_PARENT(ssp3_clk, SSP3)
507_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
508_CLK_SET_PARENT(gpmi_clk, GPMI)
509_CLK_SET_PARENT(saif0_clk, SAIF0)
510_CLK_SET_PARENT(saif1_clk, SAIF1)
511
512#define _CLK_SET_PARENT_STUB(name) \
513static int name##_set_parent(struct clk *clk, struct clk *parent) \
514{ \
515 if (parent != clk->parent) \
516 return -EINVAL; \
517 else \
518 return 0; \
519}
520
521_CLK_SET_PARENT_STUB(pwm_clk)
522_CLK_SET_PARENT_STUB(uart_clk)
523_CLK_SET_PARENT_STUB(clk32k_clk)
524_CLK_SET_PARENT_STUB(spdif_clk)
525_CLK_SET_PARENT_STUB(fec_clk)
526_CLK_SET_PARENT_STUB(can0_clk)
527_CLK_SET_PARENT_STUB(can1_clk)
528
529/*
530 * clk definition
531 */
532static struct clk cpu_clk = {
533 .get_rate = cpu_clk_get_rate,
534 .set_rate = cpu_clk_set_rate,
535 .set_parent = cpu_clk_set_parent,
536 .parent = &ref_cpu_clk,
537};
538
539static struct clk hbus_clk = {
540 .get_rate = hbus_clk_get_rate,
541 .parent = &cpu_clk,
542};
543
544static struct clk xbus_clk = {
545 .get_rate = xbus_clk_get_rate,
546 .set_rate = xbus_clk_set_rate,
547 .parent = &ref_xtal_clk,
548};
549
550static struct clk lradc_clk = {
551 .get_rate = lradc_clk_get_rate,
552 .parent = &clk32k_clk,
553};
554
555static struct clk rtc_clk = {
556 .get_rate = rtc_clk_get_rate,
557 .parent = &ref_xtal_clk,
558};
559
560/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
561static struct clk usb0_clk = {
562 .enable_reg = DIGCTRL_BASE_ADDR,
563 .enable_shift = 2,
564 .enable = _raw_clk_enable,
565 .disable = _raw_clk_disable,
566 .parent = &pll0_clk,
567};
568
569static struct clk usb1_clk = {
570 .enable_reg = DIGCTRL_BASE_ADDR,
571 .enable_shift = 16,
572 .enable = _raw_clk_enable,
573 .disable = _raw_clk_disable,
574 .parent = &pll1_clk,
575};
576
577#define _DEFINE_CLOCK(name, er, es, p) \
578 static struct clk name = { \
579 .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
580 .enable_shift = BP_CLKCTRL_##er##_##es, \
581 .get_rate = name##_get_rate, \
582 .set_rate = name##_set_rate, \
583 .set_parent = name##_set_parent, \
584 .enable = _raw_clk_enable, \
585 .disable = _raw_clk_disable, \
586 .parent = p, \
587 }
588
589_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
590_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
591_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
592_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
593_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
594_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
595_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
596_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
597_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
598_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
599_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
600_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
601_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
602_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
603_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
604_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
605
606#define _REGISTER_CLOCK(d, n, c) \
607 { \
608 .dev_id = d, \
609 .con_id = n, \
610 .clk = &c, \
611 },
612
613static struct clk_lookup lookups[] = {
614 /* for amba bus driver */
615 _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
616 /* for amba-pl011 driver */
617 _REGISTER_CLOCK("duart", NULL, uart_clk)
618 _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
619 _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
620 _REGISTER_CLOCK("imx28-gpmi-nand", NULL, gpmi_clk)
621 _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
622 _REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
623 _REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
624 _REGISTER_CLOCK("mxs-auart.3", NULL, uart_clk)
625 _REGISTER_CLOCK("mxs-auart.4", NULL, uart_clk)
626 _REGISTER_CLOCK("rtc", NULL, rtc_clk)
627 _REGISTER_CLOCK("pll2", NULL, pll2_clk)
628 _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
629 _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
630 _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
631 _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
632 _REGISTER_CLOCK("mxs-mmc.2", NULL, ssp2_clk)
633 _REGISTER_CLOCK("mxs-mmc.3", NULL, ssp3_clk)
634 _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
635 _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
636 _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
637 _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
638 _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
639 _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
640 _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
641 _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
642 _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
643 _REGISTER_CLOCK("mxs-pwm.5", NULL, pwm_clk)
644 _REGISTER_CLOCK("mxs-pwm.6", NULL, pwm_clk)
645 _REGISTER_CLOCK("mxs-pwm.7", NULL, pwm_clk)
646 _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
647 _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
648 _REGISTER_CLOCK("imx28-fb", NULL, lcdif_clk)
649 _REGISTER_CLOCK("mxs-saif.0", NULL, saif0_clk)
650 _REGISTER_CLOCK("mxs-saif.1", NULL, saif1_clk)
651};
652
653static int clk_misc_init(void)
654{
655 u32 reg;
656 int ret;
657
658 /* Fix up parent per register setting */
659 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
660 cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
661 &ref_xtal_clk : &ref_cpu_clk;
662 emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
663 &ref_xtal_clk : &ref_emi_clk;
664 ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
665 &ref_xtal_clk : &ref_io0_clk;
666 ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
667 &ref_xtal_clk : &ref_io0_clk;
668 ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
669 &ref_xtal_clk : &ref_io1_clk;
670 ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
671 &ref_xtal_clk : &ref_io1_clk;
672 lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
673 &ref_xtal_clk : &ref_pix_clk;
674 gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
675 &ref_xtal_clk : &ref_gpmi_clk;
676 saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
677 &ref_xtal_clk : &pll0_clk;
678 saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
679 &ref_xtal_clk : &pll0_clk;
680
681 /* Use int div over frac when both are available */
682 __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
683 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
684 __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
685 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
686 __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
687 CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
688
689 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
690 reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
691 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
692
693 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
694 reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
695 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
696
697 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
698 reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
699 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
700
701 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
702 reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
703 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
704
705 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
706 reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
707 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
708
709 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
710 reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
711 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
712
713 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
714 reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
715 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
716
717 /* SAIF has to use frac div for functional operation */
718 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
719 reg |= BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
720 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
721
722 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
723 reg |= BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
724 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
725
726 /*
727 * Set safe hbus clock divider. A divider of 3 ensure that
728 * the Vddd voltage required for the cpu clock is sufficiently
729 * high for the hbus clock.
730 */
731 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
732 reg &= BM_CLKCTRL_HBUS_DIV;
733 reg |= 3 << BP_CLKCTRL_HBUS_DIV;
734 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
735
736 ret = mxs_clkctrl_timeout(HW_CLKCTRL_HBUS, BM_CLKCTRL_HBUS_ASM_BUSY);
737
738 /* Gate off cpu clock in WFI for power saving */
739 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
740 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
741
742 /*
743 * Extra fec clock setting
744 * The DENX M28 uses an external clock source
745 * and the clock output must not be enabled
746 */
747 if (!machine_is_m28evk()) {
748 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
749 reg &= ~BM_CLKCTRL_ENET_SLEEP;
750 reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
751 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
752 }
753
754 /*
755 * 480 MHz seems too high to be ssp clock source directly,
756 * so set frac0 to get a 288 MHz ref_io0.
757 */
758 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
759 reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
760 reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
761 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
762
763 return ret;
764}
765
766int __init mx28_clocks_init(void)
767{
768 clk_misc_init();
769
770 /*
771 * source ssp clock from ref_io0 than ref_xtal,
772 * as ref_xtal only provides 24 MHz as maximum.
773 */
774 clk_set_parent(&ssp0_clk, &ref_io0_clk);
775 clk_set_parent(&ssp1_clk, &ref_io0_clk);
776 clk_set_parent(&ssp2_clk, &ref_io1_clk);
777 clk_set_parent(&ssp3_clk, &ref_io1_clk);
778
779 clk_prepare_enable(&cpu_clk);
780 clk_prepare_enable(&hbus_clk);
781 clk_prepare_enable(&xbus_clk);
782 clk_prepare_enable(&emi_clk);
783 clk_prepare_enable(&uart_clk);
784
785 clk_set_parent(&lcdif_clk, &ref_pix_clk);
786 clk_set_parent(&saif0_clk, &pll0_clk);
787 clk_set_parent(&saif1_clk, &pll0_clk);
788
789 /*
790 * Set an initial clock rate for the saif internal logic to work
791 * properly. This is important when working in EXTMASTER mode that
792 * uses the other saif's BITCLK&LRCLK but it still needs a basic
793 * clock which should be fast enough for the internal logic.
794 */
795 clk_set_rate(&saif0_clk, 24000000);
796 clk_set_rate(&saif1_clk, 24000000);
797
798 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
799
800 mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
801
802 return 0;
803}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
deleted file mode 100644
index 97a6f4acc6cc..000000000000
--- a/arch/arm/mach-mxs/clock.c
+++ /dev/null
@@ -1,211 +0,0 @@
1/*
2 * Based on arch/arm/plat-omap/clock.c
3 *
4 * Copyright (C) 2004 - 2005 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
7 * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
8 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301, USA.
23 */
24
25/* #define DEBUG */
26
27#include <linux/clk.h>
28#include <linux/err.h>
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/io.h>
32#include <linux/kernel.h>
33#include <linux/list.h>
34#include <linux/module.h>
35#include <linux/mutex.h>
36#include <linux/platform_device.h>
37#include <linux/proc_fs.h>
38#include <linux/semaphore.h>
39#include <linux/string.h>
40
41#include <mach/clock.h>
42
43static LIST_HEAD(clocks);
44static DEFINE_MUTEX(clocks_mutex);
45
46/*-------------------------------------------------------------------------
47 * Standard clock functions defined in include/linux/clk.h
48 *-------------------------------------------------------------------------*/
49
50static void __clk_disable(struct clk *clk)
51{
52 if (clk == NULL || IS_ERR(clk))
53 return;
54 WARN_ON(!clk->usecount);
55
56 if (!(--clk->usecount)) {
57 if (clk->disable)
58 clk->disable(clk);
59 __clk_disable(clk->parent);
60 }
61}
62
63static int __clk_enable(struct clk *clk)
64{
65 if (clk == NULL || IS_ERR(clk))
66 return -EINVAL;
67
68 if (clk->usecount++ == 0) {
69 __clk_enable(clk->parent);
70
71 if (clk->enable)
72 clk->enable(clk);
73 }
74 return 0;
75}
76
77/*
78 * The clk_enable/clk_disable could be called by drivers in atomic context,
79 * so they should not really hold mutex. Instead, clk_prepare/clk_unprepare
80 * can hold a mutex, as the pair will only be called in non-atomic context.
81 * Before migrating to common clk framework, we can have __clk_enable and
82 * __clk_disable called in clk_prepare/clk_unprepare with mutex held and
83 * leave clk_enable/clk_disable as the dummy functions.
84 */
85int clk_prepare(struct clk *clk)
86{
87 int ret = 0;
88
89 if (clk == NULL || IS_ERR(clk))
90 return -EINVAL;
91
92 mutex_lock(&clocks_mutex);
93 ret = __clk_enable(clk);
94 mutex_unlock(&clocks_mutex);
95
96 return ret;
97}
98EXPORT_SYMBOL(clk_prepare);
99
100void clk_unprepare(struct clk *clk)
101{
102 if (clk == NULL || IS_ERR(clk))
103 return;
104
105 mutex_lock(&clocks_mutex);
106 __clk_disable(clk);
107 mutex_unlock(&clocks_mutex);
108}
109EXPORT_SYMBOL(clk_unprepare);
110
111int clk_enable(struct clk *clk)
112{
113 return 0;
114}
115EXPORT_SYMBOL(clk_enable);
116
117void clk_disable(struct clk *clk)
118{
119 /* nothing to do */
120}
121EXPORT_SYMBOL(clk_disable);
122
123/* Retrieve the *current* clock rate. If the clock itself
124 * does not provide a special calculation routine, ask
125 * its parent and so on, until one is able to return
126 * a valid clock rate
127 */
128unsigned long clk_get_rate(struct clk *clk)
129{
130 if (clk == NULL || IS_ERR(clk))
131 return 0UL;
132
133 if (clk->get_rate)
134 return clk->get_rate(clk);
135
136 return clk_get_rate(clk->parent);
137}
138EXPORT_SYMBOL(clk_get_rate);
139
140/* Round the requested clock rate to the nearest supported
141 * rate that is less than or equal to the requested rate.
142 * This is dependent on the clock's current parent.
143 */
144long clk_round_rate(struct clk *clk, unsigned long rate)
145{
146 if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
147 return 0;
148
149 return clk->round_rate(clk, rate);
150}
151EXPORT_SYMBOL(clk_round_rate);
152
153/* Set the clock to the requested clock rate. The rate must
154 * match a supported rate exactly based on what clk_round_rate returns
155 */
156int clk_set_rate(struct clk *clk, unsigned long rate)
157{
158 int ret = -EINVAL;
159
160 if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
161 return ret;
162
163 mutex_lock(&clocks_mutex);
164 ret = clk->set_rate(clk, rate);
165 mutex_unlock(&clocks_mutex);
166
167 return ret;
168}
169EXPORT_SYMBOL(clk_set_rate);
170
171/* Set the clock's parent to another clock source */
172int clk_set_parent(struct clk *clk, struct clk *parent)
173{
174 int ret = -EINVAL;
175 struct clk *old;
176
177 if (clk == NULL || IS_ERR(clk) || parent == NULL ||
178 IS_ERR(parent) || clk->set_parent == NULL)
179 return ret;
180
181 if (clk->usecount)
182 clk_prepare_enable(parent);
183
184 mutex_lock(&clocks_mutex);
185 ret = clk->set_parent(clk, parent);
186 if (ret == 0) {
187 old = clk->parent;
188 clk->parent = parent;
189 } else {
190 old = parent;
191 }
192 mutex_unlock(&clocks_mutex);
193
194 if (clk->usecount)
195 clk_disable(old);
196
197 return ret;
198}
199EXPORT_SYMBOL(clk_set_parent);
200
201/* Retrieve the clock's parent clock source */
202struct clk *clk_get_parent(struct clk *clk)
203{
204 struct clk *ret = NULL;
205
206 if (clk == NULL || IS_ERR(clk))
207 return ret;
208
209 return clk->parent;
210}
211EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index b8913df4cfa2..19659de1c4e8 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -1,6 +1,5 @@
1config MXS_HAVE_AMBA_DUART 1config MXS_HAVE_AMBA_DUART
2 bool 2 bool
3 select ARM_AMBA
4 3
5config MXS_HAVE_PLATFORM_AUART 4config MXS_HAVE_PLATFORM_AUART
6 bool 5 bool
diff --git a/arch/arm/mach-mxs/devices/platform-dma.c b/arch/arm/mach-mxs/devices/platform-dma.c
index 6a0202b1016c..46824501de00 100644
--- a/arch/arm/mach-mxs/devices/platform-dma.c
+++ b/arch/arm/mach-mxs/devices/platform-dma.c
@@ -14,7 +14,7 @@
14#include <mach/mx28.h> 14#include <mach/mx28.h>
15#include <mach/devices-common.h> 15#include <mach/devices-common.h>
16 16
17static struct platform_device *__init mxs_add_dma(const char *devid, 17struct platform_device *__init mxs_add_dma(const char *devid,
18 resource_size_t base) 18 resource_size_t base)
19{ 19{
20 struct resource res[] = { 20 struct resource res[] = {
@@ -29,22 +29,3 @@ static struct platform_device *__init mxs_add_dma(const char *devid,
29 res, ARRAY_SIZE(res), NULL, 0, 29 res, ARRAY_SIZE(res), NULL, 0,
30 DMA_BIT_MASK(32)); 30 DMA_BIT_MASK(32));
31} 31}
32
33static int __init mxs_add_mxs_dma(void)
34{
35 char *apbh = "mxs-dma-apbh";
36 char *apbx = "mxs-dma-apbx";
37
38 if (cpu_is_mx23()) {
39 mxs_add_dma(apbh, MX23_APBH_DMA_BASE_ADDR);
40 mxs_add_dma(apbx, MX23_APBX_DMA_BASE_ADDR);
41 }
42
43 if (cpu_is_mx28()) {
44 mxs_add_dma(apbh, MX28_APBH_DMA_BASE_ADDR);
45 mxs_add_dma(apbx, MX28_APBX_DMA_BASE_ADDR);
46 }
47
48 return 0;
49}
50arch_initcall(mxs_add_mxs_dma);
diff --git a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
index ed0885e414e0..cd99f19ec637 100644
--- a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
+++ b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
@@ -14,7 +14,7 @@
14#include <mach/devices-common.h> 14#include <mach/devices-common.h>
15 15
16struct platform_device *__init mxs_add_gpio( 16struct platform_device *__init mxs_add_gpio(
17 int id, resource_size_t iobase, int irq) 17 char *name, int id, resource_size_t iobase, int irq)
18{ 18{
19 struct resource res[] = { 19 struct resource res[] = {
20 { 20 {
@@ -29,25 +29,5 @@ struct platform_device *__init mxs_add_gpio(
29 }; 29 };
30 30
31 return platform_device_register_resndata(&mxs_apbh_bus, 31 return platform_device_register_resndata(&mxs_apbh_bus,
32 "gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0); 32 name, id, res, ARRAY_SIZE(res), NULL, 0);
33} 33}
34
35static int __init mxs_add_mxs_gpio(void)
36{
37 if (cpu_is_mx23()) {
38 mxs_add_gpio(0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
39 mxs_add_gpio(1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
40 mxs_add_gpio(2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
41 }
42
43 if (cpu_is_mx28()) {
44 mxs_add_gpio(0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
45 mxs_add_gpio(1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
46 mxs_add_gpio(2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
47 mxs_add_gpio(3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
48 mxs_add_gpio(4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
49 }
50
51 return 0;
52}
53postcore_initcall(mxs_add_mxs_gpio);
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
index bef9d923f54e..b33c9d05c552 100644
--- a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
+++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
@@ -17,8 +17,9 @@
17#include <mach/mx28.h> 17#include <mach/mx28.h>
18#include <mach/devices-common.h> 18#include <mach/devices-common.h>
19 19
20#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid) \ 20#define mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid) \
21 { \ 21 { \
22 .devid = _devid, \
22 .id = _id, \ 23 .id = _id, \
23 .iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \ 24 .iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \
24 .dma = soc ## _DMA_SSP ## hwid, \ 25 .dma = soc ## _DMA_SSP ## hwid, \
@@ -26,23 +27,23 @@
26 .irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \ 27 .irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \
27 } 28 }
28 29
29#define mxs_mxs_mmc_data_entry(soc, _id, hwid) \ 30#define mxs_mxs_mmc_data_entry(soc, _devid, _id, hwid) \
30 [_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid) 31 [_id] = mxs_mxs_mmc_data_entry_single(soc, _devid, _id, hwid)
31 32
32 33
33#ifdef CONFIG_SOC_IMX23 34#ifdef CONFIG_SOC_IMX23
34const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = { 35const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
35 mxs_mxs_mmc_data_entry(MX23, 0, 1), 36 mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 0, 1),
36 mxs_mxs_mmc_data_entry(MX23, 1, 2), 37 mxs_mxs_mmc_data_entry(MX23, "imx23-mmc", 1, 2),
37}; 38};
38#endif 39#endif
39 40
40#ifdef CONFIG_SOC_IMX28 41#ifdef CONFIG_SOC_IMX28
41const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = { 42const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
42 mxs_mxs_mmc_data_entry(MX28, 0, 0), 43 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 0, 0),
43 mxs_mxs_mmc_data_entry(MX28, 1, 1), 44 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 1, 1),
44 mxs_mxs_mmc_data_entry(MX28, 2, 2), 45 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 2, 2),
45 mxs_mxs_mmc_data_entry(MX28, 3, 3), 46 mxs_mxs_mmc_data_entry(MX28, "imx28-mmc", 3, 3),
46}; 47};
47#endif 48#endif
48 49
@@ -70,6 +71,6 @@ struct platform_device *__init mxs_add_mxs_mmc(
70 }, 71 },
71 }; 72 };
72 73
73 return mxs_add_platform_device("mxs-mmc", data->id, 74 return mxs_add_platform_device(data->devid, data->id,
74 res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); 75 res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
75} 76}
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
deleted file mode 100644
index 592c9ab5d760..000000000000
--- a/arch/arm/mach-mxs/include/mach/clock.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#ifndef __MACH_MXS_CLOCK_H__
21#define __MACH_MXS_CLOCK_H__
22
23#ifndef __ASSEMBLY__
24#include <linux/list.h>
25
26struct module;
27
28struct clk {
29 int id;
30 /* Source clock this clk depends on */
31 struct clk *parent;
32 /* Reference count of clock enable/disable */
33 __s8 usecount;
34 /* Register bit position for clock's enable/disable control. */
35 u8 enable_shift;
36 /* Register address for clock's enable/disable control. */
37 void __iomem *enable_reg;
38 u32 flags;
39 /* get the current clock rate (always a fresh value) */
40 unsigned long (*get_rate) (struct clk *);
41 /* Function ptr to set the clock to a new rate. The rate must match a
42 supported rate returned from round_rate. Leave blank if clock is not
43 programmable */
44 int (*set_rate) (struct clk *, unsigned long);
45 /* Function ptr to round the requested clock rate to the nearest
46 supported rate that is less than or equal to the requested rate. */
47 unsigned long (*round_rate) (struct clk *, unsigned long);
48 /* Function ptr to enable the clock. Leave blank if clock can not
49 be gated. */
50 int (*enable) (struct clk *);
51 /* Function ptr to disable the clock. Leave blank if clock can not
52 be gated. */
53 void (*disable) (struct clk *);
54 /* Function ptr to set the parent clock of the clock. */
55 int (*set_parent) (struct clk *, struct clk *);
56};
57
58int clk_register(struct clk *clk);
59void clk_unregister(struct clk *clk);
60
61#endif /* __ASSEMBLY__ */
62#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index c50c3ea28a9d..de6c7ba42544 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -11,26 +11,27 @@
11#ifndef __MACH_MXS_COMMON_H__ 11#ifndef __MACH_MXS_COMMON_H__
12#define __MACH_MXS_COMMON_H__ 12#define __MACH_MXS_COMMON_H__
13 13
14struct clk;
15
16extern const u32 *mxs_get_ocotp(void); 14extern const u32 *mxs_get_ocotp(void);
17extern int mxs_reset_block(void __iomem *); 15extern int mxs_reset_block(void __iomem *);
18extern void mxs_timer_init(struct clk *, int); 16extern void mxs_timer_init(int);
19extern void mxs_restart(char, const char *); 17extern void mxs_restart(char, const char *);
20extern int mxs_saif_clkmux_select(unsigned int clkmux); 18extern int mxs_saif_clkmux_select(unsigned int clkmux);
21 19
22extern int mx23_register_gpios(void); 20extern void mx23_soc_init(void);
23extern int mx23_clocks_init(void); 21extern int mx23_clocks_init(void);
24extern void mx23_map_io(void); 22extern void mx23_map_io(void);
25extern void mx23_init_irq(void); 23extern void mx23_init_irq(void);
26 24
27extern int mx28_register_gpios(void); 25extern void mx28_soc_init(void);
28extern int mx28_clocks_init(void); 26extern int mx28_clocks_init(void);
29extern void mx28_map_io(void); 27extern void mx28_map_io(void);
30extern void mx28_init_irq(void); 28extern void mx28_init_irq(void);
31 29
32extern void icoll_init_irq(void); 30extern void icoll_init_irq(void);
33 31
34extern int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask); 32extern struct platform_device *mxs_add_dma(const char *devid,
33 resource_size_t base);
34extern struct platform_device *mxs_add_gpio(char *name, int id,
35 resource_size_t iobase, int irq);
35 36
36#endif /* __MACH_MXS_COMMON_H__ */ 37#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index f2e383955d88..6fc060151979 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -87,8 +87,9 @@ struct platform_device * __init mxs_add_mxs_i2c(
87 const struct mxs_mxs_i2c_data *data); 87 const struct mxs_mxs_i2c_data *data);
88 88
89/* mmc */ 89/* mmc */
90#include <mach/mmc.h> 90#include <linux/mmc/mxs-mmc.h>
91struct mxs_mxs_mmc_data { 91struct mxs_mxs_mmc_data {
92 const char *devid;
92 int id; 93 int id;
93 resource_size_t iobase; 94 resource_size_t iobase;
94 resource_size_t dma; 95 resource_size_t dma;
diff --git a/arch/arm/mach-mxs/mach-apx4devkit.c b/arch/arm/mach-mxs/mach-apx4devkit.c
index 48a7fab571a6..5e90b9dcdef8 100644
--- a/arch/arm/mach-mxs/mach-apx4devkit.c
+++ b/arch/arm/mach-mxs/mach-apx4devkit.c
@@ -207,6 +207,8 @@ static int apx4devkit_phy_fixup(struct phy_device *phy)
207 207
208static void __init apx4devkit_init(void) 208static void __init apx4devkit_init(void)
209{ 209{
210 mx28_soc_init();
211
210 mxs_iomux_setup_multiple_pads(apx4devkit_pads, 212 mxs_iomux_setup_multiple_pads(apx4devkit_pads,
211 ARRAY_SIZE(apx4devkit_pads)); 213 ARRAY_SIZE(apx4devkit_pads));
212 214
diff --git a/arch/arm/mach-mxs/mach-m28evk.c b/arch/arm/mach-mxs/mach-m28evk.c
index 06d79963611c..4c00c879b893 100644
--- a/arch/arm/mach-mxs/mach-m28evk.c
+++ b/arch/arm/mach-mxs/mach-m28evk.c
@@ -319,6 +319,8 @@ static struct mxs_mmc_platform_data m28evk_mmc_pdata[] __initdata = {
319 319
320static void __init m28evk_init(void) 320static void __init m28evk_init(void)
321{ 321{
322 mx28_soc_init();
323
322 mxs_iomux_setup_multiple_pads(m28evk_pads, ARRAY_SIZE(m28evk_pads)); 324 mxs_iomux_setup_multiple_pads(m28evk_pads, ARRAY_SIZE(m28evk_pads));
323 325
324 mx28_add_duart(); 326 mx28_add_duart();
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
index 5ea1c57d2606..e7272a41939d 100644
--- a/arch/arm/mach-mxs/mach-mx23evk.c
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -141,6 +141,8 @@ static void __init mx23evk_init(void)
141{ 141{
142 int ret; 142 int ret;
143 143
144 mx23_soc_init();
145
144 mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads)); 146 mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
145 147
146 mx23_add_duart(); 148 mx23_add_duart();
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index e386c142f93c..dafd48e86c8c 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -226,7 +226,7 @@ static void __init mx28evk_fec_reset(void)
226 struct clk *clk; 226 struct clk *clk;
227 227
228 /* Enable fec phy clock */ 228 /* Enable fec phy clock */
229 clk = clk_get_sys("pll2", NULL); 229 clk = clk_get_sys("enet_out", NULL);
230 if (!IS_ERR(clk)) 230 if (!IS_ERR(clk))
231 clk_prepare_enable(clk); 231 clk_prepare_enable(clk);
232 232
@@ -413,6 +413,8 @@ static void __init mx28evk_init(void)
413{ 413{
414 int ret; 414 int ret;
415 415
416 mx28_soc_init();
417
416 mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads)); 418 mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
417 419
418 mx28_add_duart(); 420 mx28_add_duart();
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
new file mode 100644
index 000000000000..8cac94b33020
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -0,0 +1,121 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/clk.h>
14#include <linux/clkdev.h>
15#include <linux/err.h>
16#include <linux/init.h>
17#include <linux/init.h>
18#include <linux/irqdomain.h>
19#include <linux/of_irq.h>
20#include <linux/of_platform.h>
21#include <asm/mach/arch.h>
22#include <asm/mach/time.h>
23#include <mach/common.h>
24
25static int __init mxs_icoll_add_irq_domain(struct device_node *np,
26 struct device_node *interrupt_parent)
27{
28 irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
29
30 return 0;
31}
32
33static int __init mxs_gpio_add_irq_domain(struct device_node *np,
34 struct device_node *interrupt_parent)
35{
36 static int gpio_irq_base = MXS_GPIO_IRQ_START;
37
38 irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
39 gpio_irq_base += 32;
40
41 return 0;
42}
43
44static const struct of_device_id mxs_irq_match[] __initconst = {
45 { .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, },
46 { .compatible = "fsl,mxs-gpio", .data = mxs_gpio_add_irq_domain, },
47 { /* sentinel */ }
48};
49
50static void __init mxs_dt_init_irq(void)
51{
52 icoll_init_irq();
53 of_irq_init(mxs_irq_match);
54}
55
56static void __init imx23_timer_init(void)
57{
58 mx23_clocks_init();
59}
60
61static struct sys_timer imx23_timer = {
62 .init = imx23_timer_init,
63};
64
65static void __init imx28_timer_init(void)
66{
67 mx28_clocks_init();
68}
69
70static struct sys_timer imx28_timer = {
71 .init = imx28_timer_init,
72};
73
74static void __init imx28_evk_init(void)
75{
76 struct clk *clk;
77
78 /* Enable fec phy clock */
79 clk = clk_get_sys("enet_out", NULL);
80 if (!IS_ERR(clk))
81 clk_prepare_enable(clk);
82}
83
84static void __init mxs_machine_init(void)
85{
86 if (of_machine_is_compatible("fsl,imx28-evk"))
87 imx28_evk_init();
88
89 of_platform_populate(NULL, of_default_bus_match_table,
90 NULL, NULL);
91}
92
93static const char *imx23_dt_compat[] __initdata = {
94 "fsl,imx23-evk",
95 "fsl,imx23",
96 NULL,
97};
98
99static const char *imx28_dt_compat[] __initdata = {
100 "fsl,imx28-evk",
101 "fsl,imx28",
102 NULL,
103};
104
105DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)")
106 .map_io = mx23_map_io,
107 .init_irq = mxs_dt_init_irq,
108 .timer = &imx23_timer,
109 .init_machine = mxs_machine_init,
110 .dt_compat = imx23_dt_compat,
111 .restart = mxs_restart,
112MACHINE_END
113
114DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)")
115 .map_io = mx28_map_io,
116 .init_irq = mxs_dt_init_irq,
117 .timer = &imx28_timer,
118 .init_machine = mxs_machine_init,
119 .dt_compat = imx28_dt_compat,
120 .restart = mxs_restart,
121MACHINE_END
diff --git a/arch/arm/mach-mxs/mach-stmp378x_devb.c b/arch/arm/mach-mxs/mach-stmp378x_devb.c
index a626c07b8713..6548965e4a76 100644
--- a/arch/arm/mach-mxs/mach-stmp378x_devb.c
+++ b/arch/arm/mach-mxs/mach-stmp378x_devb.c
@@ -85,6 +85,8 @@ static void __init stmp378x_dvb_init(void)
85{ 85{
86 int ret; 86 int ret;
87 87
88 mx23_soc_init();
89
88 mxs_iomux_setup_multiple_pads(stmp378x_dvb_pads, 90 mxs_iomux_setup_multiple_pads(stmp378x_dvb_pads,
89 ARRAY_SIZE(stmp378x_dvb_pads)); 91 ARRAY_SIZE(stmp378x_dvb_pads));
90 92
diff --git a/arch/arm/mach-mxs/mach-tx28.c b/arch/arm/mach-mxs/mach-tx28.c
index 2c0862e655ee..8837029de1a4 100644
--- a/arch/arm/mach-mxs/mach-tx28.c
+++ b/arch/arm/mach-mxs/mach-tx28.c
@@ -146,6 +146,8 @@ static struct mxs_mmc_platform_data tx28_mmc0_pdata __initdata = {
146 146
147static void __init tx28_stk5v3_init(void) 147static void __init tx28_stk5v3_init(void)
148{ 148{
149 mx28_soc_init();
150
149 mxs_iomux_setup_multiple_pads(tx28_stk5v3_pads, 151 mxs_iomux_setup_multiple_pads(tx28_stk5v3_pads,
150 ARRAY_SIZE(tx28_stk5v3_pads)); 152 ARRAY_SIZE(tx28_stk5v3_pads));
151 153
diff --git a/arch/arm/mach-mxs/mm.c b/arch/arm/mach-mxs/mm.c
index 50af5ceebf6d..dccb67a9e7c4 100644
--- a/arch/arm/mach-mxs/mm.c
+++ b/arch/arm/mach-mxs/mm.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/pinctrl/machine.h>
16 17
17#include <asm/mach/map.h> 18#include <asm/mach/map.h>
18 19
@@ -61,3 +62,29 @@ void __init mx28_init_irq(void)
61{ 62{
62 icoll_init_irq(); 63 icoll_init_irq();
63} 64}
65
66void __init mx23_soc_init(void)
67{
68 pinctrl_provide_dummies();
69
70 mxs_add_dma("imx23-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
71 mxs_add_dma("imx23-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
72
73 mxs_add_gpio("imx23-gpio", 0, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO0);
74 mxs_add_gpio("imx23-gpio", 1, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO1);
75 mxs_add_gpio("imx23-gpio", 2, MX23_PINCTRL_BASE_ADDR, MX23_INT_GPIO2);
76}
77
78void __init mx28_soc_init(void)
79{
80 pinctrl_provide_dummies();
81
82 mxs_add_dma("imx28-dma-apbh", MX23_APBH_DMA_BASE_ADDR);
83 mxs_add_dma("imx28-dma-apbx", MX23_APBX_DMA_BASE_ADDR);
84
85 mxs_add_gpio("imx28-gpio", 0, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO0);
86 mxs_add_gpio("imx28-gpio", 1, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO1);
87 mxs_add_gpio("imx28-gpio", 2, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO2);
88 mxs_add_gpio("imx28-gpio", 3, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO3);
89 mxs_add_gpio("imx28-gpio", 4, MX28_PINCTRL_BASE_ADDR, MX28_INT_GPIO4);
90}
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
deleted file mode 100644
index 0ea5c9d0e2b2..000000000000
--- a/arch/arm/mach-mxs/regs-clkctrl-mx23.h
+++ /dev/null
@@ -1,331 +0,0 @@
1/*
2 * Freescale CLKCTRL Register Definitions
3 *
4 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
5 * Copyright 2008-2010 Freescale Semiconductor, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This file is created by xml file. Don't Edit it.
22 *
23 * Xml Revision: 1.48
24 * Template revision: 26195
25 */
26
27#ifndef __REGS_CLKCTRL_MX23_H__
28#define __REGS_CLKCTRL_MX23_H__
29
30
31#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
32#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
33#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
34#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
35
36#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
37#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
38#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
39 (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
40#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
41#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
42#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
43#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
44#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
45#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
46#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
47 (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
48#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
49#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
50#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
51#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
52#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
53#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
54#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
55 (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
56#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
57#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
58#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
59#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
60#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
61#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
62
63#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
64
65#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
66#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
67#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
68#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
69#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
70 (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
71
72#define HW_CLKCTRL_CPU (0x00000020)
73#define HW_CLKCTRL_CPU_SET (0x00000024)
74#define HW_CLKCTRL_CPU_CLR (0x00000028)
75#define HW_CLKCTRL_CPU_TOG (0x0000002c)
76
77#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
78#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
79#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
80#define BP_CLKCTRL_CPU_DIV_XTAL 16
81#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
82#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
83 (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
84#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
85#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
86#define BP_CLKCTRL_CPU_DIV_CPU 0
87#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
88#define BF_CLKCTRL_CPU_DIV_CPU(v) \
89 (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
90
91#define HW_CLKCTRL_HBUS (0x00000030)
92#define HW_CLKCTRL_HBUS_SET (0x00000034)
93#define HW_CLKCTRL_HBUS_CLR (0x00000038)
94#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
95
96#define BM_CLKCTRL_HBUS_BUSY 0x20000000
97#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
98#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000
99#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
100#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
101#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
102#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
103#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
104#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
105#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000
106#define BP_CLKCTRL_HBUS_SLOW_DIV 16
107#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
108#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
109 (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
110#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
111#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
112#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
113#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
114#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
115#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
116#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
117#define BP_CLKCTRL_HBUS_DIV 0
118#define BM_CLKCTRL_HBUS_DIV 0x0000001F
119#define BF_CLKCTRL_HBUS_DIV(v) \
120 (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
121
122#define HW_CLKCTRL_XBUS (0x00000040)
123
124#define BM_CLKCTRL_XBUS_BUSY 0x80000000
125#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
126#define BP_CLKCTRL_XBUS_DIV 0
127#define BM_CLKCTRL_XBUS_DIV 0x000003FF
128#define BF_CLKCTRL_XBUS_DIV(v) \
129 (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
130
131#define HW_CLKCTRL_XTAL (0x00000050)
132#define HW_CLKCTRL_XTAL_SET (0x00000054)
133#define HW_CLKCTRL_XTAL_CLR (0x00000058)
134#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
135
136#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
137#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
138#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
139#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
140#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
141#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
142#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
143#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
144#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
145#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
146#define BP_CLKCTRL_XTAL_DIV_UART 0
147#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
148#define BF_CLKCTRL_XTAL_DIV_UART(v) \
149 (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
150
151#define HW_CLKCTRL_PIX (0x00000060)
152
153#define BP_CLKCTRL_PIX_CLKGATE 31
154#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
155#define BM_CLKCTRL_PIX_BUSY 0x20000000
156#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
157#define BP_CLKCTRL_PIX_DIV 0
158#define BM_CLKCTRL_PIX_DIV 0x00000FFF
159#define BF_CLKCTRL_PIX_DIV(v) \
160 (((v) << 0) & BM_CLKCTRL_PIX_DIV)
161
162#define HW_CLKCTRL_SSP (0x00000070)
163
164#define BP_CLKCTRL_SSP_CLKGATE 31
165#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
166#define BM_CLKCTRL_SSP_BUSY 0x20000000
167#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
168#define BP_CLKCTRL_SSP_DIV 0
169#define BM_CLKCTRL_SSP_DIV 0x000001FF
170#define BF_CLKCTRL_SSP_DIV(v) \
171 (((v) << 0) & BM_CLKCTRL_SSP_DIV)
172
173#define HW_CLKCTRL_GPMI (0x00000080)
174
175#define BP_CLKCTRL_GPMI_CLKGATE 31
176#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
177#define BM_CLKCTRL_GPMI_BUSY 0x20000000
178#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
179#define BP_CLKCTRL_GPMI_DIV 0
180#define BM_CLKCTRL_GPMI_DIV 0x000003FF
181#define BF_CLKCTRL_GPMI_DIV(v) \
182 (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
183
184#define HW_CLKCTRL_SPDIF (0x00000090)
185
186#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
187
188#define HW_CLKCTRL_EMI (0x000000a0)
189
190#define BP_CLKCTRL_EMI_CLKGATE 31
191#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
192#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
193#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
194#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
195#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
196#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
197#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
198#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
199#define BP_CLKCTRL_EMI_DIV_XTAL 8
200#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
201#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
202 (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
203#define BP_CLKCTRL_EMI_DIV_EMI 0
204#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
205#define BF_CLKCTRL_EMI_DIV_EMI(v) \
206 (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
207
208#define HW_CLKCTRL_IR (0x000000b0)
209
210#define BM_CLKCTRL_IR_CLKGATE 0x80000000
211#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
212#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
213#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
214#define BP_CLKCTRL_IR_IROV_DIV 16
215#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
216#define BF_CLKCTRL_IR_IROV_DIV(v) \
217 (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
218#define BP_CLKCTRL_IR_IR_DIV 0
219#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
220#define BF_CLKCTRL_IR_IR_DIV(v) \
221 (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
222
223#define HW_CLKCTRL_SAIF (0x000000c0)
224
225#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
226#define BM_CLKCTRL_SAIF_BUSY 0x20000000
227#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
228#define BP_CLKCTRL_SAIF_DIV 0
229#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
230#define BF_CLKCTRL_SAIF_DIV(v) \
231 (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
232
233#define HW_CLKCTRL_TV (0x000000d0)
234
235#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
236#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
237
238#define HW_CLKCTRL_ETM (0x000000e0)
239
240#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
241#define BM_CLKCTRL_ETM_BUSY 0x20000000
242#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
243#define BP_CLKCTRL_ETM_DIV 0
244#define BM_CLKCTRL_ETM_DIV 0x0000003F
245#define BF_CLKCTRL_ETM_DIV(v) \
246 (((v) << 0) & BM_CLKCTRL_ETM_DIV)
247
248#define HW_CLKCTRL_FRAC (0x000000f0)
249#define HW_CLKCTRL_FRAC_SET (0x000000f4)
250#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
251#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
252
253#define BP_CLKCTRL_FRAC_CLKGATEIO 31
254#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
255#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
256#define BP_CLKCTRL_FRAC_IOFRAC 24
257#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
258#define BF_CLKCTRL_FRAC_IOFRAC(v) \
259 (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
260#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
261#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
262#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
263#define BP_CLKCTRL_FRAC_PIXFRAC 16
264#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
265#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
266 (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
267#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
268#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
269#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
270#define BP_CLKCTRL_FRAC_EMIFRAC 8
271#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
272#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
273 (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
274#define BP_CLKCTRL_FRAC_CLKGATECPU 7
275#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
276#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
277#define BP_CLKCTRL_FRAC_CPUFRAC 0
278#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
279#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
280 (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
281
282#define HW_CLKCTRL_FRAC1 (0x00000100)
283#define HW_CLKCTRL_FRAC1_SET (0x00000104)
284#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
285#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
286
287#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
288#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
289
290#define HW_CLKCTRL_CLKSEQ (0x00000110)
291#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
292#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
293#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
294
295#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
296#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
297#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
298#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
299#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
300#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
301#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
302#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
303
304#define HW_CLKCTRL_RESET (0x00000120)
305
306#define BM_CLKCTRL_RESET_CHIP 0x00000002
307#define BM_CLKCTRL_RESET_DIG 0x00000001
308
309#define HW_CLKCTRL_STATUS (0x00000130)
310
311#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
312#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
313#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
314 (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
315
316#define HW_CLKCTRL_VERSION (0x00000140)
317
318#define BP_CLKCTRL_VERSION_MAJOR 24
319#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
320#define BF_CLKCTRL_VERSION_MAJOR(v) \
321 (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
322#define BP_CLKCTRL_VERSION_MINOR 16
323#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
324#define BF_CLKCTRL_VERSION_MINOR(v) \
325 (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
326#define BP_CLKCTRL_VERSION_STEP 0
327#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
328#define BF_CLKCTRL_VERSION_STEP(v) \
329 (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
330
331#endif /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
deleted file mode 100644
index 7d1b061d7943..000000000000
--- a/arch/arm/mach-mxs/regs-clkctrl-mx28.h
+++ /dev/null
@@ -1,486 +0,0 @@
1/*
2 * Freescale CLKCTRL Register Definitions
3 *
4 * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * This file is created by xml file. Don't Edit it.
21 *
22 * Xml Revision: 1.48
23 * Template revision: 26195
24 */
25
26#ifndef __REGS_CLKCTRL_MX28_H__
27#define __REGS_CLKCTRL_MX28_H__
28
29#define HW_CLKCTRL_PLL0CTRL0 (0x00000000)
30#define HW_CLKCTRL_PLL0CTRL0_SET (0x00000004)
31#define HW_CLKCTRL_PLL0CTRL0_CLR (0x00000008)
32#define HW_CLKCTRL_PLL0CTRL0_TOG (0x0000000c)
33
34#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL 28
35#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL 0x30000000
36#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v) \
37 (((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
38#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT 0x0
39#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2 0x1
40#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05 0x2
41#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
42#define BP_CLKCTRL_PLL0CTRL0_CP_SEL 24
43#define BM_CLKCTRL_PLL0CTRL0_CP_SEL 0x03000000
44#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v) \
45 (((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
46#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT 0x0
47#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2 0x1
48#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05 0x2
49#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
50#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL 20
51#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL 0x00300000
52#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v) \
53 (((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
54#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT 0x0
55#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER 0x1
56#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST 0x2
57#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
58#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS 0x00040000
59#define BM_CLKCTRL_PLL0CTRL0_POWER 0x00020000
60
61#define HW_CLKCTRL_PLL0CTRL1 (0x00000010)
62
63#define BM_CLKCTRL_PLL0CTRL1_LOCK 0x80000000
64#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK 0x40000000
65#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0
66#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0x0000FFFF
67#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v) \
68 (((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
69
70#define HW_CLKCTRL_PLL1CTRL0 (0x00000020)
71#define HW_CLKCTRL_PLL1CTRL0_SET (0x00000024)
72#define HW_CLKCTRL_PLL1CTRL0_CLR (0x00000028)
73#define HW_CLKCTRL_PLL1CTRL0_TOG (0x0000002c)
74
75#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI 0x80000000
76#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL 28
77#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL 0x30000000
78#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v) \
79 (((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
80#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT 0x0
81#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2 0x1
82#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05 0x2
83#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
84#define BP_CLKCTRL_PLL1CTRL0_CP_SEL 24
85#define BM_CLKCTRL_PLL1CTRL0_CP_SEL 0x03000000
86#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v) \
87 (((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
88#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT 0x0
89#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2 0x1
90#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05 0x2
91#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
92#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL 20
93#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL 0x00300000
94#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v) \
95 (((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
96#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT 0x0
97#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER 0x1
98#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST 0x2
99#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
100#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS 0x00040000
101#define BM_CLKCTRL_PLL1CTRL0_POWER 0x00020000
102
103#define HW_CLKCTRL_PLL1CTRL1 (0x00000030)
104
105#define BM_CLKCTRL_PLL1CTRL1_LOCK 0x80000000
106#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK 0x40000000
107#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0
108#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0x0000FFFF
109#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v) \
110 (((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
111
112#define HW_CLKCTRL_PLL2CTRL0 (0x00000040)
113#define HW_CLKCTRL_PLL2CTRL0_SET (0x00000044)
114#define HW_CLKCTRL_PLL2CTRL0_CLR (0x00000048)
115#define HW_CLKCTRL_PLL2CTRL0_TOG (0x0000004c)
116
117#define BM_CLKCTRL_PLL2CTRL0_CLKGATE 0x80000000
118#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL 28
119#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL 0x30000000
120#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v) \
121 (((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
122#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B 0x04000000
123#define BP_CLKCTRL_PLL2CTRL0_CP_SEL 24
124#define BM_CLKCTRL_PLL2CTRL0_CP_SEL 0x03000000
125#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v) \
126 (((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
127#define BM_CLKCTRL_PLL2CTRL0_POWER 0x00800000
128
129#define HW_CLKCTRL_CPU (0x00000050)
130#define HW_CLKCTRL_CPU_SET (0x00000054)
131#define HW_CLKCTRL_CPU_CLR (0x00000058)
132#define HW_CLKCTRL_CPU_TOG (0x0000005c)
133
134#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
135#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
136#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
137#define BP_CLKCTRL_CPU_DIV_XTAL 16
138#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
139#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
140 (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
141#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
142#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
143#define BP_CLKCTRL_CPU_DIV_CPU 0
144#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
145#define BF_CLKCTRL_CPU_DIV_CPU(v) \
146 (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
147
148#define HW_CLKCTRL_HBUS (0x00000060)
149#define HW_CLKCTRL_HBUS_SET (0x00000064)
150#define HW_CLKCTRL_HBUS_CLR (0x00000068)
151#define HW_CLKCTRL_HBUS_TOG (0x0000006c)
152
153#define BM_CLKCTRL_HBUS_ASM_BUSY 0x80000000
154#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x40000000
155#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x20000000
156#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE 0x08000000
157#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
158#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
159#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
160#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
161#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
162#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
163#define BM_CLKCTRL_HBUS_ASM_ENABLE 0x00100000
164#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE 0x00080000
165#define BP_CLKCTRL_HBUS_SLOW_DIV 16
166#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
167#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
168 (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
169#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
170#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
171#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
172#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
173#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
174#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
175#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
176#define BP_CLKCTRL_HBUS_DIV 0
177#define BM_CLKCTRL_HBUS_DIV 0x0000001F
178#define BF_CLKCTRL_HBUS_DIV(v) \
179 (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
180
181#define HW_CLKCTRL_XBUS (0x00000070)
182
183#define BM_CLKCTRL_XBUS_BUSY 0x80000000
184#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE 0x00000800
185#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
186#define BP_CLKCTRL_XBUS_DIV 0
187#define BM_CLKCTRL_XBUS_DIV 0x000003FF
188#define BF_CLKCTRL_XBUS_DIV(v) \
189 (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
190
191#define HW_CLKCTRL_XTAL (0x00000080)
192#define HW_CLKCTRL_XTAL_SET (0x00000084)
193#define HW_CLKCTRL_XTAL_CLR (0x00000088)
194#define HW_CLKCTRL_XTAL_TOG (0x0000008c)
195
196#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
197#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
198#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
199#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
200#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
201#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
202#define BP_CLKCTRL_XTAL_DIV_UART 0
203#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
204#define BF_CLKCTRL_XTAL_DIV_UART(v) \
205 (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
206
207#define HW_CLKCTRL_SSP0 (0x00000090)
208
209#define BP_CLKCTRL_SSP0_CLKGATE 31
210#define BM_CLKCTRL_SSP0_CLKGATE 0x80000000
211#define BM_CLKCTRL_SSP0_BUSY 0x20000000
212#define BM_CLKCTRL_SSP0_DIV_FRAC_EN 0x00000200
213#define BP_CLKCTRL_SSP0_DIV 0
214#define BM_CLKCTRL_SSP0_DIV 0x000001FF
215#define BF_CLKCTRL_SSP0_DIV(v) \
216 (((v) << 0) & BM_CLKCTRL_SSP0_DIV)
217
218#define HW_CLKCTRL_SSP1 (0x000000a0)
219
220#define BP_CLKCTRL_SSP1_CLKGATE 31
221#define BM_CLKCTRL_SSP1_CLKGATE 0x80000000
222#define BM_CLKCTRL_SSP1_BUSY 0x20000000
223#define BM_CLKCTRL_SSP1_DIV_FRAC_EN 0x00000200
224#define BP_CLKCTRL_SSP1_DIV 0
225#define BM_CLKCTRL_SSP1_DIV 0x000001FF
226#define BF_CLKCTRL_SSP1_DIV(v) \
227 (((v) << 0) & BM_CLKCTRL_SSP1_DIV)
228
229#define HW_CLKCTRL_SSP2 (0x000000b0)
230
231#define BP_CLKCTRL_SSP2_CLKGATE 31
232#define BM_CLKCTRL_SSP2_CLKGATE 0x80000000
233#define BM_CLKCTRL_SSP2_BUSY 0x20000000
234#define BM_CLKCTRL_SSP2_DIV_FRAC_EN 0x00000200
235#define BP_CLKCTRL_SSP2_DIV 0
236#define BM_CLKCTRL_SSP2_DIV 0x000001FF
237#define BF_CLKCTRL_SSP2_DIV(v) \
238 (((v) << 0) & BM_CLKCTRL_SSP2_DIV)
239
240#define HW_CLKCTRL_SSP3 (0x000000c0)
241
242#define BP_CLKCTRL_SSP3_CLKGATE 31
243#define BM_CLKCTRL_SSP3_CLKGATE 0x80000000
244#define BM_CLKCTRL_SSP3_BUSY 0x20000000
245#define BM_CLKCTRL_SSP3_DIV_FRAC_EN 0x00000200
246#define BP_CLKCTRL_SSP3_DIV 0
247#define BM_CLKCTRL_SSP3_DIV 0x000001FF
248#define BF_CLKCTRL_SSP3_DIV(v) \
249 (((v) << 0) & BM_CLKCTRL_SSP3_DIV)
250
251#define HW_CLKCTRL_GPMI (0x000000d0)
252
253#define BP_CLKCTRL_GPMI_CLKGATE 31
254#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
255#define BM_CLKCTRL_GPMI_BUSY 0x20000000
256#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
257#define BP_CLKCTRL_GPMI_DIV 0
258#define BM_CLKCTRL_GPMI_DIV 0x000003FF
259#define BF_CLKCTRL_GPMI_DIV(v) \
260 (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
261
262#define HW_CLKCTRL_SPDIF (0x000000e0)
263
264#define BP_CLKCTRL_SPDIF_CLKGATE 31
265#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
266
267#define HW_CLKCTRL_EMI (0x000000f0)
268
269#define BP_CLKCTRL_EMI_CLKGATE 31
270#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
271#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
272#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
273#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
274#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
275#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
276#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
277#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
278#define BP_CLKCTRL_EMI_DIV_XTAL 8
279#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
280#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
281 (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
282#define BP_CLKCTRL_EMI_DIV_EMI 0
283#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
284#define BF_CLKCTRL_EMI_DIV_EMI(v) \
285 (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
286
287#define HW_CLKCTRL_SAIF0 (0x00000100)
288
289#define BP_CLKCTRL_SAIF0_CLKGATE 31
290#define BM_CLKCTRL_SAIF0_CLKGATE 0x80000000
291#define BM_CLKCTRL_SAIF0_BUSY 0x20000000
292#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN 0x00010000
293#define BP_CLKCTRL_SAIF0_DIV 0
294#define BM_CLKCTRL_SAIF0_DIV 0x0000FFFF
295#define BF_CLKCTRL_SAIF0_DIV(v) \
296 (((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
297
298#define HW_CLKCTRL_SAIF1 (0x00000110)
299
300#define BP_CLKCTRL_SAIF1_CLKGATE 31
301#define BM_CLKCTRL_SAIF1_CLKGATE 0x80000000
302#define BM_CLKCTRL_SAIF1_BUSY 0x20000000
303#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN 0x00010000
304#define BP_CLKCTRL_SAIF1_DIV 0
305#define BM_CLKCTRL_SAIF1_DIV 0x0000FFFF
306#define BF_CLKCTRL_SAIF1_DIV(v) \
307 (((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
308
309#define HW_CLKCTRL_DIS_LCDIF (0x00000120)
310
311#define BP_CLKCTRL_DIS_LCDIF_CLKGATE 31
312#define BM_CLKCTRL_DIS_LCDIF_CLKGATE 0x80000000
313#define BM_CLKCTRL_DIS_LCDIF_BUSY 0x20000000
314#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN 0x00002000
315#define BP_CLKCTRL_DIS_LCDIF_DIV 0
316#define BM_CLKCTRL_DIS_LCDIF_DIV 0x00001FFF
317#define BF_CLKCTRL_DIS_LCDIF_DIV(v) \
318 (((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
319
320#define HW_CLKCTRL_ETM (0x00000130)
321
322#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
323#define BM_CLKCTRL_ETM_BUSY 0x20000000
324#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000080
325#define BP_CLKCTRL_ETM_DIV 0
326#define BM_CLKCTRL_ETM_DIV 0x0000007F
327#define BF_CLKCTRL_ETM_DIV(v) \
328 (((v) << 0) & BM_CLKCTRL_ETM_DIV)
329
330#define HW_CLKCTRL_ENET (0x00000140)
331
332#define BM_CLKCTRL_ENET_SLEEP 0x80000000
333#define BP_CLKCTRL_ENET_DISABLE 30
334#define BM_CLKCTRL_ENET_DISABLE 0x40000000
335#define BM_CLKCTRL_ENET_STATUS 0x20000000
336#define BM_CLKCTRL_ENET_BUSY_TIME 0x08000000
337#define BP_CLKCTRL_ENET_DIV_TIME 21
338#define BM_CLKCTRL_ENET_DIV_TIME 0x07E00000
339#define BF_CLKCTRL_ENET_DIV_TIME(v) \
340 (((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
341#define BM_CLKCTRL_ENET_BUSY 0x08000000
342#define BP_CLKCTRL_ENET_DIV 21
343#define BM_CLKCTRL_ENET_DIV 0x07E00000
344#define BF_CLKCTRL_ENET_DIV(v) \
345 (((v) << 21) & BM_CLKCTRL_ENET_DIV)
346#define BP_CLKCTRL_ENET_TIME_SEL 19
347#define BM_CLKCTRL_ENET_TIME_SEL 0x00180000
348#define BF_CLKCTRL_ENET_TIME_SEL(v) \
349 (((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
350#define BV_CLKCTRL_ENET_TIME_SEL__XTAL 0x0
351#define BV_CLKCTRL_ENET_TIME_SEL__PLL 0x1
352#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK 0x2
353#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
354#define BM_CLKCTRL_ENET_CLK_OUT_EN 0x00040000
355#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP 0x00020000
356#define BM_CLKCTRL_ENET_RESET_BY_SW 0x00010000
357
358#define HW_CLKCTRL_HSADC (0x00000150)
359
360#define BM_CLKCTRL_HSADC_RESETB 0x40000000
361#define BP_CLKCTRL_HSADC_FREQDIV 28
362#define BM_CLKCTRL_HSADC_FREQDIV 0x30000000
363#define BF_CLKCTRL_HSADC_FREQDIV(v) \
364 (((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
365
366#define HW_CLKCTRL_FLEXCAN (0x00000160)
367
368#define BP_CLKCTRL_FLEXCAN_STOP_CAN0 30
369#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
370#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS 0x20000000
371#define BP_CLKCTRL_FLEXCAN_STOP_CAN1 28
372#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
373#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS 0x08000000
374
375#define HW_CLKCTRL_FRAC0 (0x000001b0)
376#define HW_CLKCTRL_FRAC0_SET (0x000001b4)
377#define HW_CLKCTRL_FRAC0_CLR (0x000001b8)
378#define HW_CLKCTRL_FRAC0_TOG (0x000001bc)
379
380#define BP_CLKCTRL_FRAC0_CLKGATEIO0 31
381#define BM_CLKCTRL_FRAC0_CLKGATEIO0 0x80000000
382#define BM_CLKCTRL_FRAC0_IO0_STABLE 0x40000000
383#define BP_CLKCTRL_FRAC0_IO0FRAC 24
384#define BM_CLKCTRL_FRAC0_IO0FRAC 0x3F000000
385#define BF_CLKCTRL_FRAC0_IO0FRAC(v) \
386 (((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
387#define BP_CLKCTRL_FRAC0_CLKGATEIO1 23
388#define BM_CLKCTRL_FRAC0_CLKGATEIO1 0x00800000
389#define BM_CLKCTRL_FRAC0_IO1_STABLE 0x00400000
390#define BP_CLKCTRL_FRAC0_IO1FRAC 16
391#define BM_CLKCTRL_FRAC0_IO1FRAC 0x003F0000
392#define BF_CLKCTRL_FRAC0_IO1FRAC(v) \
393 (((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
394#define BP_CLKCTRL_FRAC0_CLKGATEEMI 15
395#define BM_CLKCTRL_FRAC0_CLKGATEEMI 0x00008000
396#define BM_CLKCTRL_FRAC0_EMI_STABLE 0x00004000
397#define BP_CLKCTRL_FRAC0_EMIFRAC 8
398#define BM_CLKCTRL_FRAC0_EMIFRAC 0x00003F00
399#define BF_CLKCTRL_FRAC0_EMIFRAC(v) \
400 (((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
401#define BP_CLKCTRL_FRAC0_CLKGATECPU 7
402#define BM_CLKCTRL_FRAC0_CLKGATECPU 0x00000080
403#define BM_CLKCTRL_FRAC0_CPU_STABLE 0x00000040
404#define BP_CLKCTRL_FRAC0_CPUFRAC 0
405#define BM_CLKCTRL_FRAC0_CPUFRAC 0x0000003F
406#define BF_CLKCTRL_FRAC0_CPUFRAC(v) \
407 (((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
408
409#define HW_CLKCTRL_FRAC1 (0x000001c0)
410#define HW_CLKCTRL_FRAC1_SET (0x000001c4)
411#define HW_CLKCTRL_FRAC1_CLR (0x000001c8)
412#define HW_CLKCTRL_FRAC1_TOG (0x000001cc)
413
414#define BP_CLKCTRL_FRAC1_CLKGATEGPMI 23
415#define BM_CLKCTRL_FRAC1_CLKGATEGPMI 0x00800000
416#define BM_CLKCTRL_FRAC1_GPMI_STABLE 0x00400000
417#define BP_CLKCTRL_FRAC1_GPMIFRAC 16
418#define BM_CLKCTRL_FRAC1_GPMIFRAC 0x003F0000
419#define BF_CLKCTRL_FRAC1_GPMIFRAC(v) \
420 (((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
421#define BP_CLKCTRL_FRAC1_CLKGATEHSADC 15
422#define BM_CLKCTRL_FRAC1_CLKGATEHSADC 0x00008000
423#define BM_CLKCTRL_FRAC1_HSADC_STABLE 0x00004000
424#define BP_CLKCTRL_FRAC1_HSADCFRAC 8
425#define BM_CLKCTRL_FRAC1_HSADCFRAC 0x00003F00
426#define BF_CLKCTRL_FRAC1_HSADCFRAC(v) \
427 (((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
428#define BP_CLKCTRL_FRAC1_CLKGATEPIX 7
429#define BM_CLKCTRL_FRAC1_CLKGATEPIX 0x00000080
430#define BM_CLKCTRL_FRAC1_PIX_STABLE 0x00000040
431#define BP_CLKCTRL_FRAC1_PIXFRAC 0
432#define BM_CLKCTRL_FRAC1_PIXFRAC 0x0000003F
433#define BF_CLKCTRL_FRAC1_PIXFRAC(v) \
434 (((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
435
436#define HW_CLKCTRL_CLKSEQ (0x000001d0)
437#define HW_CLKCTRL_CLKSEQ_SET (0x000001d4)
438#define HW_CLKCTRL_CLKSEQ_CLR (0x000001d8)
439#define HW_CLKCTRL_CLKSEQ_TOG (0x000001dc)
440
441#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00040000
442#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF 0x00004000
443#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
444#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD 0x0
445#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
446#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000080
447#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3 0x00000040
448#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2 0x00000020
449#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1 0x00000010
450#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0 0x00000008
451#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000004
452#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1 0x00000002
453#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0 0x00000001
454
455#define HW_CLKCTRL_RESET (0x000001e0)
456
457#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE 0x00000020
458#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE 0x00000010
459#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE 0x00000008
460#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT 0x00000004
461#define BM_CLKCTRL_RESET_CHIP 0x00000002
462#define BM_CLKCTRL_RESET_DIG 0x00000001
463
464#define HW_CLKCTRL_STATUS (0x000001f0)
465
466#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
467#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
468#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
469 (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
470
471#define HW_CLKCTRL_VERSION (0x00000200)
472
473#define BP_CLKCTRL_VERSION_MAJOR 24
474#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
475#define BF_CLKCTRL_VERSION_MAJOR(v) \
476 (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
477#define BP_CLKCTRL_VERSION_MINOR 16
478#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
479#define BF_CLKCTRL_VERSION_MINOR(v) \
480 (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
481#define BP_CLKCTRL_VERSION_STEP 0
482#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
483#define BF_CLKCTRL_VERSION_STEP(v) \
484 (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
485
486#endif /* __REGS_CLKCTRL_MX28_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index 80ac1fca8a00..30042e23bfa7 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -37,8 +37,6 @@
37#define MXS_MODULE_CLKGATE (1 << 30) 37#define MXS_MODULE_CLKGATE (1 << 30)
38#define MXS_MODULE_SFTRST (1 << 31) 38#define MXS_MODULE_SFTRST (1 << 31)
39 39
40#define CLKCTRL_TIMEOUT 10 /* 10 ms */
41
42static void __iomem *mxs_clkctrl_reset_addr; 40static void __iomem *mxs_clkctrl_reset_addr;
43 41
44/* 42/*
@@ -139,17 +137,3 @@ error:
139 return -ETIMEDOUT; 137 return -ETIMEDOUT;
140} 138}
141EXPORT_SYMBOL(mxs_reset_block); 139EXPORT_SYMBOL(mxs_reset_block);
142
143int mxs_clkctrl_timeout(unsigned int reg_offset, unsigned int mask)
144{
145 unsigned long timeout = jiffies + msecs_to_jiffies(CLKCTRL_TIMEOUT);
146 while (readl_relaxed(MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR)
147 + reg_offset) & mask) {
148 if (time_after(jiffies, timeout)) {
149 pr_err("Timeout at CLKCTRL + 0x%x\n", reg_offset);
150 return -ETIMEDOUT;
151 }
152 }
153
154 return 0;
155}
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index 564a63279f18..02d36de9c4e8 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -20,6 +20,7 @@
20 * MA 02110-1301, USA. 20 * MA 02110-1301, USA.
21 */ 21 */
22 22
23#include <linux/err.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24#include <linux/irq.h> 25#include <linux/irq.h>
25#include <linux/clockchips.h> 26#include <linux/clockchips.h>
@@ -243,8 +244,16 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
243 return 0; 244 return 0;
244} 245}
245 246
246void __init mxs_timer_init(struct clk *timer_clk, int irq) 247void __init mxs_timer_init(int irq)
247{ 248{
249 struct clk *timer_clk;
250
251 timer_clk = clk_get_sys("timrot", NULL);
252 if (IS_ERR(timer_clk)) {
253 pr_err("%s: failed to get clk\n", __func__);
254 return;
255 }
256
248 clk_prepare_enable(timer_clk); 257 clk_prepare_enable(timer_clk);
249 258
250 /* 259 /*
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 1f736bc11c4b..a576f5447d38 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -2,3 +2,5 @@
2obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o 2obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
3obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ 3obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \
4 clk-mux.o clk-divider.o 4 clk-mux.o clk-divider.o
5
6obj-$(CONFIG_ARCH_MXS) += mxs/
diff --git a/drivers/clk/mxs/Makefile b/drivers/clk/mxs/Makefile
new file mode 100644
index 000000000000..7bedeec08524
--- /dev/null
+++ b/drivers/clk/mxs/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for mxs specific clk
3#
4
5obj-y += clk.o clk-pll.o clk-ref.o clk-div.o clk-frac.o
6
7obj-$(CONFIG_SOC_IMX23) += clk-imx23.o
8obj-$(CONFIG_SOC_IMX28) += clk-imx28.o
diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c
new file mode 100644
index 000000000000..90e1da93877e
--- /dev/null
+++ b/drivers/clk/mxs/clk-div.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/slab.h>
16#include "clk.h"
17
18/**
19 * struct clk_div - mxs integer divider clock
20 * @divider: the parent class
21 * @ops: pointer to clk_ops of parent class
22 * @reg: register address
23 * @busy: busy bit shift
24 *
25 * The mxs divider clock is a subclass of basic clk_divider with an
26 * addtional busy bit.
27 */
28struct clk_div {
29 struct clk_divider divider;
30 const struct clk_ops *ops;
31 void __iomem *reg;
32 u8 busy;
33};
34
35static inline struct clk_div *to_clk_div(struct clk_hw *hw)
36{
37 struct clk_divider *divider = container_of(hw, struct clk_divider, hw);
38
39 return container_of(divider, struct clk_div, divider);
40}
41
42static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
43 unsigned long parent_rate)
44{
45 struct clk_div *div = to_clk_div(hw);
46
47 return div->ops->recalc_rate(&div->divider.hw, parent_rate);
48}
49
50static long clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
51 unsigned long *prate)
52{
53 struct clk_div *div = to_clk_div(hw);
54
55 return div->ops->round_rate(&div->divider.hw, rate, prate);
56}
57
58static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
59 unsigned long parent_rate)
60{
61 struct clk_div *div = to_clk_div(hw);
62 int ret;
63
64 ret = div->ops->set_rate(&div->divider.hw, rate, parent_rate);
65 if (!ret)
66 ret = mxs_clk_wait(div->reg, div->busy);
67
68 return ret;
69}
70
71static struct clk_ops clk_div_ops = {
72 .recalc_rate = clk_div_recalc_rate,
73 .round_rate = clk_div_round_rate,
74 .set_rate = clk_div_set_rate,
75};
76
77struct clk *mxs_clk_div(const char *name, const char *parent_name,
78 void __iomem *reg, u8 shift, u8 width, u8 busy)
79{
80 struct clk_div *div;
81 struct clk *clk;
82 struct clk_init_data init;
83
84 div = kzalloc(sizeof(*div), GFP_KERNEL);
85 if (!div)
86 return ERR_PTR(-ENOMEM);
87
88 init.name = name;
89 init.ops = &clk_div_ops;
90 init.flags = CLK_SET_RATE_PARENT;
91 init.parent_names = (parent_name ? &parent_name: NULL);
92 init.num_parents = (parent_name ? 1 : 0);
93
94 div->reg = reg;
95 div->busy = busy;
96
97 div->divider.reg = reg;
98 div->divider.shift = shift;
99 div->divider.width = width;
100 div->divider.flags = CLK_DIVIDER_ONE_BASED;
101 div->divider.lock = &mxs_lock;
102 div->divider.hw.init = &init;
103 div->ops = &clk_divider_ops;
104
105 clk = clk_register(NULL, &div->divider.hw);
106 if (IS_ERR(clk))
107 kfree(div);
108
109 return clk;
110}
diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c
new file mode 100644
index 000000000000..e6aa6b567d68
--- /dev/null
+++ b/drivers/clk/mxs/clk-frac.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include "clk.h"
18
19/**
20 * struct clk_frac - mxs fractional divider clock
21 * @hw: clk_hw for the fractional divider clock
22 * @reg: register address
23 * @shift: the divider bit shift
24 * @width: the divider bit width
25 * @busy: busy bit shift
26 *
27 * The clock is an adjustable fractional divider with a busy bit to wait
28 * when the divider is adjusted.
29 */
30struct clk_frac {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 shift;
34 u8 width;
35 u8 busy;
36};
37
38#define to_clk_frac(_hw) container_of(_hw, struct clk_frac, hw)
39
40static unsigned long clk_frac_recalc_rate(struct clk_hw *hw,
41 unsigned long parent_rate)
42{
43 struct clk_frac *frac = to_clk_frac(hw);
44 u32 div;
45
46 div = readl_relaxed(frac->reg) >> frac->shift;
47 div &= (1 << frac->width) - 1;
48
49 return (parent_rate >> frac->width) * div;
50}
51
52static long clk_frac_round_rate(struct clk_hw *hw, unsigned long rate,
53 unsigned long *prate)
54{
55 struct clk_frac *frac = to_clk_frac(hw);
56 unsigned long parent_rate = *prate;
57 u32 div;
58 u64 tmp;
59
60 if (rate > parent_rate)
61 return -EINVAL;
62
63 tmp = rate;
64 tmp <<= frac->width;
65 do_div(tmp, parent_rate);
66 div = tmp;
67
68 if (!div)
69 return -EINVAL;
70
71 return (parent_rate >> frac->width) * div;
72}
73
74static int clk_frac_set_rate(struct clk_hw *hw, unsigned long rate,
75 unsigned long parent_rate)
76{
77 struct clk_frac *frac = to_clk_frac(hw);
78 unsigned long flags;
79 u32 div, val;
80 u64 tmp;
81
82 if (rate > parent_rate)
83 return -EINVAL;
84
85 tmp = rate;
86 tmp <<= frac->width;
87 do_div(tmp, parent_rate);
88 div = tmp;
89
90 if (!div)
91 return -EINVAL;
92
93 spin_lock_irqsave(&mxs_lock, flags);
94
95 val = readl_relaxed(frac->reg);
96 val &= ~(((1 << frac->width) - 1) << frac->shift);
97 val |= div << frac->shift;
98 writel_relaxed(val, frac->reg);
99
100 spin_unlock_irqrestore(&mxs_lock, flags);
101
102 return mxs_clk_wait(frac->reg, frac->busy);
103}
104
105static struct clk_ops clk_frac_ops = {
106 .recalc_rate = clk_frac_recalc_rate,
107 .round_rate = clk_frac_round_rate,
108 .set_rate = clk_frac_set_rate,
109};
110
111struct clk *mxs_clk_frac(const char *name, const char *parent_name,
112 void __iomem *reg, u8 shift, u8 width, u8 busy)
113{
114 struct clk_frac *frac;
115 struct clk *clk;
116 struct clk_init_data init;
117
118 frac = kzalloc(sizeof(*frac), GFP_KERNEL);
119 if (!frac)
120 return ERR_PTR(-ENOMEM);
121
122 init.name = name;
123 init.ops = &clk_frac_ops;
124 init.flags = CLK_SET_RATE_PARENT;
125 init.parent_names = (parent_name ? &parent_name: NULL);
126 init.num_parents = (parent_name ? 1 : 0);
127
128 frac->reg = reg;
129 frac->shift = shift;
130 frac->width = width;
131 frac->busy = busy;
132 frac->hw.init = &init;
133
134 clk = clk_register(NULL, &frac->hw);
135 if (IS_ERR(clk))
136 kfree(frac);
137
138 return clk;
139}
diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c
new file mode 100644
index 000000000000..f7be225f544c
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx23.c
@@ -0,0 +1,205 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <mach/common.h>
18#include <mach/mx23.h>
19#include "clk.h"
20
21#define DIGCTRL MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
22#define CLKCTRL MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
23#define PLLCTRL0 (CLKCTRL + 0x0000)
24#define CPU (CLKCTRL + 0x0020)
25#define HBUS (CLKCTRL + 0x0030)
26#define XBUS (CLKCTRL + 0x0040)
27#define XTAL (CLKCTRL + 0x0050)
28#define PIX (CLKCTRL + 0x0060)
29#define SSP (CLKCTRL + 0x0070)
30#define GPMI (CLKCTRL + 0x0080)
31#define SPDIF (CLKCTRL + 0x0090)
32#define EMI (CLKCTRL + 0x00a0)
33#define SAIF (CLKCTRL + 0x00c0)
34#define TV (CLKCTRL + 0x00d0)
35#define ETM (CLKCTRL + 0x00e0)
36#define FRAC (CLKCTRL + 0x00f0)
37#define CLKSEQ (CLKCTRL + 0x0110)
38
39#define BP_CPU_INTERRUPT_WAIT 12
40#define BP_CLKSEQ_BYPASS_SAIF 0
41#define BP_CLKSEQ_BYPASS_SSP 5
42#define BP_SAIF_DIV_FRAC_EN 16
43#define BP_FRAC_IOFRAC 24
44
45static void __init clk_misc_init(void)
46{
47 u32 val;
48
49 /* Gate off cpu clock in WFI for power saving */
50 __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
51
52 /* Clear BYPASS for SAIF */
53 __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ);
54
55 /* SAIF has to use frac div for functional operation */
56 val = readl_relaxed(SAIF);
57 val |= 1 << BP_SAIF_DIV_FRAC_EN;
58 writel_relaxed(val, SAIF);
59
60 /*
61 * Source ssp clock from ref_io than ref_xtal,
62 * as ref_xtal only provides 24 MHz as maximum.
63 */
64 __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SSP, CLKSEQ);
65
66 /*
67 * 480 MHz seems too high to be ssp clock source directly,
68 * so set frac to get a 288 MHz ref_io.
69 */
70 __mxs_clrl(0x3f << BP_FRAC_IOFRAC, FRAC);
71 __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC);
72}
73
74static struct clk_lookup uart_lookups[] __initdata = {
75 { .dev_id = "duart", },
76 { .dev_id = "mxs-auart.0", },
77 { .dev_id = "mxs-auart.1", },
78 { .dev_id = "8006c000.serial", },
79 { .dev_id = "8006e000.serial", },
80 { .dev_id = "80070000.serial", },
81};
82
83static struct clk_lookup hbus_lookups[] __initdata = {
84 { .dev_id = "imx23-dma-apbh", },
85 { .dev_id = "80004000.dma-apbh", },
86};
87
88static struct clk_lookup xbus_lookups[] __initdata = {
89 { .dev_id = "duart", .con_id = "apb_pclk"},
90 { .dev_id = "80070000.serial", .con_id = "apb_pclk"},
91 { .dev_id = "imx23-dma-apbx", },
92 { .dev_id = "80024000.dma-apbx", },
93};
94
95static struct clk_lookup ssp_lookups[] __initdata = {
96 { .dev_id = "imx23-mmc.0", },
97 { .dev_id = "imx23-mmc.1", },
98 { .dev_id = "80010000.ssp", },
99 { .dev_id = "80034000.ssp", },
100};
101
102static struct clk_lookup lcdif_lookups[] __initdata = {
103 { .dev_id = "imx23-fb", },
104 { .dev_id = "80030000.lcdif", },
105};
106
107static struct clk_lookup gpmi_lookups[] __initdata = {
108 { .dev_id = "imx23-gpmi-nand", },
109 { .dev_id = "8000c000.gpmi", },
110};
111
112static const char *sel_pll[] __initconst = { "pll", "ref_xtal", };
113static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
114static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
115static const char *sel_io[] __initconst = { "ref_io", "ref_xtal", };
116static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
117static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
118
119enum imx23_clk {
120 ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel,
121 lcdif_sel, gpmi_sel, ssp_sel, emi_sel, cpu, etm_sel, cpu_pll,
122 cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll,
123 emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div,
124 clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif,
125 lcdif, etm, usb, usb_pwr,
126 clk_max
127};
128
129static struct clk *clks[clk_max];
130
131static enum imx23_clk clks_init_on[] __initdata = {
132 cpu, hbus, xbus, emi, uart,
133};
134
135int __init mx23_clocks_init(void)
136{
137 int i;
138
139 clk_misc_init();
140
141 clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
142 clks[pll] = mxs_clk_pll("pll", "ref_xtal", PLLCTRL0, 16, 480000000);
143 clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll", FRAC, 0);
144 clks[ref_emi] = mxs_clk_ref("ref_emi", "pll", FRAC, 1);
145 clks[ref_pix] = mxs_clk_ref("ref_pix", "pll", FRAC, 2);
146 clks[ref_io] = mxs_clk_ref("ref_io", "pll", FRAC, 3);
147 clks[saif_sel] = mxs_clk_mux("saif_sel", CLKSEQ, 0, 1, sel_pll, ARRAY_SIZE(sel_pll));
148 clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 1, 1, sel_pix, ARRAY_SIZE(sel_pix));
149 clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 4, 1, sel_io, ARRAY_SIZE(sel_io));
150 clks[ssp_sel] = mxs_clk_mux("ssp_sel", CLKSEQ, 5, 1, sel_io, ARRAY_SIZE(sel_io));
151 clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 6, 1, emi_sels, ARRAY_SIZE(emi_sels));
152 clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 7, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
153 clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
154 clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
155 clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
156 clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 29);
157 clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
158 clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", PIX, 0, 12, 29);
159 clks[ssp_div] = mxs_clk_div("ssp_div", "ssp_sel", SSP, 0, 9, 29);
160 clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
161 clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
162 clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
163 clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 6, 29);
164 clks[saif_div] = mxs_clk_frac("saif_div", "saif_sel", SAIF, 0, 16, 29);
165 clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
166 clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
167 clks[adc] = mxs_clk_fixed_factor("adc", "clk32k", 1, 16);
168 clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll", 1, 4);
169 clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
170 clks[dri] = mxs_clk_gate("dri", "ref_xtal", XTAL, 28);
171 clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
172 clks[filt] = mxs_clk_gate("filt", "ref_xtal", XTAL, 30);
173 clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
174 clks[ssp] = mxs_clk_gate("ssp", "ssp_div", SSP, 31);
175 clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
176 clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
177 clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
178 clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31);
179 clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31);
180 clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
181 clks[usb] = mxs_clk_gate("usb", "usb_pwr", DIGCTRL, 2);
182 clks[usb_pwr] = clk_register_gate(NULL, "usb_pwr", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock);
183
184 for (i = 0; i < ARRAY_SIZE(clks); i++)
185 if (IS_ERR(clks[i])) {
186 pr_err("i.MX23 clk %d: register failed with %ld\n",
187 i, PTR_ERR(clks[i]));
188 return PTR_ERR(clks[i]);
189 }
190
191 clk_register_clkdev(clks[clk32k], NULL, "timrot");
192 clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
193 clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
194 clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
195 clk_register_clkdevs(clks[ssp], ssp_lookups, ARRAY_SIZE(ssp_lookups));
196 clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
197 clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
198
199 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
200 clk_prepare_enable(clks[clks_init_on[i]]);
201
202 mxs_timer_init(MX23_INT_TIMER0);
203
204 return 0;
205}
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
new file mode 100644
index 000000000000..2826a2606a29
--- /dev/null
+++ b/drivers/clk/mxs/clk-imx28.c
@@ -0,0 +1,338 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clkdev.h>
14#include <linux/err.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <mach/common.h>
18#include <mach/mx28.h>
19#include "clk.h"
20
21#define CLKCTRL MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
22#define PLL0CTRL0 (CLKCTRL + 0x0000)
23#define PLL1CTRL0 (CLKCTRL + 0x0020)
24#define PLL2CTRL0 (CLKCTRL + 0x0040)
25#define CPU (CLKCTRL + 0x0050)
26#define HBUS (CLKCTRL + 0x0060)
27#define XBUS (CLKCTRL + 0x0070)
28#define XTAL (CLKCTRL + 0x0080)
29#define SSP0 (CLKCTRL + 0x0090)
30#define SSP1 (CLKCTRL + 0x00a0)
31#define SSP2 (CLKCTRL + 0x00b0)
32#define SSP3 (CLKCTRL + 0x00c0)
33#define GPMI (CLKCTRL + 0x00d0)
34#define SPDIF (CLKCTRL + 0x00e0)
35#define EMI (CLKCTRL + 0x00f0)
36#define SAIF0 (CLKCTRL + 0x0100)
37#define SAIF1 (CLKCTRL + 0x0110)
38#define LCDIF (CLKCTRL + 0x0120)
39#define ETM (CLKCTRL + 0x0130)
40#define ENET (CLKCTRL + 0x0140)
41#define FLEXCAN (CLKCTRL + 0x0160)
42#define FRAC0 (CLKCTRL + 0x01b0)
43#define FRAC1 (CLKCTRL + 0x01c0)
44#define CLKSEQ (CLKCTRL + 0x01d0)
45
46#define BP_CPU_INTERRUPT_WAIT 12
47#define BP_SAIF_DIV_FRAC_EN 16
48#define BP_ENET_DIV_TIME 21
49#define BP_ENET_SLEEP 31
50#define BP_CLKSEQ_BYPASS_SAIF0 0
51#define BP_CLKSEQ_BYPASS_SSP0 3
52#define BP_FRAC0_IO1FRAC 16
53#define BP_FRAC0_IO0FRAC 24
54
55#define DIGCTRL MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
56#define BP_SAIF_CLKMUX 10
57
58/*
59 * HW_SAIF_CLKMUX_SEL:
60 * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
61 * clock pins selected for SAIF1 input clocks.
62 * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
63 * SAIF0 clock inputs selected for SAIF1 input clocks.
64 * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
65 * clocks.
66 * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
67 * clocks.
68 */
69int mxs_saif_clkmux_select(unsigned int clkmux)
70{
71 if (clkmux > 0x3)
72 return -EINVAL;
73
74 __mxs_clrl(0x3 << BP_SAIF_CLKMUX, DIGCTRL);
75 __mxs_setl(clkmux << BP_SAIF_CLKMUX, DIGCTRL);
76
77 return 0;
78}
79
80static void __init clk_misc_init(void)
81{
82 u32 val;
83
84 /* Gate off cpu clock in WFI for power saving */
85 __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
86
87 /* 0 is a bad default value for a divider */
88 __mxs_setl(1 << BP_ENET_DIV_TIME, ENET);
89
90 /* Clear BYPASS for SAIF */
91 __mxs_clrl(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ);
92
93 /* SAIF has to use frac div for functional operation */
94 val = readl_relaxed(SAIF0);
95 val |= 1 << BP_SAIF_DIV_FRAC_EN;
96 writel_relaxed(val, SAIF0);
97
98 val = readl_relaxed(SAIF1);
99 val |= 1 << BP_SAIF_DIV_FRAC_EN;
100 writel_relaxed(val, SAIF1);
101
102 /* Extra fec clock setting */
103 val = readl_relaxed(ENET);
104 val &= ~(1 << BP_ENET_SLEEP);
105 writel_relaxed(val, ENET);
106
107 /*
108 * Source ssp clock from ref_io than ref_xtal,
109 * as ref_xtal only provides 24 MHz as maximum.
110 */
111 __mxs_clrl(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ);
112
113 /*
114 * 480 MHz seems too high to be ssp clock source directly,
115 * so set frac0 to get a 288 MHz ref_io0.
116 */
117 val = readl_relaxed(FRAC0);
118 val &= ~(0x3f << BP_FRAC0_IO0FRAC);
119 val |= 30 << BP_FRAC0_IO0FRAC;
120 writel_relaxed(val, FRAC0);
121}
122
123static struct clk_lookup uart_lookups[] __initdata = {
124 { .dev_id = "duart", },
125 { .dev_id = "mxs-auart.0", },
126 { .dev_id = "mxs-auart.1", },
127 { .dev_id = "mxs-auart.2", },
128 { .dev_id = "mxs-auart.3", },
129 { .dev_id = "mxs-auart.4", },
130 { .dev_id = "8006a000.serial", },
131 { .dev_id = "8006c000.serial", },
132 { .dev_id = "8006e000.serial", },
133 { .dev_id = "80070000.serial", },
134 { .dev_id = "80072000.serial", },
135 { .dev_id = "80074000.serial", },
136};
137
138static struct clk_lookup hbus_lookups[] __initdata = {
139 { .dev_id = "imx28-dma-apbh", },
140 { .dev_id = "80004000.dma-apbh", },
141};
142
143static struct clk_lookup xbus_lookups[] __initdata = {
144 { .dev_id = "duart", .con_id = "apb_pclk"},
145 { .dev_id = "80074000.serial", .con_id = "apb_pclk"},
146 { .dev_id = "imx28-dma-apbx", },
147 { .dev_id = "80024000.dma-apbx", },
148};
149
150static struct clk_lookup ssp0_lookups[] __initdata = {
151 { .dev_id = "imx28-mmc.0", },
152 { .dev_id = "80010000.ssp", },
153};
154
155static struct clk_lookup ssp1_lookups[] __initdata = {
156 { .dev_id = "imx28-mmc.1", },
157 { .dev_id = "80012000.ssp", },
158};
159
160static struct clk_lookup ssp2_lookups[] __initdata = {
161 { .dev_id = "imx28-mmc.2", },
162 { .dev_id = "80014000.ssp", },
163};
164
165static struct clk_lookup ssp3_lookups[] __initdata = {
166 { .dev_id = "imx28-mmc.3", },
167 { .dev_id = "80016000.ssp", },
168};
169
170static struct clk_lookup lcdif_lookups[] __initdata = {
171 { .dev_id = "imx28-fb", },
172 { .dev_id = "80030000.lcdif", },
173};
174
175static struct clk_lookup gpmi_lookups[] __initdata = {
176 { .dev_id = "imx28-gpmi-nand", },
177 { .dev_id = "8000c000.gpmi", },
178};
179
180static struct clk_lookup fec_lookups[] __initdata = {
181 { .dev_id = "imx28-fec.0", },
182 { .dev_id = "imx28-fec.1", },
183 { .dev_id = "800f0000.ethernet", },
184 { .dev_id = "800f4000.ethernet", },
185};
186
187static struct clk_lookup can0_lookups[] __initdata = {
188 { .dev_id = "flexcan.0", },
189 { .dev_id = "80032000.can", },
190};
191
192static struct clk_lookup can1_lookups[] __initdata = {
193 { .dev_id = "flexcan.1", },
194 { .dev_id = "80034000.can", },
195};
196
197static struct clk_lookup saif0_lookups[] __initdata = {
198 { .dev_id = "mxs-saif.0", },
199 { .dev_id = "80042000.saif", },
200};
201
202static struct clk_lookup saif1_lookups[] __initdata = {
203 { .dev_id = "mxs-saif.1", },
204 { .dev_id = "80046000.saif", },
205};
206
207static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
208static const char *sel_io0[] __initconst = { "ref_io0", "ref_xtal", };
209static const char *sel_io1[] __initconst = { "ref_io1", "ref_xtal", };
210static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
211static const char *sel_gpmi[] __initconst = { "ref_gpmi", "ref_xtal", };
212static const char *sel_pll0[] __initconst = { "pll0", "ref_xtal", };
213static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
214static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
215static const char *ptp_sels[] __initconst = { "ref_xtal", "pll0", };
216
217enum imx28_clk {
218 ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1,
219 ref_pix, ref_hsadc, ref_gpmi, saif0_sel, saif1_sel, gpmi_sel,
220 ssp0_sel, ssp1_sel, ssp2_sel, ssp3_sel, emi_sel, etm_sel,
221 lcdif_sel, cpu, ptp_sel, cpu_pll, cpu_xtal, hbus, xbus,
222 ssp0_div, ssp1_div, ssp2_div, ssp3_div, gpmi_div, emi_pll,
223 emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div,
224 clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0,
225 ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm,
226 fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out,
227 clk_max
228};
229
230static struct clk *clks[clk_max];
231
232static enum imx28_clk clks_init_on[] __initdata = {
233 cpu, hbus, xbus, emi, uart,
234};
235
236int __init mx28_clocks_init(void)
237{
238 int i;
239
240 clk_misc_init();
241
242 clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
243 clks[pll0] = mxs_clk_pll("pll0", "ref_xtal", PLL0CTRL0, 17, 480000000);
244 clks[pll1] = mxs_clk_pll("pll1", "ref_xtal", PLL1CTRL0, 17, 480000000);
245 clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000);
246 clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0);
247 clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1);
248 clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2);
249 clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3);
250 clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0);
251 clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1);
252 clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2);
253 clks[saif0_sel] = mxs_clk_mux("saif0_sel", CLKSEQ, 0, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
254 clks[saif1_sel] = mxs_clk_mux("saif1_sel", CLKSEQ, 1, 1, sel_pll0, ARRAY_SIZE(sel_pll0));
255 clks[gpmi_sel] = mxs_clk_mux("gpmi_sel", CLKSEQ, 2, 1, sel_gpmi, ARRAY_SIZE(sel_gpmi));
256 clks[ssp0_sel] = mxs_clk_mux("ssp0_sel", CLKSEQ, 3, 1, sel_io0, ARRAY_SIZE(sel_io0));
257 clks[ssp1_sel] = mxs_clk_mux("ssp1_sel", CLKSEQ, 4, 1, sel_io0, ARRAY_SIZE(sel_io0));
258 clks[ssp2_sel] = mxs_clk_mux("ssp2_sel", CLKSEQ, 5, 1, sel_io1, ARRAY_SIZE(sel_io1));
259 clks[ssp3_sel] = mxs_clk_mux("ssp3_sel", CLKSEQ, 6, 1, sel_io1, ARRAY_SIZE(sel_io1));
260 clks[emi_sel] = mxs_clk_mux("emi_sel", CLKSEQ, 7, 1, emi_sels, ARRAY_SIZE(emi_sels));
261 clks[etm_sel] = mxs_clk_mux("etm_sel", CLKSEQ, 8, 1, sel_cpu, ARRAY_SIZE(sel_cpu));
262 clks[lcdif_sel] = mxs_clk_mux("lcdif_sel", CLKSEQ, 14, 1, sel_pix, ARRAY_SIZE(sel_pix));
263 clks[cpu] = mxs_clk_mux("cpu", CLKSEQ, 18, 1, cpu_sels, ARRAY_SIZE(cpu_sels));
264 clks[ptp_sel] = mxs_clk_mux("ptp_sel", ENET, 19, 1, ptp_sels, ARRAY_SIZE(ptp_sels));
265 clks[cpu_pll] = mxs_clk_div("cpu_pll", "ref_cpu", CPU, 0, 6, 28);
266 clks[cpu_xtal] = mxs_clk_div("cpu_xtal", "ref_xtal", CPU, 16, 10, 29);
267 clks[hbus] = mxs_clk_div("hbus", "cpu", HBUS, 0, 5, 31);
268 clks[xbus] = mxs_clk_div("xbus", "ref_xtal", XBUS, 0, 10, 31);
269 clks[ssp0_div] = mxs_clk_div("ssp0_div", "ssp0_sel", SSP0, 0, 9, 29);
270 clks[ssp1_div] = mxs_clk_div("ssp1_div", "ssp1_sel", SSP1, 0, 9, 29);
271 clks[ssp2_div] = mxs_clk_div("ssp2_div", "ssp2_sel", SSP2, 0, 9, 29);
272 clks[ssp3_div] = mxs_clk_div("ssp3_div", "ssp3_sel", SSP3, 0, 9, 29);
273 clks[gpmi_div] = mxs_clk_div("gpmi_div", "gpmi_sel", GPMI, 0, 10, 29);
274 clks[emi_pll] = mxs_clk_div("emi_pll", "ref_emi", EMI, 0, 6, 28);
275 clks[emi_xtal] = mxs_clk_div("emi_xtal", "ref_xtal", EMI, 8, 4, 29);
276 clks[lcdif_div] = mxs_clk_div("lcdif_div", "lcdif_sel", LCDIF, 0, 13, 29);
277 clks[etm_div] = mxs_clk_div("etm_div", "etm_sel", ETM, 0, 7, 29);
278 clks[ptp] = mxs_clk_div("ptp", "ptp_sel", ENET, 21, 6, 27);
279 clks[saif0_div] = mxs_clk_frac("saif0_div", "saif0_sel", SAIF0, 0, 16, 29);
280 clks[saif1_div] = mxs_clk_frac("saif1_div", "saif1_sel", SAIF1, 0, 16, 29);
281 clks[clk32k_div] = mxs_clk_fixed_factor("clk32k_div", "ref_xtal", 1, 750);
282 clks[rtc] = mxs_clk_fixed_factor("rtc", "ref_xtal", 1, 768);
283 clks[lradc] = mxs_clk_fixed_factor("lradc", "clk32k", 1, 16);
284 clks[spdif_div] = mxs_clk_fixed_factor("spdif_div", "pll0", 1, 4);
285 clks[clk32k] = mxs_clk_gate("clk32k", "clk32k_div", XTAL, 26);
286 clks[pwm] = mxs_clk_gate("pwm", "ref_xtal", XTAL, 29);
287 clks[uart] = mxs_clk_gate("uart", "ref_xtal", XTAL, 31);
288 clks[ssp0] = mxs_clk_gate("ssp0", "ssp0_div", SSP0, 31);
289 clks[ssp1] = mxs_clk_gate("ssp1", "ssp1_div", SSP1, 31);
290 clks[ssp2] = mxs_clk_gate("ssp2", "ssp2_div", SSP2, 31);
291 clks[ssp3] = mxs_clk_gate("ssp3", "ssp3_div", SSP3, 31);
292 clks[gpmi] = mxs_clk_gate("gpmi", "gpmi_div", GPMI, 31);
293 clks[spdif] = mxs_clk_gate("spdif", "spdif_div", SPDIF, 31);
294 clks[emi] = mxs_clk_gate("emi", "emi_sel", EMI, 31);
295 clks[saif0] = mxs_clk_gate("saif0", "saif0_div", SAIF0, 31);
296 clks[saif1] = mxs_clk_gate("saif1", "saif1_div", SAIF1, 31);
297 clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", LCDIF, 31);
298 clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31);
299 clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30);
300 clks[can0] = mxs_clk_gate("can0", "ref_xtal", FLEXCAN, 30);
301 clks[can1] = mxs_clk_gate("can1", "ref_xtal", FLEXCAN, 28);
302 clks[usb0] = mxs_clk_gate("usb0", "usb0_pwr", DIGCTRL, 2);
303 clks[usb1] = mxs_clk_gate("usb1", "usb1_pwr", DIGCTRL, 16);
304 clks[usb0_pwr] = clk_register_gate(NULL, "usb0_pwr", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock);
305 clks[usb1_pwr] = clk_register_gate(NULL, "usb1_pwr", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock);
306 clks[enet_out] = clk_register_gate(NULL, "enet_out", "pll2", 0, ENET, 18, 0, &mxs_lock);
307
308 for (i = 0; i < ARRAY_SIZE(clks); i++)
309 if (IS_ERR(clks[i])) {
310 pr_err("i.MX28 clk %d: register failed with %ld\n",
311 i, PTR_ERR(clks[i]));
312 return PTR_ERR(clks[i]);
313 }
314
315 clk_register_clkdev(clks[clk32k], NULL, "timrot");
316 clk_register_clkdev(clks[enet_out], NULL, "enet_out");
317 clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups));
318 clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups));
319 clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups));
320 clk_register_clkdevs(clks[ssp0], ssp0_lookups, ARRAY_SIZE(ssp0_lookups));
321 clk_register_clkdevs(clks[ssp1], ssp1_lookups, ARRAY_SIZE(ssp1_lookups));
322 clk_register_clkdevs(clks[ssp2], ssp2_lookups, ARRAY_SIZE(ssp2_lookups));
323 clk_register_clkdevs(clks[ssp3], ssp3_lookups, ARRAY_SIZE(ssp3_lookups));
324 clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups));
325 clk_register_clkdevs(clks[saif0], saif0_lookups, ARRAY_SIZE(saif0_lookups));
326 clk_register_clkdevs(clks[saif1], saif1_lookups, ARRAY_SIZE(saif1_lookups));
327 clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups));
328 clk_register_clkdevs(clks[fec], fec_lookups, ARRAY_SIZE(fec_lookups));
329 clk_register_clkdevs(clks[can0], can0_lookups, ARRAY_SIZE(can0_lookups));
330 clk_register_clkdevs(clks[can1], can1_lookups, ARRAY_SIZE(can1_lookups));
331
332 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
333 clk_prepare_enable(clks[clks_init_on[i]]);
334
335 mxs_timer_init(MX28_INT_TIMER0);
336
337 return 0;
338}
diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c
new file mode 100644
index 000000000000..fadae41833ec
--- /dev/null
+++ b/drivers/clk/mxs/clk-pll.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/slab.h>
18#include "clk.h"
19
20/**
21 * struct clk_pll - mxs pll clock
22 * @hw: clk_hw for the pll
23 * @base: base address of the pll
24 * @power: the shift of power bit
25 * @rate: the clock rate of the pll
26 *
27 * The mxs pll is a fixed rate clock with power and gate control,
28 * and the shift of gate bit is always 31.
29 */
30struct clk_pll {
31 struct clk_hw hw;
32 void __iomem *base;
33 u8 power;
34 unsigned long rate;
35};
36
37#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
38
39static int clk_pll_prepare(struct clk_hw *hw)
40{
41 struct clk_pll *pll = to_clk_pll(hw);
42
43 writel_relaxed(1 << pll->power, pll->base + SET);
44
45 udelay(10);
46
47 return 0;
48}
49
50static void clk_pll_unprepare(struct clk_hw *hw)
51{
52 struct clk_pll *pll = to_clk_pll(hw);
53
54 writel_relaxed(1 << pll->power, pll->base + CLR);
55}
56
57static int clk_pll_enable(struct clk_hw *hw)
58{
59 struct clk_pll *pll = to_clk_pll(hw);
60
61 writel_relaxed(1 << 31, pll->base + CLR);
62
63 return 0;
64}
65
66static void clk_pll_disable(struct clk_hw *hw)
67{
68 struct clk_pll *pll = to_clk_pll(hw);
69
70 writel_relaxed(1 << 31, pll->base + SET);
71}
72
73static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
74 unsigned long parent_rate)
75{
76 struct clk_pll *pll = to_clk_pll(hw);
77
78 return pll->rate;
79}
80
81static const struct clk_ops clk_pll_ops = {
82 .prepare = clk_pll_prepare,
83 .unprepare = clk_pll_unprepare,
84 .enable = clk_pll_enable,
85 .disable = clk_pll_disable,
86 .recalc_rate = clk_pll_recalc_rate,
87};
88
89struct clk *mxs_clk_pll(const char *name, const char *parent_name,
90 void __iomem *base, u8 power, unsigned long rate)
91{
92 struct clk_pll *pll;
93 struct clk *clk;
94 struct clk_init_data init;
95
96 pll = kzalloc(sizeof(*pll), GFP_KERNEL);
97 if (!pll)
98 return ERR_PTR(-ENOMEM);
99
100 init.name = name;
101 init.ops = &clk_pll_ops;
102 init.flags = 0;
103 init.parent_names = (parent_name ? &parent_name: NULL);
104 init.num_parents = (parent_name ? 1 : 0);
105
106 pll->base = base;
107 pll->rate = rate;
108 pll->power = power;
109 pll->hw.init = &init;
110
111 clk = clk_register(NULL, &pll->hw);
112 if (IS_ERR(clk))
113 kfree(pll);
114
115 return clk;
116}
diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c
new file mode 100644
index 000000000000..4adeed6c2f94
--- /dev/null
+++ b/drivers/clk/mxs/clk-ref.c
@@ -0,0 +1,154 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/clk.h>
13#include <linux/clk-provider.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include "clk.h"
18
19/**
20 * struct clk_ref - mxs reference clock
21 * @hw: clk_hw for the reference clock
22 * @reg: register address
23 * @idx: the index of the reference clock within the same register
24 *
25 * The mxs reference clock sources from pll. Every 4 reference clocks share
26 * one register space, and @idx is used to identify them. Each reference
27 * clock has a gate control and a fractional * divider. The rate is calculated
28 * as pll rate * (18 / FRAC), where FRAC = 18 ~ 35.
29 */
30struct clk_ref {
31 struct clk_hw hw;
32 void __iomem *reg;
33 u8 idx;
34};
35
36#define to_clk_ref(_hw) container_of(_hw, struct clk_ref, hw)
37
38static int clk_ref_enable(struct clk_hw *hw)
39{
40 struct clk_ref *ref = to_clk_ref(hw);
41
42 writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + CLR);
43
44 return 0;
45}
46
47static void clk_ref_disable(struct clk_hw *hw)
48{
49 struct clk_ref *ref = to_clk_ref(hw);
50
51 writel_relaxed(1 << ((ref->idx + 1) * 8 - 1), ref->reg + SET);
52}
53
54static unsigned long clk_ref_recalc_rate(struct clk_hw *hw,
55 unsigned long parent_rate)
56{
57 struct clk_ref *ref = to_clk_ref(hw);
58 u64 tmp = parent_rate;
59 u8 frac = (readl_relaxed(ref->reg) >> (ref->idx * 8)) & 0x3f;
60
61 tmp *= 18;
62 do_div(tmp, frac);
63
64 return tmp;
65}
66
67static long clk_ref_round_rate(struct clk_hw *hw, unsigned long rate,
68 unsigned long *prate)
69{
70 unsigned long parent_rate = *prate;
71 u64 tmp = parent_rate;
72 u8 frac;
73
74 tmp = tmp * 18 + rate / 2;
75 do_div(tmp, rate);
76 frac = tmp;
77
78 if (frac < 18)
79 frac = 18;
80 else if (frac > 35)
81 frac = 35;
82
83 tmp = parent_rate;
84 tmp *= 18;
85 do_div(tmp, frac);
86
87 return tmp;
88}
89
90static int clk_ref_set_rate(struct clk_hw *hw, unsigned long rate,
91 unsigned long parent_rate)
92{
93 struct clk_ref *ref = to_clk_ref(hw);
94 unsigned long flags;
95 u64 tmp = parent_rate;
96 u32 val;
97 u8 frac, shift = ref->idx * 8;
98
99 tmp = tmp * 18 + rate / 2;
100 do_div(tmp, rate);
101 frac = tmp;
102
103 if (frac < 18)
104 frac = 18;
105 else if (frac > 35)
106 frac = 35;
107
108 spin_lock_irqsave(&mxs_lock, flags);
109
110 val = readl_relaxed(ref->reg);
111 val &= ~(0x3f << shift);
112 val |= frac << shift;
113 writel_relaxed(val, ref->reg);
114
115 spin_unlock_irqrestore(&mxs_lock, flags);
116
117 return 0;
118}
119
120static const struct clk_ops clk_ref_ops = {
121 .enable = clk_ref_enable,
122 .disable = clk_ref_disable,
123 .recalc_rate = clk_ref_recalc_rate,
124 .round_rate = clk_ref_round_rate,
125 .set_rate = clk_ref_set_rate,
126};
127
128struct clk *mxs_clk_ref(const char *name, const char *parent_name,
129 void __iomem *reg, u8 idx)
130{
131 struct clk_ref *ref;
132 struct clk *clk;
133 struct clk_init_data init;
134
135 ref = kzalloc(sizeof(*ref), GFP_KERNEL);
136 if (!ref)
137 return ERR_PTR(-ENOMEM);
138
139 init.name = name;
140 init.ops = &clk_ref_ops;
141 init.flags = 0;
142 init.parent_names = (parent_name ? &parent_name: NULL);
143 init.num_parents = (parent_name ? 1 : 0);
144
145 ref->reg = reg;
146 ref->idx = idx;
147 ref->hw.init = &init;
148
149 clk = clk_register(NULL, &ref->hw);
150 if (IS_ERR(clk))
151 kfree(ref);
152
153 return clk;
154}
diff --git a/drivers/clk/mxs/clk.c b/drivers/clk/mxs/clk.c
new file mode 100644
index 000000000000..b24d56067c80
--- /dev/null
+++ b/drivers/clk/mxs/clk.c
@@ -0,0 +1,28 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/err.h>
13#include <linux/io.h>
14#include <linux/jiffies.h>
15#include <linux/spinlock.h>
16
17DEFINE_SPINLOCK(mxs_lock);
18
19int mxs_clk_wait(void __iomem *reg, u8 shift)
20{
21 unsigned long timeout = jiffies + msecs_to_jiffies(10);
22
23 while (readl_relaxed(reg) & (1 << shift))
24 if (time_after(jiffies, timeout))
25 return -ETIMEDOUT;
26
27 return 0;
28}
diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h
new file mode 100644
index 000000000000..81421e28e69c
--- /dev/null
+++ b/drivers/clk/mxs/clk.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright 2012 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#ifndef __MXS_CLK_H
13#define __MXS_CLK_H
14
15#include <linux/clk.h>
16#include <linux/clk-provider.h>
17#include <linux/spinlock.h>
18
19#define SET 0x4
20#define CLR 0x8
21
22extern spinlock_t mxs_lock;
23
24int mxs_clk_wait(void __iomem *reg, u8 shift);
25
26struct clk *mxs_clk_pll(const char *name, const char *parent_name,
27 void __iomem *base, u8 power, unsigned long rate);
28
29struct clk *mxs_clk_ref(const char *name, const char *parent_name,
30 void __iomem *reg, u8 idx);
31
32struct clk *mxs_clk_div(const char *name, const char *parent_name,
33 void __iomem *reg, u8 shift, u8 width, u8 busy);
34
35struct clk *mxs_clk_frac(const char *name, const char *parent_name,
36 void __iomem *reg, u8 shift, u8 width, u8 busy);
37
38static inline struct clk *mxs_clk_fixed(const char *name, int rate)
39{
40 return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);
41}
42
43static inline struct clk *mxs_clk_gate(const char *name,
44 const char *parent_name, void __iomem *reg, u8 shift)
45{
46 return clk_register_gate(NULL, name, parent_name, CLK_SET_RATE_PARENT,
47 reg, shift, CLK_GATE_SET_TO_DISABLE,
48 &mxs_lock);
49}
50
51static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
52 u8 shift, u8 width, const char **parent_names, int num_parents)
53{
54 return clk_register_mux(NULL, name, parent_names, num_parents,
55 CLK_SET_RATE_PARENT, reg, shift, width,
56 0, &mxs_lock);
57}
58
59static inline struct clk *mxs_clk_fixed_factor(const char *name,
60 const char *parent_name, unsigned int mult, unsigned int div)
61{
62 return clk_register_fixed_factor(NULL, name, parent_name,
63 CLK_SET_RATE_PARENT, mult, div);
64}
65
66#endif /* __MXS_CLK_H */
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index ef378b5b17e4..aadeb5be9dba 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -238,6 +238,7 @@ config IMX_DMA
238config MXS_DMA 238config MXS_DMA
239 bool "MXS DMA support" 239 bool "MXS DMA support"
240 depends on SOC_IMX23 || SOC_IMX28 240 depends on SOC_IMX23 || SOC_IMX28
241 select STMP_DEVICE
241 select DMA_ENGINE 242 select DMA_ENGINE
242 help 243 help
243 Support the MXS DMA engine. This engine including APBH-DMA 244 Support the MXS DMA engine. This engine including APBH-DMA
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 655d4ce6ed0d..1cb9b974493f 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -22,11 +22,14 @@
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/dmaengine.h> 23#include <linux/dmaengine.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/module.h>
25#include <linux/fsl/mxs-dma.h> 26#include <linux/fsl/mxs-dma.h>
27#include <linux/stmp_device.h>
28#include <linux/of.h>
29#include <linux/of_device.h>
26 30
27#include <asm/irq.h> 31#include <asm/irq.h>
28#include <mach/mxs.h> 32#include <mach/mxs.h>
29#include <mach/common.h>
30 33
31#include "dmaengine.h" 34#include "dmaengine.h"
32 35
@@ -36,12 +39,8 @@
36 * dma can program the controller registers of peripheral devices. 39 * dma can program the controller registers of peripheral devices.
37 */ 40 */
38 41
39#define MXS_DMA_APBH 0 42#define dma_is_apbh(mxs_dma) ((mxs_dma)->type == MXS_DMA_APBH)
40#define MXS_DMA_APBX 1 43#define apbh_is_old(mxs_dma) ((mxs_dma)->dev_id == IMX23_DMA)
41#define dma_is_apbh() (mxs_dma->dev_id == MXS_DMA_APBH)
42
43#define APBH_VERSION_LATEST 3
44#define apbh_is_old() (mxs_dma->version < APBH_VERSION_LATEST)
45 44
46#define HW_APBHX_CTRL0 0x000 45#define HW_APBHX_CTRL0 0x000
47#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29) 46#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29)
@@ -51,13 +50,14 @@
51#define HW_APBHX_CTRL2 0x020 50#define HW_APBHX_CTRL2 0x020
52#define HW_APBHX_CHANNEL_CTRL 0x030 51#define HW_APBHX_CHANNEL_CTRL 0x030
53#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16 52#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16
54#define HW_APBH_VERSION (cpu_is_mx23() ? 0x3f0 : 0x800) 53/*
55#define HW_APBX_VERSION 0x800 54 * The offset of NXTCMDAR register is different per both dma type and version,
56#define BP_APBHX_VERSION_MAJOR 24 55 * while stride for each channel is all the same 0x70.
57#define HW_APBHX_CHn_NXTCMDAR(n) \ 56 */
58 (((dma_is_apbh() && apbh_is_old()) ? 0x050 : 0x110) + (n) * 0x70) 57#define HW_APBHX_CHn_NXTCMDAR(d, n) \
59#define HW_APBHX_CHn_SEMA(n) \ 58 (((dma_is_apbh(d) && apbh_is_old(d)) ? 0x050 : 0x110) + (n) * 0x70)
60 (((dma_is_apbh() && apbh_is_old()) ? 0x080 : 0x140) + (n) * 0x70) 59#define HW_APBHX_CHn_SEMA(d, n) \
60 (((dma_is_apbh(d) && apbh_is_old(d)) ? 0x080 : 0x140) + (n) * 0x70)
61 61
62/* 62/*
63 * ccw bits definitions 63 * ccw bits definitions
@@ -121,9 +121,19 @@ struct mxs_dma_chan {
121#define MXS_DMA_CHANNELS 16 121#define MXS_DMA_CHANNELS 16
122#define MXS_DMA_CHANNELS_MASK 0xffff 122#define MXS_DMA_CHANNELS_MASK 0xffff
123 123
124enum mxs_dma_devtype {
125 MXS_DMA_APBH,
126 MXS_DMA_APBX,
127};
128
129enum mxs_dma_id {
130 IMX23_DMA,
131 IMX28_DMA,
132};
133
124struct mxs_dma_engine { 134struct mxs_dma_engine {
125 int dev_id; 135 enum mxs_dma_id dev_id;
126 unsigned int version; 136 enum mxs_dma_devtype type;
127 void __iomem *base; 137 void __iomem *base;
128 struct clk *clk; 138 struct clk *clk;
129 struct dma_device dma_device; 139 struct dma_device dma_device;
@@ -131,17 +141,86 @@ struct mxs_dma_engine {
131 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS]; 141 struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
132}; 142};
133 143
144struct mxs_dma_type {
145 enum mxs_dma_id id;
146 enum mxs_dma_devtype type;
147};
148
149static struct mxs_dma_type mxs_dma_types[] = {
150 {
151 .id = IMX23_DMA,
152 .type = MXS_DMA_APBH,
153 }, {
154 .id = IMX23_DMA,
155 .type = MXS_DMA_APBX,
156 }, {
157 .id = IMX28_DMA,
158 .type = MXS_DMA_APBH,
159 }, {
160 .id = IMX28_DMA,
161 .type = MXS_DMA_APBX,
162 }
163};
164
165static struct platform_device_id mxs_dma_ids[] = {
166 {
167 .name = "imx23-dma-apbh",
168 .driver_data = (kernel_ulong_t) &mxs_dma_types[0],
169 }, {
170 .name = "imx23-dma-apbx",
171 .driver_data = (kernel_ulong_t) &mxs_dma_types[1],
172 }, {
173 .name = "imx28-dma-apbh",
174 .driver_data = (kernel_ulong_t) &mxs_dma_types[2],
175 }, {
176 .name = "imx28-dma-apbx",
177 .driver_data = (kernel_ulong_t) &mxs_dma_types[3],
178 }, {
179 /* end of list */
180 }
181};
182
183static const struct of_device_id mxs_dma_dt_ids[] = {
184 { .compatible = "fsl,imx23-dma-apbh", .data = &mxs_dma_ids[0], },
185 { .compatible = "fsl,imx23-dma-apbx", .data = &mxs_dma_ids[1], },
186 { .compatible = "fsl,imx28-dma-apbh", .data = &mxs_dma_ids[2], },
187 { .compatible = "fsl,imx28-dma-apbx", .data = &mxs_dma_ids[3], },
188 { /* sentinel */ }
189};
190MODULE_DEVICE_TABLE(of, mxs_dma_dt_ids);
191
192static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
193{
194 return container_of(chan, struct mxs_dma_chan, chan);
195}
196
197int mxs_dma_is_apbh(struct dma_chan *chan)
198{
199 struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
200 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
201
202 return dma_is_apbh(mxs_dma);
203}
204
205int mxs_dma_is_apbx(struct dma_chan *chan)
206{
207 struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
208 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
209
210 return !dma_is_apbh(mxs_dma);
211}
212
134static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan) 213static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
135{ 214{
136 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma; 215 struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
137 int chan_id = mxs_chan->chan.chan_id; 216 int chan_id = mxs_chan->chan.chan_id;
138 217
139 if (dma_is_apbh() && apbh_is_old()) 218 if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
140 writel(1 << (chan_id + BP_APBH_CTRL0_RESET_CHANNEL), 219 writel(1 << (chan_id + BP_APBH_CTRL0_RESET_CHANNEL),
141 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 220 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
142 else 221 else
143 writel(1 << (chan_id + BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL), 222 writel(1 << (chan_id + BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL),
144 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR); 223 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
145} 224}
146 225
147static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan) 226static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
@@ -151,10 +230,10 @@ static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
151 230
152 /* set cmd_addr up */ 231 /* set cmd_addr up */
153 writel(mxs_chan->ccw_phys, 232 writel(mxs_chan->ccw_phys,
154 mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id)); 233 mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(mxs_dma, chan_id));
155 234
156 /* write 1 to SEMA to kick off the channel */ 235 /* write 1 to SEMA to kick off the channel */
157 writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id)); 236 writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(mxs_dma, chan_id));
158} 237}
159 238
160static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan) 239static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
@@ -168,12 +247,12 @@ static void mxs_dma_pause_chan(struct mxs_dma_chan *mxs_chan)
168 int chan_id = mxs_chan->chan.chan_id; 247 int chan_id = mxs_chan->chan.chan_id;
169 248
170 /* freeze the channel */ 249 /* freeze the channel */
171 if (dma_is_apbh() && apbh_is_old()) 250 if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
172 writel(1 << chan_id, 251 writel(1 << chan_id,
173 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 252 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
174 else 253 else
175 writel(1 << chan_id, 254 writel(1 << chan_id,
176 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR); 255 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
177 256
178 mxs_chan->status = DMA_PAUSED; 257 mxs_chan->status = DMA_PAUSED;
179} 258}
@@ -184,21 +263,16 @@ static void mxs_dma_resume_chan(struct mxs_dma_chan *mxs_chan)
184 int chan_id = mxs_chan->chan.chan_id; 263 int chan_id = mxs_chan->chan.chan_id;
185 264
186 /* unfreeze the channel */ 265 /* unfreeze the channel */
187 if (dma_is_apbh() && apbh_is_old()) 266 if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
188 writel(1 << chan_id, 267 writel(1 << chan_id,
189 mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR); 268 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR);
190 else 269 else
191 writel(1 << chan_id, 270 writel(1 << chan_id,
192 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_CLR_ADDR); 271 mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_CLR);
193 272
194 mxs_chan->status = DMA_IN_PROGRESS; 273 mxs_chan->status = DMA_IN_PROGRESS;
195} 274}
196 275
197static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
198{
199 return container_of(chan, struct mxs_dma_chan, chan);
200}
201
202static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx) 276static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
203{ 277{
204 return dma_cookie_assign(tx); 278 return dma_cookie_assign(tx);
@@ -220,11 +294,11 @@ static irqreturn_t mxs_dma_int_handler(int irq, void *dev_id)
220 /* completion status */ 294 /* completion status */
221 stat1 = readl(mxs_dma->base + HW_APBHX_CTRL1); 295 stat1 = readl(mxs_dma->base + HW_APBHX_CTRL1);
222 stat1 &= MXS_DMA_CHANNELS_MASK; 296 stat1 &= MXS_DMA_CHANNELS_MASK;
223 writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + MXS_CLR_ADDR); 297 writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR);
224 298
225 /* error status */ 299 /* error status */
226 stat2 = readl(mxs_dma->base + HW_APBHX_CTRL2); 300 stat2 = readl(mxs_dma->base + HW_APBHX_CTRL2);
227 writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + MXS_CLR_ADDR); 301 writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + STMP_OFFSET_REG_CLR);
228 302
229 /* 303 /*
230 * When both completion and error of termination bits set at the 304 * When both completion and error of termination bits set at the
@@ -567,27 +641,21 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
567 if (ret) 641 if (ret)
568 return ret; 642 return ret;
569 643
570 ret = mxs_reset_block(mxs_dma->base); 644 ret = stmp_reset_block(mxs_dma->base);
571 if (ret) 645 if (ret)
572 goto err_out; 646 goto err_out;
573 647
574 /* only major version matters */
575 mxs_dma->version = readl(mxs_dma->base +
576 ((mxs_dma->dev_id == MXS_DMA_APBX) ?
577 HW_APBX_VERSION : HW_APBH_VERSION)) >>
578 BP_APBHX_VERSION_MAJOR;
579
580 /* enable apbh burst */ 648 /* enable apbh burst */
581 if (dma_is_apbh()) { 649 if (dma_is_apbh(mxs_dma)) {
582 writel(BM_APBH_CTRL0_APB_BURST_EN, 650 writel(BM_APBH_CTRL0_APB_BURST_EN,
583 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 651 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
584 writel(BM_APBH_CTRL0_APB_BURST8_EN, 652 writel(BM_APBH_CTRL0_APB_BURST8_EN,
585 mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR); 653 mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
586 } 654 }
587 655
588 /* enable irq for all the channels */ 656 /* enable irq for all the channels */
589 writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS, 657 writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS,
590 mxs_dma->base + HW_APBHX_CTRL1 + MXS_SET_ADDR); 658 mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_SET);
591 659
592err_out: 660err_out:
593 clk_disable_unprepare(mxs_dma->clk); 661 clk_disable_unprepare(mxs_dma->clk);
@@ -596,8 +664,9 @@ err_out:
596 664
597static int __init mxs_dma_probe(struct platform_device *pdev) 665static int __init mxs_dma_probe(struct platform_device *pdev)
598{ 666{
599 const struct platform_device_id *id_entry = 667 const struct platform_device_id *id_entry;
600 platform_get_device_id(pdev); 668 const struct of_device_id *of_id;
669 const struct mxs_dma_type *dma_type;
601 struct mxs_dma_engine *mxs_dma; 670 struct mxs_dma_engine *mxs_dma;
602 struct resource *iores; 671 struct resource *iores;
603 int ret, i; 672 int ret, i;
@@ -606,7 +675,15 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
606 if (!mxs_dma) 675 if (!mxs_dma)
607 return -ENOMEM; 676 return -ENOMEM;
608 677
609 mxs_dma->dev_id = id_entry->driver_data; 678 of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev);
679 if (of_id)
680 id_entry = of_id->data;
681 else
682 id_entry = platform_get_device_id(pdev);
683
684 dma_type = (struct mxs_dma_type *)id_entry->driver_data;
685 mxs_dma->type = dma_type->type;
686 mxs_dma->dev_id = dma_type->id;
610 687
611 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 688 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
612 689
@@ -689,23 +766,12 @@ err_request_region:
689 return ret; 766 return ret;
690} 767}
691 768
692static struct platform_device_id mxs_dma_type[] = {
693 {
694 .name = "mxs-dma-apbh",
695 .driver_data = MXS_DMA_APBH,
696 }, {
697 .name = "mxs-dma-apbx",
698 .driver_data = MXS_DMA_APBX,
699 }, {
700 /* end of list */
701 }
702};
703
704static struct platform_driver mxs_dma_driver = { 769static struct platform_driver mxs_dma_driver = {
705 .driver = { 770 .driver = {
706 .name = "mxs-dma", 771 .name = "mxs-dma",
772 .of_match_table = mxs_dma_dt_ids,
707 }, 773 },
708 .id_table = mxs_dma_type, 774 .id_table = mxs_dma_ids,
709}; 775};
710 776
711static int __init mxs_dma_module_init(void) 777static int __init mxs_dma_module_init(void)
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 385c58e8405b..429228b52acd 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -25,23 +25,25 @@
25#include <linux/io.h> 25#include <linux/io.h>
26#include <linux/irq.h> 26#include <linux/irq.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/of.h>
29#include <linux/of_address.h>
30#include <linux/of_device.h>
28#include <linux/platform_device.h> 31#include <linux/platform_device.h>
29#include <linux/slab.h> 32#include <linux/slab.h>
30#include <linux/basic_mmio_gpio.h> 33#include <linux/basic_mmio_gpio.h>
31#include <linux/module.h> 34#include <linux/module.h>
32#include <mach/mxs.h>
33 35
34#define MXS_SET 0x4 36#define MXS_SET 0x4
35#define MXS_CLR 0x8 37#define MXS_CLR 0x8
36 38
37#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10) 39#define PINCTRL_DOUT(p) ((is_imx23_gpio(p) ? 0x0500 : 0x0700) + (p->id) * 0x10)
38#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10) 40#define PINCTRL_DIN(p) ((is_imx23_gpio(p) ? 0x0600 : 0x0900) + (p->id) * 0x10)
39#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10) 41#define PINCTRL_DOE(p) ((is_imx23_gpio(p) ? 0x0700 : 0x0b00) + (p->id) * 0x10)
40#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10) 42#define PINCTRL_PIN2IRQ(p) ((is_imx23_gpio(p) ? 0x0800 : 0x1000) + (p->id) * 0x10)
41#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10) 43#define PINCTRL_IRQEN(p) ((is_imx23_gpio(p) ? 0x0900 : 0x1100) + (p->id) * 0x10)
42#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10) 44#define PINCTRL_IRQLEV(p) ((is_imx23_gpio(p) ? 0x0a00 : 0x1200) + (p->id) * 0x10)
43#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10) 45#define PINCTRL_IRQPOL(p) ((is_imx23_gpio(p) ? 0x0b00 : 0x1300) + (p->id) * 0x10)
44#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10) 46#define PINCTRL_IRQSTAT(p) ((is_imx23_gpio(p) ? 0x0c00 : 0x1400) + (p->id) * 0x10)
45 47
46#define GPIO_INT_FALL_EDGE 0x0 48#define GPIO_INT_FALL_EDGE 0x0
47#define GPIO_INT_LOW_LEV 0x1 49#define GPIO_INT_LOW_LEV 0x1
@@ -52,14 +54,30 @@
52 54
53#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START) 55#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
54 56
57enum mxs_gpio_id {
58 IMX23_GPIO,
59 IMX28_GPIO,
60};
61
55struct mxs_gpio_port { 62struct mxs_gpio_port {
56 void __iomem *base; 63 void __iomem *base;
57 int id; 64 int id;
58 int irq; 65 int irq;
59 int virtual_irq_start; 66 int virtual_irq_start;
60 struct bgpio_chip bgc; 67 struct bgpio_chip bgc;
68 enum mxs_gpio_id devid;
61}; 69};
62 70
71static inline int is_imx23_gpio(struct mxs_gpio_port *port)
72{
73 return port->devid == IMX23_GPIO;
74}
75
76static inline int is_imx28_gpio(struct mxs_gpio_port *port)
77{
78 return port->devid == IMX28_GPIO;
79}
80
63/* Note: This driver assumes 32 GPIOs are handled in one register */ 81/* Note: This driver assumes 32 GPIOs are handled in one register */
64 82
65static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type) 83static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
@@ -89,21 +107,21 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
89 } 107 }
90 108
91 /* set level or edge */ 109 /* set level or edge */
92 pin_addr = port->base + PINCTRL_IRQLEV(port->id); 110 pin_addr = port->base + PINCTRL_IRQLEV(port);
93 if (edge & GPIO_INT_LEV_MASK) 111 if (edge & GPIO_INT_LEV_MASK)
94 writel(pin_mask, pin_addr + MXS_SET); 112 writel(pin_mask, pin_addr + MXS_SET);
95 else 113 else
96 writel(pin_mask, pin_addr + MXS_CLR); 114 writel(pin_mask, pin_addr + MXS_CLR);
97 115
98 /* set polarity */ 116 /* set polarity */
99 pin_addr = port->base + PINCTRL_IRQPOL(port->id); 117 pin_addr = port->base + PINCTRL_IRQPOL(port);
100 if (edge & GPIO_INT_POL_MASK) 118 if (edge & GPIO_INT_POL_MASK)
101 writel(pin_mask, pin_addr + MXS_SET); 119 writel(pin_mask, pin_addr + MXS_SET);
102 else 120 else
103 writel(pin_mask, pin_addr + MXS_CLR); 121 writel(pin_mask, pin_addr + MXS_CLR);
104 122
105 writel(1 << (gpio & 0x1f), 123 writel(1 << (gpio & 0x1f),
106 port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); 124 port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
107 125
108 return 0; 126 return 0;
109} 127}
@@ -117,8 +135,8 @@ static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
117 135
118 desc->irq_data.chip->irq_ack(&desc->irq_data); 136 desc->irq_data.chip->irq_ack(&desc->irq_data);
119 137
120 irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) & 138 irq_stat = readl(port->base + PINCTRL_IRQSTAT(port)) &
121 readl(port->base + PINCTRL_IRQEN(port->id)); 139 readl(port->base + PINCTRL_IRQEN(port));
122 140
123 while (irq_stat != 0) { 141 while (irq_stat != 0) {
124 int irqoffset = fls(irq_stat) - 1; 142 int irqoffset = fls(irq_stat) - 1;
@@ -164,8 +182,8 @@ static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port)
164 ct->chip.irq_unmask = irq_gc_mask_set_bit; 182 ct->chip.irq_unmask = irq_gc_mask_set_bit;
165 ct->chip.irq_set_type = mxs_gpio_set_irq_type; 183 ct->chip.irq_set_type = mxs_gpio_set_irq_type;
166 ct->chip.irq_set_wake = mxs_gpio_set_wake_irq; 184 ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
167 ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR; 185 ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
168 ct->regs.mask = PINCTRL_IRQEN(port->id); 186 ct->regs.mask = PINCTRL_IRQEN(port);
169 187
170 irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0); 188 irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
171} 189}
@@ -179,60 +197,83 @@ static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
179 return port->virtual_irq_start + offset; 197 return port->virtual_irq_start + offset;
180} 198}
181 199
200static struct platform_device_id mxs_gpio_ids[] = {
201 {
202 .name = "imx23-gpio",
203 .driver_data = IMX23_GPIO,
204 }, {
205 .name = "imx28-gpio",
206 .driver_data = IMX28_GPIO,
207 }, {
208 /* sentinel */
209 }
210};
211MODULE_DEVICE_TABLE(platform, mxs_gpio_ids);
212
213static const struct of_device_id mxs_gpio_dt_ids[] = {
214 { .compatible = "fsl,imx23-gpio", .data = (void *) IMX23_GPIO, },
215 { .compatible = "fsl,imx28-gpio", .data = (void *) IMX28_GPIO, },
216 { /* sentinel */ }
217};
218MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids);
219
182static int __devinit mxs_gpio_probe(struct platform_device *pdev) 220static int __devinit mxs_gpio_probe(struct platform_device *pdev)
183{ 221{
222 const struct of_device_id *of_id =
223 of_match_device(mxs_gpio_dt_ids, &pdev->dev);
224 struct device_node *np = pdev->dev.of_node;
225 struct device_node *parent;
184 static void __iomem *base; 226 static void __iomem *base;
185 struct mxs_gpio_port *port; 227 struct mxs_gpio_port *port;
186 struct resource *iores = NULL; 228 struct resource *iores = NULL;
187 int err; 229 int err;
188 230
189 port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL); 231 port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
190 if (!port) 232 if (!port)
191 return -ENOMEM; 233 return -ENOMEM;
192 234
193 port->id = pdev->id; 235 if (np) {
236 port->id = of_alias_get_id(np, "gpio");
237 if (port->id < 0)
238 return port->id;
239 port->devid = (enum mxs_gpio_id) of_id->data;
240 } else {
241 port->id = pdev->id;
242 port->devid = pdev->id_entry->driver_data;
243 }
194 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32; 244 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
195 245
246 port->irq = platform_get_irq(pdev, 0);
247 if (port->irq < 0)
248 return port->irq;
249
196 /* 250 /*
197 * map memory region only once, as all the gpio ports 251 * map memory region only once, as all the gpio ports
198 * share the same one 252 * share the same one
199 */ 253 */
200 if (!base) { 254 if (!base) {
201 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 255 if (np) {
202 if (!iores) { 256 parent = of_get_parent(np);
203 err = -ENODEV; 257 base = of_iomap(parent, 0);
204 goto out_kfree; 258 of_node_put(parent);
205 } 259 } else {
206 260 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
207 if (!request_mem_region(iores->start, resource_size(iores), 261 base = devm_request_and_ioremap(&pdev->dev, iores);
208 pdev->name)) {
209 err = -EBUSY;
210 goto out_kfree;
211 }
212
213 base = ioremap(iores->start, resource_size(iores));
214 if (!base) {
215 err = -ENOMEM;
216 goto out_release_mem;
217 } 262 }
263 if (!base)
264 return -EADDRNOTAVAIL;
218 } 265 }
219 port->base = base; 266 port->base = base;
220 267
221 port->irq = platform_get_irq(pdev, 0);
222 if (port->irq < 0) {
223 err = -EINVAL;
224 goto out_iounmap;
225 }
226
227 /* 268 /*
228 * select the pin interrupt functionality but initially 269 * select the pin interrupt functionality but initially
229 * disable the interrupts 270 * disable the interrupts
230 */ 271 */
231 writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id)); 272 writel(~0U, port->base + PINCTRL_PIN2IRQ(port));
232 writel(0, port->base + PINCTRL_IRQEN(port->id)); 273 writel(0, port->base + PINCTRL_IRQEN(port));
233 274
234 /* clear address has to be used to clear IRQSTAT bits */ 275 /* clear address has to be used to clear IRQSTAT bits */
235 writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR); 276 writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
236 277
237 /* gpio-mxs can be a generic irq chip */ 278 /* gpio-mxs can be a generic irq chip */
238 mxs_gpio_init_gc(port); 279 mxs_gpio_init_gc(port);
@@ -242,41 +283,32 @@ static int __devinit mxs_gpio_probe(struct platform_device *pdev)
242 irq_set_handler_data(port->irq, port); 283 irq_set_handler_data(port->irq, port);
243 284
244 err = bgpio_init(&port->bgc, &pdev->dev, 4, 285 err = bgpio_init(&port->bgc, &pdev->dev, 4,
245 port->base + PINCTRL_DIN(port->id), 286 port->base + PINCTRL_DIN(port),
246 port->base + PINCTRL_DOUT(port->id), NULL, 287 port->base + PINCTRL_DOUT(port), NULL,
247 port->base + PINCTRL_DOE(port->id), NULL, false); 288 port->base + PINCTRL_DOE(port), NULL, false);
248 if (err) 289 if (err)
249 goto out_iounmap; 290 return err;
250 291
251 port->bgc.gc.to_irq = mxs_gpio_to_irq; 292 port->bgc.gc.to_irq = mxs_gpio_to_irq;
252 port->bgc.gc.base = port->id * 32; 293 port->bgc.gc.base = port->id * 32;
253 294
254 err = gpiochip_add(&port->bgc.gc); 295 err = gpiochip_add(&port->bgc.gc);
255 if (err) 296 if (err) {
256 goto out_bgpio_remove; 297 bgpio_remove(&port->bgc);
298 return err;
299 }
257 300
258 return 0; 301 return 0;
259
260out_bgpio_remove:
261 bgpio_remove(&port->bgc);
262out_iounmap:
263 if (iores)
264 iounmap(port->base);
265out_release_mem:
266 if (iores)
267 release_mem_region(iores->start, resource_size(iores));
268out_kfree:
269 kfree(port);
270 dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
271 return err;
272} 302}
273 303
274static struct platform_driver mxs_gpio_driver = { 304static struct platform_driver mxs_gpio_driver = {
275 .driver = { 305 .driver = {
276 .name = "gpio-mxs", 306 .name = "gpio-mxs",
277 .owner = THIS_MODULE, 307 .owner = THIS_MODULE,
308 .of_match_table = mxs_gpio_dt_ids,
278 }, 309 },
279 .probe = mxs_gpio_probe, 310 .probe = mxs_gpio_probe,
311 .id_table = mxs_gpio_ids,
280}; 312};
281 313
282static int __init mxs_gpio_init(void) 314static int __init mxs_gpio_init(void)
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index dfb84b7ee550..56bce9a8bcbb 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -51,6 +51,7 @@
51#include <linux/of.h> 51#include <linux/of.h>
52#include <linux/of_device.h> 52#include <linux/of_device.h>
53#include <linux/of_i2c.h> 53#include <linux/of_i2c.h>
54#include <linux/pinctrl/consumer.h>
54 55
55#include <mach/irqs.h> 56#include <mach/irqs.h>
56#include <mach/hardware.h> 57#include <mach/hardware.h>
@@ -470,6 +471,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
470 struct imx_i2c_struct *i2c_imx; 471 struct imx_i2c_struct *i2c_imx;
471 struct resource *res; 472 struct resource *res;
472 struct imxi2c_platform_data *pdata = pdev->dev.platform_data; 473 struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
474 struct pinctrl *pinctrl;
473 void __iomem *base; 475 void __iomem *base;
474 resource_size_t res_size; 476 resource_size_t res_size;
475 int irq, bitrate; 477 int irq, bitrate;
@@ -520,6 +522,12 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
520 i2c_imx->base = base; 522 i2c_imx->base = base;
521 i2c_imx->res = res; 523 i2c_imx->res = res;
522 524
525 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
526 if (IS_ERR(pinctrl)) {
527 ret = PTR_ERR(pinctrl);
528 goto fail3;
529 }
530
523 /* Get I2C clock */ 531 /* Get I2C clock */
524 i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk"); 532 i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");
525 if (IS_ERR(i2c_imx->clk)) { 533 if (IS_ERR(i2c_imx->clk)) {
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 76b8af44f634..7dca58b0e746 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -26,6 +26,10 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/pinctrl/consumer.h>
30#include <linux/of.h>
31#include <linux/of_device.h>
32#include <linux/of_i2c.h>
29 33
30#include <mach/common.h> 34#include <mach/common.h>
31 35
@@ -325,10 +329,15 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
325 struct device *dev = &pdev->dev; 329 struct device *dev = &pdev->dev;
326 struct mxs_i2c_dev *i2c; 330 struct mxs_i2c_dev *i2c;
327 struct i2c_adapter *adap; 331 struct i2c_adapter *adap;
332 struct pinctrl *pinctrl;
328 struct resource *res; 333 struct resource *res;
329 resource_size_t res_size; 334 resource_size_t res_size;
330 int err, irq; 335 int err, irq;
331 336
337 pinctrl = devm_pinctrl_get_select_default(dev);
338 if (IS_ERR(pinctrl))
339 return PTR_ERR(pinctrl);
340
332 i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL); 341 i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);
333 if (!i2c) 342 if (!i2c)
334 return -ENOMEM; 343 return -ENOMEM;
@@ -365,6 +374,7 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
365 adap->algo = &mxs_i2c_algo; 374 adap->algo = &mxs_i2c_algo;
366 adap->dev.parent = dev; 375 adap->dev.parent = dev;
367 adap->nr = pdev->id; 376 adap->nr = pdev->id;
377 adap->dev.of_node = pdev->dev.of_node;
368 i2c_set_adapdata(adap, i2c); 378 i2c_set_adapdata(adap, i2c);
369 err = i2c_add_numbered_adapter(adap); 379 err = i2c_add_numbered_adapter(adap);
370 if (err) { 380 if (err) {
@@ -374,6 +384,8 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
374 return err; 384 return err;
375 } 385 }
376 386
387 of_i2c_register_devices(adap);
388
377 return 0; 389 return 0;
378} 390}
379 391
@@ -393,10 +405,17 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev)
393 return 0; 405 return 0;
394} 406}
395 407
408static const struct of_device_id mxs_i2c_dt_ids[] = {
409 { .compatible = "fsl,imx28-i2c", },
410 { /* sentinel */ }
411};
412MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
413
396static struct platform_driver mxs_i2c_driver = { 414static struct platform_driver mxs_i2c_driver = {
397 .driver = { 415 .driver = {
398 .name = DRIVER_NAME, 416 .name = DRIVER_NAME,
399 .owner = THIS_MODULE, 417 .owner = THIS_MODULE,
418 .of_match_table = mxs_i2c_dt_ids,
400 }, 419 },
401 .remove = __devexit_p(mxs_i2c_remove), 420 .remove = __devexit_p(mxs_i2c_remove),
402}; 421};
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index e3f5af96ab87..34a90266ab11 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -23,6 +23,9 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/of.h>
27#include <linux/of_device.h>
28#include <linux/of_gpio.h>
26#include <linux/platform_device.h> 29#include <linux/platform_device.h>
27#include <linux/delay.h> 30#include <linux/delay.h>
28#include <linux/interrupt.h> 31#include <linux/interrupt.h>
@@ -39,18 +42,16 @@
39#include <linux/regulator/consumer.h> 42#include <linux/regulator/consumer.h>
40#include <linux/module.h> 43#include <linux/module.h>
41#include <linux/fsl/mxs-dma.h> 44#include <linux/fsl/mxs-dma.h>
42 45#include <linux/pinctrl/consumer.h>
43#include <mach/mxs.h> 46#include <linux/stmp_device.h>
44#include <mach/common.h> 47#include <linux/mmc/mxs-mmc.h>
45#include <mach/mmc.h>
46 48
47#define DRIVER_NAME "mxs-mmc" 49#define DRIVER_NAME "mxs-mmc"
48 50
49/* card detect polling timeout */ 51/* card detect polling timeout */
50#define MXS_MMC_DETECT_TIMEOUT (HZ/2) 52#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
51 53
52#define SSP_VERSION_LATEST 4 54#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
53#define ssp_is_old() (host->version < SSP_VERSION_LATEST)
54 55
55/* SSP registers */ 56/* SSP registers */
56#define HW_SSP_CTRL0 0x000 57#define HW_SSP_CTRL0 0x000
@@ -85,14 +86,14 @@
85#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4) 86#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
86#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0) 87#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0)
87#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf) 88#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf)
88#define HW_SSP_TIMING (ssp_is_old() ? 0x050 : 0x070) 89#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
89#define BP_SSP_TIMING_TIMEOUT (16) 90#define BP_SSP_TIMING_TIMEOUT (16)
90#define BM_SSP_TIMING_TIMEOUT (0xffff << 16) 91#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
91#define BP_SSP_TIMING_CLOCK_DIVIDE (8) 92#define BP_SSP_TIMING_CLOCK_DIVIDE (8)
92#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8) 93#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
93#define BP_SSP_TIMING_CLOCK_RATE (0) 94#define BP_SSP_TIMING_CLOCK_RATE (0)
94#define BM_SSP_TIMING_CLOCK_RATE (0xff) 95#define BM_SSP_TIMING_CLOCK_RATE (0xff)
95#define HW_SSP_CTRL1 (ssp_is_old() ? 0x060 : 0x080) 96#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
96#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31) 97#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
97#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30) 98#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
98#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29) 99#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
@@ -115,15 +116,13 @@
115#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4) 116#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
116#define BP_SSP_CTRL1_SSP_MODE (0) 117#define BP_SSP_CTRL1_SSP_MODE (0)
117#define BM_SSP_CTRL1_SSP_MODE (0xf) 118#define BM_SSP_CTRL1_SSP_MODE (0xf)
118#define HW_SSP_SDRESP0 (ssp_is_old() ? 0x080 : 0x0a0) 119#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
119#define HW_SSP_SDRESP1 (ssp_is_old() ? 0x090 : 0x0b0) 120#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
120#define HW_SSP_SDRESP2 (ssp_is_old() ? 0x0a0 : 0x0c0) 121#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
121#define HW_SSP_SDRESP3 (ssp_is_old() ? 0x0b0 : 0x0d0) 122#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
122#define HW_SSP_STATUS (ssp_is_old() ? 0x0c0 : 0x100) 123#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
123#define BM_SSP_STATUS_CARD_DETECT (1 << 28) 124#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
124#define BM_SSP_STATUS_SDIO_IRQ (1 << 17) 125#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
125#define HW_SSP_VERSION (cpu_is_mx23() ? 0x110 : 0x130)
126#define BP_SSP_VERSION_MAJOR (24)
127 126
128#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field) 127#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field)
129 128
@@ -138,6 +137,11 @@
138 137
139#define SSP_PIO_NUM 3 138#define SSP_PIO_NUM 3
140 139
140enum mxs_mmc_id {
141 IMX23_MMC,
142 IMX28_MMC,
143};
144
141struct mxs_mmc_host { 145struct mxs_mmc_host {
142 struct mmc_host *mmc; 146 struct mmc_host *mmc;
143 struct mmc_request *mrq; 147 struct mmc_request *mrq;
@@ -145,9 +149,7 @@ struct mxs_mmc_host {
145 struct mmc_data *data; 149 struct mmc_data *data;
146 150
147 void __iomem *base; 151 void __iomem *base;
148 int irq; 152 int dma_channel;
149 struct resource *res;
150 struct resource *dma_res;
151 struct clk *clk; 153 struct clk *clk;
152 unsigned int clk_rate; 154 unsigned int clk_rate;
153 155
@@ -157,32 +159,28 @@ struct mxs_mmc_host {
157 enum dma_transfer_direction slave_dirn; 159 enum dma_transfer_direction slave_dirn;
158 u32 ssp_pio_words[SSP_PIO_NUM]; 160 u32 ssp_pio_words[SSP_PIO_NUM];
159 161
160 unsigned int version; 162 enum mxs_mmc_id devid;
161 unsigned char bus_width; 163 unsigned char bus_width;
162 spinlock_t lock; 164 spinlock_t lock;
163 int sdio_irq_en; 165 int sdio_irq_en;
166 int wp_gpio;
164}; 167};
165 168
166static int mxs_mmc_get_ro(struct mmc_host *mmc) 169static int mxs_mmc_get_ro(struct mmc_host *mmc)
167{ 170{
168 struct mxs_mmc_host *host = mmc_priv(mmc); 171 struct mxs_mmc_host *host = mmc_priv(mmc);
169 struct mxs_mmc_platform_data *pdata =
170 mmc_dev(host->mmc)->platform_data;
171
172 if (!pdata)
173 return -EFAULT;
174 172
175 if (!gpio_is_valid(pdata->wp_gpio)) 173 if (!gpio_is_valid(host->wp_gpio))
176 return -EINVAL; 174 return -EINVAL;
177 175
178 return gpio_get_value(pdata->wp_gpio); 176 return gpio_get_value(host->wp_gpio);
179} 177}
180 178
181static int mxs_mmc_get_cd(struct mmc_host *mmc) 179static int mxs_mmc_get_cd(struct mmc_host *mmc)
182{ 180{
183 struct mxs_mmc_host *host = mmc_priv(mmc); 181 struct mxs_mmc_host *host = mmc_priv(mmc);
184 182
185 return !(readl(host->base + HW_SSP_STATUS) & 183 return !(readl(host->base + HW_SSP_STATUS(host)) &
186 BM_SSP_STATUS_CARD_DETECT); 184 BM_SSP_STATUS_CARD_DETECT);
187} 185}
188 186
@@ -190,7 +188,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
190{ 188{
191 u32 ctrl0, ctrl1; 189 u32 ctrl0, ctrl1;
192 190
193 mxs_reset_block(host->base); 191 stmp_reset_block(host->base);
194 192
195 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; 193 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
196 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | 194 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
@@ -206,7 +204,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
206 writel(BF_SSP(0xffff, TIMING_TIMEOUT) | 204 writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
207 BF_SSP(2, TIMING_CLOCK_DIVIDE) | 205 BF_SSP(2, TIMING_CLOCK_DIVIDE) |
208 BF_SSP(0, TIMING_CLOCK_RATE), 206 BF_SSP(0, TIMING_CLOCK_RATE),
209 host->base + HW_SSP_TIMING); 207 host->base + HW_SSP_TIMING(host));
210 208
211 if (host->sdio_irq_en) { 209 if (host->sdio_irq_en) {
212 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; 210 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
@@ -214,7 +212,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
214 } 212 }
215 213
216 writel(ctrl0, host->base + HW_SSP_CTRL0); 214 writel(ctrl0, host->base + HW_SSP_CTRL0);
217 writel(ctrl1, host->base + HW_SSP_CTRL1); 215 writel(ctrl1, host->base + HW_SSP_CTRL1(host));
218} 216}
219 217
220static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, 218static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -228,12 +226,12 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
228 226
229 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { 227 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
230 if (mmc_resp_type(cmd) & MMC_RSP_136) { 228 if (mmc_resp_type(cmd) & MMC_RSP_136) {
231 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0); 229 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
232 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1); 230 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
233 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2); 231 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
234 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3); 232 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
235 } else { 233 } else {
236 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0); 234 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
237 } 235 }
238 } 236 }
239 237
@@ -276,9 +274,9 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
276 274
277 spin_lock(&host->lock); 275 spin_lock(&host->lock);
278 276
279 stat = readl(host->base + HW_SSP_CTRL1); 277 stat = readl(host->base + HW_SSP_CTRL1(host));
280 writel(stat & MXS_MMC_IRQ_BITS, 278 writel(stat & MXS_MMC_IRQ_BITS,
281 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 279 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
282 280
283 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) 281 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
284 mmc_signal_sdio_irq(host->mmc); 282 mmc_signal_sdio_irq(host->mmc);
@@ -484,7 +482,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
484 blocks = 1; 482 blocks = 1;
485 483
486 /* xfer count, block size and count need to be set differently */ 484 /* xfer count, block size and count need to be set differently */
487 if (ssp_is_old()) { 485 if (ssp_is_old(host)) {
488 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); 486 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
489 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | 487 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
490 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); 488 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
@@ -508,10 +506,10 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
508 506
509 /* set the timeout count */ 507 /* set the timeout count */
510 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns); 508 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
511 val = readl(host->base + HW_SSP_TIMING); 509 val = readl(host->base + HW_SSP_TIMING(host));
512 val &= ~(BM_SSP_TIMING_TIMEOUT); 510 val &= ~(BM_SSP_TIMING_TIMEOUT);
513 val |= BF_SSP(timeout, TIMING_TIMEOUT); 511 val |= BF_SSP(timeout, TIMING_TIMEOUT);
514 writel(val, host->base + HW_SSP_TIMING); 512 writel(val, host->base + HW_SSP_TIMING(host));
515 513
516 /* pio */ 514 /* pio */
517 host->ssp_pio_words[0] = ctrl0; 515 host->ssp_pio_words[0] = ctrl0;
@@ -597,11 +595,11 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
597 595
598 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); 596 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
599 597
600 val = readl(host->base + HW_SSP_TIMING); 598 val = readl(host->base + HW_SSP_TIMING(host));
601 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); 599 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
602 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); 600 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
603 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); 601 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
604 writel(val, host->base + HW_SSP_TIMING); 602 writel(val, host->base + HW_SSP_TIMING(host));
605 603
606 host->clk_rate = ssp_sck; 604 host->clk_rate = ssp_sck;
607 605
@@ -636,18 +634,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
636 634
637 if (enable) { 635 if (enable) {
638 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 636 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
639 host->base + HW_SSP_CTRL0 + MXS_SET_ADDR); 637 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
640 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 638 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
641 host->base + HW_SSP_CTRL1 + MXS_SET_ADDR); 639 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
642 640
643 if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ) 641 if (readl(host->base + HW_SSP_STATUS(host)) &
642 BM_SSP_STATUS_SDIO_IRQ)
644 mmc_signal_sdio_irq(host->mmc); 643 mmc_signal_sdio_irq(host->mmc);
645 644
646 } else { 645 } else {
647 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 646 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
648 host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR); 647 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
649 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 648 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
650 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 649 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
651 } 650 }
652 651
653 spin_unlock_irqrestore(&host->lock, flags); 652 spin_unlock_irqrestore(&host->lock, flags);
@@ -668,7 +667,7 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
668 if (!mxs_dma_is_apbh(chan)) 667 if (!mxs_dma_is_apbh(chan))
669 return false; 668 return false;
670 669
671 if (chan->chan_id != host->dma_res->start) 670 if (chan->chan_id != host->dma_channel)
672 return false; 671 return false;
673 672
674 chan->private = &host->dma_data; 673 chan->private = &host->dma_data;
@@ -676,12 +675,36 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
676 return true; 675 return true;
677} 676}
678 677
678static struct platform_device_id mxs_mmc_ids[] = {
679 {
680 .name = "imx23-mmc",
681 .driver_data = IMX23_MMC,
682 }, {
683 .name = "imx28-mmc",
684 .driver_data = IMX28_MMC,
685 }, {
686 /* sentinel */
687 }
688};
689MODULE_DEVICE_TABLE(platform, mxs_mmc_ids);
690
691static const struct of_device_id mxs_mmc_dt_ids[] = {
692 { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_MMC, },
693 { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_MMC, },
694 { /* sentinel */ }
695};
696MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
697
679static int mxs_mmc_probe(struct platform_device *pdev) 698static int mxs_mmc_probe(struct platform_device *pdev)
680{ 699{
700 const struct of_device_id *of_id =
701 of_match_device(mxs_mmc_dt_ids, &pdev->dev);
702 struct device_node *np = pdev->dev.of_node;
681 struct mxs_mmc_host *host; 703 struct mxs_mmc_host *host;
682 struct mmc_host *mmc; 704 struct mmc_host *mmc;
683 struct resource *iores, *dmares, *r; 705 struct resource *iores, *dmares;
684 struct mxs_mmc_platform_data *pdata; 706 struct mxs_mmc_platform_data *pdata;
707 struct pinctrl *pinctrl;
685 int ret = 0, irq_err, irq_dma; 708 int ret = 0, irq_err, irq_dma;
686 dma_cap_mask_t mask; 709 dma_cap_mask_t mask;
687 710
@@ -689,40 +712,51 @@ static int mxs_mmc_probe(struct platform_device *pdev)
689 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 712 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
690 irq_err = platform_get_irq(pdev, 0); 713 irq_err = platform_get_irq(pdev, 0);
691 irq_dma = platform_get_irq(pdev, 1); 714 irq_dma = platform_get_irq(pdev, 1);
692 if (!iores || !dmares || irq_err < 0 || irq_dma < 0) 715 if (!iores || irq_err < 0 || irq_dma < 0)
693 return -EINVAL; 716 return -EINVAL;
694 717
695 r = request_mem_region(iores->start, resource_size(iores), pdev->name);
696 if (!r)
697 return -EBUSY;
698
699 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); 718 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
700 if (!mmc) { 719 if (!mmc)
701 ret = -ENOMEM; 720 return -ENOMEM;
702 goto out_release_mem;
703 }
704 721
705 host = mmc_priv(mmc); 722 host = mmc_priv(mmc);
706 host->base = ioremap(r->start, resource_size(r)); 723 host->base = devm_request_and_ioremap(&pdev->dev, iores);
707 if (!host->base) { 724 if (!host->base) {
708 ret = -ENOMEM; 725 ret = -EADDRNOTAVAIL;
709 goto out_mmc_free; 726 goto out_mmc_free;
710 } 727 }
711 728
712 /* only major verion does matter */ 729 if (np) {
713 host->version = readl(host->base + HW_SSP_VERSION) >> 730 host->devid = (enum mxs_mmc_id) of_id->data;
714 BP_SSP_VERSION_MAJOR; 731 /*
732 * TODO: This is a temporary solution and should be changed
733 * to use generic DMA binding later when the helpers get in.
734 */
735 ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
736 &host->dma_channel);
737 if (ret) {
738 dev_err(mmc_dev(host->mmc),
739 "failed to get dma channel\n");
740 goto out_mmc_free;
741 }
742 } else {
743 host->devid = pdev->id_entry->driver_data;
744 host->dma_channel = dmares->start;
745 }
715 746
716 host->mmc = mmc; 747 host->mmc = mmc;
717 host->res = r;
718 host->dma_res = dmares;
719 host->irq = irq_err;
720 host->sdio_irq_en = 0; 748 host->sdio_irq_en = 0;
721 749
750 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
751 if (IS_ERR(pinctrl)) {
752 ret = PTR_ERR(pinctrl);
753 goto out_mmc_free;
754 }
755
722 host->clk = clk_get(&pdev->dev, NULL); 756 host->clk = clk_get(&pdev->dev, NULL);
723 if (IS_ERR(host->clk)) { 757 if (IS_ERR(host->clk)) {
724 ret = PTR_ERR(host->clk); 758 ret = PTR_ERR(host->clk);
725 goto out_iounmap; 759 goto out_mmc_free;
726 } 760 }
727 clk_prepare_enable(host->clk); 761 clk_prepare_enable(host->clk);
728 762
@@ -744,11 +778,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
744 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; 778 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
745 779
746 pdata = mmc_dev(host->mmc)->platform_data; 780 pdata = mmc_dev(host->mmc)->platform_data;
747 if (pdata) { 781 if (!pdata) {
782 u32 bus_width = 0;
783 of_property_read_u32(np, "bus-width", &bus_width);
784 if (bus_width == 4)
785 mmc->caps |= MMC_CAP_4_BIT_DATA;
786 else if (bus_width == 8)
787 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
788 host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
789 } else {
748 if (pdata->flags & SLOTF_8_BIT_CAPABLE) 790 if (pdata->flags & SLOTF_8_BIT_CAPABLE)
749 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; 791 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
750 if (pdata->flags & SLOTF_4_BIT_CAPABLE) 792 if (pdata->flags & SLOTF_4_BIT_CAPABLE)
751 mmc->caps |= MMC_CAP_4_BIT_DATA; 793 mmc->caps |= MMC_CAP_4_BIT_DATA;
794 host->wp_gpio = pdata->wp_gpio;
752 } 795 }
753 796
754 mmc->f_min = 400000; 797 mmc->f_min = 400000;
@@ -757,13 +800,14 @@ static int mxs_mmc_probe(struct platform_device *pdev)
757 800
758 mmc->max_segs = 52; 801 mmc->max_segs = 52;
759 mmc->max_blk_size = 1 << 0xf; 802 mmc->max_blk_size = 1 << 0xf;
760 mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff; 803 mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
761 mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff; 804 mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
762 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); 805 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
763 806
764 platform_set_drvdata(pdev, mmc); 807 platform_set_drvdata(pdev, mmc);
765 808
766 ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host); 809 ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
810 DRIVER_NAME, host);
767 if (ret) 811 if (ret)
768 goto out_free_dma; 812 goto out_free_dma;
769 813
@@ -771,26 +815,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
771 815
772 ret = mmc_add_host(mmc); 816 ret = mmc_add_host(mmc);
773 if (ret) 817 if (ret)
774 goto out_free_irq; 818 goto out_free_dma;
775 819
776 dev_info(mmc_dev(host->mmc), "initialized\n"); 820 dev_info(mmc_dev(host->mmc), "initialized\n");
777 821
778 return 0; 822 return 0;
779 823
780out_free_irq:
781 free_irq(host->irq, host);
782out_free_dma: 824out_free_dma:
783 if (host->dmach) 825 if (host->dmach)
784 dma_release_channel(host->dmach); 826 dma_release_channel(host->dmach);
785out_clk_put: 827out_clk_put:
786 clk_disable_unprepare(host->clk); 828 clk_disable_unprepare(host->clk);
787 clk_put(host->clk); 829 clk_put(host->clk);
788out_iounmap:
789 iounmap(host->base);
790out_mmc_free: 830out_mmc_free:
791 mmc_free_host(mmc); 831 mmc_free_host(mmc);
792out_release_mem:
793 release_mem_region(iores->start, resource_size(iores));
794 return ret; 832 return ret;
795} 833}
796 834
@@ -798,12 +836,9 @@ static int mxs_mmc_remove(struct platform_device *pdev)
798{ 836{
799 struct mmc_host *mmc = platform_get_drvdata(pdev); 837 struct mmc_host *mmc = platform_get_drvdata(pdev);
800 struct mxs_mmc_host *host = mmc_priv(mmc); 838 struct mxs_mmc_host *host = mmc_priv(mmc);
801 struct resource *res = host->res;
802 839
803 mmc_remove_host(mmc); 840 mmc_remove_host(mmc);
804 841
805 free_irq(host->irq, host);
806
807 platform_set_drvdata(pdev, NULL); 842 platform_set_drvdata(pdev, NULL);
808 843
809 if (host->dmach) 844 if (host->dmach)
@@ -812,12 +847,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
812 clk_disable_unprepare(host->clk); 847 clk_disable_unprepare(host->clk);
813 clk_put(host->clk); 848 clk_put(host->clk);
814 849
815 iounmap(host->base);
816
817 mmc_free_host(mmc); 850 mmc_free_host(mmc);
818 851
819 release_mem_region(res->start, resource_size(res));
820
821 return 0; 852 return 0;
822} 853}
823 854
@@ -857,11 +888,13 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = {
857static struct platform_driver mxs_mmc_driver = { 888static struct platform_driver mxs_mmc_driver = {
858 .probe = mxs_mmc_probe, 889 .probe = mxs_mmc_probe,
859 .remove = mxs_mmc_remove, 890 .remove = mxs_mmc_remove,
891 .id_table = mxs_mmc_ids,
860 .driver = { 892 .driver = {
861 .name = DRIVER_NAME, 893 .name = DRIVER_NAME,
862 .owner = THIS_MODULE, 894 .owner = THIS_MODULE,
863#ifdef CONFIG_PM 895#ifdef CONFIG_PM
864 .pm = &mxs_mmc_pm_ops, 896 .pm = &mxs_mmc_pm_ops,
897 .of_match_table = mxs_mmc_dt_ids,
865#endif 898#endif
866 }, 899 },
867}; 900};
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 8abdaf6697a8..d190d04636a7 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -24,6 +24,7 @@
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_device.h> 25#include <linux/of_device.h>
26#include <linux/of_gpio.h> 26#include <linux/of_gpio.h>
27#include <linux/pinctrl/consumer.h>
27#include <mach/esdhc.h> 28#include <mach/esdhc.h>
28#include "sdhci-pltfm.h" 29#include "sdhci-pltfm.h"
29#include "sdhci-esdhc.h" 30#include "sdhci-esdhc.h"
@@ -68,6 +69,7 @@ struct pltfm_imx_data {
68 int flags; 69 int flags;
69 u32 scratchpad; 70 u32 scratchpad;
70 enum imx_esdhc_type devtype; 71 enum imx_esdhc_type devtype;
72 struct pinctrl *pinctrl;
71 struct esdhc_platform_data boarddata; 73 struct esdhc_platform_data boarddata;
72}; 74};
73 75
@@ -467,6 +469,12 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
467 clk_prepare_enable(clk); 469 clk_prepare_enable(clk);
468 pltfm_host->clk = clk; 470 pltfm_host->clk = clk;
469 471
472 imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
473 if (IS_ERR(imx_data->pinctrl)) {
474 err = PTR_ERR(imx_data->pinctrl);
475 goto pin_err;
476 }
477
470 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 478 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
471 479
472 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) 480 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
@@ -558,6 +566,7 @@ no_card_detect_irq:
558 gpio_free(boarddata->wp_gpio); 566 gpio_free(boarddata->wp_gpio);
559no_card_detect_pin: 567no_card_detect_pin:
560no_board_data: 568no_board_data:
569pin_err:
561 clk_disable_unprepare(pltfm_host->clk); 570 clk_disable_unprepare(pltfm_host->clk);
562 clk_put(pltfm_host->clk); 571 clk_put(pltfm_host->clk);
563err_clk_get: 572err_clk_get:
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 9ec51cec2e14..8478fd9701a3 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -24,6 +24,7 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/mtd/gpmi-nand.h> 25#include <linux/mtd/gpmi-nand.h>
26#include <linux/mtd/partitions.h> 26#include <linux/mtd/partitions.h>
27#include <linux/pinctrl/consumer.h>
27#include "gpmi-nand.h" 28#include "gpmi-nand.h"
28 29
29/* add our owner bbt descriptor */ 30/* add our owner bbt descriptor */
@@ -476,6 +477,7 @@ acquire_err:
476static int __devinit acquire_resources(struct gpmi_nand_data *this) 477static int __devinit acquire_resources(struct gpmi_nand_data *this)
477{ 478{
478 struct resources *res = &this->resources; 479 struct resources *res = &this->resources;
480 struct pinctrl *pinctrl;
479 int ret; 481 int ret;
480 482
481 ret = acquire_register_block(this, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME); 483 ret = acquire_register_block(this, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME);
@@ -494,6 +496,12 @@ static int __devinit acquire_resources(struct gpmi_nand_data *this)
494 if (ret) 496 if (ret)
495 goto exit_dma_channels; 497 goto exit_dma_channels;
496 498
499 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
500 if (IS_ERR(pinctrl)) {
501 ret = PTR_ERR(pinctrl);
502 goto exit_pin;
503 }
504
497 res->clock = clk_get(&this->pdev->dev, NULL); 505 res->clock = clk_get(&this->pdev->dev, NULL);
498 if (IS_ERR(res->clock)) { 506 if (IS_ERR(res->clock)) {
499 pr_err("can not get the clock\n"); 507 pr_err("can not get the clock\n");
@@ -503,6 +511,7 @@ static int __devinit acquire_resources(struct gpmi_nand_data *this)
503 return 0; 511 return 0;
504 512
505exit_clock: 513exit_clock:
514exit_pin:
506 release_dma_channels(this); 515 release_dma_channels(this);
507exit_dma_channels: 516exit_dma_channels:
508 release_bch_irq(this); 517 release_bch_irq(this);
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 1efb08386c61..38c0690df5c8 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -35,6 +35,7 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/of.h> 36#include <linux/of.h>
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/pinctrl/consumer.h>
38 39
39#define DRV_NAME "flexcan" 40#define DRV_NAME "flexcan"
40 41
@@ -927,11 +928,16 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
927 struct flexcan_priv *priv; 928 struct flexcan_priv *priv;
928 struct resource *mem; 929 struct resource *mem;
929 struct clk *clk = NULL; 930 struct clk *clk = NULL;
931 struct pinctrl *pinctrl;
930 void __iomem *base; 932 void __iomem *base;
931 resource_size_t mem_size; 933 resource_size_t mem_size;
932 int err, irq; 934 int err, irq;
933 u32 clock_freq = 0; 935 u32 clock_freq = 0;
934 936
937 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
938 if (IS_ERR(pinctrl))
939 return PTR_ERR(pinctrl);
940
935 if (pdev->dev.of_node) { 941 if (pdev->dev.of_node) {
936 const u32 *clock_freq_p; 942 const u32 *clock_freq_p;
937 943
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index a12b3f5bc025..500c106af86e 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -48,6 +48,7 @@
48#include <linux/of_device.h> 48#include <linux/of_device.h>
49#include <linux/of_gpio.h> 49#include <linux/of_gpio.h>
50#include <linux/of_net.h> 50#include <linux/of_net.h>
51#include <linux/pinctrl/consumer.h>
51 52
52#include <asm/cacheflush.h> 53#include <asm/cacheflush.h>
53 54
@@ -1542,6 +1543,7 @@ fec_probe(struct platform_device *pdev)
1542 struct resource *r; 1543 struct resource *r;
1543 const struct of_device_id *of_id; 1544 const struct of_device_id *of_id;
1544 static int dev_id; 1545 static int dev_id;
1546 struct pinctrl *pinctrl;
1545 1547
1546 of_id = of_match_device(fec_dt_ids, &pdev->dev); 1548 of_id = of_match_device(fec_dt_ids, &pdev->dev);
1547 if (of_id) 1549 if (of_id)
@@ -1609,6 +1611,12 @@ fec_probe(struct platform_device *pdev)
1609 } 1611 }
1610 } 1612 }
1611 1613
1614 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
1615 if (IS_ERR(pinctrl)) {
1616 ret = PTR_ERR(pinctrl);
1617 goto failed_pin;
1618 }
1619
1612 fep->clk = clk_get(&pdev->dev, NULL); 1620 fep->clk = clk_get(&pdev->dev, NULL);
1613 if (IS_ERR(fep->clk)) { 1621 if (IS_ERR(fep->clk)) {
1614 ret = PTR_ERR(fep->clk); 1622 ret = PTR_ERR(fep->clk);
@@ -1639,6 +1647,7 @@ failed_mii_init:
1639failed_init: 1647failed_init:
1640 clk_disable_unprepare(fep->clk); 1648 clk_disable_unprepare(fep->clk);
1641 clk_put(fep->clk); 1649 clk_put(fep->clk);
1650failed_pin:
1642failed_clk: 1651failed_clk:
1643 for (i = 0; i < FEC_IRQ_NUM; i++) { 1652 for (i = 0; i < FEC_IRQ_NUM; i++) {
1644 irq = platform_get_irq(pdev, i); 1653 irq = platform_get_irq(pdev, i);
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 570f22053be8..69c9a6601f45 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -37,6 +37,7 @@
37#include <linux/of.h> 37#include <linux/of.h>
38#include <linux/of_device.h> 38#include <linux/of_device.h>
39#include <linux/of_gpio.h> 39#include <linux/of_gpio.h>
40#include <linux/pinctrl/consumer.h>
40 41
41#include <mach/spi.h> 42#include <mach/spi.h>
42 43
@@ -758,6 +759,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
758 struct spi_master *master; 759 struct spi_master *master;
759 struct spi_imx_data *spi_imx; 760 struct spi_imx_data *spi_imx;
760 struct resource *res; 761 struct resource *res;
762 struct pinctrl *pinctrl;
761 int i, ret, num_cs; 763 int i, ret, num_cs;
762 764
763 if (!np && !mxc_platform_info) { 765 if (!np && !mxc_platform_info) {
@@ -845,6 +847,12 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
845 goto out_iounmap; 847 goto out_iounmap;
846 } 848 }
847 849
850 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
851 if (IS_ERR(pinctrl)) {
852 ret = PTR_ERR(pinctrl);
853 goto out_free_irq;
854 }
855
848 spi_imx->clk = clk_get(&pdev->dev, NULL); 856 spi_imx->clk = clk_get(&pdev->dev, NULL);
849 if (IS_ERR(spi_imx->clk)) { 857 if (IS_ERR(spi_imx->clk)) {
850 dev_err(&pdev->dev, "unable to get clock\n"); 858 dev_err(&pdev->dev, "unable to get clock\n");
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 3d569cd68f58..062ef8c2b3cb 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -52,6 +52,7 @@
52#include <linux/scatterlist.h> 52#include <linux/scatterlist.h>
53#include <linux/delay.h> 53#include <linux/delay.h>
54#include <linux/types.h> 54#include <linux/types.h>
55#include <linux/pinctrl/consumer.h>
55 56
56#include <asm/io.h> 57#include <asm/io.h>
57#include <asm/sizes.h> 58#include <asm/sizes.h>
@@ -1916,6 +1917,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
1916{ 1917{
1917 struct uart_amba_port *uap; 1918 struct uart_amba_port *uap;
1918 struct vendor_data *vendor = id->data; 1919 struct vendor_data *vendor = id->data;
1920 struct pinctrl *pinctrl;
1919 void __iomem *base; 1921 void __iomem *base;
1920 int i, ret; 1922 int i, ret;
1921 1923
@@ -1940,6 +1942,12 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
1940 goto free; 1942 goto free;
1941 } 1943 }
1942 1944
1945 pinctrl = devm_pinctrl_get_select_default(&dev->dev);
1946 if (IS_ERR(pinctrl)) {
1947 ret = PTR_ERR(pinctrl);
1948 goto unmap;
1949 }
1950
1943 uap->clk = clk_get(&dev->dev, NULL); 1951 uap->clk = clk_get(&dev->dev, NULL);
1944 if (IS_ERR(uap->clk)) { 1952 if (IS_ERR(uap->clk)) {
1945 ret = PTR_ERR(uap->clk); 1953 ret = PTR_ERR(uap->clk);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index e7feceeebc2f..ec206732f68c 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -47,6 +47,7 @@
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/of.h> 48#include <linux/of.h>
49#include <linux/of_device.h> 49#include <linux/of_device.h>
50#include <linux/pinctrl/consumer.h>
50 51
51#include <asm/io.h> 52#include <asm/io.h>
52#include <asm/irq.h> 53#include <asm/irq.h>
@@ -1464,6 +1465,7 @@ static int serial_imx_probe(struct platform_device *pdev)
1464 void __iomem *base; 1465 void __iomem *base;
1465 int ret = 0; 1466 int ret = 0;
1466 struct resource *res; 1467 struct resource *res;
1468 struct pinctrl *pinctrl;
1467 1469
1468 sport = kzalloc(sizeof(*sport), GFP_KERNEL); 1470 sport = kzalloc(sizeof(*sport), GFP_KERNEL);
1469 if (!sport) 1471 if (!sport)
@@ -1503,6 +1505,12 @@ static int serial_imx_probe(struct platform_device *pdev)
1503 sport->timer.function = imx_timeout; 1505 sport->timer.function = imx_timeout;
1504 sport->timer.data = (unsigned long)sport; 1506 sport->timer.data = (unsigned long)sport;
1505 1507
1508 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
1509 if (IS_ERR(pinctrl)) {
1510 ret = PTR_ERR(pinctrl);
1511 goto unmap;
1512 }
1513
1506 sport->clk = clk_get(&pdev->dev, "uart"); 1514 sport->clk = clk_get(&pdev->dev, "uart");
1507 if (IS_ERR(sport->clk)) { 1515 if (IS_ERR(sport->clk)) {
1508 ret = PTR_ERR(sport->clk); 1516 ret = PTR_ERR(sport->clk);
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 55fd362b9879..7081600bede4 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -32,6 +32,7 @@
32#include <linux/clk.h> 32#include <linux/clk.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/io.h> 34#include <linux/io.h>
35#include <linux/pinctrl/consumer.h>
35 36
36#include <asm/cacheflush.h> 37#include <asm/cacheflush.h>
37 38
@@ -678,6 +679,7 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
678 u32 version; 679 u32 version;
679 int ret = 0; 680 int ret = 0;
680 struct resource *r; 681 struct resource *r;
682 struct pinctrl *pinctrl;
681 683
682 s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL); 684 s = kzalloc(sizeof(struct mxs_auart_port), GFP_KERNEL);
683 if (!s) { 685 if (!s) {
@@ -685,6 +687,12 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev)
685 goto out; 687 goto out;
686 } 688 }
687 689
690 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
691 if (IS_ERR(pinctrl)) {
692 ret = PTR_ERR(pinctrl);
693 goto out_free;
694 }
695
688 s->clk = clk_get(&pdev->dev, NULL); 696 s->clk = clk_get(&pdev->dev, NULL);
689 if (IS_ERR(s->clk)) { 697 if (IS_ERR(s->clk)) {
690 ret = PTR_ERR(s->clk); 698 ret = PTR_ERR(s->clk);
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 4a89f889852d..6c6bc578d0fc 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -45,6 +45,7 @@
45#include <linux/clk.h> 45#include <linux/clk.h>
46#include <linux/dma-mapping.h> 46#include <linux/dma-mapping.h>
47#include <linux/io.h> 47#include <linux/io.h>
48#include <linux/pinctrl/consumer.h>
48#include <mach/mxsfb.h> 49#include <mach/mxsfb.h>
49 50
50#define REG_SET 4 51#define REG_SET 4
@@ -756,6 +757,7 @@ static int __devinit mxsfb_probe(struct platform_device *pdev)
756 struct mxsfb_info *host; 757 struct mxsfb_info *host;
757 struct fb_info *fb_info; 758 struct fb_info *fb_info;
758 struct fb_modelist *modelist; 759 struct fb_modelist *modelist;
760 struct pinctrl *pinctrl;
759 int i, ret; 761 int i, ret;
760 762
761 if (!pdata) { 763 if (!pdata) {
@@ -793,6 +795,12 @@ static int __devinit mxsfb_probe(struct platform_device *pdev)
793 795
794 host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data]; 796 host->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];
795 797
798 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
799 if (IS_ERR(pinctrl)) {
800 ret = PTR_ERR(pinctrl);
801 goto error_getpin;
802 }
803
796 host->clk = clk_get(&host->pdev->dev, NULL); 804 host->clk = clk_get(&host->pdev->dev, NULL);
797 if (IS_ERR(host->clk)) { 805 if (IS_ERR(host->clk)) {
798 ret = PTR_ERR(host->clk); 806 ret = PTR_ERR(host->clk);
@@ -848,6 +856,7 @@ error_init_fb:
848error_pseudo_pallette: 856error_pseudo_pallette:
849 clk_put(host->clk); 857 clk_put(host->clk);
850error_getclock: 858error_getclock:
859error_getpin:
851 iounmap(host->base); 860 iounmap(host->base);
852error_ioremap: 861error_ioremap:
853 framebuffer_release(fb_info); 862 framebuffer_release(fb_info);
diff --git a/include/linux/fsl/mxs-dma.h b/include/linux/fsl/mxs-dma.h
index 203d7c4a3e11..55d870238399 100644
--- a/include/linux/fsl/mxs-dma.h
+++ b/include/linux/fsl/mxs-dma.h
@@ -15,14 +15,6 @@ struct mxs_dma_data {
15 int chan_irq; 15 int chan_irq;
16}; 16};
17 17
18static inline int mxs_dma_is_apbh(struct dma_chan *chan) 18extern int mxs_dma_is_apbh(struct dma_chan *chan);
19{ 19extern int mxs_dma_is_apbx(struct dma_chan *chan);
20 return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbh");
21}
22
23static inline int mxs_dma_is_apbx(struct dma_chan *chan)
24{
25 return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbx");
26}
27
28#endif /* __MACH_MXS_DMA_H__ */ 20#endif /* __MACH_MXS_DMA_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mmc.h b/include/linux/mmc/mxs-mmc.h
index 211547a05564..7c2ad3a7f2f3 100644
--- a/arch/arm/mach-mxs/include/mach/mmc.h
+++ b/include/linux/mmc/mxs-mmc.h
@@ -6,8 +6,8 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#ifndef __MACH_MXS_MMC_H__ 9#ifndef __LINUX_MMC_MXS_MMC_H__
10#define __MACH_MXS_MMC_H__ 10#define __LINUX_MMC_MXS_MMC_H__
11 11
12struct mxs_mmc_platform_data { 12struct mxs_mmc_platform_data {
13 int wp_gpio; /* write protect pin */ 13 int wp_gpio; /* write protect pin */
@@ -15,4 +15,5 @@ struct mxs_mmc_platform_data {
15#define SLOTF_4_BIT_CAPABLE (1 << 0) 15#define SLOTF_4_BIT_CAPABLE (1 << 0)
16#define SLOTF_8_BIT_CAPABLE (1 << 1) 16#define SLOTF_8_BIT_CAPABLE (1 << 1)
17}; 17};
18#endif /* __MACH_MXS_MMC_H__ */ 18
19#endif /* __LINUX_MMC_MXS_MMC_H__ */
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 53f4fd8feced..7fd224bb7324 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -25,6 +25,7 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/fsl/mxs-dma.h> 27#include <linux/fsl/mxs-dma.h>
28#include <linux/pinctrl/consumer.h>
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/pcm.h> 30#include <sound/pcm.h>
30#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -625,6 +626,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
625 struct resource *iores, *dmares; 626 struct resource *iores, *dmares;
626 struct mxs_saif *saif; 627 struct mxs_saif *saif;
627 struct mxs_saif_platform_data *pdata; 628 struct mxs_saif_platform_data *pdata;
629 struct pinctrl *pinctrl;
628 int ret = 0; 630 int ret = 0;
629 631
630 if (pdev->id >= ARRAY_SIZE(mxs_saif)) 632 if (pdev->id >= ARRAY_SIZE(mxs_saif))
@@ -650,6 +652,12 @@ static int mxs_saif_probe(struct platform_device *pdev)
650 saif->master_id = saif->id; 652 saif->master_id = saif->id;
651 } 653 }
652 654
655 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
656 if (IS_ERR(pinctrl)) {
657 ret = PTR_ERR(pinctrl);
658 return ret;
659 }
660
653 saif->clk = clk_get(&pdev->dev, NULL); 661 saif->clk = clk_get(&pdev->dev, NULL);
654 if (IS_ERR(saif->clk)) { 662 if (IS_ERR(saif->clk)) {
655 ret = PTR_ERR(saif->clk); 663 ret = PTR_ERR(saif->clk);