aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-imx/mach-apf9328.c2
-rw-r--r--arch/arm/mach-imx/mach-armadillo5x0.c2
-rw-r--r--arch/arm/mach-imx/mach-bug.c2
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c2
-rw-r--r--arch/arm/mach-imx/mach-cpuimx35.c2
-rw-r--r--arch/arm/mach-imx/mach-eukrea_cpuimx25.c2
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c2
-rw-r--r--arch/arm/mach-imx/mach-imx27ipcam.c2
-rw-r--r--arch/arm/mach-imx/mach-imx27lite.c2
-rw-r--r--arch/arm/mach-imx/mach-kzm_arm11_01.c2
-rw-r--r--arch/arm/mach-imx/mach-mx1ads.c2
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c2
-rw-r--r--arch/arm/mach-imx/mach-mx25_3ds.c2
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c2
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c2
-rw-r--r--arch/arm/mach-imx/mach-mx31_3ds.c2
-rw-r--r--arch/arm/mach-imx/mach-mx31ads.c2
-rw-r--r--arch/arm/mach-imx/mach-mx31lilly.c2
-rw-r--r--arch/arm/mach-imx/mach-mx31lite.c2
-rw-r--r--arch/arm/mach-imx/mach-mx31moboard.c2
-rw-r--r--arch/arm/mach-imx/mach-mx35_3ds.c2
-rw-r--r--arch/arm/mach-imx/mach-mxt_td60.c2
-rw-r--r--arch/arm/mach-imx/mach-pca100.c2
-rw-r--r--arch/arm/mach-imx/mach-pcm037.c2
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c2
-rw-r--r--arch/arm/mach-imx/mach-pcm043.c2
-rw-r--r--arch/arm/mach-imx/mach-qong.c2
-rw-r--r--arch/arm/mach-imx/mach-scb9328.c2
-rw-r--r--arch/arm/mach-imx/mach-vpr200.c2
-rw-r--r--arch/arm/mach-imx/mm-imx1.c17
-rw-r--r--arch/arm/mach-imx/mm-imx21.c21
-rw-r--r--arch/arm/mach-imx/mm-imx25.c16
-rw-r--r--arch/arm/mach-imx/mm-imx27.c21
-rw-r--r--arch/arm/mach-imx/mm-imx31.c15
-rw-r--r--arch/arm/mach-imx/mm-imx35.c15
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51.c2
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51sd.c2
-rw-r--r--arch/arm/mach-mx5/board-mx50_rdp.c2
-rw-r--r--arch/arm/mach-mx5/board-mx51_3ds.c2
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c2
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikamx.c2
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikasb.c2
-rw-r--r--arch/arm/mach-mx5/board-mx53_evk.c2
-rw-r--r--arch/arm/mach-mx5/board-mx53_loco.c2
-rw-r--r--arch/arm/mach-mx5/board-mx53_smd.c2
-rw-r--r--arch/arm/mach-mx5/devices.c64
-rw-r--r--arch/arm/mach-mx5/mm-mx50.c21
-rw-r--r--arch/arm/mach-mx5/mm.c25
-rw-r--r--arch/arm/mach-mxs/Makefile2
-rw-r--r--arch/arm/mach-mxs/devices.c11
-rw-r--r--arch/arm/mach-mxs/devices/Makefile1
-rw-r--r--arch/arm/mach-mxs/devices/platform-gpio-mxs.c53
-rw-r--r--arch/arm/mach-mxs/gpio.h34
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h2
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c1
-rw-r--r--arch/arm/mach-mxs/mm-mx23.c1
-rw-r--r--arch/arm/mach-mxs/mm-mx28.c1
-rw-r--r--arch/arm/plat-mxc/Makefile2
-rw-r--r--arch/arm/plat-mxc/devices.c11
-rw-r--r--arch/arm/plat-mxc/devices/Makefile1
-rw-r--r--arch/arm/plat-mxc/devices/platform-gpio-mxc.c32
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h12
-rw-r--r--arch/arm/plat-mxc/include/mach/devices-common.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/gpio.h27
-rw-r--r--drivers/gpio/Kconfig9
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/gpio-mxc.c (renamed from arch/arm/plat-mxc/gpio.c)266
-rw-r--r--drivers/gpio/gpio-mxs.c (renamed from arch/arm/mach-mxs/gpio.c)227
68 files changed, 568 insertions, 422 deletions
diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c
index c11d0ab14848..a404c89485ca 100644
--- a/arch/arm/mach-imx/mach-apf9328.c
+++ b/arch/arm/mach-imx/mach-apf9328.c
@@ -110,6 +110,8 @@ static struct platform_device *devices[] __initdata = {
110 110
111static void __init apf9328_init(void) 111static void __init apf9328_init(void)
112{ 112{
113 imx1_soc_init();
114
113 mxc_gpio_setup_multiple_pins(apf9328_pins, 115 mxc_gpio_setup_multiple_pins(apf9328_pins,
114 ARRAY_SIZE(apf9328_pins), 116 ARRAY_SIZE(apf9328_pins),
115 "APF9328"); 117 "APF9328");
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c
index ffb40ff619b1..ede2710f8b76 100644
--- a/arch/arm/mach-imx/mach-armadillo5x0.c
+++ b/arch/arm/mach-imx/mach-armadillo5x0.c
@@ -490,6 +490,8 @@ static struct platform_device *devices[] __initdata = {
490 */ 490 */
491static void __init armadillo5x0_init(void) 491static void __init armadillo5x0_init(void)
492{ 492{
493 imx31_soc_init();
494
493 mxc_iomux_setup_multiple_pins(armadillo5x0_pins, 495 mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
494 ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0"); 496 ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
495 497
diff --git a/arch/arm/mach-imx/mach-bug.c b/arch/arm/mach-imx/mach-bug.c
index 42e4f078a19c..f49470553bdf 100644
--- a/arch/arm/mach-imx/mach-bug.c
+++ b/arch/arm/mach-imx/mach-bug.c
@@ -42,6 +42,8 @@ static const unsigned int bug_pins[] __initconst = {
42 42
43static void __init bug_board_init(void) 43static void __init bug_board_init(void)
44{ 44{
45 imx31_soc_init();
46
45 mxc_iomux_setup_multiple_pins(bug_pins, 47 mxc_iomux_setup_multiple_pins(bug_pins,
46 ARRAY_SIZE(bug_pins), "uart-4"); 48 ARRAY_SIZE(bug_pins), "uart-4");
47 imx31_add_imx_uart4(&uart_pdata); 49 imx31_add_imx_uart4(&uart_pdata);
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 46a2e41d43d2..87887ac5806b 100644
--- a/arch/arm/mach-imx/mach-cpuimx27.c
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -250,6 +250,8 @@ __setup("otg_mode=", eukrea_cpuimx27_otg_mode);
250 250
251static void __init eukrea_cpuimx27_init(void) 251static void __init eukrea_cpuimx27_init(void)
252{ 252{
253 imx27_soc_init();
254
253 mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins, 255 mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
254 ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27"); 256 ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
255 257
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c
index 3f8ef825fa6f..f39a478ba1a6 100644
--- a/arch/arm/mach-imx/mach-cpuimx35.c
+++ b/arch/arm/mach-imx/mach-cpuimx35.c
@@ -156,6 +156,8 @@ __setup("otg_mode=", eukrea_cpuimx35_otg_mode);
156 */ 156 */
157static void __init eukrea_cpuimx35_init(void) 157static void __init eukrea_cpuimx35_init(void)
158{ 158{
159 imx35_soc_init();
160
159 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads, 161 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
160 ARRAY_SIZE(eukrea_cpuimx35_pads)); 162 ARRAY_SIZE(eukrea_cpuimx35_pads));
161 163
diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
index 148cff2819b9..da36da52969d 100644
--- a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
+++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
@@ -125,6 +125,8 @@ __setup("otg_mode=", eukrea_cpuimx25_otg_mode);
125 125
126static void __init eukrea_cpuimx25_init(void) 126static void __init eukrea_cpuimx25_init(void)
127{ 127{
128 imx25_soc_init();
129
128 if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads, 130 if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads,
129 ARRAY_SIZE(eukrea_cpuimx25_pads))) 131 ARRAY_SIZE(eukrea_cpuimx25_pads)))
130 printk(KERN_ERR "error setting cpuimx25 pads !\n"); 132 printk(KERN_ERR "error setting cpuimx25 pads !\n");
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index 686449696543..6707de0ab716 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -231,6 +231,8 @@ static void __init visstrim_m10_board_init(void)
231{ 231{
232 int ret; 232 int ret;
233 233
234 imx27_soc_init();
235
234 ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins, 236 ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
235 ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10"); 237 ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
236 if (ret) 238 if (ret)
diff --git a/arch/arm/mach-imx/mach-imx27ipcam.c b/arch/arm/mach-imx/mach-imx27ipcam.c
index 9be6cd6fbf8c..272f793e9247 100644
--- a/arch/arm/mach-imx/mach-imx27ipcam.c
+++ b/arch/arm/mach-imx/mach-imx27ipcam.c
@@ -50,6 +50,8 @@ static const int mx27ipcam_pins[] __initconst = {
50 50
51static void __init mx27ipcam_init(void) 51static void __init mx27ipcam_init(void)
52{ 52{
53 imx27_soc_init();
54
53 mxc_gpio_setup_multiple_pins(mx27ipcam_pins, ARRAY_SIZE(mx27ipcam_pins), 55 mxc_gpio_setup_multiple_pins(mx27ipcam_pins, ARRAY_SIZE(mx27ipcam_pins),
54 "mx27ipcam"); 56 "mx27ipcam");
55 57
diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c
index 841140516ede..d81a769fe895 100644
--- a/arch/arm/mach-imx/mach-imx27lite.c
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -59,6 +59,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
59 59
60static void __init mx27lite_init(void) 60static void __init mx27lite_init(void)
61{ 61{
62 imx27_soc_init();
63
62 mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins), 64 mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
63 "imx27lite"); 65 "imx27lite");
64 imx27_add_imx_uart0(&uart_pdata); 66 imx27_add_imx_uart0(&uart_pdata);
diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c
index 1ecae20cf4e3..e472a1d88058 100644
--- a/arch/arm/mach-imx/mach-kzm_arm11_01.c
+++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c
@@ -223,6 +223,8 @@ static int kzm_pins[] __initdata = {
223 */ 223 */
224static void __init kzm_board_init(void) 224static void __init kzm_board_init(void)
225{ 225{
226 imx31_soc_init();
227
226 mxc_iomux_setup_multiple_pins(kzm_pins, 228 mxc_iomux_setup_multiple_pins(kzm_pins,
227 ARRAY_SIZE(kzm_pins), "kzm"); 229 ARRAY_SIZE(kzm_pins), "kzm");
228 kzm_init_ext_uart(); 230 kzm_init_ext_uart();
diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c
index 38ec5cbbda9b..5cd8bee46960 100644
--- a/arch/arm/mach-imx/mach-mx1ads.c
+++ b/arch/arm/mach-imx/mach-mx1ads.c
@@ -115,6 +115,8 @@ static struct i2c_board_info mx1ads_i2c_devices[] = {
115 */ 115 */
116static void __init mx1ads_init(void) 116static void __init mx1ads_init(void)
117{ 117{
118 imx1_soc_init();
119
118 mxc_gpio_setup_multiple_pins(mx1ads_pins, 120 mxc_gpio_setup_multiple_pins(mx1ads_pins,
119 ARRAY_SIZE(mx1ads_pins), "mx1ads"); 121 ARRAY_SIZE(mx1ads_pins), "mx1ads");
120 122
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index 74ac88978ddd..d389ecf9b5a8 100644
--- a/arch/arm/mach-imx/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -279,6 +279,8 @@ static struct platform_device *platform_devices[] __initdata = {
279 279
280static void __init mx21ads_board_init(void) 280static void __init mx21ads_board_init(void)
281{ 281{
282 imx21_soc_init();
283
282 mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins), 284 mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
283 "mx21ads"); 285 "mx21ads");
284 286
diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c
index 58ea3fdf0911..01534bb61305 100644
--- a/arch/arm/mach-imx/mach-mx25_3ds.c
+++ b/arch/arm/mach-imx/mach-mx25_3ds.c
@@ -219,6 +219,8 @@ static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
219 219
220static void __init mx25pdk_init(void) 220static void __init mx25pdk_init(void)
221{ 221{
222 imx25_soc_init();
223
222 mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads, 224 mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
223 ARRAY_SIZE(mx25pdk_pads)); 225 ARRAY_SIZE(mx25pdk_pads));
224 226
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index 352f75da3a4a..b31d4129e10e 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -287,6 +287,8 @@ static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
287 287
288static void __init mx27pdk_init(void) 288static void __init mx27pdk_init(void)
289{ 289{
290 imx27_soc_init();
291
290 mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), 292 mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
291 "mx27pdk"); 293 "mx27pdk");
292 mx27_3ds_sdhc1_enable_level_translator(); 294 mx27_3ds_sdhc1_enable_level_translator();
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
index 1db79506f5e4..fc26ed71b9ed 100644
--- a/arch/arm/mach-imx/mach-mx27ads.c
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -288,6 +288,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
288 288
289static void __init mx27ads_board_init(void) 289static void __init mx27ads_board_init(void)
290{ 290{
291 imx27_soc_init();
292
291 mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins), 293 mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
292 "mx27ads"); 294 "mx27ads");
293 295
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c
index 62983bd07d6a..1446b353af05 100644
--- a/arch/arm/mach-imx/mach-mx31_3ds.c
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -686,6 +686,8 @@ static void __init mx31_3ds_init(void)
686{ 686{
687 int ret; 687 int ret;
688 688
689 imx31_soc_init();
690
689 /* Configure SPI1 IOMUX */ 691 /* Configure SPI1 IOMUX */
690 mxc_iomux_set_gpr(MUX_PGP_CSPI_BB, true); 692 mxc_iomux_set_gpr(MUX_PGP_CSPI_BB, true);
691 693
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c
index f4dee0254634..0ce49478a479 100644
--- a/arch/arm/mach-imx/mach-mx31ads.c
+++ b/arch/arm/mach-imx/mach-mx31ads.c
@@ -516,6 +516,8 @@ static void __init mx31ads_init_irq(void)
516 516
517static void __init mx31ads_init(void) 517static void __init mx31ads_init(void)
518{ 518{
519 imx31_soc_init();
520
519 mxc_init_extuart(); 521 mxc_init_extuart();
520 mxc_init_imx_uart(); 522 mxc_init_imx_uart();
521 mxc_init_i2c(); 523 mxc_init_i2c();
diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c
index 410e676ae087..750368ddf0f9 100644
--- a/arch/arm/mach-imx/mach-mx31lilly.c
+++ b/arch/arm/mach-imx/mach-mx31lilly.c
@@ -243,6 +243,8 @@ core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
243 243
244static void __init mx31lilly_board_init(void) 244static void __init mx31lilly_board_init(void)
245{ 245{
246 imx31_soc_init();
247
246 switch (mx31lilly_baseboard) { 248 switch (mx31lilly_baseboard) {
247 case MX31LILLY_NOBOARD: 249 case MX31LILLY_NOBOARD:
248 break; 250 break;
diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c
index ac9b4cad320e..4b47fd9fdd89 100644
--- a/arch/arm/mach-imx/mach-mx31lite.c
+++ b/arch/arm/mach-imx/mach-mx31lite.c
@@ -230,6 +230,8 @@ static void __init mx31lite_init(void)
230{ 230{
231 int ret; 231 int ret;
232 232
233 imx31_soc_init();
234
233 switch (mx31lite_baseboard) { 235 switch (mx31lite_baseboard) {
234 case MX31LITE_NOBOARD: 236 case MX31LITE_NOBOARD:
235 break; 237 break;
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index abe688b3297d..b358383120e7 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -498,6 +498,8 @@ core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
498 */ 498 */
499static void __init mx31moboard_init(void) 499static void __init mx31moboard_init(void)
500{ 500{
501 imx31_soc_init();
502
501 mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins), 503 mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
502 "moboard"); 504 "moboard");
503 505
diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c
index c10221d3d102..b3b9bd8ac2a3 100644
--- a/arch/arm/mach-imx/mach-mx35_3ds.c
+++ b/arch/arm/mach-imx/mach-mx35_3ds.c
@@ -179,6 +179,8 @@ static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = {
179 */ 179 */
180static void __init mx35_3ds_init(void) 180static void __init mx35_3ds_init(void)
181{ 181{
182 imx35_soc_init();
183
182 mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads)); 184 mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
183 185
184 imx35_add_fec(NULL); 186 imx35_add_fec(NULL);
diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c
index 2774541511e7..c85876fed663 100644
--- a/arch/arm/mach-imx/mach-mxt_td60.c
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -233,6 +233,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
233 233
234static void __init mxt_td60_board_init(void) 234static void __init mxt_td60_board_init(void)
235{ 235{
236 imx27_soc_init();
237
236 mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins), 238 mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
237 "MXT_TD60"); 239 "MXT_TD60");
238 240
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index bbddc5a11c43..71083aa16038 100644
--- a/arch/arm/mach-imx/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -357,6 +357,8 @@ static void __init pca100_init(void)
357{ 357{
358 int ret; 358 int ret;
359 359
360 imx27_soc_init();
361
360 /* SSI unit */ 362 /* SSI unit */
361 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, 363 mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
362 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */ 364 MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
index 89c213b81295..f45b7cd72c8a 100644
--- a/arch/arm/mach-imx/mach-pcm037.c
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -576,6 +576,8 @@ static void __init pcm037_init(void)
576{ 576{
577 int ret; 577 int ret;
578 578
579 imx31_soc_init();
580
579 mxc_iomux_set_gpr(MUX_PGP_UH2, 1); 581 mxc_iomux_set_gpr(MUX_PGP_UH2, 1);
580 582
581 mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), 583 mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index 853bb871c7ed..2d6a64bbac44 100644
--- a/arch/arm/mach-imx/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -295,6 +295,8 @@ static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
295 295
296static void __init pcm038_init(void) 296static void __init pcm038_init(void)
297{ 297{
298 imx27_soc_init();
299
298 mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins), 300 mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
299 "PCM038"); 301 "PCM038");
300 302
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
index 026441628dfa..163cc318cafb 100644
--- a/arch/arm/mach-imx/mach-pcm043.c
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -356,6 +356,8 @@ static struct esdhc_platform_data sd1_pdata = {
356 */ 356 */
357static void __init pcm043_init(void) 357static void __init pcm043_init(void)
358{ 358{
359 imx35_soc_init();
360
359 mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads)); 361 mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
360 362
361 mxc_audmux_v2_configure_port(3, 363 mxc_audmux_v2_configure_port(3,
diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c
index c16328715939..3626f486498a 100644
--- a/arch/arm/mach-imx/mach-qong.c
+++ b/arch/arm/mach-imx/mach-qong.c
@@ -244,6 +244,8 @@ static void __init qong_init_fpga(void)
244 */ 244 */
245static void __init qong_init(void) 245static void __init qong_init(void)
246{ 246{
247 imx31_soc_init();
248
247 mxc_init_imx_uart(); 249 mxc_init_imx_uart();
248 qong_init_nor_mtd(); 250 qong_init_nor_mtd();
249 qong_init_fpga(); 251 qong_init_fpga();
diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c
index b77386573502..db2d60470e15 100644
--- a/arch/arm/mach-imx/mach-scb9328.c
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -115,6 +115,8 @@ static struct platform_device *devices[] __initdata = {
115 */ 115 */
116static void __init scb9328_init(void) 116static void __init scb9328_init(void)
117{ 117{
118 imx1_soc_init();
119
118 mxc_gpio_setup_multiple_pins(mxc_uart1_pins, 120 mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
119 ARRAY_SIZE(mxc_uart1_pins), "UART1"); 121 ARRAY_SIZE(mxc_uart1_pins), "UART1");
120 122
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c
index d74e3473d236..7d8e012a6335 100644
--- a/arch/arm/mach-imx/mach-vpr200.c
+++ b/arch/arm/mach-imx/mach-vpr200.c
@@ -267,6 +267,8 @@ static struct platform_device *devices[] __initdata = {
267 */ 267 */
268static void __init vpr200_board_init(void) 268static void __init vpr200_board_init(void)
269{ 269{
270 imx35_soc_init();
271
270 mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads)); 272 mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
271 273
272 imx35_add_fec(NULL); 274 imx35_add_fec(NULL);
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
index 2e482ba5a0e7..b486595701b7 100644
--- a/arch/arm/mach-imx/mm-imx1.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -23,7 +23,6 @@
23 23
24#include <mach/common.h> 24#include <mach/common.h>
25#include <mach/hardware.h> 25#include <mach/hardware.h>
26#include <mach/gpio.h>
27#include <mach/irqs.h> 26#include <mach/irqs.h>
28#include <mach/iomux-v1.h> 27#include <mach/iomux-v1.h>
29 28
@@ -44,15 +43,15 @@ void __init imx1_init_early(void)
44 MX1_NUM_GPIO_PORT); 43 MX1_NUM_GPIO_PORT);
45} 44}
46 45
47static struct mxc_gpio_port imx1_gpio_ports[] = {
48 DEFINE_IMX_GPIO_PORT_IRQ(MX1, 0, 1, MX1_GPIO_INT_PORTA),
49 DEFINE_IMX_GPIO_PORT_IRQ(MX1, 1, 2, MX1_GPIO_INT_PORTB),
50 DEFINE_IMX_GPIO_PORT_IRQ(MX1, 2, 3, MX1_GPIO_INT_PORTC),
51 DEFINE_IMX_GPIO_PORT_IRQ(MX1, 3, 4, MX1_GPIO_INT_PORTD),
52};
53
54void __init mx1_init_irq(void) 46void __init mx1_init_irq(void)
55{ 47{
56 mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR)); 48 mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
57 mxc_gpio_init(imx1_gpio_ports, ARRAY_SIZE(imx1_gpio_ports)); 49}
50
51void __init imx1_soc_init(void)
52{
53 mxc_register_gpio(0, MX1_GPIO1_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTA, 0);
54 mxc_register_gpio(1, MX1_GPIO2_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTB, 0);
55 mxc_register_gpio(2, MX1_GPIO3_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTC, 0);
56 mxc_register_gpio(3, MX1_GPIO4_BASE_ADDR, SZ_4K, MX1_GPIO_INT_PORTD, 0);
58} 57}
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index 7a0c500ac2c8..f0fb8bcce6f9 100644
--- a/arch/arm/mach-imx/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -24,7 +24,6 @@
24#include <mach/common.h> 24#include <mach/common.h>
25#include <asm/pgtable.h> 25#include <asm/pgtable.h>
26#include <asm/mach/map.h> 26#include <asm/mach/map.h>
27#include <mach/gpio.h>
28#include <mach/irqs.h> 27#include <mach/irqs.h>
29#include <mach/iomux-v1.h> 28#include <mach/iomux-v1.h>
30 29
@@ -70,17 +69,17 @@ void __init imx21_init_early(void)
70 MX21_NUM_GPIO_PORT); 69 MX21_NUM_GPIO_PORT);
71} 70}
72 71
73static struct mxc_gpio_port imx21_gpio_ports[] = {
74 DEFINE_IMX_GPIO_PORT_IRQ(MX21, 0, 1, MX21_INT_GPIO),
75 DEFINE_IMX_GPIO_PORT(MX21, 1, 2),
76 DEFINE_IMX_GPIO_PORT(MX21, 2, 3),
77 DEFINE_IMX_GPIO_PORT(MX21, 3, 4),
78 DEFINE_IMX_GPIO_PORT(MX21, 4, 5),
79 DEFINE_IMX_GPIO_PORT(MX21, 5, 6),
80};
81
82void __init mx21_init_irq(void) 72void __init mx21_init_irq(void)
83{ 73{
84 mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR)); 74 mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
85 mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports)); 75}
76
77void __init imx21_soc_init(void)
78{
79 mxc_register_gpio(0, MX21_GPIO1_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
80 mxc_register_gpio(1, MX21_GPIO2_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
81 mxc_register_gpio(2, MX21_GPIO3_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
82 mxc_register_gpio(3, MX21_GPIO4_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
83 mxc_register_gpio(4, MX21_GPIO5_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
84 mxc_register_gpio(5, MX21_GPIO6_BASE_ADDR, SZ_4K, MX21_INT_GPIO, 0);
86} 85}
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c
index 02f7b5c7fa8e..1b6d583f750a 100644
--- a/arch/arm/mach-imx/mm-imx25.c
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -27,7 +27,6 @@
27#include <mach/hardware.h> 27#include <mach/hardware.h>
28#include <mach/mx25.h> 28#include <mach/mx25.h>
29#include <mach/iomux-v3.h> 29#include <mach/iomux-v3.h>
30#include <mach/gpio.h>
31#include <mach/irqs.h> 30#include <mach/irqs.h>
32 31
33/* 32/*
@@ -57,16 +56,15 @@ void __init imx25_init_early(void)
57 mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR)); 56 mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
58} 57}
59 58
60static struct mxc_gpio_port imx25_gpio_ports[] = {
61 DEFINE_IMX_GPIO_PORT_IRQ(MX25, 0, 1, MX25_INT_GPIO1),
62 DEFINE_IMX_GPIO_PORT_IRQ(MX25, 1, 2, MX25_INT_GPIO2),
63 DEFINE_IMX_GPIO_PORT_IRQ(MX25, 2, 3, MX25_INT_GPIO3),
64 DEFINE_IMX_GPIO_PORT_IRQ(MX25, 3, 4, MX25_INT_GPIO4),
65};
66
67void __init mx25_init_irq(void) 59void __init mx25_init_irq(void)
68{ 60{
69 mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR)); 61 mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR));
70 mxc_gpio_init(imx25_gpio_ports, ARRAY_SIZE(imx25_gpio_ports));
71} 62}
72 63
64void __init imx25_soc_init(void)
65{
66 mxc_register_gpio(0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
67 mxc_register_gpio(1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
68 mxc_register_gpio(2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
69 mxc_register_gpio(3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
70}
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index a6761a39f08c..d3700cec8ec5 100644
--- a/arch/arm/mach-imx/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -24,7 +24,6 @@
24#include <mach/common.h> 24#include <mach/common.h>
25#include <asm/pgtable.h> 25#include <asm/pgtable.h>
26#include <asm/mach/map.h> 26#include <asm/mach/map.h>
27#include <mach/gpio.h>
28#include <mach/irqs.h> 27#include <mach/irqs.h>
29#include <mach/iomux-v1.h> 28#include <mach/iomux-v1.h>
30 29
@@ -70,17 +69,17 @@ void __init imx27_init_early(void)
70 MX27_NUM_GPIO_PORT); 69 MX27_NUM_GPIO_PORT);
71} 70}
72 71
73static struct mxc_gpio_port imx27_gpio_ports[] = {
74 DEFINE_IMX_GPIO_PORT_IRQ(MX27, 0, 1, MX27_INT_GPIO),
75 DEFINE_IMX_GPIO_PORT(MX27, 1, 2),
76 DEFINE_IMX_GPIO_PORT(MX27, 2, 3),
77 DEFINE_IMX_GPIO_PORT(MX27, 3, 4),
78 DEFINE_IMX_GPIO_PORT(MX27, 4, 5),
79 DEFINE_IMX_GPIO_PORT(MX27, 5, 6),
80};
81
82void __init mx27_init_irq(void) 72void __init mx27_init_irq(void)
83{ 73{
84 mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR)); 74 mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
85 mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports)); 75}
76
77void __init imx27_soc_init(void)
78{
79 mxc_register_gpio(0, MX27_GPIO1_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
80 mxc_register_gpio(1, MX27_GPIO2_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
81 mxc_register_gpio(2, MX27_GPIO3_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
82 mxc_register_gpio(3, MX27_GPIO4_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
83 mxc_register_gpio(4, MX27_GPIO5_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
84 mxc_register_gpio(5, MX27_GPIO6_BASE_ADDR, SZ_4K, MX27_INT_GPIO, 0);
86} 85}
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c
index 86b9b45864d2..cb16ac661776 100644
--- a/arch/arm/mach-imx/mm-imx31.c
+++ b/arch/arm/mach-imx/mm-imx31.c
@@ -26,7 +26,6 @@
26#include <mach/common.h> 26#include <mach/common.h>
27#include <mach/hardware.h> 27#include <mach/hardware.h>
28#include <mach/iomux-v3.h> 28#include <mach/iomux-v3.h>
29#include <mach/gpio.h>
30#include <mach/irqs.h> 29#include <mach/irqs.h>
31 30
32static struct map_desc mx31_io_desc[] __initdata = { 31static struct map_desc mx31_io_desc[] __initdata = {
@@ -53,14 +52,14 @@ void __init imx31_init_early(void)
53 mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); 52 mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
54} 53}
55 54
56static struct mxc_gpio_port imx31_gpio_ports[] = {
57 DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
58 DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
59 DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
60};
61
62void __init mx31_init_irq(void) 55void __init mx31_init_irq(void)
63{ 56{
64 mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR)); 57 mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
65 mxc_gpio_init(imx31_gpio_ports, ARRAY_SIZE(imx31_gpio_ports)); 58}
59
60void __init imx31_soc_init(void)
61{
62 mxc_register_gpio(0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
63 mxc_register_gpio(1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
64 mxc_register_gpio(2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
66} 65}
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c
index c880e6d1ae55..648bfca0163e 100644
--- a/arch/arm/mach-imx/mm-imx35.c
+++ b/arch/arm/mach-imx/mm-imx35.c
@@ -27,7 +27,6 @@
27#include <mach/common.h> 27#include <mach/common.h>
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <mach/iomux-v3.h> 29#include <mach/iomux-v3.h>
30#include <mach/gpio.h>
31#include <mach/irqs.h> 30#include <mach/irqs.h>
32 31
33static struct map_desc mx35_io_desc[] __initdata = { 32static struct map_desc mx35_io_desc[] __initdata = {
@@ -50,14 +49,14 @@ void __init imx35_init_early(void)
50 mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR)); 49 mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
51} 50}
52 51
53static struct mxc_gpio_port imx35_gpio_ports[] = {
54 DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
55 DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
56 DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
57};
58
59void __init mx35_init_irq(void) 52void __init mx35_init_irq(void)
60{ 53{
61 mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR)); 54 mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
62 mxc_gpio_init(imx35_gpio_ports, ARRAY_SIZE(imx35_gpio_ports)); 55}
56
57void __init imx35_soc_init(void)
58{
59 mxc_register_gpio(0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
60 mxc_register_gpio(1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
61 mxc_register_gpio(2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
63} 62}
diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c
index 7fbfd0636a35..7c893fa70266 100644
--- a/arch/arm/mach-mx5/board-cpuimx51.c
+++ b/arch/arm/mach-mx5/board-cpuimx51.c
@@ -241,6 +241,8 @@ __setup("otg_mode=", eukrea_cpuimx51_otg_mode);
241 */ 241 */
242static void __init eukrea_cpuimx51_init(void) 242static void __init eukrea_cpuimx51_init(void)
243{ 243{
244 imx51_soc_init();
245
244 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads, 246 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads,
245 ARRAY_SIZE(eukrea_cpuimx51_pads)); 247 ARRAY_SIZE(eukrea_cpuimx51_pads));
246 248
diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
index 5ef25a596143..ff096d587299 100644
--- a/arch/arm/mach-mx5/board-cpuimx51sd.c
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -264,6 +264,8 @@ static struct platform_device *platform_devices[] __initdata = {
264 264
265static void __init eukrea_cpuimx51sd_init(void) 265static void __init eukrea_cpuimx51sd_init(void)
266{ 266{
267 imx51_soc_init();
268
267 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads, 269 mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
268 ARRAY_SIZE(eukrea_cpuimx51sd_pads)); 270 ARRAY_SIZE(eukrea_cpuimx51sd_pads));
269 271
diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c
index 11210e1ae42a..7de25c6712eb 100644
--- a/arch/arm/mach-mx5/board-mx50_rdp.c
+++ b/arch/arm/mach-mx5/board-mx50_rdp.c
@@ -192,6 +192,8 @@ static const struct imxi2c_platform_data i2c_data __initconst = {
192 */ 192 */
193static void __init mx50_rdp_board_init(void) 193static void __init mx50_rdp_board_init(void)
194{ 194{
195 imx50_soc_init();
196
195 mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads, 197 mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads,
196 ARRAY_SIZE(mx50_rdp_pads)); 198 ARRAY_SIZE(mx50_rdp_pads));
197 199
diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c
index 11b2c7a31ddf..07a38154da21 100644
--- a/arch/arm/mach-mx5/board-mx51_3ds.c
+++ b/arch/arm/mach-mx5/board-mx51_3ds.c
@@ -136,6 +136,8 @@ static struct spi_board_info mx51_3ds_spi_nor_device[] = {
136 */ 136 */
137static void __init mx51_3ds_init(void) 137static void __init mx51_3ds_init(void)
138{ 138{
139 imx51_soc_init();
140
139 mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads, 141 mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads,
140 ARRAY_SIZE(mx51_3ds_pads)); 142 ARRAY_SIZE(mx51_3ds_pads));
141 143
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index 770f74b5ea50..e54e4bf61cfd 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -340,6 +340,8 @@ static void __init mx51_babbage_init(void)
340 iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 | 340 iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 |
341 MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP); 341 MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP);
342 342
343 imx51_soc_init();
344
343#if defined(CONFIG_CPU_FREQ_IMX) 345#if defined(CONFIG_CPU_FREQ_IMX)
344 get_cpu_op = mx51_get_cpu_op; 346 get_cpu_op = mx51_get_cpu_op;
345#endif 347#endif
diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c
index 2400f6d10099..f70700dc0ec1 100644
--- a/arch/arm/mach-mx5/board-mx51_efikamx.c
+++ b/arch/arm/mach-mx5/board-mx51_efikamx.c
@@ -229,6 +229,8 @@ late_initcall(mx51_efikamx_power_init);
229 229
230static void __init mx51_efikamx_init(void) 230static void __init mx51_efikamx_init(void)
231{ 231{
232 imx51_soc_init();
233
232 mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads, 234 mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads,
233 ARRAY_SIZE(mx51efikamx_pads)); 235 ARRAY_SIZE(mx51efikamx_pads));
234 efika_board_common_init(); 236 efika_board_common_init();
diff --git a/arch/arm/mach-mx5/board-mx51_efikasb.c b/arch/arm/mach-mx5/board-mx51_efikasb.c
index 28d68962e7df..2e4d9d32a87c 100644
--- a/arch/arm/mach-mx5/board-mx51_efikasb.c
+++ b/arch/arm/mach-mx5/board-mx51_efikasb.c
@@ -241,6 +241,8 @@ static void __init mx51_efikasb_board_id(void)
241 241
242static void __init efikasb_board_init(void) 242static void __init efikasb_board_init(void)
243{ 243{
244 imx51_soc_init();
245
244 mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads, 246 mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads,
245 ARRAY_SIZE(mx51efikasb_pads)); 247 ARRAY_SIZE(mx51efikasb_pads));
246 efika_board_common_init(); 248 efika_board_common_init();
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c
index f87d571882c6..0d9218a6e2d2 100644
--- a/arch/arm/mach-mx5/board-mx53_evk.c
+++ b/arch/arm/mach-mx5/board-mx53_evk.c
@@ -117,6 +117,8 @@ static const struct spi_imx_master mx53_evk_spi_data __initconst = {
117 117
118static void __init mx53_evk_board_init(void) 118static void __init mx53_evk_board_init(void)
119{ 119{
120 imx53_soc_init();
121
120 mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads, 122 mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads,
121 ARRAY_SIZE(mx53_evk_pads)); 123 ARRAY_SIZE(mx53_evk_pads));
122 mx53_evk_init_uart(); 124 mx53_evk_init_uart();
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
index 1b947e8c9c0c..359c3e248add 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -227,6 +227,8 @@ static const struct imxi2c_platform_data mx53_loco_i2c_data __initconst = {
227 227
228static void __init mx53_loco_board_init(void) 228static void __init mx53_loco_board_init(void)
229{ 229{
230 imx53_soc_init();
231
230 mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads, 232 mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
231 ARRAY_SIZE(mx53_loco_pads)); 233 ARRAY_SIZE(mx53_loco_pads));
232 imx53_add_imx_uart(0, NULL); 234 imx53_add_imx_uart(0, NULL);
diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c
index 817c08938f55..bc02894eafef 100644
--- a/arch/arm/mach-mx5/board-mx53_smd.c
+++ b/arch/arm/mach-mx5/board-mx53_smd.c
@@ -113,6 +113,8 @@ static const struct imxi2c_platform_data mx53_smd_i2c_data __initconst = {
113 113
114static void __init mx53_smd_board_init(void) 114static void __init mx53_smd_board_init(void)
115{ 115{
116 imx53_soc_init();
117
116 mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads, 118 mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads,
117 ARRAY_SIZE(mx53_smd_pads)); 119 ARRAY_SIZE(mx53_smd_pads));
118 mx53_smd_init_uart(); 120 mx53_smd_init_uart();
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
index 153ada53e575..371ca8c8414c 100644
--- a/arch/arm/mach-mx5/devices.c
+++ b/arch/arm/mach-mx5/devices.c
@@ -12,7 +12,6 @@
12 12
13#include <linux/platform_device.h> 13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h> 14#include <linux/dma-mapping.h>
15#include <linux/gpio.h>
16#include <mach/hardware.h> 15#include <mach/hardware.h>
17#include <mach/imx-uart.h> 16#include <mach/imx-uart.h>
18#include <mach/irqs.h> 17#include <mach/irqs.h>
@@ -119,66 +118,3 @@ struct platform_device mxc_usbh2_device = {
119 .coherent_dma_mask = DMA_BIT_MASK(32), 118 .coherent_dma_mask = DMA_BIT_MASK(32),
120 }, 119 },
121}; 120};
122
123static struct mxc_gpio_port mxc_gpio_ports[] = {
124 {
125 .chip.label = "gpio-0",
126 .base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR),
127 .irq = MX51_MXC_INT_GPIO1_LOW,
128 .irq_high = MX51_MXC_INT_GPIO1_HIGH,
129 .virtual_irq_start = MXC_GPIO_IRQ_START
130 },
131 {
132 .chip.label = "gpio-1",
133 .base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR),
134 .irq = MX51_MXC_INT_GPIO2_LOW,
135 .irq_high = MX51_MXC_INT_GPIO2_HIGH,
136 .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
137 },
138 {
139 .chip.label = "gpio-2",
140 .base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR),
141 .irq = MX51_MXC_INT_GPIO3_LOW,
142 .irq_high = MX51_MXC_INT_GPIO3_HIGH,
143 .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
144 },
145 {
146 .chip.label = "gpio-3",
147 .base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR),
148 .irq = MX51_MXC_INT_GPIO4_LOW,
149 .irq_high = MX51_MXC_INT_GPIO4_HIGH,
150 .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
151 },
152 {
153 .chip.label = "gpio-4",
154 .base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR),
155 .irq = MX53_INT_GPIO5_LOW,
156 .irq_high = MX53_INT_GPIO5_HIGH,
157 .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
158 },
159 {
160 .chip.label = "gpio-5",
161 .base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR),
162 .irq = MX53_INT_GPIO6_LOW,
163 .irq_high = MX53_INT_GPIO6_HIGH,
164 .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
165 },
166 {
167 .chip.label = "gpio-6",
168 .base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR),
169 .irq = MX53_INT_GPIO7_LOW,
170 .irq_high = MX53_INT_GPIO7_HIGH,
171 .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
172 },
173};
174
175int __init imx51_register_gpios(void)
176{
177 return mxc_gpio_init(mxc_gpio_ports, 4);
178}
179
180int __init imx53_register_gpios(void)
181{
182 return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
183}
184
diff --git a/arch/arm/mach-mx5/mm-mx50.c b/arch/arm/mach-mx5/mm-mx50.c
index b9c363b514a9..28c3f60f734f 100644
--- a/arch/arm/mach-mx5/mm-mx50.c
+++ b/arch/arm/mach-mx5/mm-mx50.c
@@ -26,7 +26,6 @@
26#include <mach/hardware.h> 26#include <mach/hardware.h>
27#include <mach/common.h> 27#include <mach/common.h>
28#include <mach/iomux-v3.h> 28#include <mach/iomux-v3.h>
29#include <mach/gpio.h>
30#include <mach/irqs.h> 29#include <mach/irqs.h>
31 30
32/* 31/*
@@ -56,17 +55,17 @@ void __init imx50_init_early(void)
56 mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR)); 55 mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR));
57} 56}
58 57
59static struct mxc_gpio_port imx50_gpio_ports[] = {
60 DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 0, 1, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH),
61 DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 1, 2, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH),
62 DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 2, 3, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
63 DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 3, 4, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
64 DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 4, 5, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
65 DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 5, 6, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
66};
67
68void __init mx50_init_irq(void) 58void __init mx50_init_irq(void)
69{ 59{
70 tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR)); 60 tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
71 mxc_gpio_init(imx50_gpio_ports, ARRAY_SIZE(imx50_gpio_ports)); 61}
62
63void __init imx50_soc_init(void)
64{
65 mxc_register_gpio(0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
66 mxc_register_gpio(1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
67 mxc_register_gpio(2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
68 mxc_register_gpio(3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
69 mxc_register_gpio(4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
70 mxc_register_gpio(5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
72} 71}
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index ff557301b42b..800bb8b21081 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -69,8 +69,6 @@ void __init imx53_init_early(void)
69 mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR)); 69 mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
70} 70}
71 71
72int imx51_register_gpios(void);
73
74void __init mx51_init_irq(void) 72void __init mx51_init_irq(void)
75{ 73{
76 unsigned long tzic_addr; 74 unsigned long tzic_addr;
@@ -86,11 +84,8 @@ void __init mx51_init_irq(void)
86 panic("unable to map TZIC interrupt controller\n"); 84 panic("unable to map TZIC interrupt controller\n");
87 85
88 tzic_init_irq(tzic_virt); 86 tzic_init_irq(tzic_virt);
89 imx51_register_gpios();
90} 87}
91 88
92int imx53_register_gpios(void);
93
94void __init mx53_init_irq(void) 89void __init mx53_init_irq(void)
95{ 90{
96 unsigned long tzic_addr; 91 unsigned long tzic_addr;
@@ -103,5 +98,23 @@ void __init mx53_init_irq(void)
103 panic("unable to map TZIC interrupt controller\n"); 98 panic("unable to map TZIC interrupt controller\n");
104 99
105 tzic_init_irq(tzic_virt); 100 tzic_init_irq(tzic_virt);
106 imx53_register_gpios(); 101}
102
103void __init imx51_soc_init(void)
104{
105 mxc_register_gpio(0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO1_LOW, MX51_MXC_INT_GPIO1_HIGH);
106 mxc_register_gpio(1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO2_LOW, MX51_MXC_INT_GPIO2_HIGH);
107 mxc_register_gpio(2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO3_LOW, MX51_MXC_INT_GPIO3_HIGH);
108 mxc_register_gpio(3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_MXC_INT_GPIO4_LOW, MX51_MXC_INT_GPIO4_HIGH);
109}
110
111void __init imx53_soc_init(void)
112{
113 mxc_register_gpio(0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
114 mxc_register_gpio(1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
115 mxc_register_gpio(2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
116 mxc_register_gpio(3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
117 mxc_register_gpio(4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
118 mxc_register_gpio(5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
119 mxc_register_gpio(6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
107} 120}
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 58e892376bf2..6c38262a3aaa 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,5 +1,5 @@
1# Common support 1# Common support
2obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o 2obj-y := clock.o devices.o icoll.o iomux.o system.o timer.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
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
index cfdb6b284702..fe3e847930c9 100644
--- a/arch/arm/mach-mxs/devices.c
+++ b/arch/arm/mach-mxs/devices.c
@@ -88,3 +88,14 @@ int __init mxs_add_amba_device(const struct amba_device *dev)
88 88
89 return amba_device_register(adev, &iomem_resource); 89 return amba_device_register(adev, &iomem_resource);
90} 90}
91
92struct device mxs_apbh_bus = {
93 .init_name = "mxs_apbh",
94 .parent = &platform_bus,
95};
96
97static int __init mxs_device_init(void)
98{
99 return device_register(&mxs_apbh_bus);
100}
101core_initcall(mxs_device_init);
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
index 324f2824d38d..351915c683ff 100644
--- a/arch/arm/mach-mxs/devices/Makefile
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
6obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o 6obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
7obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o 7obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
8obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o 8obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
9obj-y += platform-gpio-mxs.o
9obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o 10obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o
diff --git a/arch/arm/mach-mxs/devices/platform-gpio-mxs.c b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
new file mode 100644
index 000000000000..ed0885e414e0
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-gpio-mxs.c
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License version 2 as published by the
6 * Free Software Foundation.
7 */
8#include <linux/compiler.h>
9#include <linux/err.h>
10#include <linux/init.h>
11
12#include <mach/mx23.h>
13#include <mach/mx28.h>
14#include <mach/devices-common.h>
15
16struct platform_device *__init mxs_add_gpio(
17 int id, resource_size_t iobase, int irq)
18{
19 struct resource res[] = {
20 {
21 .start = iobase,
22 .end = iobase + SZ_8K - 1,
23 .flags = IORESOURCE_MEM,
24 }, {
25 .start = irq,
26 .end = irq,
27 .flags = IORESOURCE_IRQ,
28 },
29 };
30
31 return platform_device_register_resndata(&mxs_apbh_bus,
32 "gpio-mxs", id, res, ARRAY_SIZE(res), NULL, 0);
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/gpio.h b/arch/arm/mach-mxs/gpio.h
deleted file mode 100644
index 005bb06630b1..000000000000
--- a/arch/arm/mach-mxs/gpio.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright 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 __MXS_GPIO_H__
21#define __MXS_GPIO_H__
22
23struct mxs_gpio_port {
24 void __iomem *base;
25 int id;
26 int irq;
27 int irq_high;
28 int virtual_irq_start;
29 struct gpio_chip chip;
30};
31
32int mxs_gpio_init(struct mxs_gpio_port*, int);
33
34#endif /* __MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 7a37469ed5bf..812d7a813a78 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -11,6 +11,8 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/amba/bus.h> 12#include <linux/amba/bus.h>
13 13
14extern struct device mxs_apbh_bus;
15
14struct platform_device *mxs_add_platform_device_dmamask( 16struct platform_device *mxs_add_platform_device_dmamask(
15 const char *name, int id, 17 const char *name, int id,
16 const struct resource *res, unsigned int num_resources, 18 const struct resource *res, unsigned int num_resources,
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index eacdc6b0e70a..56767a5cce0e 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -26,7 +26,6 @@
26#include <mach/iomux-mx28.h> 26#include <mach/iomux-mx28.h>
27 27
28#include "devices-mx28.h" 28#include "devices-mx28.h"
29#include "gpio.h"
30 29
31#define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13) 30#define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13)
32#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15) 31#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
index 5148cd64a6b7..1b2345ac1a87 100644
--- a/arch/arm/mach-mxs/mm-mx23.c
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -41,5 +41,4 @@ void __init mx23_map_io(void)
41void __init mx23_init_irq(void) 41void __init mx23_init_irq(void)
42{ 42{
43 icoll_init_irq(); 43 icoll_init_irq();
44 mx23_register_gpios();
45} 44}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
index 7e4cea32ebc6..b6e18ddb92c0 100644
--- a/arch/arm/mach-mxs/mm-mx28.c
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -41,5 +41,4 @@ void __init mx28_map_io(void)
41void __init mx28_init_irq(void) 41void __init mx28_init_irq(void)
42{ 42{
43 icoll_init_irq(); 43 icoll_init_irq();
44 mx28_register_gpios();
45} 44}
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index a1387875a491..d53c35fe2ea7 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5# Common support 5# Common support
6obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o 6obj-y := clock.o time.o devices.o cpu.o system.o irq-common.o
7 7
8# MX51 uses the TZIC interrupt controller, older platforms use AVIC 8# MX51 uses the TZIC interrupt controller, older platforms use AVIC
9obj-$(CONFIG_MXC_TZIC) += tzic.o 9obj-$(CONFIG_MXC_TZIC) += tzic.o
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c
index eee1b6096a08..fb166b20f60f 100644
--- a/arch/arm/plat-mxc/devices.c
+++ b/arch/arm/plat-mxc/devices.c
@@ -89,3 +89,14 @@ err:
89 89
90 return pdev; 90 return pdev;
91} 91}
92
93struct device mxc_aips_bus = {
94 .init_name = "mxc_aips",
95 .parent = &platform_bus,
96};
97
98static int __init mxc_device_init(void)
99{
100 return device_register(&mxc_aips_bus);
101}
102core_initcall(mxc_device_init);
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index ad2922acf480..b41bf972b54b 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
2obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o 2obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
3obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o 3obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
4obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o 4obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
5obj-y += platform-gpio-mxc.o
5obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o 6obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
6obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o 7obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
7obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o 8obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
diff --git a/arch/arm/plat-mxc/devices/platform-gpio-mxc.c b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
new file mode 100644
index 000000000000..cf1b7fdfa20d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-gpio-mxc.c
@@ -0,0 +1,32 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2011 Linaro Limited
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 */
9#include <mach/devices-common.h>
10
11struct platform_device *__init mxc_register_gpio(int id,
12 resource_size_t iobase, resource_size_t iosize, int irq, int irq_high)
13{
14 struct resource res[] = {
15 {
16 .start = iobase,
17 .end = iobase + iosize - 1,
18 .flags = IORESOURCE_MEM,
19 }, {
20 .start = irq,
21 .end = irq,
22 .flags = IORESOURCE_IRQ,
23 }, {
24 .start = irq_high,
25 .end = irq_high,
26 .flags = IORESOURCE_IRQ,
27 },
28 };
29
30 return platform_device_register_resndata(&mxc_aips_bus,
31 "gpio-mxc", id, res, ARRAY_SIZE(res), NULL, 0);
32}
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index da7991832af6..91fa2632aa5e 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -43,6 +43,15 @@ extern void mx35_init_irq(void);
43extern void mx50_init_irq(void); 43extern void mx50_init_irq(void);
44extern void mx51_init_irq(void); 44extern void mx51_init_irq(void);
45extern void mx53_init_irq(void); 45extern void mx53_init_irq(void);
46extern void imx1_soc_init(void);
47extern void imx21_soc_init(void);
48extern void imx25_soc_init(void);
49extern void imx27_soc_init(void);
50extern void imx31_soc_init(void);
51extern void imx35_soc_init(void);
52extern void imx50_soc_init(void);
53extern void imx51_soc_init(void);
54extern void imx53_soc_init(void);
46extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq); 55extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
47extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int); 56extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
48extern int mx1_clocks_init(unsigned long fref); 57extern int mx1_clocks_init(unsigned long fref);
@@ -55,7 +64,8 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
55 unsigned long ckih1, unsigned long ckih2); 64 unsigned long ckih1, unsigned long ckih2);
56extern int mx53_clocks_init(unsigned long ckil, unsigned long osc, 65extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
57 unsigned long ckih1, unsigned long ckih2); 66 unsigned long ckih1, unsigned long ckih2);
58extern int mxc_register_gpios(void); 67extern struct platform_device *mxc_register_gpio(int id,
68 resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
59extern int mxc_register_device(struct platform_device *pdev, void *data); 69extern int mxc_register_device(struct platform_device *pdev, void *data);
60extern void mxc_set_cpu_type(unsigned int type); 70extern void mxc_set_cpu_type(unsigned int type);
61extern void mxc_arch_reset_init(void __iomem *); 71extern void mxc_arch_reset_init(void __iomem *);
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index fa8477337f91..03f626645374 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -10,6 +10,8 @@
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11#include <linux/init.h> 11#include <linux/init.h>
12 12
13extern struct device mxc_aips_bus;
14
13struct platform_device *imx_add_platform_device_dmamask( 15struct platform_device *imx_add_platform_device_dmamask(
14 const char *name, int id, 16 const char *name, int id,
15 const struct resource *res, unsigned int num_resources, 17 const struct resource *res, unsigned int num_resources,
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
index a2747f12813e..31c820c1b796 100644
--- a/arch/arm/plat-mxc/include/mach/gpio.h
+++ b/arch/arm/plat-mxc/include/mach/gpio.h
@@ -36,31 +36,4 @@
36#define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio)) 36#define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio))
37#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START) 37#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START)
38 38
39struct mxc_gpio_port {
40 void __iomem *base;
41 int irq;
42 int irq_high;
43 int virtual_irq_start;
44 struct gpio_chip chip;
45 u32 both_edges;
46 spinlock_t lock;
47};
48
49#define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high) \
50 { \
51 .chip.label = "gpio-" #_id, \
52 .irq = _irq, \
53 .irq_high = _irq_high, \
54 .base = soc ## _IO_ADDRESS( \
55 soc ## _GPIO ## _hwid ## _BASE_ADDR), \
56 .virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32, \
57 }
58
59#define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq) \
60 DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0)
61#define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid) \
62 DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0)
63
64int mxc_gpio_init(struct mxc_gpio_port*, int);
65
66#endif 39#endif
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 2967002a9f82..5e6fc222bb23 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -90,6 +90,15 @@ config GPIO_EXYNOS4
90 def_bool y 90 def_bool y
91 depends on CPU_EXYNOS4210 91 depends on CPU_EXYNOS4210
92 92
93config GPIO_MXS
94 def_bool y
95 depends on ARCH_MXS
96
97config GPIO_MXC
98 def_bool y
99 depends on ARCH_MXC
100 select GPIO_BASIC_MMIO_CORE
101
93config GPIO_PLAT_SAMSUNG 102config GPIO_PLAT_SAMSUNG
94 def_bool y 103 def_bool y
95 depends on SAMSUNG_GPIOLIB_4BIT 104 depends on SAMSUNG_GPIOLIB_4BIT
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index b605f8ec6fbe..9c37339a57a7 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -9,6 +9,8 @@ obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
9obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o 9obj-$(CONFIG_GPIO_BASIC_MMIO_CORE) += basic_mmio_gpio.o
10obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o 10obj-$(CONFIG_GPIO_BASIC_MMIO) += basic_mmio_gpio.o
11obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o 11obj-$(CONFIG_GPIO_EXYNOS4) += gpio-exynos4.o
12obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
13obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
12obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o 14obj-$(CONFIG_GPIO_PLAT_SAMSUNG) += gpio-plat-samsung.o
13obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o 15obj-$(CONFIG_GPIO_S5PC100) += gpio-s5pc100.o
14obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o 16obj-$(CONFIG_GPIO_S5PV210) += gpio-s5pv210.o
diff --git a/arch/arm/plat-mxc/gpio.c b/drivers/gpio/gpio-mxc.c
index 6cd6d7f686f6..b351952893bb 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/drivers/gpio/gpio-mxc.c
@@ -24,11 +24,28 @@
24#include <linux/io.h> 24#include <linux/io.h>
25#include <linux/irq.h> 25#include <linux/irq.h>
26#include <linux/gpio.h> 26#include <linux/gpio.h>
27#include <linux/platform_device.h>
28#include <linux/slab.h>
29#include <linux/basic_mmio_gpio.h>
27#include <mach/hardware.h> 30#include <mach/hardware.h>
28#include <asm-generic/bug.h> 31#include <asm-generic/bug.h>
29 32
30static struct mxc_gpio_port *mxc_gpio_ports; 33struct mxc_gpio_port {
31static int gpio_table_size; 34 struct list_head node;
35 void __iomem *base;
36 int irq;
37 int irq_high;
38 int virtual_irq_start;
39 struct bgpio_chip bgc;
40 u32 both_edges;
41};
42
43/*
44 * MX2 has one interrupt *for all* gpio ports. The list is used
45 * to save the references to all ports, so that mx2_gpio_irq_handler
46 * can walk through all interrupt status registers.
47 */
48static LIST_HEAD(mxc_gpio_ports);
32 49
33#define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2()) 50#define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2())
34 51
@@ -50,7 +67,7 @@ static int gpio_table_size;
50 67
51static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) 68static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
52{ 69{
53 __raw_writel(1 << index, port->base + GPIO_ISR); 70 writel(1 << index, port->base + GPIO_ISR);
54} 71}
55 72
56static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index, 73static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
@@ -58,35 +75,36 @@ static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
58{ 75{
59 u32 l; 76 u32 l;
60 77
61 l = __raw_readl(port->base + GPIO_IMR); 78 l = readl(port->base + GPIO_IMR);
62 l = (l & (~(1 << index))) | (!!enable << index); 79 l = (l & (~(1 << index))) | (!!enable << index);
63 __raw_writel(l, port->base + GPIO_IMR); 80 writel(l, port->base + GPIO_IMR);
64} 81}
65 82
66static void gpio_ack_irq(struct irq_data *d) 83static void gpio_ack_irq(struct irq_data *d)
67{ 84{
85 struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
68 u32 gpio = irq_to_gpio(d->irq); 86 u32 gpio = irq_to_gpio(d->irq);
69 _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); 87 _clear_gpio_irqstatus(port, gpio & 0x1f);
70} 88}
71 89
72static void gpio_mask_irq(struct irq_data *d) 90static void gpio_mask_irq(struct irq_data *d)
73{ 91{
92 struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
74 u32 gpio = irq_to_gpio(d->irq); 93 u32 gpio = irq_to_gpio(d->irq);
75 _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0); 94 _set_gpio_irqenable(port, gpio & 0x1f, 0);
76} 95}
77 96
78static void gpio_unmask_irq(struct irq_data *d) 97static void gpio_unmask_irq(struct irq_data *d)
79{ 98{
99 struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
80 u32 gpio = irq_to_gpio(d->irq); 100 u32 gpio = irq_to_gpio(d->irq);
81 _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1); 101 _set_gpio_irqenable(port, gpio & 0x1f, 1);
82} 102}
83 103
84static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
85
86static int gpio_set_irq_type(struct irq_data *d, u32 type) 104static int gpio_set_irq_type(struct irq_data *d, u32 type)
87{ 105{
88 u32 gpio = irq_to_gpio(d->irq); 106 u32 gpio = irq_to_gpio(d->irq);
89 struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; 107 struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
90 u32 bit, val; 108 u32 bit, val;
91 int edge; 109 int edge;
92 void __iomem *reg = port->base; 110 void __iomem *reg = port->base;
@@ -100,7 +118,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
100 edge = GPIO_INT_FALL_EDGE; 118 edge = GPIO_INT_FALL_EDGE;
101 break; 119 break;
102 case IRQ_TYPE_EDGE_BOTH: 120 case IRQ_TYPE_EDGE_BOTH:
103 val = mxc_gpio_get(&port->chip, gpio & 31); 121 val = gpio_get_value(gpio & 31);
104 if (val) { 122 if (val) {
105 edge = GPIO_INT_LOW_LEV; 123 edge = GPIO_INT_LOW_LEV;
106 pr_debug("mxc: set GPIO %d to low trigger\n", gpio); 124 pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
@@ -122,8 +140,8 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
122 140
123 reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ 141 reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
124 bit = gpio & 0xf; 142 bit = gpio & 0xf;
125 val = __raw_readl(reg) & ~(0x3 << (bit << 1)); 143 val = readl(reg) & ~(0x3 << (bit << 1));
126 __raw_writel(val | (edge << (bit << 1)), reg); 144 writel(val | (edge << (bit << 1)), reg);
127 _clear_gpio_irqstatus(port, gpio & 0x1f); 145 _clear_gpio_irqstatus(port, gpio & 0x1f);
128 146
129 return 0; 147 return 0;
@@ -137,7 +155,7 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
137 155
138 reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ 156 reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
139 bit = gpio & 0xf; 157 bit = gpio & 0xf;
140 val = __raw_readl(reg); 158 val = readl(reg);
141 edge = (val >> (bit << 1)) & 3; 159 edge = (val >> (bit << 1)) & 3;
142 val &= ~(0x3 << (bit << 1)); 160 val &= ~(0x3 << (bit << 1));
143 if (edge == GPIO_INT_HIGH_LEV) { 161 if (edge == GPIO_INT_HIGH_LEV) {
@@ -151,7 +169,7 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
151 gpio, edge); 169 gpio, edge);
152 return; 170 return;
153 } 171 }
154 __raw_writel(val | (edge << (bit << 1)), reg); 172 writel(val | (edge << (bit << 1)), reg);
155} 173}
156 174
157/* handle 32 interrupts in one status register */ 175/* handle 32 interrupts in one status register */
@@ -177,8 +195,7 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
177 u32 irq_stat; 195 u32 irq_stat;
178 struct mxc_gpio_port *port = irq_get_handler_data(irq); 196 struct mxc_gpio_port *port = irq_get_handler_data(irq);
179 197
180 irq_stat = __raw_readl(port->base + GPIO_ISR) & 198 irq_stat = readl(port->base + GPIO_ISR) & readl(port->base + GPIO_IMR);
181 __raw_readl(port->base + GPIO_IMR);
182 199
183 mxc_gpio_irq_handler(port, irq_stat); 200 mxc_gpio_irq_handler(port, irq_stat);
184} 201}
@@ -186,19 +203,18 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
186/* MX2 has one interrupt *for all* gpio ports */ 203/* MX2 has one interrupt *for all* gpio ports */
187static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc) 204static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
188{ 205{
189 int i;
190 u32 irq_msk, irq_stat; 206 u32 irq_msk, irq_stat;
191 struct mxc_gpio_port *port = irq_get_handler_data(irq); 207 struct mxc_gpio_port *port;
192 208
193 /* walk through all interrupt status registers */ 209 /* walk through all interrupt status registers */
194 for (i = 0; i < gpio_table_size; i++) { 210 list_for_each_entry(port, &mxc_gpio_ports, node) {
195 irq_msk = __raw_readl(port[i].base + GPIO_IMR); 211 irq_msk = readl(port->base + GPIO_IMR);
196 if (!irq_msk) 212 if (!irq_msk)
197 continue; 213 continue;
198 214
199 irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; 215 irq_stat = readl(port->base + GPIO_ISR) & irq_msk;
200 if (irq_stat) 216 if (irq_stat)
201 mxc_gpio_irq_handler(&port[i], irq_stat); 217 mxc_gpio_irq_handler(port, irq_stat);
202 } 218 }
203} 219}
204 220
@@ -215,7 +231,7 @@ static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
215{ 231{
216 u32 gpio = irq_to_gpio(d->irq); 232 u32 gpio = irq_to_gpio(d->irq);
217 u32 gpio_idx = gpio & 0x1F; 233 u32 gpio_idx = gpio & 0x1F;
218 struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32]; 234 struct mxc_gpio_port *port = irq_data_get_irq_chip_data(d);
219 235
220 if (enable) { 236 if (enable) {
221 if (port->irq_high && (gpio_idx >= 16)) 237 if (port->irq_high && (gpio_idx >= 16))
@@ -241,121 +257,123 @@ static struct irq_chip gpio_irq_chip = {
241 .irq_set_wake = gpio_set_wake_irq, 257 .irq_set_wake = gpio_set_wake_irq,
242}; 258};
243 259
244static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
245 int dir)
246{
247 struct mxc_gpio_port *port =
248 container_of(chip, struct mxc_gpio_port, chip);
249 u32 l;
250 unsigned long flags;
251
252 spin_lock_irqsave(&port->lock, flags);
253 l = __raw_readl(port->base + GPIO_GDIR);
254 if (dir)
255 l |= 1 << offset;
256 else
257 l &= ~(1 << offset);
258 __raw_writel(l, port->base + GPIO_GDIR);
259 spin_unlock_irqrestore(&port->lock, flags);
260}
261
262static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
263{
264 struct mxc_gpio_port *port =
265 container_of(chip, struct mxc_gpio_port, chip);
266 void __iomem *reg = port->base + GPIO_DR;
267 u32 l;
268 unsigned long flags;
269
270 spin_lock_irqsave(&port->lock, flags);
271 l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
272 __raw_writel(l, reg);
273 spin_unlock_irqrestore(&port->lock, flags);
274}
275
276static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
277{
278 struct mxc_gpio_port *port =
279 container_of(chip, struct mxc_gpio_port, chip);
280
281 return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
282}
283
284static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
285{
286 _set_gpio_direction(chip, offset, 0);
287 return 0;
288}
289
290static int mxc_gpio_direction_output(struct gpio_chip *chip,
291 unsigned offset, int value)
292{
293 mxc_gpio_set(chip, offset, value);
294 _set_gpio_direction(chip, offset, 1);
295 return 0;
296}
297
298/* 260/*
299 * This lock class tells lockdep that GPIO irqs are in a different 261 * This lock class tells lockdep that GPIO irqs are in a different
300 * category than their parents, so it won't report false recursion. 262 * category than their parents, so it won't report false recursion.
301 */ 263 */
302static struct lock_class_key gpio_lock_class; 264static struct lock_class_key gpio_lock_class;
303 265
304int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) 266static int __devinit mxc_gpio_probe(struct platform_device *pdev)
305{ 267{
306 int i, j; 268 struct mxc_gpio_port *port;
307 269 struct resource *iores;
308 /* save for local usage */ 270 int err, i;
309 mxc_gpio_ports = port;
310 gpio_table_size = cnt;
311
312 printk(KERN_INFO "MXC GPIO hardware\n");
313
314 for (i = 0; i < cnt; i++) {
315 /* disable the interrupt and clear the status */
316 __raw_writel(0, port[i].base + GPIO_IMR);
317 __raw_writel(~0, port[i].base + GPIO_ISR);
318 for (j = port[i].virtual_irq_start;
319 j < port[i].virtual_irq_start + 32; j++) {
320 irq_set_lockdep_class(j, &gpio_lock_class);
321 irq_set_chip_and_handler(j, &gpio_irq_chip,
322 handle_level_irq);
323 set_irq_flags(j, IRQF_VALID);
324 }
325 271
326 /* register gpio chip */ 272 port = kzalloc(sizeof(struct mxc_gpio_port), GFP_KERNEL);
327 port[i].chip.direction_input = mxc_gpio_direction_input; 273 if (!port)
328 port[i].chip.direction_output = mxc_gpio_direction_output; 274 return -ENOMEM;
329 port[i].chip.get = mxc_gpio_get;
330 port[i].chip.set = mxc_gpio_set;
331 port[i].chip.base = i * 32;
332 port[i].chip.ngpio = 32;
333 275
334 spin_lock_init(&port[i].lock); 276 port->virtual_irq_start = MXC_GPIO_IRQ_START + pdev->id * 32;
335 277
336 /* its a serious configuration bug when it fails */ 278 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
337 BUG_ON( gpiochip_add(&port[i].chip) < 0 ); 279 if (!iores) {
280 err = -ENODEV;
281 goto out_kfree;
282 }
338 283
339 if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) { 284 if (!request_mem_region(iores->start, resource_size(iores),
340 /* setup one handler for each entry */ 285 pdev->name)) {
341 irq_set_chained_handler(port[i].irq, 286 err = -EBUSY;
342 mx3_gpio_irq_handler); 287 goto out_kfree;
343 irq_set_handler_data(port[i].irq, &port[i]); 288 }
344 if (port[i].irq_high) { 289
345 /* setup handler for GPIO 16 to 31 */ 290 port->base = ioremap(iores->start, resource_size(iores));
346 irq_set_chained_handler(port[i].irq_high, 291 if (!port->base) {
347 mx3_gpio_irq_handler); 292 err = -ENOMEM;
348 irq_set_handler_data(port[i].irq_high, 293 goto out_release_mem;
349 &port[i]); 294 }
350 } 295
351 } 296 port->irq_high = platform_get_irq(pdev, 1);
297 port->irq = platform_get_irq(pdev, 0);
298 if (port->irq < 0) {
299 err = -EINVAL;
300 goto out_iounmap;
301 }
302
303 /* disable the interrupt and clear the status */
304 writel(0, port->base + GPIO_IMR);
305 writel(~0, port->base + GPIO_ISR);
306
307 for (i = port->virtual_irq_start;
308 i < port->virtual_irq_start + 32; i++) {
309 irq_set_lockdep_class(i, &gpio_lock_class);
310 irq_set_chip_and_handler(i, &gpio_irq_chip, handle_level_irq);
311 set_irq_flags(i, IRQF_VALID);
312 irq_set_chip_data(i, port);
352 } 313 }
353 314
354 if (cpu_is_mx2()) { 315 if (cpu_is_mx2()) {
355 /* setup one handler for all GPIO interrupts */ 316 /* setup one handler for all GPIO interrupts */
356 irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler); 317 if (pdev->id == 0)
357 irq_set_handler_data(port[0].irq, port); 318 irq_set_chained_handler(port->irq,
319 mx2_gpio_irq_handler);
320 } else {
321 /* setup one handler for each entry */
322 irq_set_chained_handler(port->irq, mx3_gpio_irq_handler);
323 irq_set_handler_data(port->irq, port);
324 if (port->irq_high > 0) {
325 /* setup handler for GPIO 16 to 31 */
326 irq_set_chained_handler(port->irq_high,
327 mx3_gpio_irq_handler);
328 irq_set_handler_data(port->irq_high, port);
329 }
358 } 330 }
359 331
332 err = bgpio_init(&port->bgc, &pdev->dev, 4,
333 port->base + GPIO_PSR,
334 port->base + GPIO_DR, NULL,
335 port->base + GPIO_GDIR, NULL, false);
336 if (err)
337 goto out_iounmap;
338
339 port->bgc.gc.base = pdev->id * 32;
340
341 err = gpiochip_add(&port->bgc.gc);
342 if (err)
343 goto out_bgpio_remove;
344
345 list_add_tail(&port->node, &mxc_gpio_ports);
346
360 return 0; 347 return 0;
348
349out_bgpio_remove:
350 bgpio_remove(&port->bgc);
351out_iounmap:
352 iounmap(port->base);
353out_release_mem:
354 release_mem_region(iores->start, resource_size(iores));
355out_kfree:
356 kfree(port);
357 dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
358 return err;
361} 359}
360
361static struct platform_driver mxc_gpio_driver = {
362 .driver = {
363 .name = "gpio-mxc",
364 .owner = THIS_MODULE,
365 },
366 .probe = mxc_gpio_probe,
367};
368
369static int __init gpio_mxc_init(void)
370{
371 return platform_driver_register(&mxc_gpio_driver);
372}
373postcore_initcall(gpio_mxc_init);
374
375MODULE_AUTHOR("Freescale Semiconductor, "
376 "Daniel Mack <danielncaiaq.de>, "
377 "Juergen Beisert <kernel@pengutronix.de>");
378MODULE_DESCRIPTION("Freescale MXC GPIO");
379MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mxs/gpio.c b/drivers/gpio/gpio-mxs.c
index 2c950fef71a8..a28761428bb0 100644
--- a/arch/arm/mach-mxs/gpio.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -25,14 +25,12 @@
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 <mach/mx23.h> 28#include <linux/platform_device.h>
29#include <mach/mx28.h> 29#include <linux/slab.h>
30#include <asm-generic/bug.h> 30#include <mach/mxs.h>
31 31
32#include "gpio.h" 32#define MXS_SET 0x4
33 33#define MXS_CLR 0x8
34static struct mxs_gpio_port *mxs_gpio_ports;
35static int gpio_table_size;
36 34
37#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10) 35#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
38#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10) 36#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
@@ -50,40 +48,55 @@ static int gpio_table_size;
50#define GPIO_INT_LEV_MASK (1 << 0) 48#define GPIO_INT_LEV_MASK (1 << 0)
51#define GPIO_INT_POL_MASK (1 << 1) 49#define GPIO_INT_POL_MASK (1 << 1)
52 50
51struct mxs_gpio_port {
52 void __iomem *base;
53 int id;
54 int irq;
55 int irq_high;
56 int virtual_irq_start;
57 struct gpio_chip chip;
58};
59
53/* Note: This driver assumes 32 GPIOs are handled in one register */ 60/* Note: This driver assumes 32 GPIOs are handled in one register */
54 61
55static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index) 62static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
56{ 63{
57 __mxs_clrl(1 << index, port->base + PINCTRL_IRQSTAT(port->id)); 64 writel(1 << index, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
58} 65}
59 66
60static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index, 67static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
61 int enable) 68 int enable)
62{ 69{
63 if (enable) { 70 if (enable) {
64 __mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id)); 71 writel(1 << index,
65 __mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id)); 72 port->base + PINCTRL_IRQEN(port->id) + MXS_SET);
73 writel(1 << index,
74 port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET);
66 } else { 75 } else {
67 __mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id)); 76 writel(1 << index,
77 port->base + PINCTRL_IRQEN(port->id) + MXS_CLR);
68 } 78 }
69} 79}
70 80
71static void mxs_gpio_ack_irq(struct irq_data *d) 81static void mxs_gpio_ack_irq(struct irq_data *d)
72{ 82{
83 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
73 u32 gpio = irq_to_gpio(d->irq); 84 u32 gpio = irq_to_gpio(d->irq);
74 clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f); 85 clear_gpio_irqstatus(port, gpio & 0x1f);
75} 86}
76 87
77static void mxs_gpio_mask_irq(struct irq_data *d) 88static void mxs_gpio_mask_irq(struct irq_data *d)
78{ 89{
90 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
79 u32 gpio = irq_to_gpio(d->irq); 91 u32 gpio = irq_to_gpio(d->irq);
80 set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0); 92 set_gpio_irqenable(port, gpio & 0x1f, 0);
81} 93}
82 94
83static void mxs_gpio_unmask_irq(struct irq_data *d) 95static void mxs_gpio_unmask_irq(struct irq_data *d)
84{ 96{
97 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
85 u32 gpio = irq_to_gpio(d->irq); 98 u32 gpio = irq_to_gpio(d->irq);
86 set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1); 99 set_gpio_irqenable(port, gpio & 0x1f, 1);
87} 100}
88 101
89static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset); 102static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
@@ -92,7 +105,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
92{ 105{
93 u32 gpio = irq_to_gpio(d->irq); 106 u32 gpio = irq_to_gpio(d->irq);
94 u32 pin_mask = 1 << (gpio & 31); 107 u32 pin_mask = 1 << (gpio & 31);
95 struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32]; 108 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
96 void __iomem *pin_addr; 109 void __iomem *pin_addr;
97 int edge; 110 int edge;
98 111
@@ -116,16 +129,16 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
116 /* set level or edge */ 129 /* set level or edge */
117 pin_addr = port->base + PINCTRL_IRQLEV(port->id); 130 pin_addr = port->base + PINCTRL_IRQLEV(port->id);
118 if (edge & GPIO_INT_LEV_MASK) 131 if (edge & GPIO_INT_LEV_MASK)
119 __mxs_setl(pin_mask, pin_addr); 132 writel(pin_mask, pin_addr + MXS_SET);
120 else 133 else
121 __mxs_clrl(pin_mask, pin_addr); 134 writel(pin_mask, pin_addr + MXS_CLR);
122 135
123 /* set polarity */ 136 /* set polarity */
124 pin_addr = port->base + PINCTRL_IRQPOL(port->id); 137 pin_addr = port->base + PINCTRL_IRQPOL(port->id);
125 if (edge & GPIO_INT_POL_MASK) 138 if (edge & GPIO_INT_POL_MASK)
126 __mxs_setl(pin_mask, pin_addr); 139 writel(pin_mask, pin_addr + MXS_SET);
127 else 140 else
128 __mxs_clrl(pin_mask, pin_addr); 141 writel(pin_mask, pin_addr + MXS_CLR);
129 142
130 clear_gpio_irqstatus(port, gpio & 0x1f); 143 clear_gpio_irqstatus(port, gpio & 0x1f);
131 144
@@ -136,13 +149,13 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
136static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc) 149static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
137{ 150{
138 u32 irq_stat; 151 u32 irq_stat;
139 struct mxs_gpio_port *port = (struct mxs_gpio_port *)irq_get_handler_data(irq); 152 struct mxs_gpio_port *port = irq_get_handler_data(irq);
140 u32 gpio_irq_no_base = port->virtual_irq_start; 153 u32 gpio_irq_no_base = port->virtual_irq_start;
141 154
142 desc->irq_data.chip->irq_ack(&desc->irq_data); 155 desc->irq_data.chip->irq_ack(&desc->irq_data);
143 156
144 irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) & 157 irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) &
145 __raw_readl(port->base + PINCTRL_IRQEN(port->id)); 158 readl(port->base + PINCTRL_IRQEN(port->id));
146 159
147 while (irq_stat != 0) { 160 while (irq_stat != 0) {
148 int irqoffset = fls(irq_stat) - 1; 161 int irqoffset = fls(irq_stat) - 1;
@@ -164,7 +177,7 @@ static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
164{ 177{
165 u32 gpio = irq_to_gpio(d->irq); 178 u32 gpio = irq_to_gpio(d->irq);
166 u32 gpio_idx = gpio & 0x1f; 179 u32 gpio_idx = gpio & 0x1f;
167 struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32]; 180 struct mxs_gpio_port *port = irq_data_get_irq_chip_data(d);
168 181
169 if (enable) { 182 if (enable) {
170 if (port->irq_high && (gpio_idx >= 16)) 183 if (port->irq_high && (gpio_idx >= 16))
@@ -198,9 +211,9 @@ static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
198 void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id); 211 void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id);
199 212
200 if (dir) 213 if (dir)
201 __mxs_setl(1 << offset, pin_addr); 214 writel(1 << offset, pin_addr + MXS_SET);
202 else 215 else
203 __mxs_clrl(1 << offset, pin_addr); 216 writel(1 << offset, pin_addr + MXS_CLR);
204} 217}
205 218
206static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset) 219static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -208,7 +221,7 @@ static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
208 struct mxs_gpio_port *port = 221 struct mxs_gpio_port *port =
209 container_of(chip, struct mxs_gpio_port, chip); 222 container_of(chip, struct mxs_gpio_port, chip);
210 223
211 return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1; 224 return (readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
212} 225}
213 226
214static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 227static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
@@ -218,9 +231,9 @@ static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
218 void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id); 231 void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id);
219 232
220 if (value) 233 if (value)
221 __mxs_setl(1 << offset, pin_addr); 234 writel(1 << offset, pin_addr + MXS_SET);
222 else 235 else
223 __mxs_clrl(1 << offset, pin_addr); 236 writel(1 << offset, pin_addr + MXS_CLR);
224} 237}
225 238
226static int mxs_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 239static int mxs_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
@@ -245,87 +258,113 @@ static int mxs_gpio_direction_output(struct gpio_chip *chip,
245 return 0; 258 return 0;
246} 259}
247 260
248int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt) 261static int __devinit mxs_gpio_probe(struct platform_device *pdev)
249{ 262{
250 int i, j; 263 static void __iomem *base;
264 struct mxs_gpio_port *port;
265 struct resource *iores = NULL;
266 int err, i;
267
268 port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL);
269 if (!port)
270 return -ENOMEM;
271
272 port->id = pdev->id;
273 port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
274
275 /*
276 * map memory region only once, as all the gpio ports
277 * share the same one
278 */
279 if (!base) {
280 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281 if (!iores) {
282 err = -ENODEV;
283 goto out_kfree;
284 }
251 285
252 /* save for local usage */ 286 if (!request_mem_region(iores->start, resource_size(iores),
253 mxs_gpio_ports = port; 287 pdev->name)) {
254 gpio_table_size = cnt; 288 err = -EBUSY;
289 goto out_kfree;
290 }
255 291
256 pr_info("MXS GPIO hardware\n"); 292 base = ioremap(iores->start, resource_size(iores));
293 if (!base) {
294 err = -ENOMEM;
295 goto out_release_mem;
296 }
297 }
298 port->base = base;
257 299
258 for (i = 0; i < cnt; i++) { 300 port->irq = platform_get_irq(pdev, 0);
259 /* disable the interrupt and clear the status */ 301 if (port->irq < 0) {
260 __raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i)); 302 err = -EINVAL;
261 __raw_writel(0, port[i].base + PINCTRL_IRQEN(i)); 303 goto out_iounmap;
304 }
262 305
263 /* clear address has to be used to clear IRQSTAT bits */ 306 /* disable the interrupt and clear the status */
264 __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i)); 307 writel(0, port->base + PINCTRL_PIN2IRQ(port->id));
308 writel(0, port->base + PINCTRL_IRQEN(port->id));
265 309
266 for (j = port[i].virtual_irq_start; 310 /* clear address has to be used to clear IRQSTAT bits */
267 j < port[i].virtual_irq_start + 32; j++) { 311 writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
268 irq_set_chip_and_handler(j, &gpio_irq_chip,
269 handle_level_irq);
270 set_irq_flags(j, IRQF_VALID);
271 }
272 312
273 /* setup one handler for each entry */ 313 for (i = port->virtual_irq_start;
274 irq_set_chained_handler(port[i].irq, mxs_gpio_irq_handler); 314 i < port->virtual_irq_start + 32; i++) {
275 irq_set_handler_data(port[i].irq, &port[i]); 315 irq_set_chip_and_handler(i, &gpio_irq_chip,
276 316 handle_level_irq);
277 /* register gpio chip */ 317 set_irq_flags(i, IRQF_VALID);
278 port[i].chip.direction_input = mxs_gpio_direction_input; 318 irq_set_chip_data(i, port);
279 port[i].chip.direction_output = mxs_gpio_direction_output;
280 port[i].chip.get = mxs_gpio_get;
281 port[i].chip.set = mxs_gpio_set;
282 port[i].chip.to_irq = mxs_gpio_to_irq;
283 port[i].chip.base = i * 32;
284 port[i].chip.ngpio = 32;
285
286 /* its a serious configuration bug when it fails */
287 BUG_ON(gpiochip_add(&port[i].chip) < 0);
288 } 319 }
289 320
290 return 0; 321 /* setup one handler for each entry */
291} 322 irq_set_chained_handler(port->irq, mxs_gpio_irq_handler);
323 irq_set_handler_data(port->irq, port);
292 324
293#define MX23_GPIO_BASE MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR) 325 /* register gpio chip */
294#define MX28_GPIO_BASE MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR) 326 port->chip.direction_input = mxs_gpio_direction_input;
327 port->chip.direction_output = mxs_gpio_direction_output;
328 port->chip.get = mxs_gpio_get;
329 port->chip.set = mxs_gpio_set;
330 port->chip.to_irq = mxs_gpio_to_irq;
331 port->chip.base = port->id * 32;
332 port->chip.ngpio = 32;
295 333
296#define DEFINE_MXS_GPIO_PORT(_base, _irq, _id) \ 334 err = gpiochip_add(&port->chip);
297 { \ 335 if (err)
298 .chip.label = "gpio-" #_id, \ 336 goto out_iounmap;
299 .id = _id, \
300 .irq = _irq, \
301 .base = _base, \
302 .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
303 }
304 337
305#ifdef CONFIG_SOC_IMX23 338 return 0;
306static struct mxs_gpio_port mx23_gpio_ports[] = {
307 DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO0, 0),
308 DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO1, 1),
309 DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO2, 2),
310};
311 339
312int __init mx23_register_gpios(void) 340out_iounmap:
313{ 341 if (iores)
314 return mxs_gpio_init(mx23_gpio_ports, ARRAY_SIZE(mx23_gpio_ports)); 342 iounmap(port->base);
343out_release_mem:
344 if (iores)
345 release_mem_region(iores->start, resource_size(iores));
346out_kfree:
347 kfree(port);
348 dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
349 return err;
315} 350}
316#endif 351
317 352static struct platform_driver mxs_gpio_driver = {
318#ifdef CONFIG_SOC_IMX28 353 .driver = {
319static struct mxs_gpio_port mx28_gpio_ports[] = { 354 .name = "gpio-mxs",
320 DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO0, 0), 355 .owner = THIS_MODULE,
321 DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO1, 1), 356 },
322 DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO2, 2), 357 .probe = mxs_gpio_probe,
323 DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO3, 3),
324 DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO4, 4),
325}; 358};
326 359
327int __init mx28_register_gpios(void) 360static int __init mxs_gpio_init(void)
328{ 361{
329 return mxs_gpio_init(mx28_gpio_ports, ARRAY_SIZE(mx28_gpio_ports)); 362 return platform_driver_register(&mxs_gpio_driver);
330} 363}
331#endif 364postcore_initcall(mxs_gpio_init);
365
366MODULE_AUTHOR("Freescale Semiconductor, "
367 "Daniel Mack <danielncaiaq.de>, "
368 "Juergen Beisert <kernel@pengutronix.de>");
369MODULE_DESCRIPTION("Freescale MXS GPIO");
370MODULE_LICENSE("GPL");