aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2009-09-03 13:17:39 -0400
committerTony Lindgren <tony@atomide.com>2009-09-03 13:17:39 -0400
commit1f685b36dbf27db55072fb738aac57aaf37d2c71 (patch)
tree43cdcd1288d3bfa042a7cd6a89d2bf40f9b0261e /arch/arm/mach-omap2
parent5567fa1f543dde3c42f8e52bf4f7005135b24896 (diff)
parentca4caa4e1d45f9542fa54263974d0ef637157b4a (diff)
Merge branch '2_6_32_for_next' of git://git.pwsan.com/linux-2.6 into for-next
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r--arch/arm/mach-omap2/Makefile7
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c13
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c18
-rw-r--r--arch/arm/mach-omap2/board-apollon.c20
-rw-r--r--arch/arm/mach-omap2/board-generic.c10
-rw-r--r--arch/arm/mach-omap2/board-h4.c20
-rw-r--r--arch/arm/mach-omap2/board-ldp.c20
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c26
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c12
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c20
-rw-r--r--arch/arm/mach-omap2/board-overo.c20
-rw-r--r--arch/arm/mach-omap2/board-rx51.c4
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c18
-rw-r--r--arch/arm/mach-omap2/clock34xx.c17
-rw-r--r--arch/arm/mach-omap2/clock34xx.h21
-rw-r--r--arch/arm/mach-omap2/cm.c70
-rw-r--r--arch/arm/mach-omap2/cm.h4
-rw-r--r--arch/arm/mach-omap2/cm4xxx.c68
-rw-r--r--arch/arm/mach-omap2/io.c23
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c1554
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420.h141
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430.h143
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_34xx.h168
-rw-r--r--arch/arm/mach-omap2/powerdomain.c4
-rw-r--r--arch/arm/mach-omap2/serial.c14
25 files changed, 2301 insertions, 134 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 8850a247bec9..8cb16777661a 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -5,7 +5,7 @@
5# Common support 5# Common support
6obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o 6obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
7 7
8omap-2-3-common = irq.o sdrc.o 8omap-2-3-common = irq.o sdrc.o omap_hwmod.o
9prcm-common = prcm.o powerdomain.o 9prcm-common = prcm.o powerdomain.o
10clock-common = clock.o clockdomain.o 10clock-common = clock.o clockdomain.o
11 11
@@ -35,6 +35,11 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
35obj-$(CONFIG_PM_DEBUG) += pm-debug.o 35obj-$(CONFIG_PM_DEBUG) += pm-debug.o
36endif 36endif
37 37
38# PRCM
39obj-$(CONFIG_ARCH_OMAP2) += cm.o
40obj-$(CONFIG_ARCH_OMAP3) += cm.o
41obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o
42
38# Clock framework 43# Clock framework
39obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o 44obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o
40obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o 45obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 7f5a74d59243..42217b32f835 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -139,18 +139,19 @@ static inline void board_smc91x_init(void)
139 139
140#endif 140#endif
141 141
142static struct omap_board_config_kernel sdp2430_config[] = {
143 {OMAP_TAG_LCD, &sdp2430_lcd_config},
144};
145
142static void __init omap_2430sdp_init_irq(void) 146static void __init omap_2430sdp_init_irq(void)
143{ 147{
148 omap_board_config = sdp2430_config;
149 omap_board_config_size = ARRAY_SIZE(sdp2430_config);
144 omap2_init_common_hw(NULL, NULL); 150 omap2_init_common_hw(NULL, NULL);
145 omap_init_irq(); 151 omap_init_irq();
146 omap_gpio_init(); 152 omap_gpio_init();
147} 153}
148 154
149static struct omap_board_config_kernel sdp2430_config[] = {
150 {OMAP_TAG_LCD, &sdp2430_lcd_config},
151};
152
153
154static struct twl4030_gpio_platform_data sdp2430_gpio_data = { 155static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
155 .gpio_base = OMAP_MAX_GPIO_LINES, 156 .gpio_base = OMAP_MAX_GPIO_LINES,
156 .irq_base = TWL4030_GPIO_IRQ_BASE, 157 .irq_base = TWL4030_GPIO_IRQ_BASE,
@@ -200,8 +201,6 @@ static void __init omap_2430sdp_init(void)
200 omap2430_i2c_init(); 201 omap2430_i2c_init();
201 202
202 platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); 203 platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
203 omap_board_config = sdp2430_config;
204 omap_board_config_size = ARRAY_SIZE(sdp2430_config);
205 omap_serial_init(); 204 omap_serial_init();
206 twl4030_mmc_init(mmc); 205 twl4030_mmc_init(mmc);
207 usb_musb_init(); 206 usb_musb_init();
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 31d9f56c6483..bd57ec76dc5e 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -167,13 +167,6 @@ static struct platform_device *sdp3430_devices[] __initdata = {
167 &sdp3430_lcd_device, 167 &sdp3430_lcd_device,
168}; 168};
169 169
170static void __init omap_3430sdp_init_irq(void)
171{
172 omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
173 omap_init_irq();
174 omap_gpio_init();
175}
176
177static struct omap_lcd_config sdp3430_lcd_config __initdata = { 170static struct omap_lcd_config sdp3430_lcd_config __initdata = {
178 .ctrl_name = "internal", 171 .ctrl_name = "internal",
179}; 172};
@@ -182,6 +175,15 @@ static struct omap_board_config_kernel sdp3430_config[] __initdata = {
182 { OMAP_TAG_LCD, &sdp3430_lcd_config }, 175 { OMAP_TAG_LCD, &sdp3430_lcd_config },
183}; 176};
184 177
178static void __init omap_3430sdp_init_irq(void)
179{
180 omap_board_config = sdp3430_config;
181 omap_board_config_size = ARRAY_SIZE(sdp3430_config);
182 omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
183 omap_init_irq();
184 omap_gpio_init();
185}
186
185static int sdp3430_batt_table[] = { 187static int sdp3430_batt_table[] = {
186/* 0 C*/ 188/* 0 C*/
18730800, 29500, 28300, 27100, 18930800, 29500, 28300, 27100,
@@ -482,8 +484,6 @@ static void __init omap_3430sdp_init(void)
482{ 484{
483 omap3430_i2c_init(); 485 omap3430_i2c_init();
484 platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices)); 486 platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices));
485 omap_board_config = sdp3430_config;
486 omap_board_config_size = ARRAY_SIZE(sdp3430_config);
487 if (omap_rev() > OMAP3430_REV_ES1_0) 487 if (omap_rev() > OMAP3430_REV_ES1_0)
488 ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2; 488 ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2;
489 else 489 else
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 615f21d1eb23..7a2b54c7291a 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -248,14 +248,6 @@ out:
248 clk_put(gpmc_fck); 248 clk_put(gpmc_fck);
249} 249}
250 250
251static void __init omap_apollon_init_irq(void)
252{
253 omap2_init_common_hw(NULL, NULL);
254 omap_init_irq();
255 omap_gpio_init();
256 apollon_init_smc91x();
257}
258
259static struct omap_usb_config apollon_usb_config __initdata = { 251static struct omap_usb_config apollon_usb_config __initdata = {
260 .register_dev = 1, 252 .register_dev = 1,
261 .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */ 253 .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
@@ -271,6 +263,16 @@ static struct omap_board_config_kernel apollon_config[] = {
271 { OMAP_TAG_LCD, &apollon_lcd_config }, 263 { OMAP_TAG_LCD, &apollon_lcd_config },
272}; 264};
273 265
266static void __init omap_apollon_init_irq(void)
267{
268 omap_board_config = apollon_config;
269 omap_board_config_size = ARRAY_SIZE(apollon_config);
270 omap2_init_common_hw(NULL, NULL);
271 omap_init_irq();
272 omap_gpio_init();
273 apollon_init_smc91x();
274}
275
274static void __init apollon_led_init(void) 276static void __init apollon_led_init(void)
275{ 277{
276 /* LED0 - AA10 */ 278 /* LED0 - AA10 */
@@ -319,8 +321,6 @@ static void __init omap_apollon_init(void)
319 * if not needed. 321 * if not needed.
320 */ 322 */
321 platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices)); 323 platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
322 omap_board_config = apollon_config;
323 omap_board_config_size = ARRAY_SIZE(apollon_config);
324 omap_serial_init(); 324 omap_serial_init();
325} 325}
326 326
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 3e401c5b6e41..2e09a1c444cb 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -31,19 +31,19 @@
31#include <mach/board.h> 31#include <mach/board.h>
32#include <mach/common.h> 32#include <mach/common.h>
33 33
34static struct omap_board_config_kernel generic_config[] = {
35};
36
34static void __init omap_generic_init_irq(void) 37static void __init omap_generic_init_irq(void)
35{ 38{
39 omap_board_config = generic_config;
40 omap_board_config_size = ARRAY_SIZE(generic_config);
36 omap2_init_common_hw(NULL, NULL); 41 omap2_init_common_hw(NULL, NULL);
37 omap_init_irq(); 42 omap_init_irq();
38} 43}
39 44
40static struct omap_board_config_kernel generic_config[] = {
41};
42
43static void __init omap_generic_init(void) 45static void __init omap_generic_init(void)
44{ 46{
45 omap_board_config = generic_config;
46 omap_board_config_size = ARRAY_SIZE(generic_config);
47 omap_serial_init(); 47 omap_serial_init();
48} 48}
49 49
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index b6501d241c10..eaa02d012c5c 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -268,14 +268,6 @@ static void __init h4_init_flash(void)
268 h4_flash_resource.end = base + SZ_64M - 1; 268 h4_flash_resource.end = base + SZ_64M - 1;
269} 269}
270 270
271static void __init omap_h4_init_irq(void)
272{
273 omap2_init_common_hw(NULL, NULL);
274 omap_init_irq();
275 omap_gpio_init();
276 h4_init_flash();
277}
278
279static struct omap_lcd_config h4_lcd_config __initdata = { 271static struct omap_lcd_config h4_lcd_config __initdata = {
280 .ctrl_name = "internal", 272 .ctrl_name = "internal",
281}; 273};
@@ -317,6 +309,16 @@ static struct omap_board_config_kernel h4_config[] = {
317 { OMAP_TAG_LCD, &h4_lcd_config }, 309 { OMAP_TAG_LCD, &h4_lcd_config },
318}; 310};
319 311
312static void __init omap_h4_init_irq(void)
313{
314 omap_board_config = h4_config;
315 omap_board_config_size = ARRAY_SIZE(h4_config);
316 omap2_init_common_hw(NULL, NULL);
317 omap_init_irq();
318 omap_gpio_init();
319 h4_init_flash();
320}
321
320static struct at24_platform_data m24c01 = { 322static struct at24_platform_data m24c01 = {
321 .byte_len = SZ_1K / 8, 323 .byte_len = SZ_1K / 8,
322 .page_size = 16, 324 .page_size = 16,
@@ -361,8 +363,6 @@ static void __init omap_h4_init(void)
361 ARRAY_SIZE(h4_i2c_board_info)); 363 ARRAY_SIZE(h4_i2c_board_info));
362 364
363 platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices)); 365 platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
364 omap_board_config = h4_config;
365 omap_board_config_size = ARRAY_SIZE(h4_config);
366 omap_usb_init(&h4_usb_config); 366 omap_usb_init(&h4_usb_config);
367 omap_serial_init(); 367 omap_serial_init();
368} 368}
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 2dd6806a1e8e..ec6854cbdd9f 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -268,14 +268,6 @@ static inline void __init ldp_init_smsc911x(void)
268 gpio_direction_input(eth_gpio); 268 gpio_direction_input(eth_gpio);
269} 269}
270 270
271static void __init omap_ldp_init_irq(void)
272{
273 omap2_init_common_hw(NULL, NULL);
274 omap_init_irq();
275 omap_gpio_init();
276 ldp_init_smsc911x();
277}
278
279static struct platform_device ldp_lcd_device = { 271static struct platform_device ldp_lcd_device = {
280 .name = "ldp_lcd", 272 .name = "ldp_lcd",
281 .id = -1, 273 .id = -1,
@@ -289,6 +281,16 @@ static struct omap_board_config_kernel ldp_config[] __initdata = {
289 { OMAP_TAG_LCD, &ldp_lcd_config }, 281 { OMAP_TAG_LCD, &ldp_lcd_config },
290}; 282};
291 283
284static void __init omap_ldp_init_irq(void)
285{
286 omap_board_config = ldp_config;
287 omap_board_config_size = ARRAY_SIZE(ldp_config);
288 omap2_init_common_hw(NULL, NULL);
289 omap_init_irq();
290 omap_gpio_init();
291 ldp_init_smsc911x();
292}
293
292static struct twl4030_usb_data ldp_usb_data = { 294static struct twl4030_usb_data ldp_usb_data = {
293 .usb_mode = T2_USB_MODE_ULPI, 295 .usb_mode = T2_USB_MODE_ULPI,
294}; 296};
@@ -372,8 +374,6 @@ static void __init omap_ldp_init(void)
372{ 374{
373 omap_i2c_init(); 375 omap_i2c_init();
374 platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices)); 376 platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
375 omap_board_config = ldp_config;
376 omap_board_config_size = ARRAY_SIZE(ldp_config);
377 ts_gpio = 54; 377 ts_gpio = 54;
378 ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio); 378 ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
379 spi_register_board_info(ldp_spi_board_info, 379 spi_register_board_info(ldp_spi_board_info,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index d79ea8da6270..500c9956876d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -281,17 +281,6 @@ static int __init omap3_beagle_i2c_init(void)
281 return 0; 281 return 0;
282} 282}
283 283
284static void __init omap3_beagle_init_irq(void)
285{
286 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
287 mt46h32m32lf6_sdrc_params);
288 omap_init_irq();
289#ifdef CONFIG_OMAP_32K_TIMER
290 omap2_gp_clockevent_set_gptimer(12);
291#endif
292 omap_gpio_init();
293}
294
295static struct gpio_led gpio_leds[] = { 284static struct gpio_led gpio_leds[] = {
296 { 285 {
297 .name = "beagleboard::usr0", 286 .name = "beagleboard::usr0",
@@ -349,6 +338,19 @@ static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
349 { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, 338 { OMAP_TAG_LCD, &omap3_beagle_lcd_config },
350}; 339};
351 340
341static void __init omap3_beagle_init_irq(void)
342{
343 omap_board_config = omap3_beagle_config;
344 omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
345 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
346 mt46h32m32lf6_sdrc_params);
347 omap_init_irq();
348#ifdef CONFIG_OMAP_32K_TIMER
349 omap2_gp_clockevent_set_gptimer(12);
350#endif
351 omap_gpio_init();
352}
353
352static struct platform_device *omap3_beagle_devices[] __initdata = { 354static struct platform_device *omap3_beagle_devices[] __initdata = {
353 &omap3_beagle_lcd_device, 355 &omap3_beagle_lcd_device,
354 &leds_gpio, 356 &leds_gpio,
@@ -398,8 +400,6 @@ static void __init omap3_beagle_init(void)
398 omap3_beagle_i2c_init(); 400 omap3_beagle_i2c_init();
399 platform_add_devices(omap3_beagle_devices, 401 platform_add_devices(omap3_beagle_devices,
400 ARRAY_SIZE(omap3_beagle_devices)); 402 ARRAY_SIZE(omap3_beagle_devices));
401 omap_board_config = omap3_beagle_config;
402 omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
403 omap_serial_init(); 403 omap_serial_init();
404 404
405 omap_cfg_reg(J25_34XX_GPIO170); 405 omap_cfg_reg(J25_34XX_GPIO170);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 3e0435371ce6..d50b9be90580 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -274,18 +274,20 @@ struct spi_board_info omap3evm_spi_board_info[] = {
274 }, 274 },
275}; 275};
276 276
277static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
278 { OMAP_TAG_LCD, &omap3_evm_lcd_config },
279};
280
277static void __init omap3_evm_init_irq(void) 281static void __init omap3_evm_init_irq(void)
278{ 282{
283 omap_board_config = omap3_evm_config;
284 omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
279 omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL); 285 omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
280 omap_init_irq(); 286 omap_init_irq();
281 omap_gpio_init(); 287 omap_gpio_init();
282 omap3evm_init_smc911x(); 288 omap3evm_init_smc911x();
283} 289}
284 290
285static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
286 { OMAP_TAG_LCD, &omap3_evm_lcd_config },
287};
288
289static struct platform_device *omap3_evm_devices[] __initdata = { 291static struct platform_device *omap3_evm_devices[] __initdata = {
290 &omap3_evm_lcd_device, 292 &omap3_evm_lcd_device,
291 &omap3evm_smc911x_device, 293 &omap3evm_smc911x_device,
@@ -296,8 +298,6 @@ static void __init omap3_evm_init(void)
296 omap3_evm_i2c_init(); 298 omap3_evm_i2c_init();
297 299
298 platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices)); 300 platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
299 omap_board_config = omap3_evm_config;
300 omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
301 301
302 spi_register_board_info(omap3evm_spi_board_info, 302 spi_register_board_info(omap3evm_spi_board_info,
303 ARRAY_SIZE(omap3evm_spi_board_info)); 303 ARRAY_SIZE(omap3evm_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 8236708c3627..b43f6e36b6d9 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -305,14 +305,6 @@ static int __init omap3pandora_i2c_init(void)
305 return 0; 305 return 0;
306} 306}
307 307
308static void __init omap3pandora_init_irq(void)
309{
310 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
311 mt46h32m32lf6_sdrc_params);
312 omap_init_irq();
313 omap_gpio_init();
314}
315
316static void __init omap3pandora_ads7846_init(void) 308static void __init omap3pandora_ads7846_init(void)
317{ 309{
318 int gpio = OMAP3_PANDORA_TS_GPIO; 310 int gpio = OMAP3_PANDORA_TS_GPIO;
@@ -375,6 +367,16 @@ static struct omap_board_config_kernel omap3pandora_config[] __initdata = {
375 { OMAP_TAG_LCD, &omap3pandora_lcd_config }, 367 { OMAP_TAG_LCD, &omap3pandora_lcd_config },
376}; 368};
377 369
370static void __init omap3pandora_init_irq(void)
371{
372 omap_board_config = omap3pandora_config;
373 omap_board_config_size = ARRAY_SIZE(omap3pandora_config);
374 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
375 mt46h32m32lf6_sdrc_params);
376 omap_init_irq();
377 omap_gpio_init();
378}
379
378static struct platform_device *omap3pandora_devices[] __initdata = { 380static struct platform_device *omap3pandora_devices[] __initdata = {
379 &omap3pandora_lcd_device, 381 &omap3pandora_lcd_device,
380 &pandora_leds_gpio, 382 &pandora_leds_gpio,
@@ -386,8 +388,6 @@ static void __init omap3pandora_init(void)
386 omap3pandora_i2c_init(); 388 omap3pandora_i2c_init();
387 platform_add_devices(omap3pandora_devices, 389 platform_add_devices(omap3pandora_devices,
388 ARRAY_SIZE(omap3pandora_devices)); 390 ARRAY_SIZE(omap3pandora_devices));
389 omap_board_config = omap3pandora_config;
390 omap_board_config_size = ARRAY_SIZE(omap3pandora_config);
391 omap_serial_init(); 391 omap_serial_init();
392 spi_register_board_info(omap3pandora_spi_board_info, 392 spi_register_board_info(omap3pandora_spi_board_info,
393 ARRAY_SIZE(omap3pandora_spi_board_info)); 393 ARRAY_SIZE(omap3pandora_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index eb78e6eab4f4..9917d2fddc2f 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -357,14 +357,6 @@ static int __init overo_i2c_init(void)
357 return 0; 357 return 0;
358} 358}
359 359
360static void __init overo_init_irq(void)
361{
362 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
363 mt46h32m32lf6_sdrc_params);
364 omap_init_irq();
365 omap_gpio_init();
366}
367
368static struct platform_device overo_lcd_device = { 360static struct platform_device overo_lcd_device = {
369 .name = "overo_lcd", 361 .name = "overo_lcd",
370 .id = -1, 362 .id = -1,
@@ -378,6 +370,16 @@ static struct omap_board_config_kernel overo_config[] __initdata = {
378 { OMAP_TAG_LCD, &overo_lcd_config }, 370 { OMAP_TAG_LCD, &overo_lcd_config },
379}; 371};
380 372
373static void __init overo_init_irq(void)
374{
375 omap_board_config = overo_config;
376 omap_board_config_size = ARRAY_SIZE(overo_config);
377 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
378 mt46h32m32lf6_sdrc_params);
379 omap_init_irq();
380 omap_gpio_init();
381}
382
381static struct platform_device *overo_devices[] __initdata = { 383static struct platform_device *overo_devices[] __initdata = {
382 &overo_lcd_device, 384 &overo_lcd_device,
383}; 385};
@@ -386,8 +388,6 @@ static void __init overo_init(void)
386{ 388{
387 overo_i2c_init(); 389 overo_i2c_init();
388 platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); 390 platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
389 omap_board_config = overo_config;
390 omap_board_config_size = ARRAY_SIZE(overo_config);
391 omap_serial_init(); 391 omap_serial_init();
392 overo_flash_init(); 392 overo_flash_init();
393 usb_musb_init(); 393 usb_musb_init();
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index c0d13401425f..f9196c3b1a7b 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -56,6 +56,8 @@ static struct omap_board_config_kernel rx51_config[] = {
56 56
57static void __init rx51_init_irq(void) 57static void __init rx51_init_irq(void)
58{ 58{
59 omap_board_config = rx51_config;
60 omap_board_config_size = ARRAY_SIZE(rx51_config);
59 omap2_init_common_hw(NULL, NULL); 61 omap2_init_common_hw(NULL, NULL);
60 omap_init_irq(); 62 omap_init_irq();
61 omap_gpio_init(); 63 omap_gpio_init();
@@ -65,8 +67,6 @@ extern void __init rx51_peripherals_init(void);
65 67
66static void __init rx51_init(void) 68static void __init rx51_init(void)
67{ 69{
68 omap_board_config = rx51_config;
69 omap_board_config_size = ARRAY_SIZE(rx51_config);
70 omap_serial_init(); 70 omap_serial_init();
71 usb_musb_init(); 71 usb_musb_init();
72 rx51_peripherals_init(); 72 rx51_peripherals_init();
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index dabba2720a9b..324009edbd53 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -90,13 +90,6 @@ static struct twl4030_keypad_data zoom2_kp_twl4030_data = {
90 .rep = 1, 90 .rep = 1,
91}; 91};
92 92
93static void __init omap_zoom2_init_irq(void)
94{
95 omap2_init_common_hw(NULL, NULL);
96 omap_init_irq();
97 omap_gpio_init();
98}
99
100static struct omap_board_config_kernel zoom2_config[] __initdata = { 93static struct omap_board_config_kernel zoom2_config[] __initdata = {
101}; 94};
102 95
@@ -212,6 +205,15 @@ static struct twl4030_usb_data zoom2_usb_data = {
212 .usb_mode = T2_USB_MODE_ULPI, 205 .usb_mode = T2_USB_MODE_ULPI,
213}; 206};
214 207
208static void __init omap_zoom2_init_irq(void)
209{
210 omap_board_config = zoom2_config;
211 omap_board_config_size = ARRAY_SIZE(zoom2_config);
212 omap2_init_common_hw(NULL, NULL);
213 omap_init_irq();
214 omap_gpio_init();
215}
216
215static struct twl4030_gpio_platform_data zoom2_gpio_data = { 217static struct twl4030_gpio_platform_data zoom2_gpio_data = {
216 .gpio_base = OMAP_MAX_GPIO_LINES, 218 .gpio_base = OMAP_MAX_GPIO_LINES,
217 .irq_base = TWL4030_GPIO_IRQ_BASE, 219 .irq_base = TWL4030_GPIO_IRQ_BASE,
@@ -262,8 +264,6 @@ extern int __init omap_zoom2_debugboard_init(void);
262static void __init omap_zoom2_init(void) 264static void __init omap_zoom2_init(void)
263{ 265{
264 omap_i2c_init(); 266 omap_i2c_init();
265 omap_board_config = zoom2_config;
266 omap_board_config_size = ARRAY_SIZE(zoom2_config);
267 omap_serial_init(); 267 omap_serial_init();
268 omap_zoom2_debugboard_init(); 268 omap_zoom2_debugboard_init();
269 usb_musb_init(); 269 usb_musb_init();
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index cd7819cc0c9e..fafcd32e6907 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -27,6 +27,7 @@
27#include <linux/limits.h> 27#include <linux/limits.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29 29
30#include <mach/cpu.h>
30#include <mach/clock.h> 31#include <mach/clock.h>
31#include <mach/sram.h> 32#include <mach/sram.h>
32#include <asm/div64.h> 33#include <asm/div64.h>
@@ -1067,17 +1068,17 @@ static int __init omap2_clk_arch_init(void)
1067 return -EINVAL; 1068 return -EINVAL;
1068 1069
1069 /* REVISIT: not yet ready for 343x */ 1070 /* REVISIT: not yet ready for 343x */
1070#if 0 1071 if (clk_set_rate(&dpll1_ck, mpurate))
1071 if (clk_set_rate(&virt_prcm_set, mpurate)) 1072 printk(KERN_ERR "*** Unable to set MPU rate\n");
1072 printk(KERN_ERR "Could not find matching MPU rate\n");
1073#endif
1074 1073
1075 recalculate_root_clocks(); 1074 recalculate_root_clocks();
1076 1075
1077 printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL3/MPU): " 1076 printk(KERN_INFO "Switched to new clocking rate (Crystal/Core/MPU): "
1078 "%ld.%01ld/%ld/%ld MHz\n", 1077 "%ld.%01ld/%ld/%ld MHz\n",
1079 (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10, 1078 (osc_sys_ck.rate / 1000000), ((osc_sys_ck.rate / 100000) % 10),
1080 (core_ck.rate / 1000000), (dpll1_fck.rate / 1000000)) ; 1079 (core_ck.rate / 1000000), (arm_fck.rate / 1000000)) ;
1080
1081 calibrate_delay();
1081 1082
1082 return 0; 1083 return 0;
1083} 1084}
@@ -1136,7 +1137,7 @@ int __init omap2_clk_init(void)
1136 1137
1137 recalculate_root_clocks(); 1138 recalculate_root_clocks();
1138 1139
1139 printk(KERN_INFO "Clocking rate (Crystal/DPLL/ARM core): " 1140 printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
1140 "%ld.%01ld/%ld/%ld MHz\n", 1141 "%ld.%01ld/%ld/%ld MHz\n",
1141 (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10, 1142 (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
1142 (core_ck.rate / 1000000), (arm_fck.rate / 1000000)); 1143 (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 57cc2725b923..c8119781e00a 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -1020,6 +1020,7 @@ static struct clk arm_fck = {
1020 .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), 1020 .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
1021 .clksel_mask = OMAP3430_ST_MPU_CLK_MASK, 1021 .clksel_mask = OMAP3430_ST_MPU_CLK_MASK,
1022 .clksel = arm_fck_clksel, 1022 .clksel = arm_fck_clksel,
1023 .clkdm_name = "mpu_clkdm",
1023 .recalc = &omap2_clksel_recalc, 1024 .recalc = &omap2_clksel_recalc,
1024}; 1025};
1025 1026
@@ -1155,7 +1156,6 @@ static struct clk gfx_cg1_ck = {
1155 .name = "gfx_cg1_ck", 1156 .name = "gfx_cg1_ck",
1156 .ops = &clkops_omap2_dflt_wait, 1157 .ops = &clkops_omap2_dflt_wait,
1157 .parent = &gfx_l3_fck, /* REVISIT: correct? */ 1158 .parent = &gfx_l3_fck, /* REVISIT: correct? */
1158 .init = &omap2_init_clk_clkdm,
1159 .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), 1159 .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
1160 .enable_bit = OMAP3430ES1_EN_2D_SHIFT, 1160 .enable_bit = OMAP3430ES1_EN_2D_SHIFT,
1161 .clkdm_name = "gfx_3430es1_clkdm", 1161 .clkdm_name = "gfx_3430es1_clkdm",
@@ -1166,7 +1166,6 @@ static struct clk gfx_cg2_ck = {
1166 .name = "gfx_cg2_ck", 1166 .name = "gfx_cg2_ck",
1167 .ops = &clkops_omap2_dflt_wait, 1167 .ops = &clkops_omap2_dflt_wait,
1168 .parent = &gfx_l3_fck, /* REVISIT: correct? */ 1168 .parent = &gfx_l3_fck, /* REVISIT: correct? */
1169 .init = &omap2_init_clk_clkdm,
1170 .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN), 1169 .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
1171 .enable_bit = OMAP3430ES1_EN_3D_SHIFT, 1170 .enable_bit = OMAP3430ES1_EN_3D_SHIFT,
1172 .clkdm_name = "gfx_3430es1_clkdm", 1171 .clkdm_name = "gfx_3430es1_clkdm",
@@ -1210,7 +1209,6 @@ static struct clk sgx_ick = {
1210 .name = "sgx_ick", 1209 .name = "sgx_ick",
1211 .ops = &clkops_omap2_dflt_wait, 1210 .ops = &clkops_omap2_dflt_wait,
1212 .parent = &l3_ick, 1211 .parent = &l3_ick,
1213 .init = &omap2_init_clk_clkdm,
1214 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN), 1212 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
1215 .enable_bit = OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT, 1213 .enable_bit = OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
1216 .clkdm_name = "sgx_clkdm", 1214 .clkdm_name = "sgx_clkdm",
@@ -1223,7 +1221,6 @@ static struct clk d2d_26m_fck = {
1223 .name = "d2d_26m_fck", 1221 .name = "d2d_26m_fck",
1224 .ops = &clkops_omap2_dflt_wait, 1222 .ops = &clkops_omap2_dflt_wait,
1225 .parent = &sys_ck, 1223 .parent = &sys_ck,
1226 .init = &omap2_init_clk_clkdm,
1227 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), 1224 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
1228 .enable_bit = OMAP3430ES1_EN_D2D_SHIFT, 1225 .enable_bit = OMAP3430ES1_EN_D2D_SHIFT,
1229 .clkdm_name = "d2d_clkdm", 1226 .clkdm_name = "d2d_clkdm",
@@ -1234,7 +1231,6 @@ static struct clk modem_fck = {
1234 .name = "modem_fck", 1231 .name = "modem_fck",
1235 .ops = &clkops_omap2_dflt_wait, 1232 .ops = &clkops_omap2_dflt_wait,
1236 .parent = &sys_ck, 1233 .parent = &sys_ck,
1237 .init = &omap2_init_clk_clkdm,
1238 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), 1234 .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
1239 .enable_bit = OMAP3430_EN_MODEM_SHIFT, 1235 .enable_bit = OMAP3430_EN_MODEM_SHIFT,
1240 .clkdm_name = "d2d_clkdm", 1236 .clkdm_name = "d2d_clkdm",
@@ -1622,7 +1618,6 @@ static struct clk core_l3_ick = {
1622 .name = "core_l3_ick", 1618 .name = "core_l3_ick",
1623 .ops = &clkops_null, 1619 .ops = &clkops_null,
1624 .parent = &l3_ick, 1620 .parent = &l3_ick,
1625 .init = &omap2_init_clk_clkdm,
1626 .clkdm_name = "core_l3_clkdm", 1621 .clkdm_name = "core_l3_clkdm",
1627 .recalc = &followparent_recalc, 1622 .recalc = &followparent_recalc,
1628}; 1623};
@@ -1691,7 +1686,6 @@ static struct clk core_l4_ick = {
1691 .name = "core_l4_ick", 1686 .name = "core_l4_ick",
1692 .ops = &clkops_null, 1687 .ops = &clkops_null,
1693 .parent = &l4_ick, 1688 .parent = &l4_ick,
1694 .init = &omap2_init_clk_clkdm,
1695 .clkdm_name = "core_l4_clkdm", 1689 .clkdm_name = "core_l4_clkdm",
1696 .recalc = &followparent_recalc, 1690 .recalc = &followparent_recalc,
1697}; 1691};
@@ -2089,7 +2083,6 @@ static struct clk dss_tv_fck = {
2089 .name = "dss_tv_fck", 2083 .name = "dss_tv_fck",
2090 .ops = &clkops_omap2_dflt, 2084 .ops = &clkops_omap2_dflt,
2091 .parent = &omap_54m_fck, 2085 .parent = &omap_54m_fck,
2092 .init = &omap2_init_clk_clkdm,
2093 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), 2086 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
2094 .enable_bit = OMAP3430_EN_TV_SHIFT, 2087 .enable_bit = OMAP3430_EN_TV_SHIFT,
2095 .clkdm_name = "dss_clkdm", 2088 .clkdm_name = "dss_clkdm",
@@ -2100,7 +2093,6 @@ static struct clk dss_96m_fck = {
2100 .name = "dss_96m_fck", 2093 .name = "dss_96m_fck",
2101 .ops = &clkops_omap2_dflt, 2094 .ops = &clkops_omap2_dflt,
2102 .parent = &omap_96m_fck, 2095 .parent = &omap_96m_fck,
2103 .init = &omap2_init_clk_clkdm,
2104 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), 2096 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
2105 .enable_bit = OMAP3430_EN_TV_SHIFT, 2097 .enable_bit = OMAP3430_EN_TV_SHIFT,
2106 .clkdm_name = "dss_clkdm", 2098 .clkdm_name = "dss_clkdm",
@@ -2111,7 +2103,6 @@ static struct clk dss2_alwon_fck = {
2111 .name = "dss2_alwon_fck", 2103 .name = "dss2_alwon_fck",
2112 .ops = &clkops_omap2_dflt, 2104 .ops = &clkops_omap2_dflt,
2113 .parent = &sys_ck, 2105 .parent = &sys_ck,
2114 .init = &omap2_init_clk_clkdm,
2115 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), 2106 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
2116 .enable_bit = OMAP3430_EN_DSS2_SHIFT, 2107 .enable_bit = OMAP3430_EN_DSS2_SHIFT,
2117 .clkdm_name = "dss_clkdm", 2108 .clkdm_name = "dss_clkdm",
@@ -2123,7 +2114,6 @@ static struct clk dss_ick_3430es1 = {
2123 .name = "dss_ick", 2114 .name = "dss_ick",
2124 .ops = &clkops_omap2_dflt, 2115 .ops = &clkops_omap2_dflt,
2125 .parent = &l4_ick, 2116 .parent = &l4_ick,
2126 .init = &omap2_init_clk_clkdm,
2127 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), 2117 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
2128 .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, 2118 .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
2129 .clkdm_name = "dss_clkdm", 2119 .clkdm_name = "dss_clkdm",
@@ -2135,7 +2125,6 @@ static struct clk dss_ick_3430es2 = {
2135 .name = "dss_ick", 2125 .name = "dss_ick",
2136 .ops = &clkops_omap3430es2_dss_usbhost_wait, 2126 .ops = &clkops_omap3430es2_dss_usbhost_wait,
2137 .parent = &l4_ick, 2127 .parent = &l4_ick,
2138 .init = &omap2_init_clk_clkdm,
2139 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN), 2128 .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
2140 .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT, 2129 .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
2141 .clkdm_name = "dss_clkdm", 2130 .clkdm_name = "dss_clkdm",
@@ -2159,7 +2148,6 @@ static struct clk cam_ick = {
2159 .name = "cam_ick", 2148 .name = "cam_ick",
2160 .ops = &clkops_omap2_dflt, 2149 .ops = &clkops_omap2_dflt,
2161 .parent = &l4_ick, 2150 .parent = &l4_ick,
2162 .init = &omap2_init_clk_clkdm,
2163 .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN), 2151 .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
2164 .enable_bit = OMAP3430_EN_CAM_SHIFT, 2152 .enable_bit = OMAP3430_EN_CAM_SHIFT,
2165 .clkdm_name = "cam_clkdm", 2153 .clkdm_name = "cam_clkdm",
@@ -2170,7 +2158,6 @@ static struct clk csi2_96m_fck = {
2170 .name = "csi2_96m_fck", 2158 .name = "csi2_96m_fck",
2171 .ops = &clkops_omap2_dflt, 2159 .ops = &clkops_omap2_dflt,
2172 .parent = &core_96m_fck, 2160 .parent = &core_96m_fck,
2173 .init = &omap2_init_clk_clkdm,
2174 .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), 2161 .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
2175 .enable_bit = OMAP3430_EN_CSI2_SHIFT, 2162 .enable_bit = OMAP3430_EN_CSI2_SHIFT,
2176 .clkdm_name = "cam_clkdm", 2163 .clkdm_name = "cam_clkdm",
@@ -2183,7 +2170,6 @@ static struct clk usbhost_120m_fck = {
2183 .name = "usbhost_120m_fck", 2170 .name = "usbhost_120m_fck",
2184 .ops = &clkops_omap2_dflt, 2171 .ops = &clkops_omap2_dflt,
2185 .parent = &dpll5_m2_ck, 2172 .parent = &dpll5_m2_ck,
2186 .init = &omap2_init_clk_clkdm,
2187 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), 2173 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
2188 .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT, 2174 .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT,
2189 .clkdm_name = "usbhost_clkdm", 2175 .clkdm_name = "usbhost_clkdm",
@@ -2194,7 +2180,6 @@ static struct clk usbhost_48m_fck = {
2194 .name = "usbhost_48m_fck", 2180 .name = "usbhost_48m_fck",
2195 .ops = &clkops_omap3430es2_dss_usbhost_wait, 2181 .ops = &clkops_omap3430es2_dss_usbhost_wait,
2196 .parent = &omap_48m_fck, 2182 .parent = &omap_48m_fck,
2197 .init = &omap2_init_clk_clkdm,
2198 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN), 2183 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
2199 .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, 2184 .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT,
2200 .clkdm_name = "usbhost_clkdm", 2185 .clkdm_name = "usbhost_clkdm",
@@ -2206,7 +2191,6 @@ static struct clk usbhost_ick = {
2206 .name = "usbhost_ick", 2191 .name = "usbhost_ick",
2207 .ops = &clkops_omap3430es2_dss_usbhost_wait, 2192 .ops = &clkops_omap3430es2_dss_usbhost_wait,
2208 .parent = &l4_ick, 2193 .parent = &l4_ick,
2209 .init = &omap2_init_clk_clkdm,
2210 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN), 2194 .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
2211 .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT, 2195 .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT,
2212 .clkdm_name = "usbhost_clkdm", 2196 .clkdm_name = "usbhost_clkdm",
@@ -2268,7 +2252,6 @@ static struct clk gpt1_fck = {
2268static struct clk wkup_32k_fck = { 2252static struct clk wkup_32k_fck = {
2269 .name = "wkup_32k_fck", 2253 .name = "wkup_32k_fck",
2270 .ops = &clkops_null, 2254 .ops = &clkops_null,
2271 .init = &omap2_init_clk_clkdm,
2272 .parent = &omap_32k_fck, 2255 .parent = &omap_32k_fck,
2273 .clkdm_name = "wkup_clkdm", 2256 .clkdm_name = "wkup_clkdm",
2274 .recalc = &followparent_recalc, 2257 .recalc = &followparent_recalc,
@@ -2383,7 +2366,6 @@ static struct clk per_96m_fck = {
2383 .name = "per_96m_fck", 2366 .name = "per_96m_fck",
2384 .ops = &clkops_null, 2367 .ops = &clkops_null,
2385 .parent = &omap_96m_alwon_fck, 2368 .parent = &omap_96m_alwon_fck,
2386 .init = &omap2_init_clk_clkdm,
2387 .clkdm_name = "per_clkdm", 2369 .clkdm_name = "per_clkdm",
2388 .recalc = &followparent_recalc, 2370 .recalc = &followparent_recalc,
2389}; 2371};
@@ -2392,7 +2374,6 @@ static struct clk per_48m_fck = {
2392 .name = "per_48m_fck", 2374 .name = "per_48m_fck",
2393 .ops = &clkops_null, 2375 .ops = &clkops_null,
2394 .parent = &omap_48m_fck, 2376 .parent = &omap_48m_fck,
2395 .init = &omap2_init_clk_clkdm,
2396 .clkdm_name = "per_clkdm", 2377 .clkdm_name = "per_clkdm",
2397 .recalc = &followparent_recalc, 2378 .recalc = &followparent_recalc,
2398}; 2379};
diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c
new file mode 100644
index 000000000000..8eb2dab8c7db
--- /dev/null
+++ b/arch/arm/mach-omap2/cm.c
@@ -0,0 +1,70 @@
1/*
2 * OMAP2/3 CM module functions
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/delay.h>
16#include <linux/spinlock.h>
17#include <linux/list.h>
18#include <linux/errno.h>
19#include <linux/err.h>
20#include <linux/io.h>
21
22#include <asm/atomic.h>
23
24#include "cm.h"
25#include "cm-regbits-24xx.h"
26#include "cm-regbits-34xx.h"
27
28/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */
29#define MAX_MODULE_READY_TIME 20000
30
31static const u8 cm_idlest_offs[] = {
32 CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
33};
34
35/**
36 * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
37 * @prcm_mod: PRCM module offset
38 * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
39 * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
40 *
41 * XXX document
42 */
43int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
44{
45 int ena = 0, i = 0;
46 u8 cm_idlest_reg;
47 u32 mask;
48
49 if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
50 return -EINVAL;
51
52 cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
53
54 if (cpu_is_omap24xx())
55 ena = idlest_shift;
56 else if (cpu_is_omap34xx())
57 ena = 0;
58 else
59 BUG();
60
61 mask = 1 << idlest_shift;
62
63 /* XXX should be OMAP2 CM */
64 while (((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) != ena) &&
65 (i++ < MAX_MODULE_READY_TIME))
66 udelay(1);
67
68 return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
69}
70
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 18d9a121aa7a..cfd0b726ba44 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -98,6 +98,10 @@ extern u32 cm_read_mod_reg(s16 module, u16 idx);
98extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); 98extern void cm_write_mod_reg(u32 val, s16 module, u16 idx);
99extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); 99extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
100 100
101extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
102 u8 idlest_shift);
103extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs);
104
101static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) 105static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
102{ 106{
103 return cm_rmw_mod_reg_bits(bits, bits, module, idx); 107 return cm_rmw_mod_reg_bits(bits, bits, module, idx);
diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c
new file mode 100644
index 000000000000..e4ebd6d53135
--- /dev/null
+++ b/arch/arm/mach-omap2/cm4xxx.c
@@ -0,0 +1,68 @@
1/*
2 * OMAP4 CM module functions
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/delay.h>
16#include <linux/spinlock.h>
17#include <linux/list.h>
18#include <linux/errno.h>
19#include <linux/err.h>
20#include <linux/io.h>
21
22#include <asm/atomic.h>
23
24#include "cm.h"
25#include "cm-regbits-4xxx.h"
26
27/* XXX move this to cm.h */
28/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */
29#define MAX_MODULE_READY_TIME 20000
30
31/*
32 * OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK: isolates the IDLEST field in the
33 * CM_CLKCTRL register.
34 */
35#define OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK (0x2 << 16)
36
37/*
38 * OMAP4 prcm_mod u32 fields contain packed data: the CM ID in bit 16 and
39 * the PRCM module offset address (from the CM module base) in bits 15-0.
40 */
41#define OMAP4_PRCM_MOD_CM_ID_SHIFT 16
42#define OMAP4_PRCM_MOD_OFFS_MASK 0xffff
43
44/**
45 * omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby
46 * @prcm_mod: PRCM module offset (XXX example)
47 * @prcm_dev_offs: PRCM device offset (e.g. MCASP XXX example)
48 *
49 * XXX document
50 */
51int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs)
52{
53 int i = 0;
54 u8 cm_id;
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}
68
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index e9b9bcb19b4e..7574b6f20e8e 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -32,17 +32,23 @@
32#include <mach/sram.h> 32#include <mach/sram.h>
33#include <mach/sdrc.h> 33#include <mach/sdrc.h>
34#include <mach/gpmc.h> 34#include <mach/gpmc.h>
35#include <mach/serial.h>
35 36
36#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */ 37#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once clkdev is ready */
37#include "clock.h" 38#include "clock.h"
38 39
40#include <mach/omap-pm.h>
39#include <mach/powerdomain.h> 41#include <mach/powerdomain.h>
40
41#include "powerdomains.h" 42#include "powerdomains.h"
42 43
43#include <mach/clockdomain.h> 44#include <mach/clockdomain.h>
44#include "clockdomains.h" 45#include "clockdomains.h"
45#endif 46#endif
47#include <mach/omap_hwmod.h>
48#include "omap_hwmod_2420.h"
49#include "omap_hwmod_2430.h"
50#include "omap_hwmod_34xx.h"
51
46/* 52/*
47 * The machine specific code may provide the extra mapping besides the 53 * The machine specific code may provide the extra mapping besides the
48 * default mapping provided here. 54 * default mapping provided here.
@@ -279,11 +285,26 @@ static int __init _omap2_init_reprogram_sdrc(void)
279void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, 285void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
280 struct omap_sdrc_params *sdrc_cs1) 286 struct omap_sdrc_params *sdrc_cs1)
281{ 287{
288 struct omap_hwmod **hwmods = NULL;
289
290 if (cpu_is_omap2420())
291 hwmods = omap2420_hwmods;
292 else if (cpu_is_omap2430())
293 hwmods = omap2430_hwmods;
294 else if (cpu_is_omap34xx())
295 hwmods = omap34xx_hwmods;
296
297 omap_hwmod_init(hwmods);
282 omap2_mux_init(); 298 omap2_mux_init();
283#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */ 299#ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
300 /* The OPP tables have to be registered before a clk init */
301 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
284 pwrdm_init(powerdomains_omap); 302 pwrdm_init(powerdomains_omap);
285 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps); 303 clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
286 omap2_clk_init(); 304 omap2_clk_init();
305 omap_serial_early_init();
306 omap_hwmod_late_init();
307 omap_pm_if_init();
287 omap2_sdrc_init(sdrc_cs0, sdrc_cs1); 308 omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
288 _omap2_init_reprogram_sdrc(); 309 _omap2_init_reprogram_sdrc();
289#endif 310#endif
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
new file mode 100644
index 000000000000..d2e0f1c95961
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -0,0 +1,1554 @@
1/*
2 * omap_hwmod implementation for OMAP2/3/4
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 * With fixes and testing from Kevin Hilman
7 *
8 * Created in collaboration with (alphabetical order): Benoit Cousson,
9 * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
10 * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This code manages "OMAP modules" (on-chip devices) and their
17 * integration with Linux device driver and bus code.
18 *
19 * References:
20 * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
21 * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
22 * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
23 * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
24 * - Open Core Protocol Specification 2.2
25 *
26 * To do:
27 * - pin mux handling
28 * - handle IO mapping
29 * - bus throughput & module latency measurement code
30 *
31 * XXX add tests at the beginning of each function to ensure the hwmod is
32 * in the appropriate state
33 * XXX error return values should be checked to ensure that they are
34 * appropriate
35 */
36#undef DEBUG
37
38#include <linux/kernel.h>
39#include <linux/errno.h>
40#include <linux/io.h>
41#include <linux/clk.h>
42#include <linux/delay.h>
43#include <linux/err.h>
44#include <linux/list.h>
45#include <linux/mutex.h>
46#include <linux/bootmem.h>
47
48#include <mach/cpu.h>
49#include <mach/clockdomain.h>
50#include <mach/powerdomain.h>
51#include <mach/clock.h>
52#include <mach/omap_hwmod.h>
53
54#include "cm.h"
55
56/* Maximum microseconds to wait for OMAP module to reset */
57#define MAX_MODULE_RESET_WAIT 10000
58
59/* Name of the OMAP hwmod for the MPU */
60#define MPU_INITIATOR_NAME "mpu_hwmod"
61
62/* omap_hwmod_list contains all registered struct omap_hwmods */
63static LIST_HEAD(omap_hwmod_list);
64
65static DEFINE_MUTEX(omap_hwmod_mutex);
66
67/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
68static struct omap_hwmod *mpu_oh;
69
70/* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */
71static u8 inited;
72
73
74/* Private functions */
75
76/**
77 * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy
78 * @oh: struct omap_hwmod *
79 *
80 * Load the current value of the hwmod OCP_SYSCONFIG register into the
81 * struct omap_hwmod for later use. Returns -EINVAL if the hwmod has no
82 * OCP_SYSCONFIG register or 0 upon success.
83 */
84static int _update_sysc_cache(struct omap_hwmod *oh)
85{
86 if (!oh->sysconfig) {
87 WARN(!oh->sysconfig, "omap_hwmod: %s: cannot read "
88 "OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
89 return -EINVAL;
90 }
91
92 /* XXX ensure module interface clock is up */
93
94 oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
95
96 oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
97
98 return 0;
99}
100
101/**
102 * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register
103 * @v: OCP_SYSCONFIG value to write
104 * @oh: struct omap_hwmod *
105 *
106 * Write @v into the module OCP_SYSCONFIG register, if it has one. No
107 * return value.
108 */
109static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
110{
111 if (!oh->sysconfig) {
112 WARN(!oh->sysconfig, "omap_hwmod: %s: cannot write "
113 "OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
114 return;
115 }
116
117 /* XXX ensure module interface clock is up */
118
119 if (oh->_sysc_cache != v) {
120 oh->_sysc_cache = v;
121 omap_hwmod_writel(v, oh, oh->sysconfig->sysc_offs);
122 }
123}
124
125/**
126 * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v
127 * @oh: struct omap_hwmod *
128 * @standbymode: MIDLEMODE field bits
129 * @v: pointer to register contents to modify
130 *
131 * Update the master standby mode bits in @v to be @standbymode for
132 * the @oh hwmod. Does not write to the hardware. Returns -EINVAL
133 * upon error or 0 upon success.
134 */
135static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
136 u32 *v)
137{
138 if (!oh->sysconfig ||
139 !(oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE))
140 return -EINVAL;
141
142 *v &= ~SYSC_MIDLEMODE_MASK;
143 *v |= __ffs(standbymode) << SYSC_MIDLEMODE_SHIFT;
144
145 return 0;
146}
147
148/**
149 * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v
150 * @oh: struct omap_hwmod *
151 * @idlemode: SIDLEMODE field bits
152 * @v: pointer to register contents to modify
153 *
154 * Update the slave idle mode bits in @v to be @idlemode for the @oh
155 * hwmod. Does not write to the hardware. Returns -EINVAL upon error
156 * or 0 upon success.
157 */
158static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
159{
160 if (!oh->sysconfig ||
161 !(oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE))
162 return -EINVAL;
163
164 *v &= ~SYSC_SIDLEMODE_MASK;
165 *v |= __ffs(idlemode) << SYSC_SIDLEMODE_SHIFT;
166
167 return 0;
168}
169
170/**
171 * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
172 * @oh: struct omap_hwmod *
173 * @clockact: CLOCKACTIVITY field bits
174 * @v: pointer to register contents to modify
175 *
176 * Update the clockactivity mode bits in @v to be @clockact for the
177 * @oh hwmod. Used for additional powersaving on some modules. Does
178 * not write to the hardware. Returns -EINVAL upon error or 0 upon
179 * success.
180 */
181static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
182{
183 if (!oh->sysconfig ||
184 !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
185 return -EINVAL;
186
187 *v &= ~SYSC_CLOCKACTIVITY_MASK;
188 *v |= clockact << SYSC_CLOCKACTIVITY_SHIFT;
189
190 return 0;
191}
192
193/**
194 * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
195 * @oh: struct omap_hwmod *
196 * @v: pointer to register contents to modify
197 *
198 * Set the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon
199 * error or 0 upon success.
200 */
201static int _set_softreset(struct omap_hwmod *oh, u32 *v)
202{
203 if (!oh->sysconfig ||
204 !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET))
205 return -EINVAL;
206
207 *v |= SYSC_SOFTRESET_MASK;
208
209 return 0;
210}
211
212/**
213 * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
214 * @oh: struct omap_hwmod *
215 *
216 * Allow the hardware module @oh to send wakeups. Returns -EINVAL
217 * upon error or 0 upon success.
218 */
219static int _enable_wakeup(struct omap_hwmod *oh)
220{
221 u32 v;
222
223 if (!oh->sysconfig ||
224 !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
225 return -EINVAL;
226
227 v = oh->_sysc_cache;
228 v |= SYSC_ENAWAKEUP_MASK;
229 _write_sysconfig(v, oh);
230
231 /* XXX test pwrdm_get_wken for this hwmod's subsystem */
232
233 oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
234
235 return 0;
236}
237
238/**
239 * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
240 * @oh: struct omap_hwmod *
241 *
242 * Prevent the hardware module @oh to send wakeups. Returns -EINVAL
243 * upon error or 0 upon success.
244 */
245static int _disable_wakeup(struct omap_hwmod *oh)
246{
247 u32 v;
248
249 if (!oh->sysconfig ||
250 !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
251 return -EINVAL;
252
253 v = oh->_sysc_cache;
254 v &= ~SYSC_ENAWAKEUP_MASK;
255 _write_sysconfig(v, oh);
256
257 /* XXX test pwrdm_get_wken for this hwmod's subsystem */
258
259 oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
260
261 return 0;
262}
263
264/**
265 * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active
266 * @oh: struct omap_hwmod *
267 *
268 * Prevent the hardware module @oh from entering idle while the
269 * hardare module initiator @init_oh is active. Useful when a module
270 * will be accessed by a particular initiator (e.g., if a module will
271 * be accessed by the IVA, there should be a sleepdep between the IVA
272 * initiator and the module). Only applies to modules in smart-idle
273 * mode. Returns -EINVAL upon error or passes along
274 * pwrdm_add_sleepdep() value upon success.
275 */
276static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
277{
278 if (!oh->_clk)
279 return -EINVAL;
280
281 return pwrdm_add_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
282 init_oh->_clk->clkdm->pwrdm.ptr);
283}
284
285/**
286 * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active
287 * @oh: struct omap_hwmod *
288 *
289 * Allow the hardware module @oh to enter idle while the hardare
290 * module initiator @init_oh is active. Useful when a module will not
291 * be accessed by a particular initiator (e.g., if a module will not
292 * be accessed by the IVA, there should be no sleepdep between the IVA
293 * initiator and the module). Only applies to modules in smart-idle
294 * mode. Returns -EINVAL upon error or passes along
295 * pwrdm_add_sleepdep() value upon success.
296 */
297static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
298{
299 if (!oh->_clk)
300 return -EINVAL;
301
302 return pwrdm_del_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
303 init_oh->_clk->clkdm->pwrdm.ptr);
304}
305
306/**
307 * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
308 * @oh: struct omap_hwmod *
309 *
310 * Called from _init_clocks(). Populates the @oh _clk (main
311 * functional clock pointer) if a main_clk is present. Returns 0 on
312 * success or -EINVAL on error.
313 */
314static int _init_main_clk(struct omap_hwmod *oh)
315{
316 struct clk *c;
317 int ret = 0;
318
319 if (!oh->clkdev_con_id)
320 return 0;
321
322 c = clk_get_sys(oh->clkdev_dev_id, oh->clkdev_con_id);
323 WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s.%s\n",
324 oh->name, oh->clkdev_dev_id, oh->clkdev_con_id);
325 if (IS_ERR(c))
326 ret = -EINVAL;
327 oh->_clk = c;
328
329 return ret;
330}
331
332/**
333 * _init_interface_clk - get a struct clk * for the the hwmod's interface clks
334 * @oh: struct omap_hwmod *
335 *
336 * Called from _init_clocks(). Populates the @oh OCP slave interface
337 * clock pointers. Returns 0 on success or -EINVAL on error.
338 */
339static int _init_interface_clks(struct omap_hwmod *oh)
340{
341 struct omap_hwmod_ocp_if *os;
342 struct clk *c;
343 int i;
344 int ret = 0;
345
346 if (oh->slaves_cnt == 0)
347 return 0;
348
349 for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
350 if (!os->clkdev_con_id)
351 continue;
352
353 c = clk_get_sys(os->clkdev_dev_id, os->clkdev_con_id);
354 WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get "
355 "interface_clk %s.%s\n", oh->name,
356 os->clkdev_dev_id, os->clkdev_con_id);
357 if (IS_ERR(c))
358 ret = -EINVAL;
359 os->_clk = c;
360 }
361
362 return ret;
363}
364
365/**
366 * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks
367 * @oh: struct omap_hwmod *
368 *
369 * Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk
370 * clock pointers. Returns 0 on success or -EINVAL on error.
371 */
372static int _init_opt_clks(struct omap_hwmod *oh)
373{
374 struct omap_hwmod_opt_clk *oc;
375 struct clk *c;
376 int i;
377 int ret = 0;
378
379 for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
380 c = clk_get_sys(oc->clkdev_dev_id, oc->clkdev_con_id);
381 WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get opt_clk "
382 "%s.%s\n", oh->name, oc->clkdev_dev_id,
383 oc->clkdev_con_id);
384 if (IS_ERR(c))
385 ret = -EINVAL;
386 oc->_clk = c;
387 }
388
389 return ret;
390}
391
392/**
393 * _enable_clocks - enable hwmod main clock and interface clocks
394 * @oh: struct omap_hwmod *
395 *
396 * Enables all clocks necessary for register reads and writes to succeed
397 * on the hwmod @oh. Returns 0.
398 */
399static int _enable_clocks(struct omap_hwmod *oh)
400{
401 struct omap_hwmod_ocp_if *os;
402 int i;
403
404 pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
405
406 if (oh->_clk && !IS_ERR(oh->_clk))
407 clk_enable(oh->_clk);
408
409 if (oh->slaves_cnt > 0) {
410 for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
411 struct clk *c = os->_clk;
412
413 if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE))
414 clk_enable(c);
415 }
416 }
417
418 /* The opt clocks are controlled by the device driver. */
419
420 return 0;
421}
422
423/**
424 * _disable_clocks - disable hwmod main clock and interface clocks
425 * @oh: struct omap_hwmod *
426 *
427 * Disables the hwmod @oh main functional and interface clocks. Returns 0.
428 */
429static int _disable_clocks(struct omap_hwmod *oh)
430{
431 struct omap_hwmod_ocp_if *os;
432 int i;
433
434 pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
435
436 if (oh->_clk && !IS_ERR(oh->_clk))
437 clk_disable(oh->_clk);
438
439 if (oh->slaves_cnt > 0) {
440 for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
441 struct clk *c = os->_clk;
442
443 if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE))
444 clk_disable(c);
445 }
446 }
447
448 /* The opt clocks are controlled by the device driver. */
449
450 return 0;
451}
452
453/**
454 * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
455 * @oh: struct omap_hwmod *
456 *
457 * Returns the array index of the OCP slave port that the MPU
458 * addresses the device on, or -EINVAL upon error or not found.
459 */
460static int _find_mpu_port_index(struct omap_hwmod *oh)
461{
462 struct omap_hwmod_ocp_if *os;
463 int i;
464 int found = 0;
465
466 if (!oh || oh->slaves_cnt == 0)
467 return -EINVAL;
468
469 for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
470 if (os->user & OCP_USER_MPU) {
471 found = 1;
472 break;
473 }
474 }
475
476 if (found)
477 pr_debug("omap_hwmod: %s: MPU OCP slave port ID %d\n",
478 oh->name, i);
479 else
480 pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n",
481 oh->name);
482
483 return (found) ? i : -EINVAL;
484}
485
486/**
487 * _find_mpu_rt_base - find hwmod register target base addr accessible by MPU
488 * @oh: struct omap_hwmod *
489 *
490 * Return the virtual address of the base of the register target of
491 * device @oh, or NULL on error.
492 */
493static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
494{
495 struct omap_hwmod_ocp_if *os;
496 struct omap_hwmod_addr_space *mem;
497 int i;
498 int found = 0;
499
500 if (!oh || oh->slaves_cnt == 0)
501 return NULL;
502
503 os = *oh->slaves + index;
504
505 for (i = 0, mem = os->addr; i < os->addr_cnt; i++, mem++) {
506 if (mem->flags & ADDR_TYPE_RT) {
507 found = 1;
508 break;
509 }
510 }
511
512 /* XXX use ioremap() instead? */
513
514 if (found)
515 pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
516 oh->name, OMAP2_IO_ADDRESS(mem->pa_start));
517 else
518 pr_debug("omap_hwmod: %s: no MPU register target found\n",
519 oh->name);
520
521 return (found) ? OMAP2_IO_ADDRESS(mem->pa_start) : NULL;
522}
523
524/**
525 * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG
526 * @oh: struct omap_hwmod *
527 *
528 * If module is marked as SWSUP_SIDLE, force the module out of slave
529 * idle; otherwise, configure it for smart-idle. If module is marked
530 * as SWSUP_MSUSPEND, force the module out of master standby;
531 * otherwise, configure it for smart-standby. No return value.
532 */
533static void _sysc_enable(struct omap_hwmod *oh)
534{
535 u8 idlemode;
536 u32 v;
537
538 if (!oh->sysconfig)
539 return;
540
541 v = oh->_sysc_cache;
542
543 if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
544 idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
545 HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
546 _set_slave_idlemode(oh, idlemode, &v);
547 }
548
549 if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
550 idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
551 HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
552 _set_master_standbymode(oh, idlemode, &v);
553 }
554
555 /* XXX OCP AUTOIDLE bit? */
556
557 if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT &&
558 oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)
559 _set_clockactivity(oh, oh->sysconfig->clockact, &v);
560
561 _write_sysconfig(v, oh);
562}
563
564/**
565 * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG
566 * @oh: struct omap_hwmod *
567 *
568 * If module is marked as SWSUP_SIDLE, force the module into slave
569 * idle; otherwise, configure it for smart-idle. If module is marked
570 * as SWSUP_MSUSPEND, force the module into master standby; otherwise,
571 * configure it for smart-standby. No return value.
572 */
573static void _sysc_idle(struct omap_hwmod *oh)
574{
575 u8 idlemode;
576 u32 v;
577
578 if (!oh->sysconfig)
579 return;
580
581 v = oh->_sysc_cache;
582
583 if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
584 idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
585 HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
586 _set_slave_idlemode(oh, idlemode, &v);
587 }
588
589 if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
590 idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
591 HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
592 _set_master_standbymode(oh, idlemode, &v);
593 }
594
595 _write_sysconfig(v, oh);
596}
597
598/**
599 * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG
600 * @oh: struct omap_hwmod *
601 *
602 * Force the module into slave idle and master suspend. No return
603 * value.
604 */
605static void _sysc_shutdown(struct omap_hwmod *oh)
606{
607 u32 v;
608
609 if (!oh->sysconfig)
610 return;
611
612 v = oh->_sysc_cache;
613
614 if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE)
615 _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
616
617 if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)
618 _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
619
620 /* XXX clear OCP AUTOIDLE bit? */
621
622 _write_sysconfig(v, oh);
623}
624
625/**
626 * _lookup - find an omap_hwmod by name
627 * @name: find an omap_hwmod by name
628 *
629 * Return a pointer to an omap_hwmod by name, or NULL if not found.
630 * Caller must hold omap_hwmod_mutex.
631 */
632static struct omap_hwmod *_lookup(const char *name)
633{
634 struct omap_hwmod *oh, *temp_oh;
635
636 oh = NULL;
637
638 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
639 if (!strcmp(name, temp_oh->name)) {
640 oh = temp_oh;
641 break;
642 }
643 }
644
645 return oh;
646}
647
648/**
649 * _init_clocks - clk_get() all clocks associated with this hwmod
650 * @oh: struct omap_hwmod *
651 *
652 * Called by omap_hwmod_late_init() (after omap2_clk_init()).
653 * Resolves all clock names embedded in the hwmod. Must be called
654 * with omap_hwmod_mutex held. Returns -EINVAL if the omap_hwmod
655 * has not yet been registered or if the clocks have already been
656 * initialized, 0 on success, or a non-zero error on failure.
657 */
658static int _init_clocks(struct omap_hwmod *oh)
659{
660 int ret = 0;
661
662 if (!oh || (oh->_state != _HWMOD_STATE_REGISTERED))
663 return -EINVAL;
664
665 pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
666
667 ret |= _init_main_clk(oh);
668 ret |= _init_interface_clks(oh);
669 ret |= _init_opt_clks(oh);
670
671 oh->_state = _HWMOD_STATE_CLKS_INITED;
672
673 return ret;
674}
675
676/**
677 * _wait_target_ready - wait for a module to leave slave idle
678 * @oh: struct omap_hwmod *
679 *
680 * Wait for a module @oh to leave slave idle. Returns 0 if the module
681 * does not have an IDLEST bit or if the module successfully leaves
682 * slave idle; otherwise, pass along the return value of the
683 * appropriate *_cm_wait_module_ready() function.
684 */
685static int _wait_target_ready(struct omap_hwmod *oh)
686{
687 struct omap_hwmod_ocp_if *os;
688 int ret;
689
690 if (!oh)
691 return -EINVAL;
692
693 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
694 return 0;
695
696 os = *oh->slaves + oh->_mpu_port_index;
697
698 if (!(os->flags & OCPIF_HAS_IDLEST))
699 return 0;
700
701 /* XXX check module SIDLEMODE */
702
703 /* XXX check clock enable states */
704
705 if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
706 ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
707 oh->prcm.omap2.idlest_reg_id,
708 oh->prcm.omap2.idlest_idle_bit);
709#if 0
710 } else if (cpu_is_omap44xx()) {
711 ret = omap4_cm_wait_module_ready(oh->prcm.omap4.module_offs,
712 oh->prcm.omap4.device_offs);
713#endif
714 } else {
715 BUG();
716 };
717
718 return ret;
719}
720
721/**
722 * _reset - reset an omap_hwmod
723 * @oh: struct omap_hwmod *
724 *
725 * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
726 * enabled for this to work. Must be called with omap_hwmod_mutex
727 * held. Returns -EINVAL if the hwmod cannot be reset this way or if
728 * the hwmod is in the wrong state, -ETIMEDOUT if the module did not
729 * reset in time, or 0 upon success.
730 */
731static int _reset(struct omap_hwmod *oh)
732{
733 u32 r, v;
734 int c;
735
736 if (!oh->sysconfig ||
737 !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) ||
738 (oh->sysconfig->sysc_flags & SYSS_MISSING))
739 return -EINVAL;
740
741 /* clocks must be on for this operation */
742 if (oh->_state != _HWMOD_STATE_ENABLED) {
743 WARN(1, "omap_hwmod: %s: reset can only be entered from "
744 "enabled state\n", oh->name);
745 return -EINVAL;
746 }
747
748 pr_debug("omap_hwmod: %s: resetting\n", oh->name);
749
750 v = oh->_sysc_cache;
751 r = _set_softreset(oh, &v);
752 if (r)
753 return r;
754 _write_sysconfig(v, oh);
755
756 c = 0;
757 while (c < MAX_MODULE_RESET_WAIT &&
758 !(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
759 SYSS_RESETDONE_MASK)) {
760 udelay(1);
761 c++;
762 }
763
764 if (c == MAX_MODULE_RESET_WAIT)
765 WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
766 oh->name, MAX_MODULE_RESET_WAIT);
767 else
768 pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c);
769
770 /*
771 * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
772 * _wait_target_ready() or _reset()
773 */
774
775 return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0;
776}
777
778/**
779 * _enable - enable an omap_hwmod
780 * @oh: struct omap_hwmod *
781 *
782 * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
783 * register target. Must be called with omap_hwmod_mutex held.
784 * Returns -EINVAL if the hwmod is in the wrong state or passes along
785 * the return value of _wait_target_ready().
786 */
787static int _enable(struct omap_hwmod *oh)
788{
789 int r;
790
791 if (oh->_state != _HWMOD_STATE_INITIALIZED &&
792 oh->_state != _HWMOD_STATE_IDLE &&
793 oh->_state != _HWMOD_STATE_DISABLED) {
794 WARN(1, "omap_hwmod: %s: enabled state can only be entered "
795 "from initialized, idle, or disabled state\n", oh->name);
796 return -EINVAL;
797 }
798
799 pr_debug("omap_hwmod: %s: enabling\n", oh->name);
800
801 /* XXX mux balls */
802
803 _add_initiator_dep(oh, mpu_oh);
804 _enable_clocks(oh);
805
806 if (oh->sysconfig) {
807 if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
808 _update_sysc_cache(oh);
809 _sysc_enable(oh);
810 }
811
812 r = _wait_target_ready(oh);
813 if (!r)
814 oh->_state = _HWMOD_STATE_ENABLED;
815
816 return r;
817}
818
819/**
820 * _idle - idle an omap_hwmod
821 * @oh: struct omap_hwmod *
822 *
823 * Idles an omap_hwmod @oh. This should be called once the hwmod has
824 * no further work. Returns -EINVAL if the hwmod is in the wrong
825 * state or returns 0.
826 */
827static int _idle(struct omap_hwmod *oh)
828{
829 if (oh->_state != _HWMOD_STATE_ENABLED) {
830 WARN(1, "omap_hwmod: %s: idle state can only be entered from "
831 "enabled state\n", oh->name);
832 return -EINVAL;
833 }
834
835 pr_debug("omap_hwmod: %s: idling\n", oh->name);
836
837 if (oh->sysconfig)
838 _sysc_idle(oh);
839 _del_initiator_dep(oh, mpu_oh);
840 _disable_clocks(oh);
841
842 oh->_state = _HWMOD_STATE_IDLE;
843
844 return 0;
845}
846
847/**
848 * _shutdown - shutdown an omap_hwmod
849 * @oh: struct omap_hwmod *
850 *
851 * Shut down an omap_hwmod @oh. This should be called when the driver
852 * used for the hwmod is removed or unloaded or if the driver is not
853 * used by the system. Returns -EINVAL if the hwmod is in the wrong
854 * state or returns 0.
855 */
856static int _shutdown(struct omap_hwmod *oh)
857{
858 if (oh->_state != _HWMOD_STATE_IDLE &&
859 oh->_state != _HWMOD_STATE_ENABLED) {
860 WARN(1, "omap_hwmod: %s: disabled state can only be entered "
861 "from idle, or enabled state\n", oh->name);
862 return -EINVAL;
863 }
864
865 pr_debug("omap_hwmod: %s: disabling\n", oh->name);
866
867 if (oh->sysconfig)
868 _sysc_shutdown(oh);
869 _del_initiator_dep(oh, mpu_oh);
870 /* XXX what about the other system initiators here? DMA, tesla, d2d */
871 _disable_clocks(oh);
872 /* XXX Should this code also force-disable the optional clocks? */
873
874 /* XXX mux any associated balls to safe mode */
875
876 oh->_state = _HWMOD_STATE_DISABLED;
877
878 return 0;
879}
880
881/**
882 * _write_clockact_lock - set the module's clockactivity bits
883 * @oh: struct omap_hwmod *
884 * @clockact: CLOCKACTIVITY field bits
885 *
886 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
887 * OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the
888 * wrong state or returns 0.
889 */
890static int _write_clockact_lock(struct omap_hwmod *oh, u8 clockact)
891{
892 u32 v;
893
894 if (!oh->sysconfig ||
895 !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
896 return -EINVAL;
897
898 mutex_lock(&omap_hwmod_mutex);
899 v = oh->_sysc_cache;
900 _set_clockactivity(oh, clockact, &v);
901 _write_sysconfig(v, oh);
902 mutex_unlock(&omap_hwmod_mutex);
903
904 return 0;
905}
906
907
908/**
909 * _setup - do initial configuration of omap_hwmod
910 * @oh: struct omap_hwmod *
911 *
912 * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
913 * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex
914 * held. Returns -EINVAL if the hwmod is in the wrong state or returns
915 * 0.
916 */
917static int _setup(struct omap_hwmod *oh)
918{
919 struct omap_hwmod_ocp_if *os;
920 int i;
921
922 if (!oh)
923 return -EINVAL;
924
925 /* Set iclk autoidle mode */
926 if (oh->slaves_cnt > 0) {
927 for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
928 struct clk *c = os->_clk;
929
930 if (!c || IS_ERR(c))
931 continue;
932
933 if (os->flags & OCPIF_SWSUP_IDLE) {
934 /* XXX omap_iclk_deny_idle(c); */
935 } else {
936 /* XXX omap_iclk_allow_idle(c); */
937 clk_enable(c);
938 }
939 }
940 }
941
942 oh->_state = _HWMOD_STATE_INITIALIZED;
943
944 _enable(oh);
945
946 if (!(oh->flags & HWMOD_INIT_NO_RESET))
947 _reset(oh);
948
949 /* XXX OCP AUTOIDLE bit? */
950 /* XXX OCP ENAWAKEUP bit? */
951
952 if (!(oh->flags & HWMOD_INIT_NO_IDLE))
953 _idle(oh);
954
955 return 0;
956}
957
958
959
960/* Public functions */
961
962u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
963{
964 return __raw_readl(oh->_rt_va + reg_offs);
965}
966
967void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
968{
969 __raw_writel(v, oh->_rt_va + reg_offs);
970}
971
972/**
973 * omap_hwmod_register - register a struct omap_hwmod
974 * @oh: struct omap_hwmod *
975 *
976 * Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod already
977 * has been registered by the same name; -EINVAL if the omap_hwmod is in the
978 * wrong state, or 0 on success.
979 *
980 * XXX The data should be copied into bootmem, so the original data
981 * should be marked __initdata and freed after init. This would allow
982 * unneeded omap_hwmods to be freed on multi-OMAP configurations. Note
983 * that the copy process would be relatively complex due to the large number
984 * of substructures.
985 */
986int omap_hwmod_register(struct omap_hwmod *oh)
987{
988 int ret, ms_id;
989
990 if (!oh || (oh->_state != _HWMOD_STATE_UNKNOWN))
991 return -EINVAL;
992
993 mutex_lock(&omap_hwmod_mutex);
994
995 pr_debug("omap_hwmod: %s: registering\n", oh->name);
996
997 if (_lookup(oh->name)) {
998 ret = -EEXIST;
999 goto ohr_unlock;
1000 }
1001
1002 ms_id = _find_mpu_port_index(oh);
1003 if (!IS_ERR_VALUE(ms_id)) {
1004 oh->_mpu_port_index = ms_id;
1005 oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
1006 } else {
1007 oh->_int_flags |= _HWMOD_NO_MPU_PORT;
1008 }
1009
1010 list_add_tail(&oh->node, &omap_hwmod_list);
1011
1012 oh->_state = _HWMOD_STATE_REGISTERED;
1013
1014 ret = 0;
1015
1016ohr_unlock:
1017 mutex_unlock(&omap_hwmod_mutex);
1018 return ret;
1019}
1020
1021/**
1022 * omap_hwmod_lookup - look up a registered omap_hwmod by name
1023 * @name: name of the omap_hwmod to look up
1024 *
1025 * Given a @name of an omap_hwmod, return a pointer to the registered
1026 * struct omap_hwmod *, or NULL upon error.
1027 */
1028struct omap_hwmod *omap_hwmod_lookup(const char *name)
1029{
1030 struct omap_hwmod *oh;
1031
1032 if (!name)
1033 return NULL;
1034
1035 mutex_lock(&omap_hwmod_mutex);
1036 oh = _lookup(name);
1037 mutex_unlock(&omap_hwmod_mutex);
1038
1039 return oh;
1040}
1041
1042/**
1043 * omap_hwmod_for_each - call function for each registered omap_hwmod
1044 * @fn: pointer to a callback function
1045 *
1046 * Call @fn for each registered omap_hwmod, passing @data to each
1047 * function. @fn must return 0 for success or any other value for
1048 * failure. If @fn returns non-zero, the iteration across omap_hwmods
1049 * will stop and the non-zero return value will be passed to the
1050 * caller of omap_hwmod_for_each(). @fn is called with
1051 * omap_hwmod_for_each() held.
1052 */
1053int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
1054{
1055 struct omap_hwmod *temp_oh;
1056 int ret;
1057
1058 if (!fn)
1059 return -EINVAL;
1060
1061 mutex_lock(&omap_hwmod_mutex);
1062 list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
1063 ret = (*fn)(temp_oh);
1064 if (ret)
1065 break;
1066 }
1067 mutex_unlock(&omap_hwmod_mutex);
1068
1069 return ret;
1070}
1071
1072
1073/**
1074 * omap_hwmod_init - init omap_hwmod code and register hwmods
1075 * @ohs: pointer to an array of omap_hwmods to register
1076 *
1077 * Intended to be called early in boot before the clock framework is
1078 * initialized. If @ohs is not null, will register all omap_hwmods
1079 * listed in @ohs that are valid for this chip. Returns -EINVAL if
1080 * omap_hwmod_init() has already been called or 0 otherwise.
1081 */
1082int omap_hwmod_init(struct omap_hwmod **ohs)
1083{
1084 struct omap_hwmod *oh;
1085 int r;
1086
1087 if (inited)
1088 return -EINVAL;
1089
1090 inited = 1;
1091
1092 if (!ohs)
1093 return 0;
1094
1095 oh = *ohs;
1096 while (oh) {
1097 if (omap_chip_is(oh->omap_chip)) {
1098 r = omap_hwmod_register(oh);
1099 WARN(r, "omap_hwmod: %s: omap_hwmod_register returned "
1100 "%d\n", oh->name, r);
1101 }
1102 oh = *++ohs;
1103 }
1104
1105 return 0;
1106}
1107
1108/**
1109 * omap_hwmod_late_init - do some post-clock framework initialization
1110 *
1111 * Must be called after omap2_clk_init(). Resolves the struct clk names
1112 * to struct clk pointers for each registered omap_hwmod. Also calls
1113 * _setup() on each hwmod. Returns 0.
1114 */
1115int omap_hwmod_late_init(void)
1116{
1117 int r;
1118
1119 /* XXX check return value */
1120 r = omap_hwmod_for_each(_init_clocks);
1121 WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
1122
1123 mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
1124 WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
1125 MPU_INITIATOR_NAME);
1126
1127 omap_hwmod_for_each(_setup);
1128
1129 return 0;
1130}
1131
1132/**
1133 * omap_hwmod_unregister - unregister an omap_hwmod
1134 * @oh: struct omap_hwmod *
1135 *
1136 * Unregisters a previously-registered omap_hwmod @oh. There's probably
1137 * no use case for this, so it is likely to be removed in a later version.
1138 *
1139 * XXX Free all of the bootmem-allocated structures here when that is
1140 * implemented. Make it clear that core code is the only code that is
1141 * expected to unregister modules.
1142 */
1143int omap_hwmod_unregister(struct omap_hwmod *oh)
1144{
1145 if (!oh)
1146 return -EINVAL;
1147
1148 pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
1149
1150 mutex_lock(&omap_hwmod_mutex);
1151 list_del(&oh->node);
1152 mutex_unlock(&omap_hwmod_mutex);
1153
1154 return 0;
1155}
1156
1157/**
1158 * omap_hwmod_enable - enable an omap_hwmod
1159 * @oh: struct omap_hwmod *
1160 *
1161 * Enable an omap_hwomd @oh. Intended to be called by omap_device_enable().
1162 * Returns -EINVAL on error or passes along the return value from _enable().
1163 */
1164int omap_hwmod_enable(struct omap_hwmod *oh)
1165{
1166 int r;
1167
1168 if (!oh)
1169 return -EINVAL;
1170
1171 mutex_lock(&omap_hwmod_mutex);
1172 r = _enable(oh);
1173 mutex_unlock(&omap_hwmod_mutex);
1174
1175 return r;
1176}
1177
1178/**
1179 * omap_hwmod_idle - idle an omap_hwmod
1180 * @oh: struct omap_hwmod *
1181 *
1182 * Idle an omap_hwomd @oh. Intended to be called by omap_device_idle().
1183 * Returns -EINVAL on error or passes along the return value from _idle().
1184 */
1185int omap_hwmod_idle(struct omap_hwmod *oh)
1186{
1187 if (!oh)
1188 return -EINVAL;
1189
1190 mutex_lock(&omap_hwmod_mutex);
1191 _idle(oh);
1192 mutex_unlock(&omap_hwmod_mutex);
1193
1194 return 0;
1195}
1196
1197/**
1198 * omap_hwmod_shutdown - shutdown an omap_hwmod
1199 * @oh: struct omap_hwmod *
1200 *
1201 * Shutdown an omap_hwomd @oh. Intended to be called by
1202 * omap_device_shutdown(). Returns -EINVAL on error or passes along
1203 * the return value from _shutdown().
1204 */
1205int omap_hwmod_shutdown(struct omap_hwmod *oh)
1206{
1207 if (!oh)
1208 return -EINVAL;
1209
1210 mutex_lock(&omap_hwmod_mutex);
1211 _shutdown(oh);
1212 mutex_unlock(&omap_hwmod_mutex);
1213
1214 return 0;
1215}
1216
1217/**
1218 * omap_hwmod_enable_clocks - enable main_clk, all interface clocks
1219 * @oh: struct omap_hwmod *oh
1220 *
1221 * Intended to be called by the omap_device code.
1222 */
1223int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
1224{
1225 mutex_lock(&omap_hwmod_mutex);
1226 _enable_clocks(oh);
1227 mutex_unlock(&omap_hwmod_mutex);
1228
1229 return 0;
1230}
1231
1232/**
1233 * omap_hwmod_disable_clocks - disable main_clk, all interface clocks
1234 * @oh: struct omap_hwmod *oh
1235 *
1236 * Intended to be called by the omap_device code.
1237 */
1238int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
1239{
1240 mutex_lock(&omap_hwmod_mutex);
1241 _disable_clocks(oh);
1242 mutex_unlock(&omap_hwmod_mutex);
1243
1244 return 0;
1245}
1246
1247/**
1248 * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete
1249 * @oh: struct omap_hwmod *oh
1250 *
1251 * Intended to be called by drivers and core code when all posted
1252 * writes to a device must complete before continuing further
1253 * execution (for example, after clearing some device IRQSTATUS
1254 * register bits)
1255 *
1256 * XXX what about targets with multiple OCP threads?
1257 */
1258void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
1259{
1260 BUG_ON(!oh);
1261
1262 if (!oh->sysconfig || !oh->sysconfig->sysc_flags) {
1263 WARN(1, "omap_device: %s: OCP barrier impossible due to "
1264 "device configuration\n", oh->name);
1265 return;
1266 }
1267
1268 /*
1269 * Forces posted writes to complete on the OCP thread handling
1270 * register writes
1271 */
1272 omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
1273}
1274
1275/**
1276 * omap_hwmod_reset - reset the hwmod
1277 * @oh: struct omap_hwmod *
1278 *
1279 * Under some conditions, a driver may wish to reset the entire device.
1280 * Called from omap_device code. Returns -EINVAL on error or passes along
1281 * the return value from _reset()/_enable().
1282 */
1283int omap_hwmod_reset(struct omap_hwmod *oh)
1284{
1285 int r;
1286
1287 if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED))
1288 return -EINVAL;
1289
1290 mutex_lock(&omap_hwmod_mutex);
1291 r = _reset(oh);
1292 if (!r)
1293 r = _enable(oh);
1294 mutex_unlock(&omap_hwmod_mutex);
1295
1296 return r;
1297}
1298
1299/**
1300 * omap_hwmod_count_resources - count number of struct resources needed by hwmod
1301 * @oh: struct omap_hwmod *
1302 * @res: pointer to the first element of an array of struct resource to fill
1303 *
1304 * Count the number of struct resource array elements necessary to
1305 * contain omap_hwmod @oh resources. Intended to be called by code
1306 * that registers omap_devices. Intended to be used to determine the
1307 * size of a dynamically-allocated struct resource array, before
1308 * calling omap_hwmod_fill_resources(). Returns the number of struct
1309 * resource array elements needed.
1310 *
1311 * XXX This code is not optimized. It could attempt to merge adjacent
1312 * resource IDs.
1313 *
1314 */
1315int omap_hwmod_count_resources(struct omap_hwmod *oh)
1316{
1317 int ret, i;
1318
1319 ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt;
1320
1321 for (i = 0; i < oh->slaves_cnt; i++)
1322 ret += (*oh->slaves + i)->addr_cnt;
1323
1324 return ret;
1325}
1326
1327/**
1328 * omap_hwmod_fill_resources - fill struct resource array with hwmod data
1329 * @oh: struct omap_hwmod *
1330 * @res: pointer to the first element of an array of struct resource to fill
1331 *
1332 * Fill the struct resource array @res with resource data from the
1333 * omap_hwmod @oh. Intended to be called by code that registers
1334 * omap_devices. See also omap_hwmod_count_resources(). Returns the
1335 * number of array elements filled.
1336 */
1337int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
1338{
1339 int i, j;
1340 int r = 0;
1341
1342 /* For each IRQ, DMA, memory area, fill in array.*/
1343
1344 for (i = 0; i < oh->mpu_irqs_cnt; i++) {
1345 (res + r)->start = *(oh->mpu_irqs + i);
1346 (res + r)->end = *(oh->mpu_irqs + i);
1347 (res + r)->flags = IORESOURCE_IRQ;
1348 r++;
1349 }
1350
1351 for (i = 0; i < oh->sdma_chs_cnt; i++) {
1352 (res + r)->name = (oh->sdma_chs + i)->name;
1353 (res + r)->start = (oh->sdma_chs + i)->dma_ch;
1354 (res + r)->end = (oh->sdma_chs + i)->dma_ch;
1355 (res + r)->flags = IORESOURCE_DMA;
1356 r++;
1357 }
1358
1359 for (i = 0; i < oh->slaves_cnt; i++) {
1360 struct omap_hwmod_ocp_if *os;
1361
1362 os = *oh->slaves + i;
1363
1364 for (j = 0; j < os->addr_cnt; j++) {
1365 (res + r)->start = (os->addr + j)->pa_start;
1366 (res + r)->end = (os->addr + j)->pa_end;
1367 (res + r)->flags = IORESOURCE_MEM;
1368 r++;
1369 }
1370 }
1371
1372 return r;
1373}
1374
1375/**
1376 * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain
1377 * @oh: struct omap_hwmod *
1378 *
1379 * Return the powerdomain pointer associated with the OMAP module
1380 * @oh's main clock. If @oh does not have a main clk, return the
1381 * powerdomain associated with the interface clock associated with the
1382 * module's MPU port. (XXX Perhaps this should use the SDMA port
1383 * instead?) Returns NULL on error, or a struct powerdomain * on
1384 * success.
1385 */
1386struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
1387{
1388 struct clk *c;
1389
1390 if (!oh)
1391 return NULL;
1392
1393 if (oh->_clk) {
1394 c = oh->_clk;
1395 } else {
1396 if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
1397 return NULL;
1398 c = oh->slaves[oh->_mpu_port_index]->_clk;
1399 }
1400
1401 return c->clkdm->pwrdm.ptr;
1402
1403}
1404
1405/**
1406 * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
1407 * @oh: struct omap_hwmod *
1408 * @init_oh: struct omap_hwmod * (initiator)
1409 *
1410 * Add a sleep dependency between the initiator @init_oh and @oh.
1411 * Intended to be called by DSP/Bridge code via platform_data for the
1412 * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
1413 * code needs to add/del initiator dependencies dynamically
1414 * before/after accessing a device. Returns the return value from
1415 * _add_initiator_dep().
1416 *
1417 * XXX Keep a usecount in the clockdomain code
1418 */
1419int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
1420 struct omap_hwmod *init_oh)
1421{
1422 return _add_initiator_dep(oh, init_oh);
1423}
1424
1425/*
1426 * XXX what about functions for drivers to save/restore ocp_sysconfig
1427 * for context save/restore operations?
1428 */
1429
1430/**
1431 * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh
1432 * @oh: struct omap_hwmod *
1433 * @init_oh: struct omap_hwmod * (initiator)
1434 *
1435 * Remove a sleep dependency between the initiator @init_oh and @oh.
1436 * Intended to be called by DSP/Bridge code via platform_data for the
1437 * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
1438 * code needs to add/del initiator dependencies dynamically
1439 * before/after accessing a device. Returns the return value from
1440 * _del_initiator_dep().
1441 *
1442 * XXX Keep a usecount in the clockdomain code
1443 */
1444int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
1445 struct omap_hwmod *init_oh)
1446{
1447 return _del_initiator_dep(oh, init_oh);
1448}
1449
1450/**
1451 * omap_hwmod_set_clockact_none - set clockactivity test to BOTH
1452 * @oh: struct omap_hwmod *
1453 *
1454 * On some modules, this function can affect the wakeup latency vs.
1455 * power consumption balance. Intended to be called by the
1456 * omap_device layer. Passes along the return value from
1457 * _write_clockact_lock().
1458 */
1459int omap_hwmod_set_clockact_both(struct omap_hwmod *oh)
1460{
1461 return _write_clockact_lock(oh, CLOCKACT_TEST_BOTH);
1462}
1463
1464/**
1465 * omap_hwmod_set_clockact_none - set clockactivity test to MAIN
1466 * @oh: struct omap_hwmod *
1467 *
1468 * On some modules, this function can affect the wakeup latency vs.
1469 * power consumption balance. Intended to be called by the
1470 * omap_device layer. Passes along the return value from
1471 * _write_clockact_lock().
1472 */
1473int omap_hwmod_set_clockact_main(struct omap_hwmod *oh)
1474{
1475 return _write_clockact_lock(oh, CLOCKACT_TEST_MAIN);
1476}
1477
1478/**
1479 * omap_hwmod_set_clockact_none - set clockactivity test to ICLK
1480 * @oh: struct omap_hwmod *
1481 *
1482 * On some modules, this function can affect the wakeup latency vs.
1483 * power consumption balance. Intended to be called by the
1484 * omap_device layer. Passes along the return value from
1485 * _write_clockact_lock().
1486 */
1487int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh)
1488{
1489 return _write_clockact_lock(oh, CLOCKACT_TEST_ICLK);
1490}
1491
1492/**
1493 * omap_hwmod_set_clockact_none - set clockactivity test to NONE
1494 * @oh: struct omap_hwmod *
1495 *
1496 * On some modules, this function can affect the wakeup latency vs.
1497 * power consumption balance. Intended to be called by the
1498 * omap_device layer. Passes along the return value from
1499 * _write_clockact_lock().
1500 */
1501int omap_hwmod_set_clockact_none(struct omap_hwmod *oh)
1502{
1503 return _write_clockact_lock(oh, CLOCKACT_TEST_NONE);
1504}
1505
1506/**
1507 * omap_hwmod_enable_wakeup - allow device to wake up the system
1508 * @oh: struct omap_hwmod *
1509 *
1510 * Sets the module OCP socket ENAWAKEUP bit to allow the module to
1511 * send wakeups to the PRCM. Eventually this should sets PRCM wakeup
1512 * registers to cause the PRCM to receive wakeup events from the
1513 * module. Does not set any wakeup routing registers beyond this
1514 * point - if the module is to wake up any other module or subsystem,
1515 * that must be set separately. Called by omap_device code. Returns
1516 * -EINVAL on error or 0 upon success.
1517 */
1518int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
1519{
1520 if (!oh->sysconfig ||
1521 !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
1522 return -EINVAL;
1523
1524 mutex_lock(&omap_hwmod_mutex);
1525 _enable_wakeup(oh);
1526 mutex_unlock(&omap_hwmod_mutex);
1527
1528 return 0;
1529}
1530
1531/**
1532 * omap_hwmod_disable_wakeup - prevent device from waking the system
1533 * @oh: struct omap_hwmod *
1534 *
1535 * Clears the module OCP socket ENAWAKEUP bit to prevent the module
1536 * from sending wakeups to the PRCM. Eventually this should clear
1537 * PRCM wakeup registers to cause the PRCM to ignore wakeup events
1538 * from the module. Does not set any wakeup routing registers beyond
1539 * this point - if the module is to wake up any other module or
1540 * subsystem, that must be set separately. Called by omap_device
1541 * code. Returns -EINVAL on error or 0 upon success.
1542 */
1543int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
1544{
1545 if (!oh->sysconfig ||
1546 !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
1547 return -EINVAL;
1548
1549 mutex_lock(&omap_hwmod_mutex);
1550 _disable_wakeup(oh);
1551 mutex_unlock(&omap_hwmod_mutex);
1552
1553 return 0;
1554}
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420.h b/arch/arm/mach-omap2/omap_hwmod_2420.h
new file mode 100644
index 000000000000..767e4965ac4e
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2420.h
@@ -0,0 +1,141 @@
1/*
2 * omap_hwmod_2420.h - hardware modules present on the OMAP2420 chips
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * XXX handle crossbar/shared link difference for L3?
12 *
13 */
14#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
15#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
16
17#ifdef CONFIG_ARCH_OMAP2420
18
19#include <mach/omap_hwmod.h>
20#include <mach/irqs.h>
21#include <mach/cpu.h>
22#include <mach/dma.h>
23
24#include "prm-regbits-24xx.h"
25
26static struct omap_hwmod omap2420_mpu_hwmod;
27static struct omap_hwmod omap2420_l3_hwmod;
28static struct omap_hwmod omap2420_l4_core_hwmod;
29
30/* L3 -> L4_CORE interface */
31static struct omap_hwmod_ocp_if omap2420_l3__l4_core = {
32 .master = &omap2420_l3_hwmod,
33 .slave = &omap2420_l4_core_hwmod,
34 .user = OCP_USER_MPU | OCP_USER_SDMA,
35};
36
37/* MPU -> L3 interface */
38static struct omap_hwmod_ocp_if omap2420_mpu__l3 = {
39 .master = &omap2420_mpu_hwmod,
40 .slave = &omap2420_l3_hwmod,
41 .user = OCP_USER_MPU,
42};
43
44/* Slave interfaces on the L3 interconnect */
45static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = {
46 &omap2420_mpu__l3,
47};
48
49/* Master interfaces on the L3 interconnect */
50static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
51 &omap2420_l3__l4_core,
52};
53
54/* L3 */
55static struct omap_hwmod omap2420_l3_hwmod = {
56 .name = "l3_hwmod",
57 .masters = omap2420_l3_masters,
58 .masters_cnt = ARRAY_SIZE(omap2420_l3_masters),
59 .slaves = omap2420_l3_slaves,
60 .slaves_cnt = ARRAY_SIZE(omap2420_l3_slaves),
61 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
62};
63
64static struct omap_hwmod omap2420_l4_wkup_hwmod;
65
66/* L4_CORE -> L4_WKUP interface */
67static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
68 .master = &omap2420_l4_core_hwmod,
69 .slave = &omap2420_l4_wkup_hwmod,
70 .user = OCP_USER_MPU | OCP_USER_SDMA,
71};
72
73/* Slave interfaces on the L4_CORE interconnect */
74static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
75 &omap2420_l3__l4_core,
76};
77
78/* Master interfaces on the L4_CORE interconnect */
79static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
80 &omap2420_l4_core__l4_wkup,
81};
82
83/* L4 CORE */
84static struct omap_hwmod omap2420_l4_core_hwmod = {
85 .name = "l4_core_hwmod",
86 .masters = omap2420_l4_core_masters,
87 .masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
88 .slaves = omap2420_l4_core_slaves,
89 .slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves),
90 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
91};
92
93/* Slave interfaces on the L4_WKUP interconnect */
94static struct omap_hwmod_ocp_if *omap2420_l4_wkup_slaves[] = {
95 &omap2420_l4_core__l4_wkup,
96};
97
98/* Master interfaces on the L4_WKUP interconnect */
99static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
100};
101
102/* L4 WKUP */
103static struct omap_hwmod omap2420_l4_wkup_hwmod = {
104 .name = "l4_wkup_hwmod",
105 .masters = omap2420_l4_wkup_masters,
106 .masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
107 .slaves = omap2420_l4_wkup_slaves,
108 .slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves),
109 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
110};
111
112/* Master interfaces on the MPU device */
113static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
114 &omap2420_mpu__l3,
115};
116
117/* MPU */
118static struct omap_hwmod omap2420_mpu_hwmod = {
119 .name = "mpu_hwmod",
120 .clkdev_dev_id = NULL,
121 .clkdev_con_id = "mpu_ck",
122 .masters = omap2420_mpu_masters,
123 .masters_cnt = ARRAY_SIZE(omap2420_mpu_masters),
124 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
125};
126
127static __initdata struct omap_hwmod *omap2420_hwmods[] = {
128 &omap2420_l3_hwmod,
129 &omap2420_l4_core_hwmod,
130 &omap2420_l4_wkup_hwmod,
131 &omap2420_mpu_hwmod,
132 NULL,
133};
134
135#else
136# define omap2420_hwmods 0
137#endif
138
139#endif
140
141
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430.h b/arch/arm/mach-omap2/omap_hwmod_2430.h
new file mode 100644
index 000000000000..a412be6420ec
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2430.h
@@ -0,0 +1,143 @@
1/*
2 * omap_hwmod_2430.h - hardware modules present on the OMAP2430 chips
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * XXX handle crossbar/shared link difference for L3?
12 *
13 */
14#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
15#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
16
17#ifdef CONFIG_ARCH_OMAP2430
18
19#include <mach/omap_hwmod.h>
20#include <mach/irqs.h>
21#include <mach/cpu.h>
22#include <mach/dma.h>
23
24#include "prm-regbits-24xx.h"
25
26static struct omap_hwmod omap2430_mpu_hwmod;
27static struct omap_hwmod omap2430_l3_hwmod;
28static struct omap_hwmod omap2430_l4_core_hwmod;
29
30/* L3 -> L4_CORE interface */
31static struct omap_hwmod_ocp_if omap2430_l3__l4_core = {
32 .master = &omap2430_l3_hwmod,
33 .slave = &omap2430_l4_core_hwmod,
34 .user = OCP_USER_MPU | OCP_USER_SDMA,
35};
36
37/* MPU -> L3 interface */
38static struct omap_hwmod_ocp_if omap2430_mpu__l3 = {
39 .master = &omap2430_mpu_hwmod,
40 .slave = &omap2430_l3_hwmod,
41 .user = OCP_USER_MPU,
42};
43
44/* Slave interfaces on the L3 interconnect */
45static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = {
46 &omap2430_mpu__l3,
47};
48
49/* Master interfaces on the L3 interconnect */
50static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
51 &omap2430_l3__l4_core,
52};
53
54/* L3 */
55static struct omap_hwmod omap2430_l3_hwmod = {
56 .name = "l3_hwmod",
57 .masters = omap2430_l3_masters,
58 .masters_cnt = ARRAY_SIZE(omap2430_l3_masters),
59 .slaves = omap2430_l3_slaves,
60 .slaves_cnt = ARRAY_SIZE(omap2430_l3_slaves),
61 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
62};
63
64static struct omap_hwmod omap2430_l4_wkup_hwmod;
65static struct omap_hwmod omap2430_mmc1_hwmod;
66static struct omap_hwmod omap2430_mmc2_hwmod;
67
68/* L4_CORE -> L4_WKUP interface */
69static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
70 .master = &omap2430_l4_core_hwmod,
71 .slave = &omap2430_l4_wkup_hwmod,
72 .user = OCP_USER_MPU | OCP_USER_SDMA,
73};
74
75/* Slave interfaces on the L4_CORE interconnect */
76static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
77 &omap2430_l3__l4_core,
78};
79
80/* Master interfaces on the L4_CORE interconnect */
81static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
82 &omap2430_l4_core__l4_wkup,
83};
84
85/* L4 CORE */
86static struct omap_hwmod omap2430_l4_core_hwmod = {
87 .name = "l4_core_hwmod",
88 .masters = omap2430_l4_core_masters,
89 .masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
90 .slaves = omap2430_l4_core_slaves,
91 .slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves),
92 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
93};
94
95/* Slave interfaces on the L4_WKUP interconnect */
96static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = {
97 &omap2430_l4_core__l4_wkup,
98};
99
100/* Master interfaces on the L4_WKUP interconnect */
101static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
102};
103
104/* L4 WKUP */
105static struct omap_hwmod omap2430_l4_wkup_hwmod = {
106 .name = "l4_wkup_hwmod",
107 .masters = omap2430_l4_wkup_masters,
108 .masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
109 .slaves = omap2430_l4_wkup_slaves,
110 .slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves),
111 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
112};
113
114/* Master interfaces on the MPU device */
115static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
116 &omap2430_mpu__l3,
117};
118
119/* MPU */
120static struct omap_hwmod omap2430_mpu_hwmod = {
121 .name = "mpu_hwmod",
122 .clkdev_dev_id = NULL,
123 .clkdev_con_id = "mpu_ck",
124 .masters = omap2430_mpu_masters,
125 .masters_cnt = ARRAY_SIZE(omap2430_mpu_masters),
126 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
127};
128
129static __initdata struct omap_hwmod *omap2430_hwmods[] = {
130 &omap2430_l3_hwmod,
131 &omap2430_l4_core_hwmod,
132 &omap2430_l4_wkup_hwmod,
133 &omap2430_mpu_hwmod,
134 NULL,
135};
136
137#else
138# define omap2430_hwmods 0
139#endif
140
141#endif
142
143
diff --git a/arch/arm/mach-omap2/omap_hwmod_34xx.h b/arch/arm/mach-omap2/omap_hwmod_34xx.h
new file mode 100644
index 000000000000..1e069f831575
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_34xx.h
@@ -0,0 +1,168 @@
1/*
2 * omap_hwmod_34xx.h - hardware modules present on the OMAP34xx chips
3 *
4 * Copyright (C) 2009 Nokia Corporation
5 * Paul Walmsley
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
13#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
14
15#ifdef CONFIG_ARCH_OMAP34XX
16
17#include <mach/omap_hwmod.h>
18#include <mach/irqs.h>
19#include <mach/cpu.h>
20#include <mach/dma.h>
21
22#include "prm-regbits-34xx.h"
23
24static struct omap_hwmod omap34xx_mpu_hwmod;
25static struct omap_hwmod omap34xx_l3_hwmod;
26static struct omap_hwmod omap34xx_l4_core_hwmod;
27static struct omap_hwmod omap34xx_l4_per_hwmod;
28
29/* L3 -> L4_CORE interface */
30static struct omap_hwmod_ocp_if omap34xx_l3__l4_core = {
31 .master = &omap34xx_l3_hwmod,
32 .slave = &omap34xx_l4_core_hwmod,
33 .user = OCP_USER_MPU | OCP_USER_SDMA,
34};
35
36/* L3 -> L4_PER interface */
37static struct omap_hwmod_ocp_if omap34xx_l3__l4_per = {
38 .master = &omap34xx_l3_hwmod,
39 .slave = &omap34xx_l4_per_hwmod,
40 .user = OCP_USER_MPU | OCP_USER_SDMA,
41};
42
43/* MPU -> L3 interface */
44static struct omap_hwmod_ocp_if omap34xx_mpu__l3 = {
45 .master = &omap34xx_mpu_hwmod,
46 .slave = &omap34xx_l3_hwmod,
47 .user = OCP_USER_MPU,
48};
49
50/* Slave interfaces on the L3 interconnect */
51static struct omap_hwmod_ocp_if *omap34xx_l3_slaves[] = {
52 &omap34xx_mpu__l3,
53};
54
55/* Master interfaces on the L3 interconnect */
56static struct omap_hwmod_ocp_if *omap34xx_l3_masters[] = {
57 &omap34xx_l3__l4_core,
58 &omap34xx_l3__l4_per,
59};
60
61/* L3 */
62static struct omap_hwmod omap34xx_l3_hwmod = {
63 .name = "l3_hwmod",
64 .masters = omap34xx_l3_masters,
65 .masters_cnt = ARRAY_SIZE(omap34xx_l3_masters),
66 .slaves = omap34xx_l3_slaves,
67 .slaves_cnt = ARRAY_SIZE(omap34xx_l3_slaves),
68 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
69};
70
71static struct omap_hwmod omap34xx_l4_wkup_hwmod;
72
73/* L4_CORE -> L4_WKUP interface */
74static struct omap_hwmod_ocp_if omap34xx_l4_core__l4_wkup = {
75 .master = &omap34xx_l4_core_hwmod,
76 .slave = &omap34xx_l4_wkup_hwmod,
77 .user = OCP_USER_MPU | OCP_USER_SDMA,
78};
79
80/* Slave interfaces on the L4_CORE interconnect */
81static struct omap_hwmod_ocp_if *omap34xx_l4_core_slaves[] = {
82 &omap34xx_l3__l4_core,
83};
84
85/* Master interfaces on the L4_CORE interconnect */
86static struct omap_hwmod_ocp_if *omap34xx_l4_core_masters[] = {
87 &omap34xx_l4_core__l4_wkup,
88};
89
90/* L4 CORE */
91static struct omap_hwmod omap34xx_l4_core_hwmod = {
92 .name = "l4_core_hwmod",
93 .masters = omap34xx_l4_core_masters,
94 .masters_cnt = ARRAY_SIZE(omap34xx_l4_core_masters),
95 .slaves = omap34xx_l4_core_slaves,
96 .slaves_cnt = ARRAY_SIZE(omap34xx_l4_core_slaves),
97 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
98};
99
100/* Slave interfaces on the L4_PER interconnect */
101static struct omap_hwmod_ocp_if *omap34xx_l4_per_slaves[] = {
102 &omap34xx_l3__l4_per,
103};
104
105/* Master interfaces on the L4_PER interconnect */
106static struct omap_hwmod_ocp_if *omap34xx_l4_per_masters[] = {
107};
108
109/* L4 PER */
110static struct omap_hwmod omap34xx_l4_per_hwmod = {
111 .name = "l4_per_hwmod",
112 .masters = omap34xx_l4_per_masters,
113 .masters_cnt = ARRAY_SIZE(omap34xx_l4_per_masters),
114 .slaves = omap34xx_l4_per_slaves,
115 .slaves_cnt = ARRAY_SIZE(omap34xx_l4_per_slaves),
116 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
117};
118
119/* Slave interfaces on the L4_WKUP interconnect */
120static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_slaves[] = {
121 &omap34xx_l4_core__l4_wkup,
122};
123
124/* Master interfaces on the L4_WKUP interconnect */
125static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_masters[] = {
126};
127
128/* L4 WKUP */
129static struct omap_hwmod omap34xx_l4_wkup_hwmod = {
130 .name = "l4_wkup_hwmod",
131 .masters = omap34xx_l4_wkup_masters,
132 .masters_cnt = ARRAY_SIZE(omap34xx_l4_wkup_masters),
133 .slaves = omap34xx_l4_wkup_slaves,
134 .slaves_cnt = ARRAY_SIZE(omap34xx_l4_wkup_slaves),
135 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
136};
137
138/* Master interfaces on the MPU device */
139static struct omap_hwmod_ocp_if *omap34xx_mpu_masters[] = {
140 &omap34xx_mpu__l3,
141};
142
143/* MPU */
144static struct omap_hwmod omap34xx_mpu_hwmod = {
145 .name = "mpu_hwmod",
146 .clkdev_dev_id = NULL,
147 .clkdev_con_id = "arm_fck",
148 .masters = omap34xx_mpu_masters,
149 .masters_cnt = ARRAY_SIZE(omap34xx_mpu_masters),
150 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
151};
152
153static __initdata struct omap_hwmod *omap34xx_hwmods[] = {
154 &omap34xx_l3_hwmod,
155 &omap34xx_l4_core_hwmod,
156 &omap34xx_l4_per_hwmod,
157 &omap34xx_l4_wkup_hwmod,
158 &omap34xx_mpu_hwmod,
159 NULL,
160};
161
162#else
163# define omap34xx_hwmods 0
164#endif
165
166#endif
167
168
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 5a6cef3e42bf..2594cbff3947 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -90,7 +90,7 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
90 if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip)) 90 if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
91 return ERR_PTR(-EINVAL); 91 return ERR_PTR(-EINVAL);
92 92
93 for (pd = deps; pd; pd++) { 93 for (pd = deps; pd->pwrdm_name; pd++) {
94 94
95 if (!omap_chip_is(pd->omap_chip)) 95 if (!omap_chip_is(pd->omap_chip))
96 continue; 96 continue;
@@ -103,7 +103,7 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
103 103
104 } 104 }
105 105
106 if (!pd) 106 if (!pd->pwrdm_name)
107 return ERR_PTR(-ENOENT); 107 return ERR_PTR(-ENOENT);
108 108
109 return pd->pwrdm; 109 return pd->pwrdm;
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 0f508109adcc..021130d830b5 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -578,7 +578,7 @@ static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = {
578#endif 578#endif
579}; 579};
580 580
581void __init omap_serial_init(void) 581void __init omap_serial_early_init(void)
582{ 582{
583 int i; 583 int i;
584 char name[16]; 584 char name[16];
@@ -624,6 +624,18 @@ void __init omap_serial_init(void)
624 p->irq += 32; 624 p->irq += 32;
625 625
626 omap_uart_enable_clocks(uart); 626 omap_uart_enable_clocks(uart);
627 }
628}
629
630void __init omap_serial_init(void)
631{
632 int i;
633
634 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
635 struct omap_uart_state *uart = &omap_uart[i];
636 struct platform_device *pdev = &uart->pdev;
637 struct device *dev = &pdev->dev;
638
627 omap_uart_reset(uart); 639 omap_uart_reset(uart);
628 omap_uart_idle_init(uart); 640 omap_uart_idle_init(uart);
629 641