aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c10
-rw-r--r--arch/arm/mach-omap2/board-ldp.c10
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c7
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c10
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c10
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c90
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c14
-rw-r--r--arch/arm/mach-omap2/clock24xx.c1
-rw-r--r--arch/arm/mach-omap2/clock34xx.c35
-rw-r--r--arch/arm/mach-omap2/clockdomain.c74
-rw-r--r--arch/arm/mach-omap2/cm4xxx.c17
-rw-r--r--arch/arm/mach-omap2/devices.c65
-rw-r--r--arch/arm/mach-omap2/io.c4
-rw-r--r--arch/arm/mach-omap2/iommu2.c2
-rw-r--r--arch/arm/mach-omap2/mailbox.c33
-rw-r--r--arch/arm/mach-omap2/mux.c4
-rw-r--r--arch/arm/mach-omap2/pm-debug.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c187
-rw-r--r--arch/arm/mach-omap2/powerdomain.c39
-rw-r--r--arch/arm/mach-omap2/serial.c6
20 files changed, 394 insertions, 228 deletions
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index bd57ec76dc5e..efaf053eba85 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -54,7 +54,7 @@
54 54
55#define TWL4030_MSECURE_GPIO 22 55#define TWL4030_MSECURE_GPIO 22
56 56
57static int sdp3430_keymap[] = { 57static int board_keymap[] = {
58 KEY(0, 0, KEY_LEFT), 58 KEY(0, 0, KEY_LEFT),
59 KEY(0, 1, KEY_RIGHT), 59 KEY(0, 1, KEY_RIGHT),
60 KEY(0, 2, KEY_A), 60 KEY(0, 2, KEY_A),
@@ -88,11 +88,15 @@ static int sdp3430_keymap[] = {
88 0 88 0
89}; 89};
90 90
91static struct matrix_keymap_data board_map_data = {
92 .keymap = board_keymap,
93 .keymap_size = ARRAY_SIZE(board_keymap),
94};
95
91static struct twl4030_keypad_data sdp3430_kp_data = { 96static struct twl4030_keypad_data sdp3430_kp_data = {
97 .keymap_data = &board_map_data,
92 .rows = 5, 98 .rows = 5,
93 .cols = 6, 99 .cols = 6,
94 .keymap = sdp3430_keymap,
95 .keymapsize = ARRAY_SIZE(sdp3430_keymap),
96 .rep = 1, 100 .rep = 1,
97}; 101};
98 102
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index ec6854cbdd9f..d110a7fdfbd8 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -80,7 +80,7 @@ static struct platform_device ldp_smsc911x_device = {
80 }, 80 },
81}; 81};
82 82
83static int ldp_twl4030_keymap[] = { 83static int board_keymap[] = {
84 KEY(0, 0, KEY_1), 84 KEY(0, 0, KEY_1),
85 KEY(1, 0, KEY_2), 85 KEY(1, 0, KEY_2),
86 KEY(2, 0, KEY_3), 86 KEY(2, 0, KEY_3),
@@ -101,11 +101,15 @@ static int ldp_twl4030_keymap[] = {
101 0 101 0
102}; 102};
103 103
104static struct matrix_keymap_data board_map_data = {
105 .keymap = board_keymap,
106 .keymap_size = ARRAY_SIZE(board_keymap),
107};
108
104static struct twl4030_keypad_data ldp_kp_twl4030_data = { 109static struct twl4030_keypad_data ldp_kp_twl4030_data = {
110 .keymap_data = &board_map_data,
105 .rows = 6, 111 .rows = 6,
106 .cols = 6, 112 .cols = 6,
107 .keymap = ldp_twl4030_keymap,
108 .keymapsize = ARRAY_SIZE(ldp_twl4030_keymap),
109 .rep = 1, 113 .rep = 1,
110}; 114};
111 115
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 500c9956876d..70df6b4dbcd4 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -139,8 +139,13 @@ static struct gpio_led gpio_leds[];
139static int beagle_twl_gpio_setup(struct device *dev, 139static int beagle_twl_gpio_setup(struct device *dev,
140 unsigned gpio, unsigned ngpio) 140 unsigned gpio, unsigned ngpio)
141{ 141{
142 if (system_rev >= 0x20 && system_rev <= 0x34301000) {
143 omap_cfg_reg(AG9_34XX_GPIO23);
144 mmc[0].gpio_wp = 23;
145 } else {
146 omap_cfg_reg(AH8_34XX_GPIO29);
147 }
142 /* gpio + 0 is "mmc0_cd" (input/IRQ) */ 148 /* gpio + 0 is "mmc0_cd" (input/IRQ) */
143 omap_cfg_reg(AH8_34XX_GPIO29);
144 mmc[0].gpio_cd = gpio + 0; 149 mmc[0].gpio_cd = gpio + 0;
145 twl4030_mmc_init(mmc); 150 twl4030_mmc_init(mmc);
146 151
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index d50b9be90580..e4ec0c591216 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -159,7 +159,7 @@ static struct twl4030_usb_data omap3evm_usb_data = {
159 .usb_mode = T2_USB_MODE_ULPI, 159 .usb_mode = T2_USB_MODE_ULPI,
160}; 160};
161 161
162static int omap3evm_keymap[] = { 162static int board_keymap[] = {
163 KEY(0, 0, KEY_LEFT), 163 KEY(0, 0, KEY_LEFT),
164 KEY(0, 1, KEY_RIGHT), 164 KEY(0, 1, KEY_RIGHT),
165 KEY(0, 2, KEY_A), 165 KEY(0, 2, KEY_A),
@@ -178,11 +178,15 @@ static int omap3evm_keymap[] = {
178 KEY(3, 3, KEY_P) 178 KEY(3, 3, KEY_P)
179}; 179};
180 180
181static struct matrix_keymap_data board_map_data = {
182 .keymap = board_keymap,
183 .keymap_size = ARRAY_SIZE(board_keymap),
184};
185
181static struct twl4030_keypad_data omap3evm_kp_data = { 186static struct twl4030_keypad_data omap3evm_kp_data = {
187 .keymap_data = &board_map_data,
182 .rows = 4, 188 .rows = 4,
183 .cols = 4, 189 .cols = 4,
184 .keymap = omap3evm_keymap,
185 .keymapsize = ARRAY_SIZE(omap3evm_keymap),
186 .rep = 1, 190 .rep = 1,
187}; 191};
188 192
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index b43f6e36b6d9..7f6bf8772af7 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -133,7 +133,7 @@ static void __init pandora_keys_gpio_init(void)
133 omap_set_gpio_debounce_time(32 * 5, GPIO_DEBOUNCE_TIME); 133 omap_set_gpio_debounce_time(32 * 5, GPIO_DEBOUNCE_TIME);
134} 134}
135 135
136static int pandora_keypad_map[] = { 136static int board_keymap[] = {
137 /* col, row, code */ 137 /* col, row, code */
138 KEY(0, 0, KEY_9), 138 KEY(0, 0, KEY_9),
139 KEY(0, 1, KEY_0), 139 KEY(0, 1, KEY_0),
@@ -180,11 +180,15 @@ static int pandora_keypad_map[] = {
180 KEY(5, 2, KEY_FN), 180 KEY(5, 2, KEY_FN),
181}; 181};
182 182
183static struct matrix_keymap_data board_map_data = {
184 .keymap = board_keymap,
185 .keymap_size = ARRAY_SIZE(board_keymap),
186};
187
183static struct twl4030_keypad_data pandora_kp_data = { 188static struct twl4030_keypad_data pandora_kp_data = {
189 .keymap_data = &board_map_data,
184 .rows = 8, 190 .rows = 8,
185 .cols = 6, 191 .cols = 6,
186 .keymap = pandora_keypad_map,
187 .keymapsize = ARRAY_SIZE(pandora_keypad_map),
188 .rep = 1, 192 .rep = 1,
189}; 193};
190 194
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index e6e8290b7828..2b0eb1ba5d7f 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -36,58 +36,62 @@
36#define SYSTEM_REV_B_USES_VAUX3 0x1699 36#define SYSTEM_REV_B_USES_VAUX3 0x1699
37#define SYSTEM_REV_S_USES_VAUX3 0x8 37#define SYSTEM_REV_S_USES_VAUX3 0x8
38 38
39static int rx51_keymap[] = { 39static int board_keymap[] = {
40 KEY(0, 0, KEY_Q), 40 KEY(0, 0, KEY_Q),
41 KEY(0, 1, KEY_W), 41 KEY(0, 1, KEY_O),
42 KEY(0, 2, KEY_E), 42 KEY(0, 2, KEY_P),
43 KEY(0, 3, KEY_R), 43 KEY(0, 3, KEY_COMMA),
44 KEY(0, 4, KEY_T), 44 KEY(0, 4, KEY_BACKSPACE),
45 KEY(0, 5, KEY_Y), 45 KEY(0, 6, KEY_A),
46 KEY(0, 6, KEY_U), 46 KEY(0, 7, KEY_S),
47 KEY(0, 7, KEY_I), 47 KEY(1, 0, KEY_W),
48 KEY(1, 0, KEY_O),
49 KEY(1, 1, KEY_D), 48 KEY(1, 1, KEY_D),
50 KEY(1, 2, KEY_DOT), 49 KEY(1, 2, KEY_F),
51 KEY(1, 3, KEY_V), 50 KEY(1, 3, KEY_G),
52 KEY(1, 4, KEY_DOWN), 51 KEY(1, 4, KEY_H),
53 KEY(2, 0, KEY_P), 52 KEY(1, 5, KEY_J),
54 KEY(2, 1, KEY_F), 53 KEY(1, 6, KEY_K),
54 KEY(1, 7, KEY_L),
55 KEY(2, 0, KEY_E),
56 KEY(2, 1, KEY_DOT),
55 KEY(2, 2, KEY_UP), 57 KEY(2, 2, KEY_UP),
56 KEY(2, 3, KEY_B), 58 KEY(2, 3, KEY_ENTER),
57 KEY(2, 4, KEY_RIGHT), 59 KEY(2, 5, KEY_Z),
58 KEY(3, 0, KEY_COMMA), 60 KEY(2, 6, KEY_X),
59 KEY(3, 1, KEY_G), 61 KEY(2, 7, KEY_C),
60 KEY(3, 2, KEY_ENTER), 62 KEY(3, 0, KEY_R),
63 KEY(3, 1, KEY_V),
64 KEY(3, 2, KEY_B),
61 KEY(3, 3, KEY_N), 65 KEY(3, 3, KEY_N),
62 KEY(4, 0, KEY_BACKSPACE), 66 KEY(3, 4, KEY_M),
63 KEY(4, 1, KEY_H), 67 KEY(3, 5, KEY_SPACE),
64 KEY(4, 3, KEY_M), 68 KEY(3, 6, KEY_SPACE),
69 KEY(3, 7, KEY_LEFT),
70 KEY(4, 0, KEY_T),
71 KEY(4, 1, KEY_DOWN),
72 KEY(4, 2, KEY_RIGHT),
65 KEY(4, 4, KEY_LEFTCTRL), 73 KEY(4, 4, KEY_LEFTCTRL),
66 KEY(5, 1, KEY_J), 74 KEY(4, 5, KEY_RIGHTALT),
67 KEY(5, 2, KEY_Z), 75 KEY(4, 6, KEY_LEFTSHIFT),
68 KEY(5, 3, KEY_SPACE), 76 KEY(5, 0, KEY_Y),
69 KEY(5, 4, KEY_LEFTSHIFT), 77 KEY(6, 0, KEY_U),
70 KEY(6, 0, KEY_A), 78 KEY(7, 0, KEY_I),
71 KEY(6, 1, KEY_K), 79 KEY(7, 1, KEY_F7),
72 KEY(6, 2, KEY_X), 80 KEY(7, 2, KEY_F8),
73 KEY(6, 3, KEY_SPACE), 81 KEY(0xff, 2, KEY_F9),
74 KEY(6, 4, KEY_FN), 82 KEY(0xff, 4, KEY_F10),
75 KEY(7, 0, KEY_S), 83 KEY(0xff, 5, KEY_F11),
76 KEY(7, 1, KEY_L), 84};
77 KEY(7, 2, KEY_C), 85
78 KEY(7, 3, KEY_LEFT), 86static struct matrix_keymap_data board_map_data = {
79 KEY(0xff, 0, KEY_F6), 87 .keymap = board_keymap,
80 KEY(0xff, 1, KEY_F7), 88 .keymap_size = ARRAY_SIZE(board_keymap),
81 KEY(0xff, 2, KEY_F8),
82 KEY(0xff, 4, KEY_F9),
83 KEY(0xff, 5, KEY_F10),
84}; 89};
85 90
86static struct twl4030_keypad_data rx51_kp_data = { 91static struct twl4030_keypad_data rx51_kp_data = {
92 .keymap_data = &board_map_data,
87 .rows = 8, 93 .rows = 8,
88 .cols = 8, 94 .cols = 8,
89 .keymap = rx51_keymap,
90 .keymapsize = ARRAY_SIZE(rx51_keymap),
91 .rep = 1, 95 .rep = 1,
92}; 96};
93 97
@@ -440,7 +444,7 @@ static int __init rx51_i2c_init(void)
440 rx51_twldata.vaux3 = &rx51_vaux3_cam; 444 rx51_twldata.vaux3 = &rx51_vaux3_cam;
441 rx51_twldata.vmmc2 = &rx51_vmmc2; 445 rx51_twldata.vmmc2 = &rx51_vmmc2;
442 } 446 }
443 omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1, 447 omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1,
444 ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); 448 ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
445 omap_register_i2c_bus(2, 100, NULL, 0); 449 omap_register_i2c_bus(2, 100, NULL, 0);
446 omap_register_i2c_bus(3, 400, NULL, 0); 450 omap_register_i2c_bus(3, 400, NULL, 0);
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 324009edbd53..fd3369d5e5cb 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -25,9 +25,10 @@
25#include <mach/keypad.h> 25#include <mach/keypad.h>
26 26
27#include "mmc-twl4030.h" 27#include "mmc-twl4030.h"
28#include "sdram-micron-mt46h32m32lf-6.h"
28 29
29/* Zoom2 has Qwerty keyboard*/ 30/* Zoom2 has Qwerty keyboard*/
30static int zoom2_twl4030_keymap[] = { 31static int board_keymap[] = {
31 KEY(0, 0, KEY_E), 32 KEY(0, 0, KEY_E),
32 KEY(1, 0, KEY_R), 33 KEY(1, 0, KEY_R),
33 KEY(2, 0, KEY_T), 34 KEY(2, 0, KEY_T),
@@ -82,11 +83,15 @@ static int zoom2_twl4030_keymap[] = {
82 0 83 0
83}; 84};
84 85
86static struct matrix_keymap_data board_map_data = {
87 .keymap = board_keymap,
88 .keymap_size = ARRAY_SIZE(board_keymap),
89};
90
85static struct twl4030_keypad_data zoom2_kp_twl4030_data = { 91static struct twl4030_keypad_data zoom2_kp_twl4030_data = {
92 .keymap_data = &board_map_data,
86 .rows = 8, 93 .rows = 8,
87 .cols = 8, 94 .cols = 8,
88 .keymap = zoom2_twl4030_keymap,
89 .keymapsize = ARRAY_SIZE(zoom2_twl4030_keymap),
90 .rep = 1, 95 .rep = 1,
91}; 96};
92 97
@@ -209,7 +214,8 @@ static void __init omap_zoom2_init_irq(void)
209{ 214{
210 omap_board_config = zoom2_config; 215 omap_board_config = zoom2_config;
211 omap_board_config_size = ARRAY_SIZE(zoom2_config); 216 omap_board_config_size = ARRAY_SIZE(zoom2_config);
212 omap2_init_common_hw(NULL, NULL); 217 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
218 mt46h32m32lf6_sdrc_params);
213 omap_init_irq(); 219 omap_init_irq();
214 omap_gpio_init(); 220 omap_gpio_init();
215} 221}
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index bc5d3ac66611..e2dbedd581e8 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -769,6 +769,7 @@ int __init omap2_clk_init(void)
769 if (c->cpu & cpu_mask) { 769 if (c->cpu & cpu_mask) {
770 clkdev_add(&c->lk); 770 clkdev_add(&c->lk);
771 clk_register(c->lk.clk); 771 clk_register(c->lk.clk);
772 omap2_init_clk_clkdm(c->lk.clk);
772 } 773 }
773 774
774 /* Check the MPU rate set by bootloader */ 775 /* Check the MPU rate set by bootloader */
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index fafcd32e6907..489556eecbd1 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -338,6 +338,13 @@ static struct omap_clk omap34xx_clks[] = {
338 */ 338 */
339#define SDRC_MPURATE_LOOPS 96 339#define SDRC_MPURATE_LOOPS 96
340 340
341/*
342 * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
343 * that are sourced by DPLL5, and both of these require this clock
344 * to be at 120 MHz for proper operation.
345 */
346#define DPLL5_FREQ_FOR_USBHOST 120000000
347
341/** 348/**
342 * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI 349 * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
343 * @clk: struct clk * being enabled 350 * @clk: struct clk * being enabled
@@ -1056,6 +1063,28 @@ void omap2_clk_prepare_for_reboot(void)
1056#endif 1063#endif
1057} 1064}
1058 1065
1066static void omap3_clk_lock_dpll5(void)
1067{
1068 struct clk *dpll5_clk;
1069 struct clk *dpll5_m2_clk;
1070
1071 dpll5_clk = clk_get(NULL, "dpll5_ck");
1072 clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
1073 clk_enable(dpll5_clk);
1074
1075 /* Enable autoidle to allow it to enter low power bypass */
1076 omap3_dpll_allow_idle(dpll5_clk);
1077
1078 /* Program dpll5_m2_clk divider for no division */
1079 dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
1080 clk_enable(dpll5_m2_clk);
1081 clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
1082
1083 clk_disable(dpll5_m2_clk);
1084 clk_disable(dpll5_clk);
1085 return;
1086}
1087
1059/* REVISIT: Move this init stuff out into clock.c */ 1088/* REVISIT: Move this init stuff out into clock.c */
1060 1089
1061/* 1090/*
@@ -1148,6 +1177,12 @@ int __init omap2_clk_init(void)
1148 */ 1177 */
1149 clk_enable_init_clocks(); 1178 clk_enable_init_clocks();
1150 1179
1180 /*
1181 * Lock DPLL5 and put it in autoidle.
1182 */
1183 if (omap_rev() >= OMAP3430_REV_ES2_0)
1184 omap3_clk_lock_dpll5();
1185
1151 /* Avoid sleeping during omap2_clk_prepare_for_reboot() */ 1186 /* Avoid sleeping during omap2_clk_prepare_for_reboot() */
1152 /* REVISIT: not yet ready for 343x */ 1187 /* REVISIT: not yet ready for 343x */
1153#if 0 1188#if 0
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 4ef7b4f5474e..58aff8485df9 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -137,6 +137,36 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
137 } 137 }
138} 138}
139 139
140/*
141 * _omap2_clkdm_set_hwsup - set the hwsup idle transition bit
142 * @clkdm: struct clockdomain *
143 * @enable: int 0 to disable, 1 to enable
144 *
145 * Internal helper for actually switching the bit that controls hwsup
146 * idle transitions for clkdm.
147 */
148static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
149{
150 u32 v;
151
152 if (cpu_is_omap24xx()) {
153 if (enable)
154 v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
155 else
156 v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
157 } else if (cpu_is_omap34xx()) {
158 if (enable)
159 v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
160 else
161 v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
162 } else {
163 BUG();
164 }
165
166 cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
167 v << __ffs(clkdm->clktrctrl_mask),
168 clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
169}
140 170
141static struct clockdomain *_clkdm_lookup(const char *name) 171static struct clockdomain *_clkdm_lookup(const char *name)
142{ 172{
@@ -456,8 +486,6 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
456 */ 486 */
457void omap2_clkdm_allow_idle(struct clockdomain *clkdm) 487void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
458{ 488{
459 u32 v;
460
461 if (!clkdm) 489 if (!clkdm)
462 return; 490 return;
463 491
@@ -473,18 +501,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
473 if (atomic_read(&clkdm->usecount) > 0) 501 if (atomic_read(&clkdm->usecount) > 0)
474 _clkdm_add_autodeps(clkdm); 502 _clkdm_add_autodeps(clkdm);
475 503
476 if (cpu_is_omap24xx()) 504 _omap2_clkdm_set_hwsup(clkdm, 1);
477 v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
478 else if (cpu_is_omap34xx())
479 v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
480 else
481 BUG();
482
483
484 cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
485 v << __ffs(clkdm->clktrctrl_mask),
486 clkdm->pwrdm.ptr->prcm_offs,
487 CM_CLKSTCTRL);
488 505
489 pwrdm_clkdm_state_switch(clkdm); 506 pwrdm_clkdm_state_switch(clkdm);
490} 507}
@@ -500,8 +517,6 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
500 */ 517 */
501void omap2_clkdm_deny_idle(struct clockdomain *clkdm) 518void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
502{ 519{
503 u32 v;
504
505 if (!clkdm) 520 if (!clkdm)
506 return; 521 return;
507 522
@@ -514,16 +529,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
514 pr_debug("clockdomain: disabling automatic idle transitions for %s\n", 529 pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
515 clkdm->name); 530 clkdm->name);
516 531
517 if (cpu_is_omap24xx()) 532 _omap2_clkdm_set_hwsup(clkdm, 0);
518 v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
519 else if (cpu_is_omap34xx())
520 v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
521 else
522 BUG();
523
524 cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
525 v << __ffs(clkdm->clktrctrl_mask),
526 clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
527 533
528 if (atomic_read(&clkdm->usecount) > 0) 534 if (atomic_read(&clkdm->usecount) > 0)
529 _clkdm_del_autodeps(clkdm); 535 _clkdm_del_autodeps(clkdm);
@@ -569,10 +575,14 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
569 v = omap2_clkdm_clktrctrl_read(clkdm); 575 v = omap2_clkdm_clktrctrl_read(clkdm);
570 576
571 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || 577 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
572 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) 578 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
579 /* Disable HW transitions when we are changing deps */
580 _omap2_clkdm_set_hwsup(clkdm, 0);
573 _clkdm_add_autodeps(clkdm); 581 _clkdm_add_autodeps(clkdm);
574 else 582 _omap2_clkdm_set_hwsup(clkdm, 1);
583 } else {
575 omap2_clkdm_wakeup(clkdm); 584 omap2_clkdm_wakeup(clkdm);
585 }
576 586
577 pwrdm_wait_transition(clkdm->pwrdm.ptr); 587 pwrdm_wait_transition(clkdm->pwrdm.ptr);
578 pwrdm_clkdm_state_switch(clkdm); 588 pwrdm_clkdm_state_switch(clkdm);
@@ -623,10 +633,14 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
623 v = omap2_clkdm_clktrctrl_read(clkdm); 633 v = omap2_clkdm_clktrctrl_read(clkdm);
624 634
625 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || 635 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
626 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) 636 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
637 /* Disable HW transitions when we are changing deps */
638 _omap2_clkdm_set_hwsup(clkdm, 0);
627 _clkdm_del_autodeps(clkdm); 639 _clkdm_del_autodeps(clkdm);
628 else 640 _omap2_clkdm_set_hwsup(clkdm, 1);
641 } else {
629 omap2_clkdm_sleep(clkdm); 642 omap2_clkdm_sleep(clkdm);
643 }
630 644
631 pwrdm_clkdm_state_switch(clkdm); 645 pwrdm_clkdm_state_switch(clkdm);
632 646
diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c
index e4ebd6d53135..4af76bb1003a 100644
--- a/arch/arm/mach-omap2/cm4xxx.c
+++ b/arch/arm/mach-omap2/cm4xxx.c
@@ -22,7 +22,6 @@
22#include <asm/atomic.h> 22#include <asm/atomic.h>
23 23
24#include "cm.h" 24#include "cm.h"
25#include "cm-regbits-4xxx.h"
26 25
27/* XXX move this to cm.h */ 26/* XXX move this to cm.h */
28/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */ 27/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */
@@ -50,19 +49,7 @@
50 */ 49 */
51int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs) 50int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs)
52{ 51{
53 int i = 0; 52 /* FIXME: Add clock manager related code */
54 u8 cm_id; 53 return 0;
55 u16 prcm_mod_offs;
56 u32 mask = OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK;
57
58 cm_id = prcm_mod >> OMAP4_PRCM_MOD_CM_ID_SHIFT;
59 prcm_mod_offs = prcm_mod & OMAP4_PRCM_MOD_OFFS_MASK;
60
61 while (((omap4_cm_read_mod_reg(cm_id, prcm_mod_offs, prcm_dev_offs,
62 OMAP4_CM_CLKCTRL_DREG) & mask) != 0) &&
63 (i++ < MAX_MODULE_READY_TIME))
64 udelay(1);
65
66 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
67} 54}
68 55
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index bcfcfc7fdb9b..faf7a1e0c525 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -355,29 +355,60 @@ static struct platform_device omap2_mcspi4 = {
355}; 355};
356#endif 356#endif
357 357
358static void omap_init_mcspi(void) 358#ifdef CONFIG_ARCH_OMAP4
359static inline void omap4_mcspi_fixup(void)
359{ 360{
360 if (cpu_is_omap44xx()) { 361 omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE;
361 omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE; 362 omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff;
362 omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff; 363 omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE;
363 omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE; 364 omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff;
364 omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff; 365 omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE;
365 omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE; 366 omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff;
366 omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff; 367 omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE;
367 omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE; 368 omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff;
368 omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff; 369}
369 } 370#else
370 platform_device_register(&omap2_mcspi1); 371static inline void omap4_mcspi_fixup(void)
371 platform_device_register(&omap2_mcspi2); 372{
373}
374#endif
375
372#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ 376#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \
373 defined(CONFIG_ARCH_OMAP4) 377 defined(CONFIG_ARCH_OMAP4)
374 if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) 378static inline void omap2_mcspi3_init(void)
375 platform_device_register(&omap2_mcspi3); 379{
380 platform_device_register(&omap2_mcspi3);
381}
382#else
383static inline void omap2_mcspi3_init(void)
384{
385}
376#endif 386#endif
387
377#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) 388#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
378 if (cpu_is_omap343x() || cpu_is_omap44xx()) 389static inline void omap2_mcspi4_init(void)
379 platform_device_register(&omap2_mcspi4); 390{
391 platform_device_register(&omap2_mcspi4);
392}
393#else
394static inline void omap2_mcspi4_init(void)
395{
396}
380#endif 397#endif
398
399static void omap_init_mcspi(void)
400{
401 if (cpu_is_omap44xx())
402 omap4_mcspi_fixup();
403
404 platform_device_register(&omap2_mcspi1);
405 platform_device_register(&omap2_mcspi2);
406
407 if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx())
408 omap2_mcspi3_init();
409
410 if (cpu_is_omap343x() || cpu_is_omap44xx())
411 omap2_mcspi4_init();
381} 412}
382 413
383#else 414#else
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 7574b6f20e8e..e3a3bad1d84f 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -294,10 +294,10 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
294 else if (cpu_is_omap34xx()) 294 else if (cpu_is_omap34xx())
295 hwmods = omap34xx_hwmods; 295 hwmods = omap34xx_hwmods;
296 296
297 omap_hwmod_init(hwmods);
298 omap2_mux_init();
299#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ 297#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
300 /* The OPP tables have to be registered before a clk init */ 298 /* The OPP tables have to be registered before a clk init */
299 omap_hwmod_init(hwmods);
300 omap2_mux_init();
301 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps); 301 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
302 pwrdm_init(powerdomains_omap); 302 pwrdm_init(powerdomains_omap);
303 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); 303 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 2d9b5cc981cd..4a0e1cd5c1f4 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -79,7 +79,7 @@ static int omap2_iommu_enable(struct iommu *obj)
79 l = iommu_read_reg(obj, MMU_SYSSTATUS); 79 l = iommu_read_reg(obj, MMU_SYSSTATUS);
80 if (l & MMU_SYS_RESETDONE) 80 if (l & MMU_SYS_RESETDONE)
81 break; 81 break;
82 } while (time_after(jiffies, timeout)); 82 } while (!time_after(jiffies, timeout));
83 83
84 if (!(l & MMU_SYS_RESETDONE)) { 84 if (!(l & MMU_SYS_RESETDONE)) {
85 dev_err(obj->dev, "can't take mmu out of reset\n"); 85 dev_err(obj->dev, "can't take mmu out of reset\n");
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 6f71f3730c97..c035ad3426d0 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -30,6 +30,14 @@
30#define MAILBOX_IRQ_NEWMSG(u) (1 << (2 * (u))) 30#define MAILBOX_IRQ_NEWMSG(u) (1 << (2 * (u)))
31#define MAILBOX_IRQ_NOTFULL(u) (1 << (2 * (u) + 1)) 31#define MAILBOX_IRQ_NOTFULL(u) (1 << (2 * (u) + 1))
32 32
33/* SYSCONFIG: register bit definition */
34#define AUTOIDLE (1 << 0)
35#define SOFTRESET (1 << 1)
36#define SMARTIDLE (2 << 3)
37
38/* SYSSTATUS: register bit definition */
39#define RESETDONE (1 << 0)
40
33#define MBOX_REG_SIZE 0x120 41#define MBOX_REG_SIZE 0x120
34#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32)) 42#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32))
35 43
@@ -69,21 +77,33 @@ static inline void mbox_write_reg(u32 val, size_t ofs)
69/* Mailbox H/W preparations */ 77/* Mailbox H/W preparations */
70static int omap2_mbox_startup(struct omap_mbox *mbox) 78static int omap2_mbox_startup(struct omap_mbox *mbox)
71{ 79{
72 unsigned int l; 80 u32 l;
81 unsigned long timeout;
73 82
74 mbox_ick_handle = clk_get(NULL, "mailboxes_ick"); 83 mbox_ick_handle = clk_get(NULL, "mailboxes_ick");
75 if (IS_ERR(mbox_ick_handle)) { 84 if (IS_ERR(mbox_ick_handle)) {
76 printk("Could not get mailboxes_ick\n"); 85 pr_err("Can't get mailboxes_ick\n");
77 return -ENODEV; 86 return -ENODEV;
78 } 87 }
79 clk_enable(mbox_ick_handle); 88 clk_enable(mbox_ick_handle);
80 89
90 mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG);
91 timeout = jiffies + msecs_to_jiffies(20);
92 do {
93 l = mbox_read_reg(MAILBOX_SYSSTATUS);
94 if (l & RESETDONE)
95 break;
96 } while (!time_after(jiffies, timeout));
97
98 if (!(l & RESETDONE)) {
99 pr_err("Can't take mmu out of reset\n");
100 return -ENODEV;
101 }
102
81 l = mbox_read_reg(MAILBOX_REVISION); 103 l = mbox_read_reg(MAILBOX_REVISION);
82 pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); 104 pr_info("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
83 105
84 /* set smart-idle & autoidle */ 106 l = SMARTIDLE | AUTOIDLE;
85 l = mbox_read_reg(MAILBOX_SYSCONFIG);
86 l |= 0x00000011;
87 mbox_write_reg(l, MAILBOX_SYSCONFIG); 107 mbox_write_reg(l, MAILBOX_SYSCONFIG);
88 108
89 omap2_mbox_enable_irq(mbox, IRQ_RX); 109 omap2_mbox_enable_irq(mbox, IRQ_RX);
@@ -156,6 +176,9 @@ static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
156 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; 176 u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
157 177
158 mbox_write_reg(bit, p->irqstatus); 178 mbox_write_reg(bit, p->irqstatus);
179
180 /* Flush posted write for irq status to avoid spurious interrupts */
181 mbox_read_reg(p->irqstatus);
159} 182}
160 183
161static int omap2_mbox_is_irq(struct omap_mbox *mbox, 184static int omap2_mbox_is_irq(struct omap_mbox *mbox,
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 2daa595aaff4..b5fac32aae70 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -460,6 +460,8 @@ MUX_CFG_34XX("AF26_34XX_GPIO0", 0x1e0,
460 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) 460 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
461MUX_CFG_34XX("AF22_34XX_GPIO9", 0xa18, 461MUX_CFG_34XX("AF22_34XX_GPIO9", 0xa18,
462 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) 462 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
463MUX_CFG_34XX("AG9_34XX_GPIO23", 0x5ee,
464 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
463MUX_CFG_34XX("AH8_34XX_GPIO29", 0x5fa, 465MUX_CFG_34XX("AH8_34XX_GPIO29", 0x5fa,
464 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT) 466 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
465MUX_CFG_34XX("U8_34XX_GPIO54_OUT", 0x0b4, 467MUX_CFG_34XX("U8_34XX_GPIO54_OUT", 0x0b4,
@@ -472,6 +474,8 @@ MUX_CFG_34XX("G25_34XX_GPIO86_OUT", 0x0fc,
472 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) 474 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
473MUX_CFG_34XX("AG4_34XX_GPIO134_OUT", 0x160, 475MUX_CFG_34XX("AG4_34XX_GPIO134_OUT", 0x160,
474 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) 476 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
477MUX_CFG_34XX("AF4_34XX_GPIO135_OUT", 0x162,
478 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
475MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164, 479MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164,
476 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) 480 OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
477MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c, 481MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c,
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 1b4c1600f8d8..2fc4d6abbd0a 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -541,7 +541,7 @@ static int __init pm_dbg_init(void)
541 printk(KERN_ERR "%s: only OMAP3 supported\n", __func__); 541 printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
542 return -ENODEV; 542 return -ENODEV;
543 } 543 }
544 544
545 d = debugfs_create_dir("pm_debug", NULL); 545 d = debugfs_create_dir("pm_debug", NULL);
546 if (IS_ERR(d)) 546 if (IS_ERR(d))
547 return PTR_ERR(d); 547 return PTR_ERR(d);
@@ -551,7 +551,7 @@ static int __init pm_dbg_init(void)
551 (void) debugfs_create_file("time", S_IRUGO, 551 (void) debugfs_create_file("time", S_IRUGO,
552 d, (void *)DEBUG_FILE_TIMERS, &debug_fops); 552 d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
553 553
554 pwrdm_for_each(pwrdms_setup, (void *)d); 554 pwrdm_for_each_nolock(pwrdms_setup, (void *)d);
555 555
556 pm_dbg_dir = debugfs_create_dir("registers", d); 556 pm_dbg_dir = debugfs_create_dir("registers", d);
557 if (IS_ERR(pm_dbg_dir)) 557 if (IS_ERR(pm_dbg_dir))
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0ff5a6c53aa0..378c2f618358 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -51,97 +51,112 @@ static void (*_omap_sram_idle)(u32 *addr, int save_state);
51 51
52static struct powerdomain *mpu_pwrdm; 52static struct powerdomain *mpu_pwrdm;
53 53
54/* PRCM Interrupt Handler for wakeups */ 54/*
55static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) 55 * PRCM Interrupt Handler Helper Function
56 *
57 * The purpose of this function is to clear any wake-up events latched
58 * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
59 * may occur whilst attempting to clear a PM_WKST_x register and thus
60 * set another bit in this register. A while loop is used to ensure
61 * that any peripheral wake-up events occurring while attempting to
62 * clear the PM_WKST_x are detected and cleared.
63 */
64static int prcm_clear_mod_irqs(s16 module, u8 regs)
56{ 65{
57 u32 wkst, irqstatus_mpu; 66 u32 wkst, fclk, iclk, clken;
58 u32 fclk, iclk; 67 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
59 68 u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
60 /* WKUP */ 69 u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
61 wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST); 70 u16 grpsel_off = (regs == 3) ?
71 OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
72 int c = 0;
73
74 wkst = prm_read_mod_reg(module, wkst_off);
75 wkst &= prm_read_mod_reg(module, grpsel_off);
62 if (wkst) { 76 if (wkst) {
63 iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN); 77 iclk = cm_read_mod_reg(module, iclk_off);
64 fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN); 78 fclk = cm_read_mod_reg(module, fclk_off);
65 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN); 79 while (wkst) {
66 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN); 80 clken = wkst;
67 prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST); 81 cm_set_mod_reg_bits(clken, module, iclk_off);
68 while (prm_read_mod_reg(WKUP_MOD, PM_WKST)) 82 /*
69 cpu_relax(); 83 * For USBHOST, we don't know whether HOST1 or
70 cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN); 84 * HOST2 woke us up, so enable both f-clocks
71 cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN); 85 */
86 if (module == OMAP3430ES2_USBHOST_MOD)
87 clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
88 cm_set_mod_reg_bits(clken, module, fclk_off);
89 prm_write_mod_reg(wkst, module, wkst_off);
90 wkst = prm_read_mod_reg(module, wkst_off);
91 c++;
92 }
93 cm_write_mod_reg(iclk, module, iclk_off);
94 cm_write_mod_reg(fclk, module, fclk_off);
72 } 95 }
73 96
74 /* CORE */ 97 return c;
75 wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1); 98}
76 if (wkst) {
77 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
78 fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
79 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
80 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
81 prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
82 while (prm_read_mod_reg(CORE_MOD, PM_WKST1))
83 cpu_relax();
84 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
85 cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
86 }
87 wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
88 if (wkst) {
89 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
90 fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
91 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
92 cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
93 prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
94 while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3))
95 cpu_relax();
96 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
97 cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
98 }
99 99
100 /* PER */ 100static int _prcm_int_handle_wakeup(void)
101 wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST); 101{
102 if (wkst) { 102 int c;
103 iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
104 fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
105 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
106 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
107 prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
108 while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST))
109 cpu_relax();
110 cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
111 cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
112 }
113 103
104 c = prcm_clear_mod_irqs(WKUP_MOD, 1);
105 c += prcm_clear_mod_irqs(CORE_MOD, 1);
106 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
114 if (omap_rev() > OMAP3430_REV_ES1_0) { 107 if (omap_rev() > OMAP3430_REV_ES1_0) {
115 /* USBHOST */ 108 c += prcm_clear_mod_irqs(CORE_MOD, 3);
116 wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST); 109 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
117 if (wkst) {
118 iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
119 CM_ICLKEN);
120 fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
121 CM_FCLKEN);
122 cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
123 CM_ICLKEN);
124 cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
125 CM_FCLKEN);
126 prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
127 PM_WKST);
128 while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
129 PM_WKST))
130 cpu_relax();
131 cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
132 CM_ICLKEN);
133 cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
134 CM_FCLKEN);
135 }
136 } 110 }
137 111
138 irqstatus_mpu = prm_read_mod_reg(OCP_MOD, 112 return c;
139 OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 113}
140 prm_write_mod_reg(irqstatus_mpu, OCP_MOD, 114
141 OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 115/*
116 * PRCM Interrupt Handler
117 *
118 * The PRM_IRQSTATUS_MPU register indicates if there are any pending
119 * interrupts from the PRCM for the MPU. These bits must be cleared in
120 * order to clear the PRCM interrupt. The PRCM interrupt handler is
121 * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
122 * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
123 * register indicates that a wake-up event is pending for the MPU and
124 * this bit can only be cleared if the all the wake-up events latched
125 * in the various PM_WKST_x registers have been cleared. The interrupt
126 * handler is implemented using a do-while loop so that if a wake-up
127 * event occurred during the processing of the prcm interrupt handler
128 * (setting a bit in the corresponding PM_WKST_x register and thus
129 * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
130 * this would be handled.
131 */
132static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
133{
134 u32 irqstatus_mpu;
135 int c = 0;
136
137 do {
138 irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
139 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
140
141 if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) {
142 c = _prcm_int_handle_wakeup();
143
144 /*
145 * Is the MPU PRCM interrupt handler racing with the
146 * IVA2 PRCM interrupt handler ?
147 */
148 WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
149 "but no wakeup sources are marked\n");
150 } else {
151 /* XXX we need to expand our PRCM interrupt handler */
152 WARN(1, "prcm: WARNING: PRCM interrupt received, but "
153 "no code to handle it (%08x)\n", irqstatus_mpu);
154 }
155
156 prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
157 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
142 158
143 while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET)) 159 } while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
144 cpu_relax();
145 160
146 return IRQ_HANDLED; 161 return IRQ_HANDLED;
147} 162}
@@ -624,6 +639,16 @@ static void __init prcm_setup_regs(void)
624 prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN, 639 prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
625 OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); 640 OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
626 641
642 /* Enable GPIO wakeups in PER */
643 prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
644 OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
645 OMAP3430_EN_GPIO6, OMAP3430_PER_MOD, PM_WKEN);
646 /* and allow them to wake up MPU */
647 prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
648 OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
649 OMAP3430_GRPSEL_GPIO6,
650 OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
651
627 /* Don't attach IVA interrupts */ 652 /* Don't attach IVA interrupts */
628 prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); 653 prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
629 prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); 654 prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 2594cbff3947..f00289abd30f 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -273,35 +273,50 @@ struct powerdomain *pwrdm_lookup(const char *name)
273} 273}
274 274
275/** 275/**
276 * pwrdm_for_each - call function on each registered clockdomain 276 * pwrdm_for_each_nolock - call function on each registered clockdomain
277 * @fn: callback function * 277 * @fn: callback function *
278 * 278 *
279 * Call the supplied function for each registered powerdomain. The 279 * Call the supplied function for each registered powerdomain. The
280 * callback function can return anything but 0 to bail out early from 280 * callback function can return anything but 0 to bail out early from
281 * the iterator. The callback function is called with the pwrdm_rwlock 281 * the iterator. Returns the last return value of the callback function, which
282 * held for reading, so no powerdomain structure manipulation 282 * should be 0 for success or anything else to indicate failure; or -EINVAL if
283 * functions should be called from the callback, although hardware 283 * the function pointer is null.
284 * powerdomain control functions are fine. Returns the last return
285 * value of the callback function, which should be 0 for success or
286 * anything else to indicate failure; or -EINVAL if the function
287 * pointer is null.
288 */ 284 */
289int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), 285int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
290 void *user) 286 void *user)
291{ 287{
292 struct powerdomain *temp_pwrdm; 288 struct powerdomain *temp_pwrdm;
293 unsigned long flags;
294 int ret = 0; 289 int ret = 0;
295 290
296 if (!fn) 291 if (!fn)
297 return -EINVAL; 292 return -EINVAL;
298 293
299 read_lock_irqsave(&pwrdm_rwlock, flags);
300 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 294 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
301 ret = (*fn)(temp_pwrdm, user); 295 ret = (*fn)(temp_pwrdm, user);
302 if (ret) 296 if (ret)
303 break; 297 break;
304 } 298 }
299
300 return ret;
301}
302
303/**
304 * pwrdm_for_each - call function on each registered clockdomain
305 * @fn: callback function *
306 *
307 * This function is the same as 'pwrdm_for_each_nolock()', but keeps the
308 * &pwrdm_rwlock locked for reading, so no powerdomain structure manipulation
309 * functions should be called from the callback, although hardware powerdomain
310 * control functions are fine.
311 */
312int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
313 void *user)
314{
315 unsigned long flags;
316 int ret;
317
318 read_lock_irqsave(&pwrdm_rwlock, flags);
319 ret = pwrdm_for_each_nolock(fn, user);
305 read_unlock_irqrestore(&pwrdm_rwlock, flags); 320 read_unlock_irqrestore(&pwrdm_rwlock, flags);
306 321
307 return ret; 322 return ret;
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 3a529c77daa8..ae2186892c85 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -110,7 +110,7 @@ static struct plat_serial8250_port serial_platform_data2[] = {
110 .uartclk = OMAP24XX_BASE_BAUD * 16, 110 .uartclk = OMAP24XX_BASE_BAUD * 16,
111 }, { 111 }, {
112#ifdef CONFIG_ARCH_OMAP4 112#ifdef CONFIG_ARCH_OMAP4
113 .membase = IO_ADDRESS(OMAP_UART4_BASE), 113 .membase = OMAP2_IO_ADDRESS(OMAP_UART4_BASE),
114 .mapbase = OMAP_UART4_BASE, 114 .mapbase = OMAP_UART4_BASE,
115 .irq = 70, 115 .irq = 70,
116 .flags = UPF_BOOT_AUTOCONF, 116 .flags = UPF_BOOT_AUTOCONF,
@@ -126,7 +126,7 @@ static struct plat_serial8250_port serial_platform_data2[] = {
126#ifdef CONFIG_ARCH_OMAP4 126#ifdef CONFIG_ARCH_OMAP4
127static struct plat_serial8250_port serial_platform_data3[] = { 127static struct plat_serial8250_port serial_platform_data3[] = {
128 { 128 {
129 .membase = IO_ADDRESS(OMAP_UART4_BASE), 129 .membase = OMAP2_IO_ADDRESS(OMAP_UART4_BASE),
130 .mapbase = OMAP_UART4_BASE, 130 .mapbase = OMAP_UART4_BASE,
131 .irq = 70, 131 .irq = 70,
132 .flags = UPF_BOOT_AUTOCONF, 132 .flags = UPF_BOOT_AUTOCONF,
@@ -579,7 +579,7 @@ static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = {
579 { 579 {
580 .pdev = { 580 .pdev = {
581 .name = "serial8250", 581 .name = "serial8250",
582 .id = 3 582 .id = 3,
583 .dev = { 583 .dev = {
584 .platform_data = serial_platform_data3, 584 .platform_data = serial_platform_data3,
585 }, 585 },