diff options
author | Tony Lindgren <tony@atomide.com> | 2009-09-03 13:17:39 -0400 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2009-09-03 13:17:39 -0400 |
commit | 1f685b36dbf27db55072fb738aac57aaf37d2c71 (patch) | |
tree | 43cdcd1288d3bfa042a7cd6a89d2bf40f9b0261e /arch/arm/mach-omap2 | |
parent | 5567fa1f543dde3c42f8e52bf4f7005135b24896 (diff) | |
parent | ca4caa4e1d45f9542fa54263974d0ef637157b4a (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')
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 |
6 | obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o | 6 | obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o |
7 | 7 | ||
8 | omap-2-3-common = irq.o sdrc.o | 8 | omap-2-3-common = irq.o sdrc.o omap_hwmod.o |
9 | prcm-common = prcm.o powerdomain.o | 9 | prcm-common = prcm.o powerdomain.o |
10 | clock-common = clock.o clockdomain.o | 10 | clock-common = clock.o clockdomain.o |
11 | 11 | ||
@@ -35,6 +35,11 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o | |||
35 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o | 35 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o |
36 | endif | 36 | endif |
37 | 37 | ||
38 | # PRCM | ||
39 | obj-$(CONFIG_ARCH_OMAP2) += cm.o | ||
40 | obj-$(CONFIG_ARCH_OMAP3) += cm.o | ||
41 | obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o | ||
42 | |||
38 | # Clock framework | 43 | # Clock framework |
39 | obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o | 44 | obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o |
40 | obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o | 45 | obj-$(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 | ||
142 | static struct omap_board_config_kernel sdp2430_config[] = { | ||
143 | {OMAP_TAG_LCD, &sdp2430_lcd_config}, | ||
144 | }; | ||
145 | |||
142 | static void __init omap_2430sdp_init_irq(void) | 146 | static 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 | ||
149 | static struct omap_board_config_kernel sdp2430_config[] = { | ||
150 | {OMAP_TAG_LCD, &sdp2430_lcd_config}, | ||
151 | }; | ||
152 | |||
153 | |||
154 | static struct twl4030_gpio_platform_data sdp2430_gpio_data = { | 155 | static 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 | ||
170 | static 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 | |||
177 | static struct omap_lcd_config sdp3430_lcd_config __initdata = { | 170 | static 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 | ||
178 | static 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 | |||
185 | static int sdp3430_batt_table[] = { | 187 | static int sdp3430_batt_table[] = { |
186 | /* 0 C*/ | 188 | /* 0 C*/ |
187 | 30800, 29500, 28300, 27100, | 189 | 30800, 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 | ||
251 | static 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 | |||
259 | static struct omap_usb_config apollon_usb_config __initdata = { | 251 | static 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 | ||
266 | static 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 | |||
274 | static void __init apollon_led_init(void) | 276 | static 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 | ||
34 | static struct omap_board_config_kernel generic_config[] = { | ||
35 | }; | ||
36 | |||
34 | static void __init omap_generic_init_irq(void) | 37 | static 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 | ||
40 | static struct omap_board_config_kernel generic_config[] = { | ||
41 | }; | ||
42 | |||
43 | static void __init omap_generic_init(void) | 45 | static 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 | ||
271 | static 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 | |||
279 | static struct omap_lcd_config h4_lcd_config __initdata = { | 271 | static 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 | ||
312 | static 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 | |||
320 | static struct at24_platform_data m24c01 = { | 322 | static 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 | ||
271 | static 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 | |||
279 | static struct platform_device ldp_lcd_device = { | 271 | static 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 | ||
284 | static 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 | |||
292 | static struct twl4030_usb_data ldp_usb_data = { | 294 | static 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 | ||
284 | static 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 | |||
295 | static struct gpio_led gpio_leds[] = { | 284 | static 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 | ||
341 | static 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 | |||
352 | static struct platform_device *omap3_beagle_devices[] __initdata = { | 354 | static 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 | ||
277 | static struct omap_board_config_kernel omap3_evm_config[] __initdata = { | ||
278 | { OMAP_TAG_LCD, &omap3_evm_lcd_config }, | ||
279 | }; | ||
280 | |||
277 | static void __init omap3_evm_init_irq(void) | 281 | static 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 | ||
285 | static struct omap_board_config_kernel omap3_evm_config[] __initdata = { | ||
286 | { OMAP_TAG_LCD, &omap3_evm_lcd_config }, | ||
287 | }; | ||
288 | |||
289 | static struct platform_device *omap3_evm_devices[] __initdata = { | 291 | static 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 | ||
308 | static 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 | |||
316 | static void __init omap3pandora_ads7846_init(void) | 308 | static 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 | ||
370 | static 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 | |||
378 | static struct platform_device *omap3pandora_devices[] __initdata = { | 380 | static 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 | ||
360 | static 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 | |||
368 | static struct platform_device overo_lcd_device = { | 360 | static 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 | ||
373 | static 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 | |||
381 | static struct platform_device *overo_devices[] __initdata = { | 383 | static 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 | ||
57 | static void __init rx51_init_irq(void) | 57 | static 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 | ||
66 | static void __init rx51_init(void) | 68 | static 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 | ||
93 | static 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 | |||
100 | static struct omap_board_config_kernel zoom2_config[] __initdata = { | 93 | static 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 | ||
208 | static 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 | |||
215 | static struct twl4030_gpio_platform_data zoom2_gpio_data = { | 217 | static 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); | |||
262 | static void __init omap_zoom2_init(void) | 264 | static 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 = { | |||
2268 | static struct clk wkup_32k_fck = { | 2252 | static 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 | |||
31 | static 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 | */ | ||
43 | int 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); | |||
98 | extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); | 98 | extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); |
99 | extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); | 99 | extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); |
100 | 100 | ||
101 | extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, | ||
102 | u8 idlest_shift); | ||
103 | extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs); | ||
104 | |||
101 | static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) | 105 | static 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 | */ | ||
51 | int 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) | |||
279 | void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0, | 285 | void __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 */ | ||
63 | static LIST_HEAD(omap_hwmod_list); | ||
64 | |||
65 | static DEFINE_MUTEX(omap_hwmod_mutex); | ||
66 | |||
67 | /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ | ||
68 | static struct omap_hwmod *mpu_oh; | ||
69 | |||
70 | /* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */ | ||
71 | static 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 | */ | ||
84 | static 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 | */ | ||
109 | static 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 | */ | ||
135 | static 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 | */ | ||
158 | static 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 | */ | ||
181 | static 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 | */ | ||
201 | static 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 | */ | ||
219 | static 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 | */ | ||
245 | static 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 | */ | ||
276 | static 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 | */ | ||
297 | static 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 | */ | ||
314 | static 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 | */ | ||
339 | static 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 | */ | ||
372 | static 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 | */ | ||
399 | static 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 | */ | ||
429 | static 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 | */ | ||
460 | static 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 | */ | ||
493 | static 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 | */ | ||
533 | static 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 | */ | ||
573 | static 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 | */ | ||
605 | static 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 | */ | ||
632 | static 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 | */ | ||
658 | static 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 | */ | ||
685 | static 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 | */ | ||
731 | static 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 | */ | ||
787 | static 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 | */ | ||
827 | static 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 | */ | ||
856 | static 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 | */ | ||
890 | static 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 | */ | ||
917 | static 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 | |||
962 | u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs) | ||
963 | { | ||
964 | return __raw_readl(oh->_rt_va + reg_offs); | ||
965 | } | ||
966 | |||
967 | void 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 | */ | ||
986 | int 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 | |||
1016 | ohr_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 | */ | ||
1028 | struct 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 | */ | ||
1053 | int 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 | */ | ||
1082 | int 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 | */ | ||
1115 | int 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 | */ | ||
1143 | int 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 | */ | ||
1164 | int 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 | */ | ||
1185 | int 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 | */ | ||
1205 | int 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 | */ | ||
1223 | int 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 | */ | ||
1238 | int 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 | */ | ||
1258 | void 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 | */ | ||
1283 | int 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 | */ | ||
1315 | int 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 | */ | ||
1337 | int 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 | */ | ||
1386 | struct 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 | */ | ||
1419 | int 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 | */ | ||
1444 | int 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 | */ | ||
1459 | int 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 | */ | ||
1473 | int 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 | */ | ||
1487 | int 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 | */ | ||
1501 | int 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 | */ | ||
1518 | int 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 | */ | ||
1543 | int 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 | |||
26 | static struct omap_hwmod omap2420_mpu_hwmod; | ||
27 | static struct omap_hwmod omap2420_l3_hwmod; | ||
28 | static struct omap_hwmod omap2420_l4_core_hwmod; | ||
29 | |||
30 | /* L3 -> L4_CORE interface */ | ||
31 | static 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 */ | ||
38 | static 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 */ | ||
45 | static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = { | ||
46 | &omap2420_mpu__l3, | ||
47 | }; | ||
48 | |||
49 | /* Master interfaces on the L3 interconnect */ | ||
50 | static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = { | ||
51 | &omap2420_l3__l4_core, | ||
52 | }; | ||
53 | |||
54 | /* L3 */ | ||
55 | static 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 | |||
64 | static struct omap_hwmod omap2420_l4_wkup_hwmod; | ||
65 | |||
66 | /* L4_CORE -> L4_WKUP interface */ | ||
67 | static 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 */ | ||
74 | static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = { | ||
75 | &omap2420_l3__l4_core, | ||
76 | }; | ||
77 | |||
78 | /* Master interfaces on the L4_CORE interconnect */ | ||
79 | static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = { | ||
80 | &omap2420_l4_core__l4_wkup, | ||
81 | }; | ||
82 | |||
83 | /* L4 CORE */ | ||
84 | static 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 */ | ||
94 | static 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 */ | ||
99 | static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = { | ||
100 | }; | ||
101 | |||
102 | /* L4 WKUP */ | ||
103 | static 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 */ | ||
113 | static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = { | ||
114 | &omap2420_mpu__l3, | ||
115 | }; | ||
116 | |||
117 | /* MPU */ | ||
118 | static 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 | |||
127 | static __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 | |||
26 | static struct omap_hwmod omap2430_mpu_hwmod; | ||
27 | static struct omap_hwmod omap2430_l3_hwmod; | ||
28 | static struct omap_hwmod omap2430_l4_core_hwmod; | ||
29 | |||
30 | /* L3 -> L4_CORE interface */ | ||
31 | static 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 */ | ||
38 | static 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 */ | ||
45 | static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = { | ||
46 | &omap2430_mpu__l3, | ||
47 | }; | ||
48 | |||
49 | /* Master interfaces on the L3 interconnect */ | ||
50 | static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = { | ||
51 | &omap2430_l3__l4_core, | ||
52 | }; | ||
53 | |||
54 | /* L3 */ | ||
55 | static 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 | |||
64 | static struct omap_hwmod omap2430_l4_wkup_hwmod; | ||
65 | static struct omap_hwmod omap2430_mmc1_hwmod; | ||
66 | static struct omap_hwmod omap2430_mmc2_hwmod; | ||
67 | |||
68 | /* L4_CORE -> L4_WKUP interface */ | ||
69 | static 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 */ | ||
76 | static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { | ||
77 | &omap2430_l3__l4_core, | ||
78 | }; | ||
79 | |||
80 | /* Master interfaces on the L4_CORE interconnect */ | ||
81 | static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = { | ||
82 | &omap2430_l4_core__l4_wkup, | ||
83 | }; | ||
84 | |||
85 | /* L4 CORE */ | ||
86 | static 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 */ | ||
96 | static 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 */ | ||
101 | static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = { | ||
102 | }; | ||
103 | |||
104 | /* L4 WKUP */ | ||
105 | static 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 */ | ||
115 | static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = { | ||
116 | &omap2430_mpu__l3, | ||
117 | }; | ||
118 | |||
119 | /* MPU */ | ||
120 | static 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 | |||
129 | static __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 | |||
24 | static struct omap_hwmod omap34xx_mpu_hwmod; | ||
25 | static struct omap_hwmod omap34xx_l3_hwmod; | ||
26 | static struct omap_hwmod omap34xx_l4_core_hwmod; | ||
27 | static struct omap_hwmod omap34xx_l4_per_hwmod; | ||
28 | |||
29 | /* L3 -> L4_CORE interface */ | ||
30 | static 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 */ | ||
37 | static 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 */ | ||
44 | static 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 */ | ||
51 | static struct omap_hwmod_ocp_if *omap34xx_l3_slaves[] = { | ||
52 | &omap34xx_mpu__l3, | ||
53 | }; | ||
54 | |||
55 | /* Master interfaces on the L3 interconnect */ | ||
56 | static struct omap_hwmod_ocp_if *omap34xx_l3_masters[] = { | ||
57 | &omap34xx_l3__l4_core, | ||
58 | &omap34xx_l3__l4_per, | ||
59 | }; | ||
60 | |||
61 | /* L3 */ | ||
62 | static 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 | |||
71 | static struct omap_hwmod omap34xx_l4_wkup_hwmod; | ||
72 | |||
73 | /* L4_CORE -> L4_WKUP interface */ | ||
74 | static 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 */ | ||
81 | static struct omap_hwmod_ocp_if *omap34xx_l4_core_slaves[] = { | ||
82 | &omap34xx_l3__l4_core, | ||
83 | }; | ||
84 | |||
85 | /* Master interfaces on the L4_CORE interconnect */ | ||
86 | static struct omap_hwmod_ocp_if *omap34xx_l4_core_masters[] = { | ||
87 | &omap34xx_l4_core__l4_wkup, | ||
88 | }; | ||
89 | |||
90 | /* L4 CORE */ | ||
91 | static 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 */ | ||
101 | static struct omap_hwmod_ocp_if *omap34xx_l4_per_slaves[] = { | ||
102 | &omap34xx_l3__l4_per, | ||
103 | }; | ||
104 | |||
105 | /* Master interfaces on the L4_PER interconnect */ | ||
106 | static struct omap_hwmod_ocp_if *omap34xx_l4_per_masters[] = { | ||
107 | }; | ||
108 | |||
109 | /* L4 PER */ | ||
110 | static 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 */ | ||
120 | static 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 */ | ||
125 | static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_masters[] = { | ||
126 | }; | ||
127 | |||
128 | /* L4 WKUP */ | ||
129 | static 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 */ | ||
139 | static struct omap_hwmod_ocp_if *omap34xx_mpu_masters[] = { | ||
140 | &omap34xx_mpu__l3, | ||
141 | }; | ||
142 | |||
143 | /* MPU */ | ||
144 | static 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 | |||
153 | static __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 | ||
581 | void __init omap_serial_init(void) | 581 | void __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 | |||
630 | void __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 | ||