diff options
author | Tony Lindgren <tony@atomide.com> | 2012-02-17 18:12:36 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2012-02-17 18:12:36 -0500 |
commit | 4d68c05ce11f4cdf6a6392f3a18dc6a985b4d0c4 (patch) | |
tree | 72e500b97c4bdcb9631209f3121f42b05ae30fea /arch/arm/mach-omap2 | |
parent | 40c0591f0a349ec074357e05c6ab1a3bc951807c (diff) | |
parent | 19bfb76ca32f8e4fa80746608ff4a77707f40520 (diff) |
Merge branch 'for_3.4/dt_base' of git://git.kernel.org/pub/scm/linux/kernel/git/bcousson/linux-omap-dt into dt
Diffstat (limited to 'arch/arm/mach-omap2')
89 files changed, 4666 insertions, 1457 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index bdd5b68fba80..72ce50ecf328 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -33,7 +33,6 @@ config ARCH_OMAP3 | |||
33 | default y | 33 | default y |
34 | select CPU_V7 | 34 | select CPU_V7 |
35 | select USB_ARCH_HAS_EHCI | 35 | select USB_ARCH_HAS_EHCI |
36 | select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4 | ||
37 | select ARCH_HAS_OPP | 36 | select ARCH_HAS_OPP |
38 | select PM_OPP if PM | 37 | select PM_OPP if PM |
39 | select ARM_CPU_SUSPEND if PM | 38 | select ARM_CPU_SUSPEND if PM |
@@ -43,8 +42,10 @@ config ARCH_OMAP4 | |||
43 | bool "TI OMAP4" | 42 | bool "TI OMAP4" |
44 | default y | 43 | default y |
45 | depends on ARCH_OMAP2PLUS | 44 | depends on ARCH_OMAP2PLUS |
45 | select CACHE_L2X0 | ||
46 | select CPU_V7 | 46 | select CPU_V7 |
47 | select ARM_GIC | 47 | select ARM_GIC |
48 | select HAVE_SMP | ||
48 | select LOCAL_TIMERS if SMP | 49 | select LOCAL_TIMERS if SMP |
49 | select PL310_ERRATA_588369 | 50 | select PL310_ERRATA_588369 |
50 | select PL310_ERRATA_727915 | 51 | select PL310_ERRATA_727915 |
@@ -76,8 +77,13 @@ config SOC_OMAP3430 | |||
76 | default y | 77 | default y |
77 | select ARCH_OMAP_OTG | 78 | select ARCH_OMAP_OTG |
78 | 79 | ||
79 | config SOC_OMAPTI816X | 80 | config SOC_OMAPTI81XX |
80 | bool "TI816X support" | 81 | bool "TI81XX support" |
82 | depends on ARCH_OMAP3 | ||
83 | default y | ||
84 | |||
85 | config SOC_OMAPAM33XX | ||
86 | bool "AM33XX support" | ||
81 | depends on ARCH_OMAP3 | 87 | depends on ARCH_OMAP3 |
82 | default y | 88 | default y |
83 | 89 | ||
@@ -206,13 +212,12 @@ config MACH_OMAP3_PANDORA | |||
206 | depends on ARCH_OMAP3 | 212 | depends on ARCH_OMAP3 |
207 | default y | 213 | default y |
208 | select OMAP_PACKAGE_CBB | 214 | select OMAP_PACKAGE_CBB |
209 | select REGULATOR_FIXED_VOLTAGE | 215 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
210 | 216 | ||
211 | config MACH_OMAP3_TOUCHBOOK | 217 | config MACH_OMAP3_TOUCHBOOK |
212 | bool "OMAP3 Touch Book" | 218 | bool "OMAP3 Touch Book" |
213 | depends on ARCH_OMAP3 | 219 | depends on ARCH_OMAP3 |
214 | default y | 220 | default y |
215 | select BACKLIGHT_CLASS_DEVICE | ||
216 | 221 | ||
217 | config MACH_OMAP_3430SDP | 222 | config MACH_OMAP_3430SDP |
218 | bool "OMAP 3430 SDP board" | 223 | bool "OMAP 3430 SDP board" |
@@ -258,7 +263,7 @@ config MACH_OMAP_ZOOM2 | |||
258 | select SERIAL_8250 | 263 | select SERIAL_8250 |
259 | select SERIAL_CORE_CONSOLE | 264 | select SERIAL_CORE_CONSOLE |
260 | select SERIAL_8250_CONSOLE | 265 | select SERIAL_8250_CONSOLE |
261 | select REGULATOR_FIXED_VOLTAGE | 266 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
262 | 267 | ||
263 | config MACH_OMAP_ZOOM3 | 268 | config MACH_OMAP_ZOOM3 |
264 | bool "OMAP3630 Zoom3 board" | 269 | bool "OMAP3630 Zoom3 board" |
@@ -268,7 +273,7 @@ config MACH_OMAP_ZOOM3 | |||
268 | select SERIAL_8250 | 273 | select SERIAL_8250 |
269 | select SERIAL_CORE_CONSOLE | 274 | select SERIAL_CORE_CONSOLE |
270 | select SERIAL_8250_CONSOLE | 275 | select SERIAL_8250_CONSOLE |
271 | select REGULATOR_FIXED_VOLTAGE | 276 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
272 | 277 | ||
273 | config MACH_CM_T35 | 278 | config MACH_CM_T35 |
274 | bool "CompuLab CM-T35/CM-T3730 modules" | 279 | bool "CompuLab CM-T35/CM-T3730 modules" |
@@ -313,7 +318,12 @@ config MACH_OMAP_3630SDP | |||
313 | 318 | ||
314 | config MACH_TI8168EVM | 319 | config MACH_TI8168EVM |
315 | bool "TI8168 Evaluation Module" | 320 | bool "TI8168 Evaluation Module" |
316 | depends on SOC_OMAPTI816X | 321 | depends on SOC_OMAPTI81XX |
322 | default y | ||
323 | |||
324 | config MACH_TI8148EVM | ||
325 | bool "TI8148 Evaluation Module" | ||
326 | depends on SOC_OMAPTI81XX | ||
317 | default y | 327 | default y |
318 | 328 | ||
319 | config MACH_OMAP_4430SDP | 329 | config MACH_OMAP_4430SDP |
@@ -322,7 +332,7 @@ config MACH_OMAP_4430SDP | |||
322 | depends on ARCH_OMAP4 | 332 | depends on ARCH_OMAP4 |
323 | select OMAP_PACKAGE_CBL | 333 | select OMAP_PACKAGE_CBL |
324 | select OMAP_PACKAGE_CBS | 334 | select OMAP_PACKAGE_CBS |
325 | select REGULATOR_FIXED_VOLTAGE | 335 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
326 | 336 | ||
327 | config MACH_OMAP4_PANDA | 337 | config MACH_OMAP4_PANDA |
328 | bool "OMAP4 Panda Board" | 338 | bool "OMAP4 Panda Board" |
@@ -330,7 +340,7 @@ config MACH_OMAP4_PANDA | |||
330 | depends on ARCH_OMAP4 | 340 | depends on ARCH_OMAP4 |
331 | select OMAP_PACKAGE_CBL | 341 | select OMAP_PACKAGE_CBL |
332 | select OMAP_PACKAGE_CBS | 342 | select OMAP_PACKAGE_CBS |
333 | select REGULATOR_FIXED_VOLTAGE | 343 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
334 | 344 | ||
335 | config OMAP3_EMU | 345 | config OMAP3_EMU |
336 | bool "OMAP3 debugging peripherals" | 346 | bool "OMAP3 debugging peripherals" |
@@ -352,6 +362,27 @@ config OMAP3_SDRC_AC_TIMING | |||
352 | wish to say no. Selecting yes without understanding what is | 362 | wish to say no. Selecting yes without understanding what is |
353 | going on could result in system crashes; | 363 | going on could result in system crashes; |
354 | 364 | ||
365 | config OMAP4_ERRATA_I688 | ||
366 | bool "OMAP4 errata: Async Bridge Corruption (BROKEN)" | ||
367 | depends on ARCH_OMAP4 && BROKEN | ||
368 | select ARCH_HAS_BARRIERS | ||
369 | help | ||
370 | If a data is stalled inside asynchronous bridge because of back | ||
371 | pressure, it may be accepted multiple times, creating pointer | ||
372 | misalignment that will corrupt next transfers on that data path | ||
373 | until next reset of the system (No recovery procedure once the | ||
374 | issue is hit, the path remains consistently broken). Async bridge | ||
375 | can be found on path between MPU to EMIF and MPU to L3 interconnect. | ||
376 | This situation can happen only when the idle is initiated by a | ||
377 | Master Request Disconnection (which is trigged by software when | ||
378 | executing WFI on CPU). | ||
379 | The work-around for this errata needs all the initiators connected | ||
380 | through async bridge must ensure that data path is properly drained | ||
381 | before issuing WFI. This condition will be met if one Strongly ordered | ||
382 | access is performed to the target right before executing the WFI. | ||
383 | In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained. | ||
384 | IO barrier ensure that there is no synchronisation loss on initiators | ||
385 | operating on both interconnect port simultaneously. | ||
355 | endmenu | 386 | endmenu |
356 | 387 | ||
357 | endif | 388 | endif |
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index b009f17dee56..fc9b238cbc19 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -11,10 +11,11 @@ hwmod-common = omap_hwmod.o \ | |||
11 | omap_hwmod_common_data.o | 11 | omap_hwmod_common_data.o |
12 | clock-common = clock.o clock_common_data.o \ | 12 | clock-common = clock.o clock_common_data.o \ |
13 | clkt_dpll.o clkt_clksel.o | 13 | clkt_dpll.o clkt_clksel.o |
14 | secure-common = omap-smc.o omap-secure.o | ||
14 | 15 | ||
15 | obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) | 16 | obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common) |
16 | obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) | 17 | obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) |
17 | obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) | 18 | obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common) |
18 | 19 | ||
19 | obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o | 20 | obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o |
20 | 21 | ||
@@ -24,11 +25,13 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o | |||
24 | obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o | 25 | obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o |
25 | obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o | 26 | obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o |
26 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o | 27 | obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o |
27 | obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o | 28 | obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \ |
29 | sleep44xx.o | ||
28 | 30 | ||
29 | plus_sec := $(call as-instr,.arch_extension sec,+sec) | 31 | plus_sec := $(call as-instr,.arch_extension sec,+sec) |
30 | AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) | 32 | AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) |
31 | AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec) | 33 | AFLAGS_omap-smc.o :=-Wa,-march=armv7-a$(plus_sec) |
34 | AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec) | ||
32 | 35 | ||
33 | # Functions loaded to SRAM | 36 | # Functions loaded to SRAM |
34 | obj-$(CONFIG_SOC_OMAP2420) += sram242x.o | 37 | obj-$(CONFIG_SOC_OMAP2420) += sram242x.o |
@@ -62,7 +65,8 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o | |||
62 | obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o | 65 | obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o |
63 | obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ | 66 | obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ |
64 | cpuidle34xx.o | 67 | cpuidle34xx.o |
65 | obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o | 68 | obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o \ |
69 | cpuidle44xx.o | ||
66 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o | 70 | obj-$(CONFIG_PM_DEBUG) += pm-debug.o |
67 | obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o | 71 | obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o |
68 | obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o | 72 | obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o |
@@ -77,6 +81,7 @@ endif | |||
77 | endif | 81 | endif |
78 | 82 | ||
79 | # PRCM | 83 | # PRCM |
84 | obj-y += prm_common.o | ||
80 | obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o | 85 | obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o |
81 | obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \ | 86 | obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \ |
82 | vc3xxx_data.o vp3xxx_data.o | 87 | vc3xxx_data.o vp3xxx_data.o |
@@ -86,7 +91,7 @@ obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \ | |||
86 | obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \ | 91 | obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \ |
87 | cm44xx.o prcm_mpu44xx.o \ | 92 | cm44xx.o prcm_mpu44xx.o \ |
88 | prminst44xx.o vc44xx_data.o \ | 93 | prminst44xx.o vc44xx_data.o \ |
89 | vp44xx_data.o | 94 | vp44xx_data.o prm44xx.o |
90 | 95 | ||
91 | # OMAP voltage domains | 96 | # OMAP voltage domains |
92 | voltagedomain-common := voltage.o vc.o vp.o | 97 | voltagedomain-common := voltage.o vc.o vp.o |
@@ -232,6 +237,7 @@ obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o | |||
232 | 237 | ||
233 | obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o | 238 | obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o |
234 | obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o | 239 | obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o |
240 | obj-$(CONFIG_MACH_TI8148EVM) += board-ti8168evm.o | ||
235 | 241 | ||
236 | # Platform specific device init code | 242 | # Platform specific device init code |
237 | 243 | ||
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c index d88143faca59..7370983f809f 100644 --- a/arch/arm/mach-omap2/board-2430sdp.c +++ b/arch/arm/mach-omap2/board-2430sdp.c | |||
@@ -304,4 +304,5 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board") | |||
304 | .handle_irq = omap2_intc_handle_irq, | 304 | .handle_irq = omap2_intc_handle_irq, |
305 | .init_machine = omap_2430sdp_init, | 305 | .init_machine = omap_2430sdp_init, |
306 | .timer = &omap2_timer, | 306 | .timer = &omap2_timer, |
307 | .restart = omap_prcm_restart, | ||
307 | MACHINE_END | 308 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 83126368ed99..383717ba63b9 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
@@ -475,106 +475,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = { | |||
475 | static struct omap_board_mux board_mux[] __initdata = { | 475 | static struct omap_board_mux board_mux[] __initdata = { |
476 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 476 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
477 | }; | 477 | }; |
478 | |||
479 | static struct omap_device_pad serial1_pads[] __initdata = { | ||
480 | /* | ||
481 | * Note that off output enable is an active low | ||
482 | * signal. So setting this means pin is a | ||
483 | * input enabled in off mode | ||
484 | */ | ||
485 | OMAP_MUX_STATIC("uart1_cts.uart1_cts", | ||
486 | OMAP_PIN_INPUT | | ||
487 | OMAP_PIN_OFF_INPUT_PULLDOWN | | ||
488 | OMAP_OFFOUT_EN | | ||
489 | OMAP_MUX_MODE0), | ||
490 | OMAP_MUX_STATIC("uart1_rts.uart1_rts", | ||
491 | OMAP_PIN_OUTPUT | | ||
492 | OMAP_OFF_EN | | ||
493 | OMAP_MUX_MODE0), | ||
494 | OMAP_MUX_STATIC("uart1_rx.uart1_rx", | ||
495 | OMAP_PIN_INPUT | | ||
496 | OMAP_PIN_OFF_INPUT_PULLDOWN | | ||
497 | OMAP_OFFOUT_EN | | ||
498 | OMAP_MUX_MODE0), | ||
499 | OMAP_MUX_STATIC("uart1_tx.uart1_tx", | ||
500 | OMAP_PIN_OUTPUT | | ||
501 | OMAP_OFF_EN | | ||
502 | OMAP_MUX_MODE0), | ||
503 | }; | ||
504 | |||
505 | static struct omap_device_pad serial2_pads[] __initdata = { | ||
506 | OMAP_MUX_STATIC("uart2_cts.uart2_cts", | ||
507 | OMAP_PIN_INPUT_PULLUP | | ||
508 | OMAP_PIN_OFF_INPUT_PULLDOWN | | ||
509 | OMAP_OFFOUT_EN | | ||
510 | OMAP_MUX_MODE0), | ||
511 | OMAP_MUX_STATIC("uart2_rts.uart2_rts", | ||
512 | OMAP_PIN_OUTPUT | | ||
513 | OMAP_OFF_EN | | ||
514 | OMAP_MUX_MODE0), | ||
515 | OMAP_MUX_STATIC("uart2_rx.uart2_rx", | ||
516 | OMAP_PIN_INPUT | | ||
517 | OMAP_PIN_OFF_INPUT_PULLDOWN | | ||
518 | OMAP_OFFOUT_EN | | ||
519 | OMAP_MUX_MODE0), | ||
520 | OMAP_MUX_STATIC("uart2_tx.uart2_tx", | ||
521 | OMAP_PIN_OUTPUT | | ||
522 | OMAP_OFF_EN | | ||
523 | OMAP_MUX_MODE0), | ||
524 | }; | ||
525 | |||
526 | static struct omap_device_pad serial3_pads[] __initdata = { | ||
527 | OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx", | ||
528 | OMAP_PIN_INPUT_PULLDOWN | | ||
529 | OMAP_PIN_OFF_INPUT_PULLDOWN | | ||
530 | OMAP_OFFOUT_EN | | ||
531 | OMAP_MUX_MODE0), | ||
532 | OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd", | ||
533 | OMAP_PIN_OUTPUT | | ||
534 | OMAP_OFF_EN | | ||
535 | OMAP_MUX_MODE0), | ||
536 | OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx", | ||
537 | OMAP_PIN_INPUT | | ||
538 | OMAP_PIN_OFF_INPUT_PULLDOWN | | ||
539 | OMAP_OFFOUT_EN | | ||
540 | OMAP_MUX_MODE0), | ||
541 | OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx", | ||
542 | OMAP_PIN_OUTPUT | | ||
543 | OMAP_OFF_EN | | ||
544 | OMAP_MUX_MODE0), | ||
545 | }; | ||
546 | |||
547 | static struct omap_board_data serial1_data __initdata = { | ||
548 | .id = 0, | ||
549 | .pads = serial1_pads, | ||
550 | .pads_cnt = ARRAY_SIZE(serial1_pads), | ||
551 | }; | ||
552 | |||
553 | static struct omap_board_data serial2_data __initdata = { | ||
554 | .id = 1, | ||
555 | .pads = serial2_pads, | ||
556 | .pads_cnt = ARRAY_SIZE(serial2_pads), | ||
557 | }; | ||
558 | |||
559 | static struct omap_board_data serial3_data __initdata = { | ||
560 | .id = 2, | ||
561 | .pads = serial3_pads, | ||
562 | .pads_cnt = ARRAY_SIZE(serial3_pads), | ||
563 | }; | ||
564 | |||
565 | static inline void board_serial_init(void) | ||
566 | { | ||
567 | omap_serial_init_port(&serial1_data); | ||
568 | omap_serial_init_port(&serial2_data); | ||
569 | omap_serial_init_port(&serial3_data); | ||
570 | } | ||
571 | #else | 478 | #else |
572 | #define board_mux NULL | 479 | #define board_mux NULL |
573 | |||
574 | static inline void board_serial_init(void) | ||
575 | { | ||
576 | omap_serial_init(); | ||
577 | } | ||
578 | #endif | 480 | #endif |
579 | 481 | ||
580 | /* | 482 | /* |
@@ -711,7 +613,7 @@ static void __init omap_3430sdp_init(void) | |||
711 | else | 613 | else |
712 | gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1; | 614 | gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1; |
713 | omap_ads7846_init(1, gpio_pendown, 310, NULL); | 615 | omap_ads7846_init(1, gpio_pendown, 310, NULL); |
714 | board_serial_init(); | 616 | omap_serial_init(); |
715 | omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL); | 617 | omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL); |
716 | usb_musb_init(NULL); | 618 | usb_musb_init(NULL); |
717 | board_smc91x_init(); | 619 | board_smc91x_init(); |
@@ -731,4 +633,5 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board") | |||
731 | .handle_irq = omap3_intc_handle_irq, | 633 | .handle_irq = omap3_intc_handle_irq, |
732 | .init_machine = omap_3430sdp_init, | 634 | .init_machine = omap_3430sdp_init, |
733 | .timer = &omap3_timer, | 635 | .timer = &omap3_timer, |
636 | .restart = omap_prcm_restart, | ||
734 | MACHINE_END | 637 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c index 7969dd904bd3..6ef350d1ae4f 100644 --- a/arch/arm/mach-omap2/board-3630sdp.c +++ b/arch/arm/mach-omap2/board-3630sdp.c | |||
@@ -218,4 +218,5 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board") | |||
218 | .handle_irq = omap3_intc_handle_irq, | 218 | .handle_irq = omap3_intc_handle_irq, |
219 | .init_machine = omap_sdp_init, | 219 | .init_machine = omap_sdp_init, |
220 | .timer = &omap3_timer, | 220 | .timer = &omap3_timer, |
221 | .restart = omap_prcm_restart, | ||
221 | MACHINE_END | 222 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index ef2bbc09428a..21fc87648660 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c | |||
@@ -52,8 +52,9 @@ | |||
52 | #define ETH_KS8851_QUART 138 | 52 | #define ETH_KS8851_QUART 138 |
53 | #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 | 53 | #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 |
54 | #define OMAP4_SFH7741_ENABLE_GPIO 188 | 54 | #define OMAP4_SFH7741_ENABLE_GPIO 188 |
55 | #define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ | 55 | #define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ |
56 | #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ | 56 | #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ |
57 | #define HDMI_GPIO_HPD 63 /* Hotplug detect */ | ||
57 | #define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */ | 58 | #define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */ |
58 | #define DLP_POWER_ON_GPIO 40 | 59 | #define DLP_POWER_ON_GPIO 40 |
59 | 60 | ||
@@ -372,11 +373,17 @@ static struct platform_device sdp4430_vbat = { | |||
372 | }, | 373 | }, |
373 | }; | 374 | }; |
374 | 375 | ||
376 | static struct platform_device sdp4430_dmic_codec = { | ||
377 | .name = "dmic-codec", | ||
378 | .id = -1, | ||
379 | }; | ||
380 | |||
375 | static struct platform_device *sdp4430_devices[] __initdata = { | 381 | static struct platform_device *sdp4430_devices[] __initdata = { |
376 | &sdp4430_gpio_keys_device, | 382 | &sdp4430_gpio_keys_device, |
377 | &sdp4430_leds_gpio, | 383 | &sdp4430_leds_gpio, |
378 | &sdp4430_leds_pwm, | 384 | &sdp4430_leds_pwm, |
379 | &sdp4430_vbat, | 385 | &sdp4430_vbat, |
386 | &sdp4430_dmic_codec, | ||
380 | }; | 387 | }; |
381 | 388 | ||
382 | static struct omap_musb_board_data musb_board_data = { | 389 | static struct omap_musb_board_data musb_board_data = { |
@@ -404,6 +411,7 @@ static struct omap2_hsmmc_info mmc[] = { | |||
404 | { | 411 | { |
405 | .mmc = 5, | 412 | .mmc = 5, |
406 | .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, | 413 | .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, |
414 | .pm_caps = MMC_PM_KEEP_POWER, | ||
407 | .gpio_cd = -EINVAL, | 415 | .gpio_cd = -EINVAL, |
408 | .gpio_wp = -EINVAL, | 416 | .gpio_wp = -EINVAL, |
409 | .ocr_mask = MMC_VDD_165_195, | 417 | .ocr_mask = MMC_VDD_165_195, |
@@ -595,23 +603,10 @@ static void __init omap_sfh7741prox_init(void) | |||
595 | __func__, OMAP4_SFH7741_ENABLE_GPIO, error); | 603 | __func__, OMAP4_SFH7741_ENABLE_GPIO, error); |
596 | } | 604 | } |
597 | 605 | ||
598 | static void sdp4430_hdmi_mux_init(void) | ||
599 | { | ||
600 | /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ | ||
601 | omap_mux_init_signal("hdmi_hpd", | ||
602 | OMAP_PIN_INPUT_PULLUP); | ||
603 | omap_mux_init_signal("hdmi_cec", | ||
604 | OMAP_PIN_INPUT_PULLUP); | ||
605 | /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ | ||
606 | omap_mux_init_signal("hdmi_ddc_scl", | ||
607 | OMAP_PIN_INPUT_PULLUP); | ||
608 | omap_mux_init_signal("hdmi_ddc_sda", | ||
609 | OMAP_PIN_INPUT_PULLUP); | ||
610 | } | ||
611 | |||
612 | static struct gpio sdp4430_hdmi_gpios[] = { | 606 | static struct gpio sdp4430_hdmi_gpios[] = { |
613 | { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, | 607 | { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" }, |
614 | { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, | 608 | { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, |
609 | { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" }, | ||
615 | }; | 610 | }; |
616 | 611 | ||
617 | static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) | 612 | static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) |
@@ -628,8 +623,7 @@ static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) | |||
628 | 623 | ||
629 | static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev) | 624 | static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev) |
630 | { | 625 | { |
631 | gpio_free(HDMI_GPIO_LS_OE); | 626 | gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios)); |
632 | gpio_free(HDMI_GPIO_HPD); | ||
633 | } | 627 | } |
634 | 628 | ||
635 | static struct nokia_dsi_panel_data dsi1_panel = { | 629 | static struct nokia_dsi_panel_data dsi1_panel = { |
@@ -745,6 +739,10 @@ static void sdp4430_lcd_init(void) | |||
745 | pr_err("%s: Could not get lcd2_reset_gpio\n", __func__); | 739 | pr_err("%s: Could not get lcd2_reset_gpio\n", __func__); |
746 | } | 740 | } |
747 | 741 | ||
742 | static struct omap_dss_hdmi_data sdp4430_hdmi_data = { | ||
743 | .hpd_gpio = HDMI_GPIO_HPD, | ||
744 | }; | ||
745 | |||
748 | static struct omap_dss_device sdp4430_hdmi_device = { | 746 | static struct omap_dss_device sdp4430_hdmi_device = { |
749 | .name = "hdmi", | 747 | .name = "hdmi", |
750 | .driver_name = "hdmi_panel", | 748 | .driver_name = "hdmi_panel", |
@@ -752,6 +750,7 @@ static struct omap_dss_device sdp4430_hdmi_device = { | |||
752 | .platform_enable = sdp4430_panel_enable_hdmi, | 750 | .platform_enable = sdp4430_panel_enable_hdmi, |
753 | .platform_disable = sdp4430_panel_disable_hdmi, | 751 | .platform_disable = sdp4430_panel_disable_hdmi, |
754 | .channel = OMAP_DSS_CHANNEL_DIGIT, | 752 | .channel = OMAP_DSS_CHANNEL_DIGIT, |
753 | .data = &sdp4430_hdmi_data, | ||
755 | }; | 754 | }; |
756 | 755 | ||
757 | static struct picodlp_panel_data sdp4430_picodlp_pdata = { | 756 | static struct picodlp_panel_data sdp4430_picodlp_pdata = { |
@@ -826,9 +825,20 @@ static void omap_4430sdp_display_init(void) | |||
826 | pr_err("%s: Could not get display_sel GPIO\n", __func__); | 825 | pr_err("%s: Could not get display_sel GPIO\n", __func__); |
827 | 826 | ||
828 | sdp4430_lcd_init(); | 827 | sdp4430_lcd_init(); |
829 | sdp4430_hdmi_mux_init(); | ||
830 | sdp4430_picodlp_init(); | 828 | sdp4430_picodlp_init(); |
831 | omap_display_init(&sdp4430_dss_data); | 829 | omap_display_init(&sdp4430_dss_data); |
830 | /* | ||
831 | * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and | ||
832 | * later have external pull up on the HDMI I2C lines | ||
833 | */ | ||
834 | if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) | ||
835 | omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); | ||
836 | else | ||
837 | omap_hdmi_init(0); | ||
838 | |||
839 | omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); | ||
840 | omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); | ||
841 | omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); | ||
832 | } | 842 | } |
833 | 843 | ||
834 | #ifdef CONFIG_OMAP_MUX | 844 | #ifdef CONFIG_OMAP_MUX |
@@ -837,74 +847,8 @@ static struct omap_board_mux board_mux[] __initdata = { | |||
837 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 847 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
838 | }; | 848 | }; |
839 | 849 | ||
840 | static struct omap_device_pad serial2_pads[] __initdata = { | ||
841 | OMAP_MUX_STATIC("uart2_cts.uart2_cts", | ||
842 | OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), | ||
843 | OMAP_MUX_STATIC("uart2_rts.uart2_rts", | ||
844 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
845 | OMAP_MUX_STATIC("uart2_rx.uart2_rx", | ||
846 | OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), | ||
847 | OMAP_MUX_STATIC("uart2_tx.uart2_tx", | ||
848 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
849 | }; | ||
850 | |||
851 | static struct omap_device_pad serial3_pads[] __initdata = { | ||
852 | OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx", | ||
853 | OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), | ||
854 | OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd", | ||
855 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
856 | OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx", | ||
857 | OMAP_PIN_INPUT | OMAP_MUX_MODE0), | ||
858 | OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx", | ||
859 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
860 | }; | ||
861 | |||
862 | static struct omap_device_pad serial4_pads[] __initdata = { | ||
863 | OMAP_MUX_STATIC("uart4_rx.uart4_rx", | ||
864 | OMAP_PIN_INPUT | OMAP_MUX_MODE0), | ||
865 | OMAP_MUX_STATIC("uart4_tx.uart4_tx", | ||
866 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
867 | }; | ||
868 | |||
869 | static struct omap_board_data serial2_data __initdata = { | ||
870 | .id = 1, | ||
871 | .pads = serial2_pads, | ||
872 | .pads_cnt = ARRAY_SIZE(serial2_pads), | ||
873 | }; | ||
874 | |||
875 | static struct omap_board_data serial3_data __initdata = { | ||
876 | .id = 2, | ||
877 | .pads = serial3_pads, | ||
878 | .pads_cnt = ARRAY_SIZE(serial3_pads), | ||
879 | }; | ||
880 | |||
881 | static struct omap_board_data serial4_data __initdata = { | ||
882 | .id = 3, | ||
883 | .pads = serial4_pads, | ||
884 | .pads_cnt = ARRAY_SIZE(serial4_pads), | ||
885 | }; | ||
886 | |||
887 | static inline void board_serial_init(void) | ||
888 | { | ||
889 | struct omap_board_data bdata; | ||
890 | bdata.flags = 0; | ||
891 | bdata.pads = NULL; | ||
892 | bdata.pads_cnt = 0; | ||
893 | bdata.id = 0; | ||
894 | /* pass dummy data for UART1 */ | ||
895 | omap_serial_init_port(&bdata); | ||
896 | |||
897 | omap_serial_init_port(&serial2_data); | ||
898 | omap_serial_init_port(&serial3_data); | ||
899 | omap_serial_init_port(&serial4_data); | ||
900 | } | ||
901 | #else | 850 | #else |
902 | #define board_mux NULL | 851 | #define board_mux NULL |
903 | |||
904 | static inline void board_serial_init(void) | ||
905 | { | ||
906 | omap_serial_init(); | ||
907 | } | ||
908 | #endif | 852 | #endif |
909 | 853 | ||
910 | static void omap4_sdp4430_wifi_mux_init(void) | 854 | static void omap4_sdp4430_wifi_mux_init(void) |
@@ -954,7 +898,7 @@ static void __init omap_4430sdp_init(void) | |||
954 | omap4_i2c_init(); | 898 | omap4_i2c_init(); |
955 | omap_sfh7741prox_init(); | 899 | omap_sfh7741prox_init(); |
956 | platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); | 900 | platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); |
957 | board_serial_init(); | 901 | omap_serial_init(); |
958 | omap_sdrc_init(NULL, NULL); | 902 | omap_sdrc_init(NULL, NULL); |
959 | omap4_sdp4430_wifi_init(); | 903 | omap4_sdp4430_wifi_init(); |
960 | omap4_twl6030_hsmmc_init(mmc); | 904 | omap4_twl6030_hsmmc_init(mmc); |
@@ -987,4 +931,5 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board") | |||
987 | .handle_irq = gic_handle_irq, | 931 | .handle_irq = gic_handle_irq, |
988 | .init_machine = omap_4430sdp_init, | 932 | .init_machine = omap_4430sdp_init, |
989 | .timer = &omap4_timer, | 933 | .timer = &omap4_timer, |
934 | .restart = omap_prcm_restart, | ||
990 | MACHINE_END | 935 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c index 7e90f93263db..c3851e8de28b 100644 --- a/arch/arm/mach-omap2/board-am3517crane.c +++ b/arch/arm/mach-omap2/board-am3517crane.c | |||
@@ -101,4 +101,5 @@ MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD") | |||
101 | .handle_irq = omap3_intc_handle_irq, | 101 | .handle_irq = omap3_intc_handle_irq, |
102 | .init_machine = am3517_crane_init, | 102 | .init_machine = am3517_crane_init, |
103 | .timer = &omap3_timer, | 103 | .timer = &omap3_timer, |
104 | .restart = omap_prcm_restart, | ||
104 | MACHINE_END | 105 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 551cae8d9b8a..4b1cfe32e6ba 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/i2c/pca953x.h> | 24 | #include <linux/i2c/pca953x.h> |
25 | #include <linux/can/platform/ti_hecc.h> | 25 | #include <linux/can/platform/ti_hecc.h> |
26 | #include <linux/davinci_emac.h> | 26 | #include <linux/davinci_emac.h> |
27 | #include <linux/mmc/host.h> | ||
27 | 28 | ||
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
29 | #include <mach/am35xx.h> | 30 | #include <mach/am35xx.h> |
@@ -40,6 +41,7 @@ | |||
40 | 41 | ||
41 | #include "mux.h" | 42 | #include "mux.h" |
42 | #include "control.h" | 43 | #include "control.h" |
44 | #include "hsmmc.h" | ||
43 | 45 | ||
44 | #define AM35XX_EVM_MDIO_FREQUENCY (1000000) | 46 | #define AM35XX_EVM_MDIO_FREQUENCY (1000000) |
45 | 47 | ||
@@ -455,6 +457,23 @@ static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata) | |||
455 | static struct omap_board_config_kernel am3517_evm_config[] __initdata = { | 457 | static struct omap_board_config_kernel am3517_evm_config[] __initdata = { |
456 | }; | 458 | }; |
457 | 459 | ||
460 | static struct omap2_hsmmc_info mmc[] = { | ||
461 | { | ||
462 | .mmc = 1, | ||
463 | .caps = MMC_CAP_4_BIT_DATA, | ||
464 | .gpio_cd = 127, | ||
465 | .gpio_wp = 126, | ||
466 | }, | ||
467 | { | ||
468 | .mmc = 2, | ||
469 | .caps = MMC_CAP_4_BIT_DATA, | ||
470 | .gpio_cd = 128, | ||
471 | .gpio_wp = 129, | ||
472 | }, | ||
473 | {} /* Terminator */ | ||
474 | }; | ||
475 | |||
476 | |||
458 | static void __init am3517_evm_init(void) | 477 | static void __init am3517_evm_init(void) |
459 | { | 478 | { |
460 | omap_board_config = am3517_evm_config; | 479 | omap_board_config = am3517_evm_config; |
@@ -483,6 +502,9 @@ static void __init am3517_evm_init(void) | |||
483 | 502 | ||
484 | /* MUSB */ | 503 | /* MUSB */ |
485 | am3517_evm_musb_init(); | 504 | am3517_evm_musb_init(); |
505 | |||
506 | /* MMC init function */ | ||
507 | omap2_hsmmc_init(mmc); | ||
486 | } | 508 | } |
487 | 509 | ||
488 | MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") | 510 | MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") |
@@ -494,4 +516,5 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") | |||
494 | .handle_irq = omap3_intc_handle_irq, | 516 | .handle_irq = omap3_intc_handle_irq, |
495 | .init_machine = am3517_evm_init, | 517 | .init_machine = am3517_evm_init, |
496 | .timer = &omap3_timer, | 518 | .timer = &omap3_timer, |
519 | .restart = omap_prcm_restart, | ||
497 | MACHINE_END | 520 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c index 5a66480feed0..ac773829941f 100644 --- a/arch/arm/mach-omap2/board-apollon.c +++ b/arch/arm/mach-omap2/board-apollon.c | |||
@@ -357,4 +357,5 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") | |||
357 | .handle_irq = omap2_intc_handle_irq, | 357 | .handle_irq = omap2_intc_handle_irq, |
358 | .init_machine = omap_apollon_init, | 358 | .init_machine = omap_apollon_init, |
359 | .timer = &omap2_timer, | 359 | .timer = &omap2_timer, |
360 | .restart = omap_prcm_restart, | ||
360 | MACHINE_END | 361 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c index 510b6a2ff0fa..e921e3be24a4 100644 --- a/arch/arm/mach-omap2/board-cm-t35.c +++ b/arch/arm/mach-omap2/board-cm-t35.c | |||
@@ -53,7 +53,8 @@ | |||
53 | #include "hsmmc.h" | 53 | #include "hsmmc.h" |
54 | #include "common-board-devices.h" | 54 | #include "common-board-devices.h" |
55 | 55 | ||
56 | #define CM_T35_GPIO_PENDOWN 57 | 56 | #define CM_T35_GPIO_PENDOWN 57 |
57 | #define SB_T35_USB_HUB_RESET_GPIO 167 | ||
57 | 58 | ||
58 | #define CM_T35_SMSC911X_CS 5 | 59 | #define CM_T35_SMSC911X_CS 5 |
59 | #define CM_T35_SMSC911X_GPIO 163 | 60 | #define CM_T35_SMSC911X_GPIO 163 |
@@ -339,8 +340,10 @@ static struct regulator_consumer_supply cm_t35_vsim_supply[] = { | |||
339 | REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), | 340 | REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), |
340 | }; | 341 | }; |
341 | 342 | ||
342 | static struct regulator_consumer_supply cm_t35_vdvi_supply[] = { | 343 | static struct regulator_consumer_supply cm_t35_vio_supplies[] = { |
343 | REGULATOR_SUPPLY("vdvi", "omapdss"), | 344 | REGULATOR_SUPPLY("vcc", "spi1.0"), |
345 | REGULATOR_SUPPLY("vdds_dsi", "omapdss"), | ||
346 | REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), | ||
344 | }; | 347 | }; |
345 | 348 | ||
346 | /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ | 349 | /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ |
@@ -373,6 +376,19 @@ static struct regulator_init_data cm_t35_vsim = { | |||
373 | .consumer_supplies = cm_t35_vsim_supply, | 376 | .consumer_supplies = cm_t35_vsim_supply, |
374 | }; | 377 | }; |
375 | 378 | ||
379 | static struct regulator_init_data cm_t35_vio = { | ||
380 | .constraints = { | ||
381 | .min_uV = 1800000, | ||
382 | .max_uV = 1800000, | ||
383 | .apply_uV = true, | ||
384 | .valid_modes_mask = REGULATOR_MODE_NORMAL | ||
385 | | REGULATOR_MODE_STANDBY, | ||
386 | .valid_ops_mask = REGULATOR_CHANGE_MODE, | ||
387 | }, | ||
388 | .num_consumer_supplies = ARRAY_SIZE(cm_t35_vio_supplies), | ||
389 | .consumer_supplies = cm_t35_vio_supplies, | ||
390 | }; | ||
391 | |||
376 | static uint32_t cm_t35_keymap[] = { | 392 | static uint32_t cm_t35_keymap[] = { |
377 | KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT), | 393 | KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT), |
378 | KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN), | 394 | KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN), |
@@ -421,6 +437,23 @@ static struct usbhs_omap_board_data usbhs_bdata __initdata = { | |||
421 | .reset_gpio_port[2] = -EINVAL | 437 | .reset_gpio_port[2] = -EINVAL |
422 | }; | 438 | }; |
423 | 439 | ||
440 | static void cm_t35_init_usbh(void) | ||
441 | { | ||
442 | int err; | ||
443 | |||
444 | err = gpio_request_one(SB_T35_USB_HUB_RESET_GPIO, | ||
445 | GPIOF_OUT_INIT_LOW, "usb hub rst"); | ||
446 | if (err) { | ||
447 | pr_err("SB-T35: usb hub rst gpio request failed: %d\n", err); | ||
448 | } else { | ||
449 | udelay(10); | ||
450 | gpio_set_value(SB_T35_USB_HUB_RESET_GPIO, 1); | ||
451 | msleep(1); | ||
452 | } | ||
453 | |||
454 | usbhs_init(&usbhs_bdata); | ||
455 | } | ||
456 | |||
424 | static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, | 457 | static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, |
425 | unsigned ngpio) | 458 | unsigned ngpio) |
426 | { | 459 | { |
@@ -456,17 +489,14 @@ static struct twl4030_platform_data cm_t35_twldata = { | |||
456 | .gpio = &cm_t35_gpio_data, | 489 | .gpio = &cm_t35_gpio_data, |
457 | .vmmc1 = &cm_t35_vmmc1, | 490 | .vmmc1 = &cm_t35_vmmc1, |
458 | .vsim = &cm_t35_vsim, | 491 | .vsim = &cm_t35_vsim, |
492 | .vio = &cm_t35_vio, | ||
459 | }; | 493 | }; |
460 | 494 | ||
461 | static void __init cm_t35_init_i2c(void) | 495 | static void __init cm_t35_init_i2c(void) |
462 | { | 496 | { |
463 | omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB, | 497 | omap3_pmic_get_config(&cm_t35_twldata, TWL_COMMON_PDATA_USB, |
464 | TWL_COMMON_REGULATOR_VDAC | TWL_COMMON_REGULATOR_VPLL2); | 498 | TWL_COMMON_REGULATOR_VDAC | |
465 | 499 | TWL_COMMON_PDATA_AUDIO); | |
466 | cm_t35_twldata.vpll2->constraints.name = "VDVI"; | ||
467 | cm_t35_twldata.vpll2->num_consumer_supplies = | ||
468 | ARRAY_SIZE(cm_t35_vdvi_supply); | ||
469 | cm_t35_twldata.vpll2->consumer_supplies = cm_t35_vdvi_supply; | ||
470 | 500 | ||
471 | omap3_pmic_init("tps65930", &cm_t35_twldata); | 501 | omap3_pmic_init("tps65930", &cm_t35_twldata); |
472 | } | 502 | } |
@@ -570,24 +600,28 @@ static void __init cm_t3x_common_dss_mux_init(int mux_mode) | |||
570 | 600 | ||
571 | static void __init cm_t35_init_mux(void) | 601 | static void __init cm_t35_init_mux(void) |
572 | { | 602 | { |
573 | omap_mux_init_signal("gpio_70", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); | 603 | int mux_mode = OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT; |
574 | omap_mux_init_signal("gpio_71", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); | 604 | |
575 | omap_mux_init_signal("gpio_72", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); | 605 | omap_mux_init_signal("dss_data0.dss_data0", mux_mode); |
576 | omap_mux_init_signal("gpio_73", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); | 606 | omap_mux_init_signal("dss_data1.dss_data1", mux_mode); |
577 | omap_mux_init_signal("gpio_74", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); | 607 | omap_mux_init_signal("dss_data2.dss_data2", mux_mode); |
578 | omap_mux_init_signal("gpio_75", OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); | 608 | omap_mux_init_signal("dss_data3.dss_data3", mux_mode); |
579 | cm_t3x_common_dss_mux_init(OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT); | 609 | omap_mux_init_signal("dss_data4.dss_data4", mux_mode); |
610 | omap_mux_init_signal("dss_data5.dss_data5", mux_mode); | ||
611 | cm_t3x_common_dss_mux_init(mux_mode); | ||
580 | } | 612 | } |
581 | 613 | ||
582 | static void __init cm_t3730_init_mux(void) | 614 | static void __init cm_t3730_init_mux(void) |
583 | { | 615 | { |
584 | omap_mux_init_signal("sys_boot0", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); | 616 | int mux_mode = OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT; |
585 | omap_mux_init_signal("sys_boot1", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); | 617 | |
586 | omap_mux_init_signal("sys_boot3", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); | 618 | omap_mux_init_signal("sys_boot0", mux_mode); |
587 | omap_mux_init_signal("sys_boot4", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); | 619 | omap_mux_init_signal("sys_boot1", mux_mode); |
588 | omap_mux_init_signal("sys_boot5", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); | 620 | omap_mux_init_signal("sys_boot3", mux_mode); |
589 | omap_mux_init_signal("sys_boot6", OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); | 621 | omap_mux_init_signal("sys_boot4", mux_mode); |
590 | cm_t3x_common_dss_mux_init(OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT); | 622 | omap_mux_init_signal("sys_boot5", mux_mode); |
623 | omap_mux_init_signal("sys_boot6", mux_mode); | ||
624 | cm_t3x_common_dss_mux_init(mux_mode); | ||
591 | } | 625 | } |
592 | #else | 626 | #else |
593 | static inline void cm_t35_init_mux(void) {} | 627 | static inline void cm_t35_init_mux(void) {} |
@@ -612,7 +646,7 @@ static void __init cm_t3x_common_init(void) | |||
612 | cm_t35_init_display(); | 646 | cm_t35_init_display(); |
613 | 647 | ||
614 | usb_musb_init(NULL); | 648 | usb_musb_init(NULL); |
615 | usbhs_init(&usbhs_bdata); | 649 | cm_t35_init_usbh(); |
616 | } | 650 | } |
617 | 651 | ||
618 | static void __init cm_t35_init(void) | 652 | static void __init cm_t35_init(void) |
@@ -637,6 +671,7 @@ MACHINE_START(CM_T35, "Compulab CM-T35") | |||
637 | .handle_irq = omap3_intc_handle_irq, | 671 | .handle_irq = omap3_intc_handle_irq, |
638 | .init_machine = cm_t35_init, | 672 | .init_machine = cm_t35_init, |
639 | .timer = &omap3_timer, | 673 | .timer = &omap3_timer, |
674 | .restart = omap_prcm_restart, | ||
640 | MACHINE_END | 675 | MACHINE_END |
641 | 676 | ||
642 | MACHINE_START(CM_T3730, "Compulab CM-T3730") | 677 | MACHINE_START(CM_T3730, "Compulab CM-T3730") |
@@ -648,4 +683,5 @@ MACHINE_START(CM_T3730, "Compulab CM-T3730") | |||
648 | .handle_irq = omap3_intc_handle_irq, | 683 | .handle_irq = omap3_intc_handle_irq, |
649 | .init_machine = cm_t3730_init, | 684 | .init_machine = cm_t3730_init, |
650 | .timer = &omap3_timer, | 685 | .timer = &omap3_timer, |
686 | .restart = omap_prcm_restart, | ||
651 | MACHINE_END | 687 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index efc5cedb1fbb..f36d694d2159 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c | |||
@@ -302,4 +302,5 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517") | |||
302 | .handle_irq = omap3_intc_handle_irq, | 302 | .handle_irq = omap3_intc_handle_irq, |
303 | .init_machine = cm_t3517_init, | 303 | .init_machine = cm_t3517_init, |
304 | .timer = &omap3_timer, | 304 | .timer = &omap3_timer, |
305 | .restart = omap_prcm_restart, | ||
305 | MACHINE_END | 306 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index d81ea7fa75ef..e873063f4fda 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c | |||
@@ -663,4 +663,5 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000") | |||
663 | .handle_irq = omap3_intc_handle_irq, | 663 | .handle_irq = omap3_intc_handle_irq, |
664 | .init_machine = devkit8000_init, | 664 | .init_machine = devkit8000_init, |
665 | .timer = &omap3_secure_timer, | 665 | .timer = &omap3_secure_timer, |
666 | .restart = omap_prcm_restart, | ||
666 | MACHINE_END | 667 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index e493877957c9..d32b5935233f 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
@@ -70,7 +70,6 @@ static void __init omap_generic_init(void) | |||
70 | if (node) | 70 | if (node) |
71 | irq_domain_add_simple(node, 0); | 71 | irq_domain_add_simple(node, 0); |
72 | 72 | ||
73 | omap_serial_init(); | ||
74 | omap_sdrc_init(NULL, NULL); | 73 | omap_sdrc_init(NULL, NULL); |
75 | 74 | ||
76 | of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); | 75 | of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); |
@@ -92,14 +91,13 @@ static void __init omap3_init(void) | |||
92 | } | 91 | } |
93 | #endif | 92 | #endif |
94 | 93 | ||
95 | #if defined(CONFIG_SOC_OMAP2420) | 94 | #ifdef CONFIG_SOC_OMAP2420 |
96 | static const char *omap242x_boards_compat[] __initdata = { | 95 | static const char *omap242x_boards_compat[] __initdata = { |
97 | "ti,omap2420", | 96 | "ti,omap2420", |
98 | NULL, | 97 | NULL, |
99 | }; | 98 | }; |
100 | 99 | ||
101 | DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") | 100 | DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") |
102 | .atag_offset = 0x100, | ||
103 | .reserve = omap_reserve, | 101 | .reserve = omap_reserve, |
104 | .map_io = omap242x_map_io, | 102 | .map_io = omap242x_map_io, |
105 | .init_early = omap2420_init_early, | 103 | .init_early = omap2420_init_early, |
@@ -108,17 +106,17 @@ DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") | |||
108 | .init_machine = omap_generic_init, | 106 | .init_machine = omap_generic_init, |
109 | .timer = &omap2_timer, | 107 | .timer = &omap2_timer, |
110 | .dt_compat = omap242x_boards_compat, | 108 | .dt_compat = omap242x_boards_compat, |
109 | .restart = omap_prcm_restart, | ||
111 | MACHINE_END | 110 | MACHINE_END |
112 | #endif | 111 | #endif |
113 | 112 | ||
114 | #if defined(CONFIG_SOC_OMAP2430) | 113 | #ifdef CONFIG_SOC_OMAP2430 |
115 | static const char *omap243x_boards_compat[] __initdata = { | 114 | static const char *omap243x_boards_compat[] __initdata = { |
116 | "ti,omap2430", | 115 | "ti,omap2430", |
117 | NULL, | 116 | NULL, |
118 | }; | 117 | }; |
119 | 118 | ||
120 | DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") | 119 | DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") |
121 | .atag_offset = 0x100, | ||
122 | .reserve = omap_reserve, | 120 | .reserve = omap_reserve, |
123 | .map_io = omap243x_map_io, | 121 | .map_io = omap243x_map_io, |
124 | .init_early = omap2430_init_early, | 122 | .init_early = omap2430_init_early, |
@@ -127,17 +125,17 @@ DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") | |||
127 | .init_machine = omap_generic_init, | 125 | .init_machine = omap_generic_init, |
128 | .timer = &omap2_timer, | 126 | .timer = &omap2_timer, |
129 | .dt_compat = omap243x_boards_compat, | 127 | .dt_compat = omap243x_boards_compat, |
128 | .restart = omap_prcm_restart, | ||
130 | MACHINE_END | 129 | MACHINE_END |
131 | #endif | 130 | #endif |
132 | 131 | ||
133 | #if defined(CONFIG_ARCH_OMAP3) | 132 | #ifdef CONFIG_ARCH_OMAP3 |
134 | static const char *omap3_boards_compat[] __initdata = { | 133 | static const char *omap3_boards_compat[] __initdata = { |
135 | "ti,omap3", | 134 | "ti,omap3", |
136 | NULL, | 135 | NULL, |
137 | }; | 136 | }; |
138 | 137 | ||
139 | DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") | 138 | DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") |
140 | .atag_offset = 0x100, | ||
141 | .reserve = omap_reserve, | 139 | .reserve = omap_reserve, |
142 | .map_io = omap3_map_io, | 140 | .map_io = omap3_map_io, |
143 | .init_early = omap3430_init_early, | 141 | .init_early = omap3430_init_early, |
@@ -146,17 +144,17 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") | |||
146 | .init_machine = omap3_init, | 144 | .init_machine = omap3_init, |
147 | .timer = &omap3_timer, | 145 | .timer = &omap3_timer, |
148 | .dt_compat = omap3_boards_compat, | 146 | .dt_compat = omap3_boards_compat, |
147 | .restart = omap_prcm_restart, | ||
149 | MACHINE_END | 148 | MACHINE_END |
150 | #endif | 149 | #endif |
151 | 150 | ||
152 | #if defined(CONFIG_ARCH_OMAP4) | 151 | #ifdef CONFIG_ARCH_OMAP4 |
153 | static const char *omap4_boards_compat[] __initdata = { | 152 | static const char *omap4_boards_compat[] __initdata = { |
154 | "ti,omap4", | 153 | "ti,omap4", |
155 | NULL, | 154 | NULL, |
156 | }; | 155 | }; |
157 | 156 | ||
158 | DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") | 157 | DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") |
159 | .atag_offset = 0x100, | ||
160 | .reserve = omap_reserve, | 158 | .reserve = omap_reserve, |
161 | .map_io = omap4_map_io, | 159 | .map_io = omap4_map_io, |
162 | .init_early = omap4430_init_early, | 160 | .init_early = omap4430_init_early, |
@@ -165,5 +163,6 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") | |||
165 | .init_machine = omap4_init, | 163 | .init_machine = omap4_init, |
166 | .timer = &omap4_timer, | 164 | .timer = &omap4_timer, |
167 | .dt_compat = omap4_boards_compat, | 165 | .dt_compat = omap4_boards_compat, |
166 | .restart = omap_prcm_restart, | ||
168 | MACHINE_END | 167 | MACHINE_END |
169 | #endif | 168 | #endif |
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index ec4018362e8e..54af800d143c 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
@@ -399,4 +399,5 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board") | |||
399 | .handle_irq = omap2_intc_handle_irq, | 399 | .handle_irq = omap2_intc_handle_irq, |
400 | .init_machine = omap_h4_init, | 400 | .init_machine = omap_h4_init, |
401 | .timer = &omap2_timer, | 401 | .timer = &omap2_timer, |
402 | .restart = omap_prcm_restart, | ||
402 | MACHINE_END | 403 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 5949f6ae3edf..a59ace0ed560 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c | |||
@@ -675,6 +675,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board") | |||
675 | .handle_irq = omap3_intc_handle_irq, | 675 | .handle_irq = omap3_intc_handle_irq, |
676 | .init_machine = igep_init, | 676 | .init_machine = igep_init, |
677 | .timer = &omap3_timer, | 677 | .timer = &omap3_timer, |
678 | .restart = omap_prcm_restart, | ||
678 | MACHINE_END | 679 | MACHINE_END |
679 | 680 | ||
680 | MACHINE_START(IGEP0030, "IGEP OMAP3 module") | 681 | MACHINE_START(IGEP0030, "IGEP OMAP3 module") |
@@ -686,4 +687,5 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module") | |||
686 | .handle_irq = omap3_intc_handle_irq, | 687 | .handle_irq = omap3_intc_handle_irq, |
687 | .init_machine = igep_init, | 688 | .init_machine = igep_init, |
688 | .timer = &omap3_timer, | 689 | .timer = &omap3_timer, |
690 | .restart = omap_prcm_restart, | ||
689 | MACHINE_END | 691 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c index 13bde0e66934..2d2a61f7dcbf 100644 --- a/arch/arm/mach-omap2/board-ldp.c +++ b/arch/arm/mach-omap2/board-ldp.c | |||
@@ -437,4 +437,5 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board") | |||
437 | .handle_irq = omap3_intc_handle_irq, | 437 | .handle_irq = omap3_intc_handle_irq, |
438 | .init_machine = omap_ldp_init, | 438 | .init_machine = omap_ldp_init, |
439 | .timer = &omap3_timer, | 439 | .timer = &omap3_timer, |
440 | .restart = omap_prcm_restart, | ||
440 | MACHINE_END | 441 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index bebd3d84365e..42a4d11fad23 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c | |||
@@ -46,7 +46,7 @@ static struct device *mmc_device; | |||
46 | #define TUSB6010_GPIO_ENABLE 0 | 46 | #define TUSB6010_GPIO_ENABLE 0 |
47 | #define TUSB6010_DMACHAN 0x3f | 47 | #define TUSB6010_DMACHAN 0x3f |
48 | 48 | ||
49 | #ifdef CONFIG_USB_MUSB_TUSB6010 | 49 | #if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_TUSB6010_MODULE) |
50 | /* | 50 | /* |
51 | * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and | 51 | * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and |
52 | * 1.5 V voltage regulators of PM companion chip. Companion chip will then | 52 | * 1.5 V voltage regulators of PM companion chip. Companion chip will then |
@@ -644,15 +644,15 @@ static inline void board_serial_init(void) | |||
644 | bdata.pads_cnt = 0; | 644 | bdata.pads_cnt = 0; |
645 | 645 | ||
646 | bdata.id = 0; | 646 | bdata.id = 0; |
647 | omap_serial_init_port(&bdata); | 647 | omap_serial_init_port(&bdata, NULL); |
648 | 648 | ||
649 | bdata.id = 1; | 649 | bdata.id = 1; |
650 | omap_serial_init_port(&bdata); | 650 | omap_serial_init_port(&bdata, NULL); |
651 | 651 | ||
652 | bdata.id = 2; | 652 | bdata.id = 2; |
653 | bdata.pads = serial2_pads; | 653 | bdata.pads = serial2_pads; |
654 | bdata.pads_cnt = ARRAY_SIZE(serial2_pads); | 654 | bdata.pads_cnt = ARRAY_SIZE(serial2_pads); |
655 | omap_serial_init_port(&bdata); | 655 | omap_serial_init_port(&bdata, NULL); |
656 | } | 656 | } |
657 | 657 | ||
658 | #else | 658 | #else |
@@ -692,6 +692,7 @@ MACHINE_START(NOKIA_N800, "Nokia N800") | |||
692 | .handle_irq = omap2_intc_handle_irq, | 692 | .handle_irq = omap2_intc_handle_irq, |
693 | .init_machine = n8x0_init_machine, | 693 | .init_machine = n8x0_init_machine, |
694 | .timer = &omap2_timer, | 694 | .timer = &omap2_timer, |
695 | .restart = omap_prcm_restart, | ||
695 | MACHINE_END | 696 | MACHINE_END |
696 | 697 | ||
697 | MACHINE_START(NOKIA_N810, "Nokia N810") | 698 | MACHINE_START(NOKIA_N810, "Nokia N810") |
@@ -703,6 +704,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810") | |||
703 | .handle_irq = omap2_intc_handle_irq, | 704 | .handle_irq = omap2_intc_handle_irq, |
704 | .init_machine = n8x0_init_machine, | 705 | .init_machine = n8x0_init_machine, |
705 | .timer = &omap2_timer, | 706 | .timer = &omap2_timer, |
707 | .restart = omap_prcm_restart, | ||
706 | MACHINE_END | 708 | MACHINE_END |
707 | 709 | ||
708 | MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX") | 710 | MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX") |
@@ -714,4 +716,5 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX") | |||
714 | .handle_irq = omap2_intc_handle_irq, | 716 | .handle_irq = omap2_intc_handle_irq, |
715 | .init_machine = n8x0_init_machine, | 717 | .init_machine = n8x0_init_machine, |
716 | .timer = &omap2_timer, | 718 | .timer = &omap2_timer, |
719 | .restart = omap_prcm_restart, | ||
717 | MACHINE_END | 720 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index c34f56588284..7ffcd2839e7b 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c | |||
@@ -562,4 +562,5 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") | |||
562 | .handle_irq = omap3_intc_handle_irq, | 562 | .handle_irq = omap3_intc_handle_irq, |
563 | .init_machine = omap3_beagle_init, | 563 | .init_machine = omap3_beagle_init, |
564 | .timer = &omap3_secure_timer, | 564 | .timer = &omap3_secure_timer, |
565 | .restart = omap_prcm_restart, | ||
565 | MACHINE_END | 566 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index f11bc444e7be..003fe34c9343 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -684,4 +684,5 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM") | |||
684 | .handle_irq = omap3_intc_handle_irq, | 684 | .handle_irq = omap3_intc_handle_irq, |
685 | .init_machine = omap3_evm_init, | 685 | .init_machine = omap3_evm_init, |
686 | .timer = &omap3_timer, | 686 | .timer = &omap3_timer, |
687 | .restart = omap_prcm_restart, | ||
687 | MACHINE_END | 688 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c index 5fa6bad9574e..4198dd017d8f 100644 --- a/arch/arm/mach-omap2/board-omap3logic.c +++ b/arch/arm/mach-omap2/board-omap3logic.c | |||
@@ -211,6 +211,7 @@ MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board") | |||
211 | .handle_irq = omap3_intc_handle_irq, | 211 | .handle_irq = omap3_intc_handle_irq, |
212 | .init_machine = omap3logic_init, | 212 | .init_machine = omap3logic_init, |
213 | .timer = &omap3_timer, | 213 | .timer = &omap3_timer, |
214 | .restart = omap_prcm_restart, | ||
214 | MACHINE_END | 215 | MACHINE_END |
215 | 216 | ||
216 | MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") | 217 | MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") |
@@ -221,4 +222,5 @@ MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") | |||
221 | .handle_irq = omap3_intc_handle_irq, | 222 | .handle_irq = omap3_intc_handle_irq, |
222 | .init_machine = omap3logic_init, | 223 | .init_machine = omap3logic_init, |
223 | .timer = &omap3_timer, | 224 | .timer = &omap3_timer, |
225 | .restart = omap_prcm_restart, | ||
224 | MACHINE_END | 226 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index ef315c585b75..1644b73017fc 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c | |||
@@ -609,4 +609,5 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console") | |||
609 | .handle_irq = omap3_intc_handle_irq, | 609 | .handle_irq = omap3_intc_handle_irq, |
610 | .init_machine = omap3pandora_init, | 610 | .init_machine = omap3pandora_init, |
611 | .timer = &omap3_timer, | 611 | .timer = &omap3_timer, |
612 | .restart = omap_prcm_restart, | ||
612 | MACHINE_END | 613 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index b21d70a2e4a7..cb089a46f62f 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c | |||
@@ -457,4 +457,5 @@ MACHINE_START(SBC3530, "OMAP3 STALKER") | |||
457 | .handle_irq = omap3_intc_handle_irq, | 457 | .handle_irq = omap3_intc_handle_irq, |
458 | .init_machine = omap3_stalker_init, | 458 | .init_machine = omap3_stalker_init, |
459 | .timer = &omap3_secure_timer, | 459 | .timer = &omap3_secure_timer, |
460 | .restart = omap_prcm_restart, | ||
460 | MACHINE_END | 461 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c index 18cd340f9b7b..a0b851aafcca 100644 --- a/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/arch/arm/mach-omap2/board-omap3touchbook.c | |||
@@ -384,4 +384,5 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board") | |||
384 | .handle_irq = omap3_intc_handle_irq, | 384 | .handle_irq = omap3_intc_handle_irq, |
385 | .init_machine = omap3_touchbook_init, | 385 | .init_machine = omap3_touchbook_init, |
386 | .timer = &omap3_secure_timer, | 386 | .timer = &omap3_secure_timer, |
387 | .restart = omap_prcm_restart, | ||
387 | MACHINE_END | 388 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index b6f114436dbc..b7779c206a90 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c | |||
@@ -51,8 +51,9 @@ | |||
51 | #define GPIO_HUB_NRESET 62 | 51 | #define GPIO_HUB_NRESET 62 |
52 | #define GPIO_WIFI_PMENA 43 | 52 | #define GPIO_WIFI_PMENA 43 |
53 | #define GPIO_WIFI_IRQ 53 | 53 | #define GPIO_WIFI_IRQ 53 |
54 | #define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ | 54 | #define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */ |
55 | #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ | 55 | #define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ |
56 | #define HDMI_GPIO_HPD 63 /* Hotplug detect */ | ||
56 | 57 | ||
57 | /* wl127x BT, FM, GPS connectivity chip */ | 58 | /* wl127x BT, FM, GPS connectivity chip */ |
58 | static int wl1271_gpios[] = {46, -1, -1}; | 59 | static int wl1271_gpios[] = {46, -1, -1}; |
@@ -364,74 +365,8 @@ static struct omap_board_mux board_mux[] __initdata = { | |||
364 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 365 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
365 | }; | 366 | }; |
366 | 367 | ||
367 | static struct omap_device_pad serial2_pads[] __initdata = { | ||
368 | OMAP_MUX_STATIC("uart2_cts.uart2_cts", | ||
369 | OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), | ||
370 | OMAP_MUX_STATIC("uart2_rts.uart2_rts", | ||
371 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
372 | OMAP_MUX_STATIC("uart2_rx.uart2_rx", | ||
373 | OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), | ||
374 | OMAP_MUX_STATIC("uart2_tx.uart2_tx", | ||
375 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
376 | }; | ||
377 | |||
378 | static struct omap_device_pad serial3_pads[] __initdata = { | ||
379 | OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx", | ||
380 | OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), | ||
381 | OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd", | ||
382 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
383 | OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx", | ||
384 | OMAP_PIN_INPUT | OMAP_MUX_MODE0), | ||
385 | OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx", | ||
386 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
387 | }; | ||
388 | |||
389 | static struct omap_device_pad serial4_pads[] __initdata = { | ||
390 | OMAP_MUX_STATIC("uart4_rx.uart4_rx", | ||
391 | OMAP_PIN_INPUT | OMAP_MUX_MODE0), | ||
392 | OMAP_MUX_STATIC("uart4_tx.uart4_tx", | ||
393 | OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), | ||
394 | }; | ||
395 | |||
396 | static struct omap_board_data serial2_data __initdata = { | ||
397 | .id = 1, | ||
398 | .pads = serial2_pads, | ||
399 | .pads_cnt = ARRAY_SIZE(serial2_pads), | ||
400 | }; | ||
401 | |||
402 | static struct omap_board_data serial3_data __initdata = { | ||
403 | .id = 2, | ||
404 | .pads = serial3_pads, | ||
405 | .pads_cnt = ARRAY_SIZE(serial3_pads), | ||
406 | }; | ||
407 | |||
408 | static struct omap_board_data serial4_data __initdata = { | ||
409 | .id = 3, | ||
410 | .pads = serial4_pads, | ||
411 | .pads_cnt = ARRAY_SIZE(serial4_pads), | ||
412 | }; | ||
413 | |||
414 | static inline void board_serial_init(void) | ||
415 | { | ||
416 | struct omap_board_data bdata; | ||
417 | bdata.flags = 0; | ||
418 | bdata.pads = NULL; | ||
419 | bdata.pads_cnt = 0; | ||
420 | bdata.id = 0; | ||
421 | /* pass dummy data for UART1 */ | ||
422 | omap_serial_init_port(&bdata); | ||
423 | |||
424 | omap_serial_init_port(&serial2_data); | ||
425 | omap_serial_init_port(&serial3_data); | ||
426 | omap_serial_init_port(&serial4_data); | ||
427 | } | ||
428 | #else | 368 | #else |
429 | #define board_mux NULL | 369 | #define board_mux NULL |
430 | |||
431 | static inline void board_serial_init(void) | ||
432 | { | ||
433 | omap_serial_init(); | ||
434 | } | ||
435 | #endif | 370 | #endif |
436 | 371 | ||
437 | /* Display DVI */ | 372 | /* Display DVI */ |
@@ -478,24 +413,10 @@ int __init omap4_panda_dvi_init(void) | |||
478 | return r; | 413 | return r; |
479 | } | 414 | } |
480 | 415 | ||
481 | |||
482 | static void omap4_panda_hdmi_mux_init(void) | ||
483 | { | ||
484 | /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ | ||
485 | omap_mux_init_signal("hdmi_hpd", | ||
486 | OMAP_PIN_INPUT_PULLUP); | ||
487 | omap_mux_init_signal("hdmi_cec", | ||
488 | OMAP_PIN_INPUT_PULLUP); | ||
489 | /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ | ||
490 | omap_mux_init_signal("hdmi_ddc_scl", | ||
491 | OMAP_PIN_INPUT_PULLUP); | ||
492 | omap_mux_init_signal("hdmi_ddc_sda", | ||
493 | OMAP_PIN_INPUT_PULLUP); | ||
494 | } | ||
495 | |||
496 | static struct gpio panda_hdmi_gpios[] = { | 416 | static struct gpio panda_hdmi_gpios[] = { |
497 | { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, | 417 | { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" }, |
498 | { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, | 418 | { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, |
419 | { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" }, | ||
499 | }; | 420 | }; |
500 | 421 | ||
501 | static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) | 422 | static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) |
@@ -512,10 +433,13 @@ static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) | |||
512 | 433 | ||
513 | static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev) | 434 | static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev) |
514 | { | 435 | { |
515 | gpio_free(HDMI_GPIO_LS_OE); | 436 | gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios)); |
516 | gpio_free(HDMI_GPIO_HPD); | ||
517 | } | 437 | } |
518 | 438 | ||
439 | static struct omap_dss_hdmi_data omap4_panda_hdmi_data = { | ||
440 | .hpd_gpio = HDMI_GPIO_HPD, | ||
441 | }; | ||
442 | |||
519 | static struct omap_dss_device omap4_panda_hdmi_device = { | 443 | static struct omap_dss_device omap4_panda_hdmi_device = { |
520 | .name = "hdmi", | 444 | .name = "hdmi", |
521 | .driver_name = "hdmi_panel", | 445 | .driver_name = "hdmi_panel", |
@@ -523,6 +447,7 @@ static struct omap_dss_device omap4_panda_hdmi_device = { | |||
523 | .platform_enable = omap4_panda_panel_enable_hdmi, | 447 | .platform_enable = omap4_panda_panel_enable_hdmi, |
524 | .platform_disable = omap4_panda_panel_disable_hdmi, | 448 | .platform_disable = omap4_panda_panel_disable_hdmi, |
525 | .channel = OMAP_DSS_CHANNEL_DIGIT, | 449 | .channel = OMAP_DSS_CHANNEL_DIGIT, |
450 | .data = &omap4_panda_hdmi_data, | ||
526 | }; | 451 | }; |
527 | 452 | ||
528 | static struct omap_dss_device *omap4_panda_dss_devices[] = { | 453 | static struct omap_dss_device *omap4_panda_dss_devices[] = { |
@@ -544,8 +469,20 @@ void omap4_panda_display_init(void) | |||
544 | if (r) | 469 | if (r) |
545 | pr_err("error initializing panda DVI\n"); | 470 | pr_err("error initializing panda DVI\n"); |
546 | 471 | ||
547 | omap4_panda_hdmi_mux_init(); | ||
548 | omap_display_init(&omap4_panda_dss_data); | 472 | omap_display_init(&omap4_panda_dss_data); |
473 | |||
474 | /* | ||
475 | * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and | ||
476 | * later have external pull up on the HDMI I2C lines | ||
477 | */ | ||
478 | if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2) | ||
479 | omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP); | ||
480 | else | ||
481 | omap_hdmi_init(0); | ||
482 | |||
483 | omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT); | ||
484 | omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT); | ||
485 | omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN); | ||
549 | } | 486 | } |
550 | 487 | ||
551 | static void __init omap4_panda_init(void) | 488 | static void __init omap4_panda_init(void) |
@@ -562,7 +499,7 @@ static void __init omap4_panda_init(void) | |||
562 | omap4_panda_i2c_init(); | 499 | omap4_panda_i2c_init(); |
563 | platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); | 500 | platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); |
564 | platform_device_register(&omap_vwlan_device); | 501 | platform_device_register(&omap_vwlan_device); |
565 | board_serial_init(); | 502 | omap_serial_init(); |
566 | omap_sdrc_init(NULL, NULL); | 503 | omap_sdrc_init(NULL, NULL); |
567 | omap4_twl6030_hsmmc_init(mmc); | 504 | omap4_twl6030_hsmmc_init(mmc); |
568 | omap4_ehci_init(); | 505 | omap4_ehci_init(); |
@@ -580,4 +517,5 @@ MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board") | |||
580 | .handle_irq = gic_handle_irq, | 517 | .handle_irq = gic_handle_irq, |
581 | .init_machine = omap4_panda_init, | 518 | .init_machine = omap4_panda_init, |
582 | .timer = &omap4_timer, | 519 | .timer = &omap4_timer, |
520 | .restart = omap_prcm_restart, | ||
583 | MACHINE_END | 521 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index 60a61ea759bf..52c0cef77165 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c | |||
@@ -565,4 +565,5 @@ MACHINE_START(OVERO, "Gumstix Overo") | |||
565 | .handle_irq = omap3_intc_handle_irq, | 565 | .handle_irq = omap3_intc_handle_irq, |
566 | .init_machine = overo_init, | 566 | .init_machine = overo_init, |
567 | .timer = &omap3_timer, | 567 | .timer = &omap3_timer, |
568 | .restart = omap_prcm_restart, | ||
568 | MACHINE_END | 569 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c index a79d49e3fe09..8678b386c6a2 100644 --- a/arch/arm/mach-omap2/board-rm680.c +++ b/arch/arm/mach-omap2/board-rm680.c | |||
@@ -152,4 +152,5 @@ MACHINE_START(NOKIA_RM680, "Nokia RM-680 board") | |||
152 | .handle_irq = omap3_intc_handle_irq, | 152 | .handle_irq = omap3_intc_handle_irq, |
153 | .init_machine = rm680_init, | 153 | .init_machine = rm680_init, |
154 | .timer = &omap3_timer, | 154 | .timer = &omap3_timer, |
155 | .restart = omap_prcm_restart, | ||
155 | MACHINE_END | 156 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index bd18d691c6ad..acb4e77b39ef 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/input/matrix_keypad.h> | 15 | #include <linux/input/matrix_keypad.h> |
16 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
17 | #include <linux/wl12xx.h> | 17 | #include <linux/wl12xx.h> |
18 | #include <linux/spi/tsc2005.h> | ||
18 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
19 | #include <linux/i2c/twl.h> | 20 | #include <linux/i2c/twl.h> |
20 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
@@ -58,6 +59,9 @@ | |||
58 | 59 | ||
59 | #define RX51_USB_TRANSCEIVER_RST_GPIO 67 | 60 | #define RX51_USB_TRANSCEIVER_RST_GPIO 67 |
60 | 61 | ||
62 | #define RX51_TSC2005_RESET_GPIO 104 | ||
63 | #define RX51_TSC2005_IRQ_GPIO 100 | ||
64 | |||
61 | /* list all spi devices here */ | 65 | /* list all spi devices here */ |
62 | enum { | 66 | enum { |
63 | RX51_SPI_WL1251, | 67 | RX51_SPI_WL1251, |
@@ -66,6 +70,7 @@ enum { | |||
66 | }; | 70 | }; |
67 | 71 | ||
68 | static struct wl12xx_platform_data wl1251_pdata; | 72 | static struct wl12xx_platform_data wl1251_pdata; |
73 | static struct tsc2005_platform_data tsc2005_pdata; | ||
69 | 74 | ||
70 | #if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE) | 75 | #if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE) |
71 | static struct tsl2563_platform_data rx51_tsl2563_platform_data = { | 76 | static struct tsl2563_platform_data rx51_tsl2563_platform_data = { |
@@ -167,10 +172,10 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { | |||
167 | .modalias = "tsc2005", | 172 | .modalias = "tsc2005", |
168 | .bus_num = 1, | 173 | .bus_num = 1, |
169 | .chip_select = 0, | 174 | .chip_select = 0, |
170 | /* .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),*/ | 175 | .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO), |
171 | .max_speed_hz = 6000000, | 176 | .max_speed_hz = 6000000, |
172 | .controller_data = &tsc2005_mcspi_config, | 177 | .controller_data = &tsc2005_mcspi_config, |
173 | /* .platform_data = &tsc2005_config,*/ | 178 | .platform_data = &tsc2005_pdata, |
174 | }, | 179 | }, |
175 | }; | 180 | }; |
176 | 181 | ||
@@ -193,7 +198,7 @@ static struct platform_device rx51_charger_device = { | |||
193 | static void __init rx51_charger_init(void) | 198 | static void __init rx51_charger_init(void) |
194 | { | 199 | { |
195 | WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, | 200 | WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, |
196 | GPIOF_OUT_INIT_LOW, "isp1704_reset")); | 201 | GPIOF_OUT_INIT_HIGH, "isp1704_reset")); |
197 | 202 | ||
198 | platform_device_register(&rx51_charger_device); | 203 | platform_device_register(&rx51_charger_device); |
199 | } | 204 | } |
@@ -940,6 +945,9 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = { | |||
940 | }, | 945 | }, |
941 | #endif | 946 | #endif |
942 | { | 947 | { |
948 | I2C_BOARD_INFO("bq27200", 0x55), | ||
949 | }, | ||
950 | { | ||
943 | I2C_BOARD_INFO("tpa6130a2", 0x60), | 951 | I2C_BOARD_INFO("tpa6130a2", 0x60), |
944 | .platform_data = &rx51_tpa6130a2_data, | 952 | .platform_data = &rx51_tpa6130a2_data, |
945 | } | 953 | } |
@@ -1086,6 +1094,42 @@ error: | |||
1086 | */ | 1094 | */ |
1087 | } | 1095 | } |
1088 | 1096 | ||
1097 | static struct tsc2005_platform_data tsc2005_pdata = { | ||
1098 | .ts_pressure_max = 2048, | ||
1099 | .ts_pressure_fudge = 2, | ||
1100 | .ts_x_max = 4096, | ||
1101 | .ts_x_fudge = 4, | ||
1102 | .ts_y_max = 4096, | ||
1103 | .ts_y_fudge = 7, | ||
1104 | .ts_x_plate_ohm = 280, | ||
1105 | .esd_timeout_ms = 8000, | ||
1106 | }; | ||
1107 | |||
1108 | static void rx51_tsc2005_set_reset(bool enable) | ||
1109 | { | ||
1110 | gpio_set_value(RX51_TSC2005_RESET_GPIO, enable); | ||
1111 | } | ||
1112 | |||
1113 | static void __init rx51_init_tsc2005(void) | ||
1114 | { | ||
1115 | int r; | ||
1116 | |||
1117 | r = gpio_request_one(RX51_TSC2005_IRQ_GPIO, GPIOF_IN, "tsc2005 IRQ"); | ||
1118 | if (r < 0) { | ||
1119 | printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 IRQ"); | ||
1120 | rx51_peripherals_spi_board_info[RX51_SPI_TSC2005].irq = 0; | ||
1121 | } | ||
1122 | |||
1123 | r = gpio_request_one(RX51_TSC2005_RESET_GPIO, GPIOF_OUT_INIT_HIGH, | ||
1124 | "tsc2005 reset"); | ||
1125 | if (r >= 0) { | ||
1126 | tsc2005_pdata.set_reset = rx51_tsc2005_set_reset; | ||
1127 | } else { | ||
1128 | printk(KERN_ERR "unable to get %s GPIO\n", "tsc2005 reset"); | ||
1129 | tsc2005_pdata.esd_timeout_ms = 0; | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1089 | void __init rx51_peripherals_init(void) | 1133 | void __init rx51_peripherals_init(void) |
1090 | { | 1134 | { |
1091 | rx51_i2c_init(); | 1135 | rx51_i2c_init(); |
@@ -1094,6 +1138,7 @@ void __init rx51_peripherals_init(void) | |||
1094 | board_smc91x_init(); | 1138 | board_smc91x_init(); |
1095 | rx51_add_gpio_keys(); | 1139 | rx51_add_gpio_keys(); |
1096 | rx51_init_wl1251(); | 1140 | rx51_init_wl1251(); |
1141 | rx51_init_tsc2005(); | ||
1097 | rx51_init_si4713(); | 1142 | rx51_init_si4713(); |
1098 | spi_register_board_info(rx51_peripherals_spi_board_info, | 1143 | spi_register_board_info(rx51_peripherals_spi_board_info, |
1099 | ARRAY_SIZE(rx51_peripherals_spi_board_info)); | 1144 | ARRAY_SIZE(rx51_peripherals_spi_board_info)); |
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 4e3c0965edf3..27f01f051dff 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c | |||
@@ -130,4 +130,5 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board") | |||
130 | .handle_irq = omap3_intc_handle_irq, | 130 | .handle_irq = omap3_intc_handle_irq, |
131 | .init_machine = rx51_init, | 131 | .init_machine = rx51_init, |
132 | .timer = &omap3_timer, | 132 | .timer = &omap3_timer, |
133 | .restart = omap_prcm_restart, | ||
133 | MACHINE_END | 134 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index 8402b39b2840..ab9a7a9e9d64 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Code for TI8168 EVM. | 2 | * Code for TI8168/TI8148 EVM. |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ | 4 | * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ |
5 | * | 5 | * |
@@ -23,29 +23,45 @@ | |||
23 | #include <plat/irqs.h> | 23 | #include <plat/irqs.h> |
24 | #include <plat/board.h> | 24 | #include <plat/board.h> |
25 | #include "common.h" | 25 | #include "common.h" |
26 | #include <plat/usb.h> | ||
26 | 27 | ||
27 | static struct omap_board_config_kernel ti8168_evm_config[] __initdata = { | 28 | static struct omap_musb_board_data musb_board_data = { |
29 | .set_phy_power = ti81xx_musb_phy_power, | ||
30 | .interface_type = MUSB_INTERFACE_ULPI, | ||
31 | .mode = MUSB_OTG, | ||
32 | .power = 500, | ||
28 | }; | 33 | }; |
29 | 34 | ||
30 | static void __init ti8168_evm_init(void) | 35 | static struct omap_board_config_kernel ti81xx_evm_config[] __initdata = { |
36 | }; | ||
37 | |||
38 | static void __init ti81xx_evm_init(void) | ||
31 | { | 39 | { |
32 | omap_serial_init(); | 40 | omap_serial_init(); |
33 | omap_sdrc_init(NULL, NULL); | 41 | omap_sdrc_init(NULL, NULL); |
34 | omap_board_config = ti8168_evm_config; | 42 | omap_board_config = ti81xx_evm_config; |
35 | omap_board_config_size = ARRAY_SIZE(ti8168_evm_config); | 43 | omap_board_config_size = ARRAY_SIZE(ti81xx_evm_config); |
36 | } | 44 | usb_musb_init(&musb_board_data); |
37 | |||
38 | static void __init ti8168_evm_map_io(void) | ||
39 | { | ||
40 | omapti816x_map_common_io(); | ||
41 | } | 45 | } |
42 | 46 | ||
43 | MACHINE_START(TI8168EVM, "ti8168evm") | 47 | MACHINE_START(TI8168EVM, "ti8168evm") |
44 | /* Maintainer: Texas Instruments */ | 48 | /* Maintainer: Texas Instruments */ |
45 | .atag_offset = 0x100, | 49 | .atag_offset = 0x100, |
46 | .map_io = ti8168_evm_map_io, | 50 | .map_io = ti81xx_map_io, |
47 | .init_early = ti816x_init_early, | 51 | .init_early = ti81xx_init_early, |
48 | .init_irq = ti816x_init_irq, | 52 | .init_irq = ti81xx_init_irq, |
53 | .timer = &omap3_timer, | ||
54 | .init_machine = ti81xx_evm_init, | ||
55 | .restart = omap_prcm_restart, | ||
56 | MACHINE_END | ||
57 | |||
58 | MACHINE_START(TI8148EVM, "ti8148evm") | ||
59 | /* Maintainer: Texas Instruments */ | ||
60 | .atag_offset = 0x100, | ||
61 | .map_io = ti81xx_map_io, | ||
62 | .init_early = ti81xx_init_early, | ||
63 | .init_irq = ti81xx_init_irq, | ||
49 | .timer = &omap3_timer, | 64 | .timer = &omap3_timer, |
50 | .init_machine = ti8168_evm_init, | 65 | .init_machine = ti81xx_evm_init, |
66 | .restart = omap_prcm_restart, | ||
51 | MACHINE_END | 67 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c index 70e5b54a2115..5c20bcc57f2b 100644 --- a/arch/arm/mach-omap2/board-zoom.c +++ b/arch/arm/mach-omap2/board-zoom.c | |||
@@ -138,6 +138,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") | |||
138 | .handle_irq = omap3_intc_handle_irq, | 138 | .handle_irq = omap3_intc_handle_irq, |
139 | .init_machine = omap_zoom_init, | 139 | .init_machine = omap_zoom_init, |
140 | .timer = &omap3_timer, | 140 | .timer = &omap3_timer, |
141 | .restart = omap_prcm_restart, | ||
141 | MACHINE_END | 142 | MACHINE_END |
142 | 143 | ||
143 | MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") | 144 | MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") |
@@ -149,4 +150,5 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") | |||
149 | .handle_irq = omap3_intc_handle_irq, | 150 | .handle_irq = omap3_intc_handle_irq, |
150 | .init_machine = omap_zoom_init, | 151 | .init_machine = omap_zoom_init, |
151 | .timer = &omap3_timer, | 152 | .timer = &omap3_timer, |
153 | .restart = omap_prcm_restart, | ||
152 | MACHINE_END | 154 | MACHINE_END |
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 1f3481f8d695..f57ed5baeccf 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "cm-regbits-24xx.h" | 35 | #include "cm-regbits-24xx.h" |
36 | #include "cm-regbits-34xx.h" | 36 | #include "cm-regbits-34xx.h" |
37 | 37 | ||
38 | u8 cpu_mask; | 38 | u16 cpu_mask; |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * clkdm_control: if true, then when a clock is enabled in the | 41 | * clkdm_control: if true, then when a clock is enabled in the |
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 2311bc217226..b8c2a686481c 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -132,7 +132,7 @@ void omap2_clk_print_new_rates(const char *hfclkin_ck_name, | |||
132 | const char *core_ck_name, | 132 | const char *core_ck_name, |
133 | const char *mpu_ck_name); | 133 | const char *mpu_ck_name); |
134 | 134 | ||
135 | extern u8 cpu_mask; | 135 | extern u16 cpu_mask; |
136 | 136 | ||
137 | extern const struct clkops clkops_omap2_dflt_wait; | 137 | extern const struct clkops clkops_omap2_dflt_wait; |
138 | extern const struct clkops clkops_dummy; | 138 | extern const struct clkops clkops_dummy; |
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 5d0064a4fb5a..d75e5f6b8a01 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
@@ -2480,6 +2480,16 @@ static struct clk uart4_fck = { | |||
2480 | .recalc = &followparent_recalc, | 2480 | .recalc = &followparent_recalc, |
2481 | }; | 2481 | }; |
2482 | 2482 | ||
2483 | static struct clk uart4_fck_am35xx = { | ||
2484 | .name = "uart4_fck", | ||
2485 | .ops = &clkops_omap2_dflt_wait, | ||
2486 | .parent = &per_48m_fck, | ||
2487 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | ||
2488 | .enable_bit = OMAP3430_EN_UART4_SHIFT, | ||
2489 | .clkdm_name = "core_l4_clkdm", | ||
2490 | .recalc = &followparent_recalc, | ||
2491 | }; | ||
2492 | |||
2483 | static struct clk gpt2_fck = { | 2493 | static struct clk gpt2_fck = { |
2484 | .name = "gpt2_fck", | 2494 | .name = "gpt2_fck", |
2485 | .ops = &clkops_omap2_dflt_wait, | 2495 | .ops = &clkops_omap2_dflt_wait, |
@@ -3287,7 +3297,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3287 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3297 | CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3288 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3298 | CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3289 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3299 | CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3290 | CLK("usbhs-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3300 | CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3291 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), | 3301 | CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), |
3292 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), | 3302 | CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), |
3293 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), | 3303 | CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), |
@@ -3323,7 +3333,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3323 | CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX), | 3333 | CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX), |
3324 | CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), | 3334 | CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), |
3325 | CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3335 | CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3326 | CLK("usbhs-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3336 | CLK("usbhs_omap", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3327 | CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3337 | CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3328 | CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX), | 3338 | CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX), |
3329 | CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX), | 3339 | CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX), |
@@ -3369,20 +3379,18 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3369 | CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), | 3379 | CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), |
3370 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), | 3380 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), |
3371 | CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3381 | CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3372 | CLK("usbhs-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | ||
3373 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3382 | CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3374 | CLK("usbhs-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | ||
3375 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3383 | CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3376 | CLK("usbhs-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), | 3384 | CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), |
3377 | CLK("usbhs-omap.0", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), | 3385 | CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), |
3378 | CLK("usbhs-omap.0", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), | 3386 | CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), |
3379 | CLK("usbhs-omap.0", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), | 3387 | CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), |
3380 | CLK("usbhs-omap.0", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), | 3388 | CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), |
3381 | CLK("usbhs-omap.0", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), | 3389 | CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), |
3382 | CLK("usbhs-omap.0", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), | 3390 | CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), |
3383 | CLK("usbhs-omap.0", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), | 3391 | CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), |
3384 | CLK("usbhs-omap.0", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), | 3392 | CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), |
3385 | CLK("usbhs-omap.0", "init_60m_fclk", &dummy_ck, CK_3XXX), | 3393 | CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX), |
3386 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), | 3394 | CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), |
3387 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), | 3395 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), |
3388 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), | 3396 | CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), |
@@ -3403,6 +3411,7 @@ static struct omap_clk omap3xxx_clks[] = { | |||
3403 | CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX), | 3411 | CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX), |
3404 | CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX), | 3412 | CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX), |
3405 | CLK(NULL, "uart4_fck", &uart4_fck, CK_36XX), | 3413 | CLK(NULL, "uart4_fck", &uart4_fck, CK_36XX), |
3414 | CLK(NULL, "uart4_fck", &uart4_fck_am35xx, CK_3505 | CK_3517), | ||
3406 | CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX), | 3415 | CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX), |
3407 | CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX), | 3416 | CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX), |
3408 | CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX), | 3417 | CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX), |
@@ -3517,6 +3526,10 @@ int __init omap3xxx_clk_init(void) | |||
3517 | } else if (cpu_is_ti816x()) { | 3526 | } else if (cpu_is_ti816x()) { |
3518 | cpu_mask = RATE_IN_TI816X; | 3527 | cpu_mask = RATE_IN_TI816X; |
3519 | cpu_clkflg = CK_TI816X; | 3528 | cpu_clkflg = CK_TI816X; |
3529 | } else if (cpu_is_am33xx()) { | ||
3530 | cpu_mask = RATE_IN_AM33XX; | ||
3531 | } else if (cpu_is_ti814x()) { | ||
3532 | cpu_mask = RATE_IN_TI814X; | ||
3520 | } else if (cpu_is_omap34xx()) { | 3533 | } else if (cpu_is_omap34xx()) { |
3521 | if (omap_rev() == OMAP3430_REV_ES1_0) { | 3534 | if (omap_rev() == OMAP3430_REV_ES1_0) { |
3522 | cpu_mask = RATE_IN_3430ES1; | 3535 | cpu_mask = RATE_IN_3430ES1; |
@@ -3600,7 +3613,7 @@ int __init omap3xxx_clk_init(void) | |||
3600 | * Lock DPLL5 -- here only until other device init code can | 3613 | * Lock DPLL5 -- here only until other device init code can |
3601 | * handle this | 3614 | * handle this |
3602 | */ | 3615 | */ |
3603 | if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0)) | 3616 | if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0)) |
3604 | omap3_clk_lock_dpll5(); | 3617 | omap3_clk_lock_dpll5(); |
3605 | 3618 | ||
3606 | /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ | 3619 | /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ |
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 0798a802497a..08e86d793a1f 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c | |||
@@ -1206,6 +1206,14 @@ static const struct clksel ocp_abe_iclk_div[] = { | |||
1206 | { .parent = NULL }, | 1206 | { .parent = NULL }, |
1207 | }; | 1207 | }; |
1208 | 1208 | ||
1209 | static struct clk mpu_periphclk = { | ||
1210 | .name = "mpu_periphclk", | ||
1211 | .parent = &dpll_mpu_ck, | ||
1212 | .ops = &clkops_null, | ||
1213 | .fixed_div = 2, | ||
1214 | .recalc = &omap_fixed_divisor_recalc, | ||
1215 | }; | ||
1216 | |||
1209 | static struct clk ocp_abe_iclk = { | 1217 | static struct clk ocp_abe_iclk = { |
1210 | .name = "ocp_abe_iclk", | 1218 | .name = "ocp_abe_iclk", |
1211 | .parent = &aess_fclk, | 1219 | .parent = &aess_fclk, |
@@ -3189,6 +3197,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
3189 | CLK(NULL, "l4_div_ck", &l4_div_ck, CK_443X), | 3197 | CLK(NULL, "l4_div_ck", &l4_div_ck, CK_443X), |
3190 | CLK(NULL, "lp_clk_div_ck", &lp_clk_div_ck, CK_443X), | 3198 | CLK(NULL, "lp_clk_div_ck", &lp_clk_div_ck, CK_443X), |
3191 | CLK(NULL, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, CK_443X), | 3199 | CLK(NULL, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, CK_443X), |
3200 | CLK("smp_twd", NULL, &mpu_periphclk, CK_443X), | ||
3192 | CLK(NULL, "ocp_abe_iclk", &ocp_abe_iclk, CK_443X), | 3201 | CLK(NULL, "ocp_abe_iclk", &ocp_abe_iclk, CK_443X), |
3193 | CLK(NULL, "per_abe_24m_fclk", &per_abe_24m_fclk, CK_443X), | 3202 | CLK(NULL, "per_abe_24m_fclk", &per_abe_24m_fclk, CK_443X), |
3194 | CLK(NULL, "per_abe_nc_fclk", &per_abe_nc_fclk, CK_443X), | 3203 | CLK(NULL, "per_abe_nc_fclk", &per_abe_nc_fclk, CK_443X), |
@@ -3295,7 +3304,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
3295 | CLK(NULL, "uart2_fck", &uart2_fck, CK_443X), | 3304 | CLK(NULL, "uart2_fck", &uart2_fck, CK_443X), |
3296 | CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), | 3305 | CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), |
3297 | CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), | 3306 | CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), |
3298 | CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X), | 3307 | CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X), |
3299 | CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), | 3308 | CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), |
3300 | CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X), | 3309 | CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X), |
3301 | CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X), | 3310 | CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X), |
@@ -3306,7 +3315,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
3306 | CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X), | 3315 | CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X), |
3307 | CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), | 3316 | CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), |
3308 | CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), | 3317 | CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), |
3309 | CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X), | 3318 | CLK("usbhs_omap", "hs_fck", &usb_host_hs_fck, CK_443X), |
3310 | CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), | 3319 | CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), |
3311 | CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), | 3320 | CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), |
3312 | CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X), | 3321 | CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X), |
@@ -3314,7 +3323,7 @@ static struct omap_clk omap44xx_clks[] = { | |||
3314 | CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X), | 3323 | CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X), |
3315 | CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), | 3324 | CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), |
3316 | CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), | 3325 | CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), |
3317 | CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X), | 3326 | CLK("usbhs_omap", "usbtll_ick", &usb_tll_hs_ick, CK_443X), |
3318 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), | 3327 | CLK(NULL, "usim_ck", &usim_ck, CK_443X), |
3319 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), | 3328 | CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), |
3320 | CLK(NULL, "usim_fck", &usim_fck, CK_443X), | 3329 | CLK(NULL, "usim_fck", &usim_fck, CK_443X), |
@@ -3374,8 +3383,8 @@ static struct omap_clk omap44xx_clks[] = { | |||
3374 | CLK(NULL, "uart2_ick", &dummy_ck, CK_443X), | 3383 | CLK(NULL, "uart2_ick", &dummy_ck, CK_443X), |
3375 | CLK(NULL, "uart3_ick", &dummy_ck, CK_443X), | 3384 | CLK(NULL, "uart3_ick", &dummy_ck, CK_443X), |
3376 | CLK(NULL, "uart4_ick", &dummy_ck, CK_443X), | 3385 | CLK(NULL, "uart4_ick", &dummy_ck, CK_443X), |
3377 | CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X), | 3386 | CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X), |
3378 | CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X), | 3387 | CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X), |
3379 | CLK("omap_wdt", "ick", &dummy_ck, CK_443X), | 3388 | CLK("omap_wdt", "ick", &dummy_ck, CK_443X), |
3380 | CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X), | 3389 | CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X), |
3381 | CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X), | 3390 | CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X), |
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 684b8a7cd401..aaf421178c91 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c | |||
@@ -110,23 +110,49 @@ void __init omap3_map_io(void) | |||
110 | 110 | ||
111 | /* | 111 | /* |
112 | * Adjust TAP register base such that omap3_check_revision accesses the correct | 112 | * Adjust TAP register base such that omap3_check_revision accesses the correct |
113 | * TI816X register for checking device ID (it adds 0x204 to tap base while | 113 | * TI81XX register for checking device ID (it adds 0x204 to tap base while |
114 | * TI816X DEVICE ID register is at offset 0x600 from control base). | 114 | * TI81XX DEVICE ID register is at offset 0x600 from control base). |
115 | */ | 115 | */ |
116 | #define TI816X_TAP_BASE (TI816X_CTRL_BASE + \ | 116 | #define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \ |
117 | TI816X_CONTROL_DEVICE_ID - 0x204) | 117 | TI81XX_CONTROL_DEVICE_ID - 0x204) |
118 | 118 | ||
119 | static struct omap_globals ti816x_globals = { | 119 | static struct omap_globals ti81xx_globals = { |
120 | .class = OMAP343X_CLASS, | 120 | .class = OMAP343X_CLASS, |
121 | .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), | 121 | .tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE), |
122 | .ctrl = OMAP2_L4_IO_ADDRESS(TI816X_CTRL_BASE), | 122 | .ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE), |
123 | .prm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), | 123 | .prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), |
124 | .cm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), | 124 | .cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), |
125 | }; | 125 | }; |
126 | 126 | ||
127 | void __init omap2_set_globals_ti816x(void) | 127 | void __init omap2_set_globals_ti81xx(void) |
128 | { | 128 | { |
129 | __omap2_set_globals(&ti816x_globals); | 129 | __omap2_set_globals(&ti81xx_globals); |
130 | } | ||
131 | |||
132 | void __init ti81xx_map_io(void) | ||
133 | { | ||
134 | omapti81xx_map_common_io(); | ||
135 | } | ||
136 | |||
137 | #define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \ | ||
138 | TI81XX_CONTROL_DEVICE_ID - 0x204) | ||
139 | |||
140 | static struct omap_globals am33xx_globals = { | ||
141 | .class = AM335X_CLASS, | ||
142 | .tap = AM33XX_L4_WK_IO_ADDRESS(AM33XX_TAP_BASE), | ||
143 | .ctrl = AM33XX_L4_WK_IO_ADDRESS(AM33XX_CTRL_BASE), | ||
144 | .prm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), | ||
145 | .cm = AM33XX_L4_WK_IO_ADDRESS(AM33XX_PRCM_BASE), | ||
146 | }; | ||
147 | |||
148 | void __init omap2_set_globals_am33xx(void) | ||
149 | { | ||
150 | __omap2_set_globals(&am33xx_globals); | ||
151 | } | ||
152 | |||
153 | void __init am33xx_map_io(void) | ||
154 | { | ||
155 | omapam33xx_map_common_io(); | ||
130 | } | 156 | } |
131 | #endif | 157 | #endif |
132 | 158 | ||
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 012bac7d56a5..febffde2ff10 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h | |||
@@ -24,9 +24,11 @@ | |||
24 | 24 | ||
25 | #ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H | 25 | #ifndef __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H |
26 | #define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H | 26 | #define __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H |
27 | #ifndef __ASSEMBLER__ | ||
27 | 28 | ||
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
29 | #include <plat/common.h> | 30 | #include <plat/common.h> |
31 | #include <asm/proc-fns.h> | ||
30 | 32 | ||
31 | #ifdef CONFIG_SOC_OMAP2420 | 33 | #ifdef CONFIG_SOC_OMAP2420 |
32 | extern void omap242x_map_common_io(void); | 34 | extern void omap242x_map_common_io(void); |
@@ -52,10 +54,18 @@ static inline void omap34xx_map_common_io(void) | |||
52 | } | 54 | } |
53 | #endif | 55 | #endif |
54 | 56 | ||
55 | #ifdef CONFIG_SOC_OMAPTI816X | 57 | #ifdef CONFIG_SOC_OMAPTI81XX |
56 | extern void omapti816x_map_common_io(void); | 58 | extern void omapti81xx_map_common_io(void); |
57 | #else | 59 | #else |
58 | static inline void omapti816x_map_common_io(void) | 60 | static inline void omapti81xx_map_common_io(void) |
61 | { | ||
62 | } | ||
63 | #endif | ||
64 | |||
65 | #ifdef CONFIG_SOC_OMAPAM33XX | ||
66 | extern void omapam33xx_map_common_io(void); | ||
67 | #else | ||
68 | static inline void omapam33xx_map_common_io(void) | ||
59 | { | 69 | { |
60 | } | 70 | } |
61 | #endif | 71 | #endif |
@@ -82,8 +92,9 @@ void omap35xx_init_early(void); | |||
82 | void omap3630_init_early(void); | 92 | void omap3630_init_early(void); |
83 | void omap3_init_early(void); /* Do not use this one */ | 93 | void omap3_init_early(void); /* Do not use this one */ |
84 | void am35xx_init_early(void); | 94 | void am35xx_init_early(void); |
85 | void ti816x_init_early(void); | 95 | void ti81xx_init_early(void); |
86 | void omap4430_init_early(void); | 96 | void omap4430_init_early(void); |
97 | void omap_prcm_restart(char, const char *); | ||
87 | 98 | ||
88 | /* | 99 | /* |
89 | * IO bases for various OMAP processors | 100 | * IO bases for various OMAP processors |
@@ -106,7 +117,8 @@ void omap2_set_globals_242x(void); | |||
106 | void omap2_set_globals_243x(void); | 117 | void omap2_set_globals_243x(void); |
107 | void omap2_set_globals_3xxx(void); | 118 | void omap2_set_globals_3xxx(void); |
108 | void omap2_set_globals_443x(void); | 119 | void omap2_set_globals_443x(void); |
109 | void omap2_set_globals_ti816x(void); | 120 | void omap2_set_globals_ti81xx(void); |
121 | void omap2_set_globals_am33xx(void); | ||
110 | 122 | ||
111 | /* These get called from omap2_set_globals_xxxx(), do not call these */ | 123 | /* These get called from omap2_set_globals_xxxx(), do not call these */ |
112 | void omap2_set_globals_tap(struct omap_globals *); | 124 | void omap2_set_globals_tap(struct omap_globals *); |
@@ -117,7 +129,9 @@ void omap2_set_globals_prcm(struct omap_globals *); | |||
117 | void omap242x_map_io(void); | 129 | void omap242x_map_io(void); |
118 | void omap243x_map_io(void); | 130 | void omap243x_map_io(void); |
119 | void omap3_map_io(void); | 131 | void omap3_map_io(void); |
132 | void am33xx_map_io(void); | ||
120 | void omap4_map_io(void); | 133 | void omap4_map_io(void); |
134 | void ti81xx_map_io(void); | ||
121 | 135 | ||
122 | /** | 136 | /** |
123 | * omap_test_timeout - busy-loop, testing a condition | 137 | * omap_test_timeout - busy-loop, testing a condition |
@@ -146,7 +160,7 @@ extern struct device *omap4_get_dsp_device(void); | |||
146 | 160 | ||
147 | void omap2_init_irq(void); | 161 | void omap2_init_irq(void); |
148 | void omap3_init_irq(void); | 162 | void omap3_init_irq(void); |
149 | void ti816x_init_irq(void); | 163 | void ti81xx_init_irq(void); |
150 | extern int omap_irq_pending(void); | 164 | extern int omap_irq_pending(void); |
151 | void omap_intc_save_context(void); | 165 | void omap_intc_save_context(void); |
152 | void omap_intc_restore_context(void); | 166 | void omap_intc_restore_context(void); |
@@ -156,23 +170,23 @@ void omap3_intc_resume_idle(void); | |||
156 | void omap2_intc_handle_irq(struct pt_regs *regs); | 170 | void omap2_intc_handle_irq(struct pt_regs *regs); |
157 | void omap3_intc_handle_irq(struct pt_regs *regs); | 171 | void omap3_intc_handle_irq(struct pt_regs *regs); |
158 | 172 | ||
159 | /* | 173 | #ifdef CONFIG_CACHE_L2X0 |
160 | * wfi used in low power code. Directly opcode is used instead | 174 | extern void __iomem *omap4_get_l2cache_base(void); |
161 | * of instruction to avoid mulit-omap build break | ||
162 | */ | ||
163 | #ifdef CONFIG_THUMB2_KERNEL | ||
164 | #define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory") | ||
165 | #else | ||
166 | #define do_wfi() \ | ||
167 | __asm__ __volatile__ (".word 0xe320f003" : : : "memory") | ||
168 | #endif | 175 | #endif |
169 | 176 | ||
170 | #ifdef CONFIG_CACHE_L2X0 | 177 | #ifdef CONFIG_SMP |
171 | extern void __iomem *l2cache_base; | 178 | extern void __iomem *omap4_get_scu_base(void); |
179 | #else | ||
180 | static inline void __iomem *omap4_get_scu_base(void) | ||
181 | { | ||
182 | return NULL; | ||
183 | } | ||
172 | #endif | 184 | #endif |
173 | 185 | ||
174 | extern void __init gic_init_irq(void); | 186 | extern void __init gic_init_irq(void); |
175 | extern void omap_smc1(u32 fn, u32 arg); | 187 | extern void omap_smc1(u32 fn, u32 arg); |
188 | extern void __iomem *omap4_get_sar_ram_base(void); | ||
189 | extern void omap_do_wfi(void); | ||
176 | 190 | ||
177 | #ifdef CONFIG_SMP | 191 | #ifdef CONFIG_SMP |
178 | /* Needed for secondary core boot */ | 192 | /* Needed for secondary core boot */ |
@@ -182,4 +196,44 @@ extern void omap_auxcoreboot_addr(u32 cpu_addr); | |||
182 | extern u32 omap_read_auxcoreboot0(void); | 196 | extern u32 omap_read_auxcoreboot0(void); |
183 | #endif | 197 | #endif |
184 | 198 | ||
199 | #if defined(CONFIG_SMP) && defined(CONFIG_PM) | ||
200 | extern int omap4_mpuss_init(void); | ||
201 | extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state); | ||
202 | extern int omap4_finish_suspend(unsigned long cpu_state); | ||
203 | extern void omap4_cpu_resume(void); | ||
204 | extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); | ||
205 | extern u32 omap4_mpuss_read_prev_context_state(void); | ||
206 | #else | ||
207 | static inline int omap4_enter_lowpower(unsigned int cpu, | ||
208 | unsigned int power_state) | ||
209 | { | ||
210 | cpu_do_idle(); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) | ||
215 | { | ||
216 | cpu_do_idle(); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static inline int omap4_mpuss_init(void) | ||
221 | { | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static inline int omap4_finish_suspend(unsigned long cpu_state) | ||
226 | { | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static inline void omap4_cpu_resume(void) | ||
231 | {} | ||
232 | |||
233 | static inline u32 omap4_mpuss_read_prev_context_state(void) | ||
234 | { | ||
235 | return 0; | ||
236 | } | ||
237 | #endif | ||
238 | #endif /* __ASSEMBLER__ */ | ||
185 | #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ | 239 | #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ |
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index d4ef75d5a382..0ba68d3764bc 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h | |||
@@ -52,8 +52,8 @@ | |||
52 | #define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 | 52 | #define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 |
53 | #define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 | 53 | #define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 |
54 | 54 | ||
55 | /* TI816X spefic control submodules */ | 55 | /* TI81XX spefic control submodules */ |
56 | #define TI816X_CONTROL_DEVCONF 0x600 | 56 | #define TI81XX_CONTROL_DEVCONF 0x600 |
57 | 57 | ||
58 | /* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ | 58 | /* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ |
59 | 59 | ||
@@ -244,8 +244,8 @@ | |||
244 | #define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 | 244 | #define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 |
245 | #define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 | 245 | #define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 |
246 | 246 | ||
247 | /* TI816X CONTROL_DEVCONF register offsets */ | 247 | /* TI81XX CONTROL_DEVCONF register offsets */ |
248 | #define TI816X_CONTROL_DEVICE_ID (TI816X_CONTROL_DEVCONF + 0x000) | 248 | #define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000) |
249 | 249 | ||
250 | /* | 250 | /* |
251 | * REVISIT: This list of registers is not comprehensive - there are more | 251 | * REVISIT: This list of registers is not comprehensive - there are more |
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index e20332f4abdc..464cffde58fe 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c | |||
@@ -25,12 +25,12 @@ | |||
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/cpuidle.h> | 26 | #include <linux/cpuidle.h> |
27 | #include <linux/export.h> | 27 | #include <linux/export.h> |
28 | #include <linux/cpu_pm.h> | ||
28 | 29 | ||
29 | #include <plat/prcm.h> | 30 | #include <plat/prcm.h> |
30 | #include <plat/irqs.h> | 31 | #include <plat/irqs.h> |
31 | #include "powerdomain.h" | 32 | #include "powerdomain.h" |
32 | #include "clockdomain.h" | 33 | #include "clockdomain.h" |
33 | #include <plat/serial.h> | ||
34 | 34 | ||
35 | #include "pm.h" | 35 | #include "pm.h" |
36 | #include "control.h" | 36 | #include "control.h" |
@@ -124,9 +124,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev, | |||
124 | pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); | 124 | pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle); |
125 | } | 125 | } |
126 | 126 | ||
127 | /* | ||
128 | * Call idle CPU PM enter notifier chain so that | ||
129 | * VFP context is saved. | ||
130 | */ | ||
131 | if (mpu_state == PWRDM_POWER_OFF) | ||
132 | cpu_pm_enter(); | ||
133 | |||
127 | /* Execute ARM wfi */ | 134 | /* Execute ARM wfi */ |
128 | omap_sram_idle(); | 135 | omap_sram_idle(); |
129 | 136 | ||
137 | /* | ||
138 | * Call idle CPU PM enter notifier chain to restore | ||
139 | * VFP context. | ||
140 | */ | ||
141 | if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) | ||
142 | cpu_pm_exit(); | ||
143 | |||
130 | /* Re-allow idle for C1 */ | 144 | /* Re-allow idle for C1 */ |
131 | if (index == 0) { | 145 | if (index == 0) { |
132 | pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); | 146 | pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle); |
@@ -245,11 +259,6 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
245 | struct omap3_idle_statedata *cx; | 259 | struct omap3_idle_statedata *cx; |
246 | int ret; | 260 | int ret; |
247 | 261 | ||
248 | if (!omap3_can_sleep()) { | ||
249 | new_state_idx = drv->safe_state_index; | ||
250 | goto select_state; | ||
251 | } | ||
252 | |||
253 | /* | 262 | /* |
254 | * Prevent idle completely if CAM is active. | 263 | * Prevent idle completely if CAM is active. |
255 | * CAM does not have wakeup capability in OMAP3. | 264 | * CAM does not have wakeup capability in OMAP3. |
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c new file mode 100644 index 000000000000..cfdbb86bc84e --- /dev/null +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
@@ -0,0 +1,245 @@ | |||
1 | /* | ||
2 | * OMAP4 CPU idle Routines | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
6 | * Rajendra Nayak <rnayak@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/sched.h> | ||
14 | #include <linux/cpuidle.h> | ||
15 | #include <linux/cpu_pm.h> | ||
16 | #include <linux/export.h> | ||
17 | #include <linux/clockchips.h> | ||
18 | |||
19 | #include <asm/proc-fns.h> | ||
20 | |||
21 | #include "common.h" | ||
22 | #include "pm.h" | ||
23 | #include "prm.h" | ||
24 | |||
25 | #ifdef CONFIG_CPU_IDLE | ||
26 | |||
27 | /* Machine specific information to be recorded in the C-state driver_data */ | ||
28 | struct omap4_idle_statedata { | ||
29 | u32 cpu_state; | ||
30 | u32 mpu_logic_state; | ||
31 | u32 mpu_state; | ||
32 | u8 valid; | ||
33 | }; | ||
34 | |||
35 | static struct cpuidle_params cpuidle_params_table[] = { | ||
36 | /* C1 - CPU0 ON + CPU1 ON + MPU ON */ | ||
37 | {.exit_latency = 2 + 2 , .target_residency = 5, .valid = 1}, | ||
38 | /* C2- CPU0 OFF + CPU1 OFF + MPU CSWR */ | ||
39 | {.exit_latency = 328 + 440 , .target_residency = 960, .valid = 1}, | ||
40 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | ||
41 | {.exit_latency = 460 + 518 , .target_residency = 1100, .valid = 1}, | ||
42 | }; | ||
43 | |||
44 | #define OMAP4_NUM_STATES ARRAY_SIZE(cpuidle_params_table) | ||
45 | |||
46 | struct omap4_idle_statedata omap4_idle_data[OMAP4_NUM_STATES]; | ||
47 | static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; | ||
48 | |||
49 | /** | ||
50 | * omap4_enter_idle - Programs OMAP4 to enter the specified state | ||
51 | * @dev: cpuidle device | ||
52 | * @drv: cpuidle driver | ||
53 | * @index: the index of state to be entered | ||
54 | * | ||
55 | * Called from the CPUidle framework to program the device to the | ||
56 | * specified low power state selected by the governor. | ||
57 | * Returns the amount of time spent in the low power state. | ||
58 | */ | ||
59 | static int omap4_enter_idle(struct cpuidle_device *dev, | ||
60 | struct cpuidle_driver *drv, | ||
61 | int index) | ||
62 | { | ||
63 | struct omap4_idle_statedata *cx = | ||
64 | cpuidle_get_statedata(&dev->states_usage[index]); | ||
65 | struct timespec ts_preidle, ts_postidle, ts_idle; | ||
66 | u32 cpu1_state; | ||
67 | int idle_time; | ||
68 | int new_state_idx; | ||
69 | int cpu_id = smp_processor_id(); | ||
70 | |||
71 | /* Used to keep track of the total time in idle */ | ||
72 | getnstimeofday(&ts_preidle); | ||
73 | |||
74 | local_irq_disable(); | ||
75 | local_fiq_disable(); | ||
76 | |||
77 | /* | ||
78 | * CPU0 has to stay ON (i.e in C1) until CPU1 is OFF state. | ||
79 | * This is necessary to honour hardware recommondation | ||
80 | * of triggeing all the possible low power modes once CPU1 is | ||
81 | * out of coherency and in OFF mode. | ||
82 | * Update dev->last_state so that governor stats reflects right | ||
83 | * data. | ||
84 | */ | ||
85 | cpu1_state = pwrdm_read_pwrst(cpu1_pd); | ||
86 | if (cpu1_state != PWRDM_POWER_OFF) { | ||
87 | new_state_idx = drv->safe_state_index; | ||
88 | cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]); | ||
89 | } | ||
90 | |||
91 | if (index > 0) | ||
92 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); | ||
93 | |||
94 | /* | ||
95 | * Call idle CPU PM enter notifier chain so that | ||
96 | * VFP and per CPU interrupt context is saved. | ||
97 | */ | ||
98 | if (cx->cpu_state == PWRDM_POWER_OFF) | ||
99 | cpu_pm_enter(); | ||
100 | |||
101 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); | ||
102 | omap_set_pwrdm_state(mpu_pd, cx->mpu_state); | ||
103 | |||
104 | /* | ||
105 | * Call idle CPU cluster PM enter notifier chain | ||
106 | * to save GIC and wakeupgen context. | ||
107 | */ | ||
108 | if ((cx->mpu_state == PWRDM_POWER_RET) && | ||
109 | (cx->mpu_logic_state == PWRDM_POWER_OFF)) | ||
110 | cpu_cluster_pm_enter(); | ||
111 | |||
112 | omap4_enter_lowpower(dev->cpu, cx->cpu_state); | ||
113 | |||
114 | /* | ||
115 | * Call idle CPU PM exit notifier chain to restore | ||
116 | * VFP and per CPU IRQ context. Only CPU0 state is | ||
117 | * considered since CPU1 is managed by CPU hotplug. | ||
118 | */ | ||
119 | if (pwrdm_read_prev_pwrst(cpu0_pd) == PWRDM_POWER_OFF) | ||
120 | cpu_pm_exit(); | ||
121 | |||
122 | /* | ||
123 | * Call idle CPU cluster PM exit notifier chain | ||
124 | * to restore GIC and wakeupgen context. | ||
125 | */ | ||
126 | if (omap4_mpuss_read_prev_context_state()) | ||
127 | cpu_cluster_pm_exit(); | ||
128 | |||
129 | if (index > 0) | ||
130 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); | ||
131 | |||
132 | getnstimeofday(&ts_postidle); | ||
133 | ts_idle = timespec_sub(ts_postidle, ts_preidle); | ||
134 | |||
135 | local_irq_enable(); | ||
136 | local_fiq_enable(); | ||
137 | |||
138 | idle_time = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * \ | ||
139 | USEC_PER_SEC; | ||
140 | |||
141 | /* Update cpuidle counters */ | ||
142 | dev->last_residency = idle_time; | ||
143 | |||
144 | return index; | ||
145 | } | ||
146 | |||
147 | DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); | ||
148 | |||
149 | struct cpuidle_driver omap4_idle_driver = { | ||
150 | .name = "omap4_idle", | ||
151 | .owner = THIS_MODULE, | ||
152 | }; | ||
153 | |||
154 | static inline void _fill_cstate(struct cpuidle_driver *drv, | ||
155 | int idx, const char *descr) | ||
156 | { | ||
157 | struct cpuidle_state *state = &drv->states[idx]; | ||
158 | |||
159 | state->exit_latency = cpuidle_params_table[idx].exit_latency; | ||
160 | state->target_residency = cpuidle_params_table[idx].target_residency; | ||
161 | state->flags = CPUIDLE_FLAG_TIME_VALID; | ||
162 | state->enter = omap4_enter_idle; | ||
163 | sprintf(state->name, "C%d", idx + 1); | ||
164 | strncpy(state->desc, descr, CPUIDLE_DESC_LEN); | ||
165 | } | ||
166 | |||
167 | static inline struct omap4_idle_statedata *_fill_cstate_usage( | ||
168 | struct cpuidle_device *dev, | ||
169 | int idx) | ||
170 | { | ||
171 | struct omap4_idle_statedata *cx = &omap4_idle_data[idx]; | ||
172 | struct cpuidle_state_usage *state_usage = &dev->states_usage[idx]; | ||
173 | |||
174 | cx->valid = cpuidle_params_table[idx].valid; | ||
175 | cpuidle_set_statedata(state_usage, cx); | ||
176 | |||
177 | return cx; | ||
178 | } | ||
179 | |||
180 | |||
181 | |||
182 | /** | ||
183 | * omap4_idle_init - Init routine for OMAP4 idle | ||
184 | * | ||
185 | * Registers the OMAP4 specific cpuidle driver to the cpuidle | ||
186 | * framework with the valid set of states. | ||
187 | */ | ||
188 | int __init omap4_idle_init(void) | ||
189 | { | ||
190 | struct omap4_idle_statedata *cx; | ||
191 | struct cpuidle_device *dev; | ||
192 | struct cpuidle_driver *drv = &omap4_idle_driver; | ||
193 | unsigned int cpu_id = 0; | ||
194 | |||
195 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); | ||
196 | cpu0_pd = pwrdm_lookup("cpu0_pwrdm"); | ||
197 | cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); | ||
198 | if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) | ||
199 | return -ENODEV; | ||
200 | |||
201 | |||
202 | drv->safe_state_index = -1; | ||
203 | dev = &per_cpu(omap4_idle_dev, cpu_id); | ||
204 | dev->cpu = cpu_id; | ||
205 | |||
206 | /* C1 - CPU0 ON + CPU1 ON + MPU ON */ | ||
207 | _fill_cstate(drv, 0, "MPUSS ON"); | ||
208 | drv->safe_state_index = 0; | ||
209 | cx = _fill_cstate_usage(dev, 0); | ||
210 | cx->valid = 1; /* C1 is always valid */ | ||
211 | cx->cpu_state = PWRDM_POWER_ON; | ||
212 | cx->mpu_state = PWRDM_POWER_ON; | ||
213 | cx->mpu_logic_state = PWRDM_POWER_RET; | ||
214 | |||
215 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ | ||
216 | _fill_cstate(drv, 1, "MPUSS CSWR"); | ||
217 | cx = _fill_cstate_usage(dev, 1); | ||
218 | cx->cpu_state = PWRDM_POWER_OFF; | ||
219 | cx->mpu_state = PWRDM_POWER_RET; | ||
220 | cx->mpu_logic_state = PWRDM_POWER_RET; | ||
221 | |||
222 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | ||
223 | _fill_cstate(drv, 2, "MPUSS OSWR"); | ||
224 | cx = _fill_cstate_usage(dev, 2); | ||
225 | cx->cpu_state = PWRDM_POWER_OFF; | ||
226 | cx->mpu_state = PWRDM_POWER_RET; | ||
227 | cx->mpu_logic_state = PWRDM_POWER_OFF; | ||
228 | |||
229 | drv->state_count = OMAP4_NUM_STATES; | ||
230 | cpuidle_register_driver(&omap4_idle_driver); | ||
231 | |||
232 | dev->state_count = OMAP4_NUM_STATES; | ||
233 | if (cpuidle_register_device(dev)) { | ||
234 | pr_err("%s: CPUidle register device failed\n", __func__); | ||
235 | return -EIO; | ||
236 | } | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | #else | ||
241 | int __init omap4_idle_init(void) | ||
242 | { | ||
243 | return 0; | ||
244 | } | ||
245 | #endif /* CONFIG_CPU_IDLE */ | ||
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index c15cfada5f13..283d11eae693 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -127,6 +127,10 @@ static struct platform_device omap2cam_device = { | |||
127 | }; | 127 | }; |
128 | #endif | 128 | #endif |
129 | 129 | ||
130 | #if defined(CONFIG_IOMMU_API) | ||
131 | |||
132 | #include <plat/iommu.h> | ||
133 | |||
130 | static struct resource omap3isp_resources[] = { | 134 | static struct resource omap3isp_resources[] = { |
131 | { | 135 | { |
132 | .start = OMAP3430_ISP_BASE, | 136 | .start = OMAP3430_ISP_BASE, |
@@ -211,12 +215,27 @@ static struct platform_device omap3isp_device = { | |||
211 | .resource = omap3isp_resources, | 215 | .resource = omap3isp_resources, |
212 | }; | 216 | }; |
213 | 217 | ||
218 | static struct omap_iommu_arch_data omap3_isp_iommu = { | ||
219 | .name = "isp", | ||
220 | }; | ||
221 | |||
214 | int omap3_init_camera(struct isp_platform_data *pdata) | 222 | int omap3_init_camera(struct isp_platform_data *pdata) |
215 | { | 223 | { |
216 | omap3isp_device.dev.platform_data = pdata; | 224 | omap3isp_device.dev.platform_data = pdata; |
225 | omap3isp_device.dev.archdata.iommu = &omap3_isp_iommu; | ||
226 | |||
217 | return platform_device_register(&omap3isp_device); | 227 | return platform_device_register(&omap3isp_device); |
218 | } | 228 | } |
219 | 229 | ||
230 | #else /* !CONFIG_IOMMU_API */ | ||
231 | |||
232 | int omap3_init_camera(struct isp_platform_data *pdata) | ||
233 | { | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | #endif | ||
238 | |||
220 | static inline void omap_init_camera(void) | 239 | static inline void omap_init_camera(void) |
221 | { | 240 | { |
222 | #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) | 241 | #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) |
@@ -336,6 +355,27 @@ static void omap_init_mcpdm(void) | |||
336 | static inline void omap_init_mcpdm(void) {} | 355 | static inline void omap_init_mcpdm(void) {} |
337 | #endif | 356 | #endif |
338 | 357 | ||
358 | #if defined(CONFIG_SND_OMAP_SOC_DMIC) || \ | ||
359 | defined(CONFIG_SND_OMAP_SOC_DMIC_MODULE) | ||
360 | |||
361 | static void omap_init_dmic(void) | ||
362 | { | ||
363 | struct omap_hwmod *oh; | ||
364 | struct platform_device *pdev; | ||
365 | |||
366 | oh = omap_hwmod_lookup("dmic"); | ||
367 | if (!oh) { | ||
368 | printk(KERN_ERR "Could not look up mcpdm hw_mod\n"); | ||
369 | return; | ||
370 | } | ||
371 | |||
372 | pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0); | ||
373 | WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n"); | ||
374 | } | ||
375 | #else | ||
376 | static inline void omap_init_dmic(void) {} | ||
377 | #endif | ||
378 | |||
339 | #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) | 379 | #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) |
340 | 380 | ||
341 | #include <plat/mcspi.h> | 381 | #include <plat/mcspi.h> |
@@ -365,6 +405,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) | |||
365 | break; | 405 | break; |
366 | default: | 406 | default: |
367 | pr_err("Invalid McSPI Revision value\n"); | 407 | pr_err("Invalid McSPI Revision value\n"); |
408 | kfree(pdata); | ||
368 | return -EINVAL; | 409 | return -EINVAL; |
369 | } | 410 | } |
370 | 411 | ||
@@ -681,6 +722,7 @@ static int __init omap2_init_devices(void) | |||
681 | */ | 722 | */ |
682 | omap_init_audio(); | 723 | omap_init_audio(); |
683 | omap_init_mcpdm(); | 724 | omap_init_mcpdm(); |
725 | omap_init_dmic(); | ||
684 | omap_init_camera(); | 726 | omap_init_camera(); |
685 | omap_init_mbox(); | 727 | omap_init_mbox(); |
686 | omap_init_mcspi(); | 728 | omap_init_mcspi(); |
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index bc6cf863a563..3677b1f58b85 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <plat/omap-pm.h> | 30 | #include <plat/omap-pm.h> |
31 | #include "common.h" | 31 | #include "common.h" |
32 | 32 | ||
33 | #include "mux.h" | ||
33 | #include "control.h" | 34 | #include "control.h" |
34 | #include "display.h" | 35 | #include "display.h" |
35 | 36 | ||
@@ -97,6 +98,32 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = { | |||
97 | { "dss_hdmi", "omapdss_hdmi", -1 }, | 98 | { "dss_hdmi", "omapdss_hdmi", -1 }, |
98 | }; | 99 | }; |
99 | 100 | ||
101 | static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) | ||
102 | { | ||
103 | u32 reg; | ||
104 | u16 control_i2c_1; | ||
105 | |||
106 | omap_mux_init_signal("hdmi_cec", | ||
107 | OMAP_PIN_INPUT_PULLUP); | ||
108 | omap_mux_init_signal("hdmi_ddc_scl", | ||
109 | OMAP_PIN_INPUT_PULLUP); | ||
110 | omap_mux_init_signal("hdmi_ddc_sda", | ||
111 | OMAP_PIN_INPUT_PULLUP); | ||
112 | |||
113 | /* | ||
114 | * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and | ||
115 | * HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable | ||
116 | * internal pull up resistor. | ||
117 | */ | ||
118 | if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) { | ||
119 | control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1; | ||
120 | reg = omap4_ctrl_pad_readl(control_i2c_1); | ||
121 | reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK | | ||
122 | OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK); | ||
123 | omap4_ctrl_pad_writel(reg, control_i2c_1); | ||
124 | } | ||
125 | } | ||
126 | |||
100 | static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) | 127 | static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) |
101 | { | 128 | { |
102 | u32 enable_mask, enable_shift; | 129 | u32 enable_mask, enable_shift; |
@@ -130,6 +157,14 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) | |||
130 | return 0; | 157 | return 0; |
131 | } | 158 | } |
132 | 159 | ||
160 | int omap_hdmi_init(enum omap_hdmi_flags flags) | ||
161 | { | ||
162 | if (cpu_is_omap44xx()) | ||
163 | omap4_hdmi_mux_pads(flags); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
133 | static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask) | 168 | static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask) |
134 | { | 169 | { |
135 | if (cpu_is_omap44xx()) | 170 | if (cpu_is_omap44xx()) |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 130034bf01d5..dfffbbf4c009 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -528,7 +528,13 @@ int gpmc_cs_configure(int cs, int cmd, int wval) | |||
528 | 528 | ||
529 | case GPMC_CONFIG_DEV_SIZE: | 529 | case GPMC_CONFIG_DEV_SIZE: |
530 | regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); | 530 | regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); |
531 | |||
532 | /* clear 2 target bits */ | ||
533 | regval &= ~GPMC_CONFIG1_DEVICESIZE(3); | ||
534 | |||
535 | /* set the proper value */ | ||
531 | regval |= GPMC_CONFIG1_DEVICESIZE(wval); | 536 | regval |= GPMC_CONFIG1_DEVICESIZE(wval); |
537 | |||
532 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); | 538 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval); |
533 | break; | 539 | break; |
534 | 540 | ||
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index f4a1020559a7..ad0adb5a1e0e 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c | |||
@@ -171,7 +171,19 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot, | |||
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
174 | static void hsmmc23_before_set_reg(struct device *dev, int slot, | 174 | static void hsmmc2_select_input_clk_src(struct omap_mmc_platform_data *mmc) |
175 | { | ||
176 | u32 reg; | ||
177 | |||
178 | reg = omap_ctrl_readl(control_devconf1_offset); | ||
179 | if (mmc->slots[0].internal_clock) | ||
180 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; | ||
181 | else | ||
182 | reg &= ~OMAP2_MMCSDIO2ADPCLKISEL; | ||
183 | omap_ctrl_writel(reg, control_devconf1_offset); | ||
184 | } | ||
185 | |||
186 | static void hsmmc2_before_set_reg(struct device *dev, int slot, | ||
175 | int power_on, int vdd) | 187 | int power_on, int vdd) |
176 | { | 188 | { |
177 | struct omap_mmc_platform_data *mmc = dev->platform_data; | 189 | struct omap_mmc_platform_data *mmc = dev->platform_data; |
@@ -179,16 +191,19 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot, | |||
179 | if (mmc->slots[0].remux) | 191 | if (mmc->slots[0].remux) |
180 | mmc->slots[0].remux(dev, slot, power_on); | 192 | mmc->slots[0].remux(dev, slot, power_on); |
181 | 193 | ||
182 | if (power_on) { | 194 | if (power_on) |
183 | /* Only MMC2 supports a CLKIN */ | 195 | hsmmc2_select_input_clk_src(mmc); |
184 | if (mmc->slots[0].internal_clock) { | 196 | } |
185 | u32 reg; | ||
186 | 197 | ||
187 | reg = omap_ctrl_readl(control_devconf1_offset); | 198 | static int am35x_hsmmc2_set_power(struct device *dev, int slot, |
188 | reg |= OMAP2_MMCSDIO2ADPCLKISEL; | 199 | int power_on, int vdd) |
189 | omap_ctrl_writel(reg, control_devconf1_offset); | 200 | { |
190 | } | 201 | struct omap_mmc_platform_data *mmc = dev->platform_data; |
191 | } | 202 | |
203 | if (power_on) | ||
204 | hsmmc2_select_input_clk_src(mmc); | ||
205 | |||
206 | return 0; | ||
192 | } | 207 | } |
193 | 208 | ||
194 | static int nop_mmc_set_power(struct device *dev, int slot, int power_on, | 209 | static int nop_mmc_set_power(struct device *dev, int slot, int power_on, |
@@ -200,10 +215,12 @@ static int nop_mmc_set_power(struct device *dev, int slot, int power_on, | |||
200 | static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, | 215 | static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, |
201 | int controller_nr) | 216 | int controller_nr) |
202 | { | 217 | { |
203 | if (gpio_is_valid(mmc_controller->slots[0].switch_pin)) | 218 | if (gpio_is_valid(mmc_controller->slots[0].switch_pin) && |
219 | (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) | ||
204 | omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, | 220 | omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, |
205 | OMAP_PIN_INPUT_PULLUP); | 221 | OMAP_PIN_INPUT_PULLUP); |
206 | if (gpio_is_valid(mmc_controller->slots[0].gpio_wp)) | 222 | if (gpio_is_valid(mmc_controller->slots[0].gpio_wp) && |
223 | (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) | ||
207 | omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, | 224 | omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, |
208 | OMAP_PIN_INPUT_PULLUP); | 225 | OMAP_PIN_INPUT_PULLUP); |
209 | if (cpu_is_omap34xx()) { | 226 | if (cpu_is_omap34xx()) { |
@@ -296,6 +313,7 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, | |||
296 | mmc->slots[0].name = hc_name; | 313 | mmc->slots[0].name = hc_name; |
297 | mmc->nr_slots = 1; | 314 | mmc->nr_slots = 1; |
298 | mmc->slots[0].caps = c->caps; | 315 | mmc->slots[0].caps = c->caps; |
316 | mmc->slots[0].pm_caps = c->pm_caps; | ||
299 | mmc->slots[0].internal_clock = !c->ext_clock; | 317 | mmc->slots[0].internal_clock = !c->ext_clock; |
300 | mmc->dma_mask = 0xffffffff; | 318 | mmc->dma_mask = 0xffffffff; |
301 | if (cpu_is_omap44xx()) | 319 | if (cpu_is_omap44xx()) |
@@ -336,11 +354,17 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, | |||
336 | * | 354 | * |
337 | * temporary HACK: ocr_mask instead of fixed supply | 355 | * temporary HACK: ocr_mask instead of fixed supply |
338 | */ | 356 | */ |
339 | mmc->slots[0].ocr_mask = c->ocr_mask; | 357 | if (cpu_is_omap3505() || cpu_is_omap3517()) |
340 | 358 | mmc->slots[0].ocr_mask = MMC_VDD_165_195 | | |
341 | if (cpu_is_omap3517() || cpu_is_omap3505()) | 359 | MMC_VDD_26_27 | |
342 | mmc->slots[0].set_power = nop_mmc_set_power; | 360 | MMC_VDD_27_28 | |
361 | MMC_VDD_29_30 | | ||
362 | MMC_VDD_30_31 | | ||
363 | MMC_VDD_31_32; | ||
343 | else | 364 | else |
365 | mmc->slots[0].ocr_mask = c->ocr_mask; | ||
366 | |||
367 | if (!cpu_is_omap3517() && !cpu_is_omap3505()) | ||
344 | mmc->slots[0].features |= HSMMC_HAS_PBIAS; | 368 | mmc->slots[0].features |= HSMMC_HAS_PBIAS; |
345 | 369 | ||
346 | if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) | 370 | if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) |
@@ -363,6 +387,9 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, | |||
363 | } | 387 | } |
364 | } | 388 | } |
365 | 389 | ||
390 | if (cpu_is_omap3517() || cpu_is_omap3505()) | ||
391 | mmc->slots[0].set_power = nop_mmc_set_power; | ||
392 | |||
366 | /* OMAP3630 HSMMC1 supports only 4-bit */ | 393 | /* OMAP3630 HSMMC1 supports only 4-bit */ |
367 | if (cpu_is_omap3630() && | 394 | if (cpu_is_omap3630() && |
368 | (c->caps & MMC_CAP_8_BIT_DATA)) { | 395 | (c->caps & MMC_CAP_8_BIT_DATA)) { |
@@ -372,20 +399,22 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, | |||
372 | } | 399 | } |
373 | break; | 400 | break; |
374 | case 2: | 401 | case 2: |
402 | if (cpu_is_omap3517() || cpu_is_omap3505()) | ||
403 | mmc->slots[0].set_power = am35x_hsmmc2_set_power; | ||
404 | |||
375 | if (c->ext_clock) | 405 | if (c->ext_clock) |
376 | c->transceiver = 1; | 406 | c->transceiver = 1; |
377 | if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { | 407 | if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { |
378 | c->caps &= ~MMC_CAP_8_BIT_DATA; | 408 | c->caps &= ~MMC_CAP_8_BIT_DATA; |
379 | c->caps |= MMC_CAP_4_BIT_DATA; | 409 | c->caps |= MMC_CAP_4_BIT_DATA; |
380 | } | 410 | } |
381 | /* FALLTHROUGH */ | ||
382 | case 3: | ||
383 | if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { | 411 | if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { |
384 | /* off-chip level shifting, or none */ | 412 | /* off-chip level shifting, or none */ |
385 | mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; | 413 | mmc->slots[0].before_set_reg = hsmmc2_before_set_reg; |
386 | mmc->slots[0].after_set_reg = NULL; | 414 | mmc->slots[0].after_set_reg = NULL; |
387 | } | 415 | } |
388 | break; | 416 | break; |
417 | case 3: | ||
389 | case 4: | 418 | case 4: |
390 | case 5: | 419 | case 5: |
391 | mmc->slots[0].before_set_reg = NULL; | 420 | mmc->slots[0].before_set_reg = NULL; |
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h index f757e78d4d4f..c4409730c4bb 100644 --- a/arch/arm/mach-omap2/hsmmc.h +++ b/arch/arm/mach-omap2/hsmmc.h | |||
@@ -12,6 +12,7 @@ struct omap2_hsmmc_info { | |||
12 | u8 mmc; /* controller 1/2/3 */ | 12 | u8 mmc; /* controller 1/2/3 */ |
13 | u32 caps; /* 4/8 wires and any additional host | 13 | u32 caps; /* 4/8 wires and any additional host |
14 | * capabilities OR'd (ref. linux/mmc/host.h) */ | 14 | * capabilities OR'd (ref. linux/mmc/host.h) */ |
15 | u32 pm_caps; /* PM capabilities */ | ||
15 | bool transceiver; /* MMC-2 option */ | 16 | bool transceiver; /* MMC-2 option */ |
16 | bool ext_clock; /* use external pin for input clock */ | 17 | bool ext_clock; /* use external pin for input clock */ |
17 | bool cover_only; /* No card detect - just cover switch */ | 18 | bool cover_only; /* No card detect - just cover switch */ |
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 27ad722df637..6c5826605eae 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c | |||
@@ -226,7 +226,7 @@ static void __init omap4_check_features(void) | |||
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
229 | static void __init ti816x_check_features(void) | 229 | static void __init ti81xx_check_features(void) |
230 | { | 230 | { |
231 | omap_features = OMAP3_HAS_NEON; | 231 | omap_features = OMAP3_HAS_NEON; |
232 | } | 232 | } |
@@ -340,6 +340,29 @@ static void __init omap3_check_revision(const char **cpu_rev) | |||
340 | break; | 340 | break; |
341 | } | 341 | } |
342 | break; | 342 | break; |
343 | case 0xb944: | ||
344 | omap_revision = AM335X_REV_ES1_0; | ||
345 | *cpu_rev = "1.0"; | ||
346 | case 0xb8f2: | ||
347 | switch (rev) { | ||
348 | case 0: | ||
349 | /* FALLTHROUGH */ | ||
350 | case 1: | ||
351 | omap_revision = TI8148_REV_ES1_0; | ||
352 | *cpu_rev = "1.0"; | ||
353 | break; | ||
354 | case 2: | ||
355 | omap_revision = TI8148_REV_ES2_0; | ||
356 | *cpu_rev = "2.0"; | ||
357 | break; | ||
358 | case 3: | ||
359 | /* FALLTHROUGH */ | ||
360 | default: | ||
361 | omap_revision = TI8148_REV_ES2_1; | ||
362 | *cpu_rev = "2.1"; | ||
363 | break; | ||
364 | } | ||
365 | break; | ||
343 | default: | 366 | default: |
344 | /* Unknown default to latest silicon rev as default */ | 367 | /* Unknown default to latest silicon rev as default */ |
345 | omap_revision = OMAP3630_REV_ES1_2; | 368 | omap_revision = OMAP3630_REV_ES1_2; |
@@ -367,7 +390,7 @@ static void __init omap4_check_revision(void) | |||
367 | * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 | 390 | * Few initial 4430 ES2.0 samples IDCODE is same as ES1.0 |
368 | * Use ARM register to detect the correct ES version | 391 | * Use ARM register to detect the correct ES version |
369 | */ | 392 | */ |
370 | if (!rev && (hawkeye != 0xb94e)) { | 393 | if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) { |
371 | idcode = read_cpuid(CPUID_ID); | 394 | idcode = read_cpuid(CPUID_ID); |
372 | rev = (idcode & 0xf) - 1; | 395 | rev = (idcode & 0xf) - 1; |
373 | } | 396 | } |
@@ -389,8 +412,11 @@ static void __init omap4_check_revision(void) | |||
389 | omap_revision = OMAP4430_REV_ES2_1; | 412 | omap_revision = OMAP4430_REV_ES2_1; |
390 | break; | 413 | break; |
391 | case 4: | 414 | case 4: |
392 | default: | ||
393 | omap_revision = OMAP4430_REV_ES2_2; | 415 | omap_revision = OMAP4430_REV_ES2_2; |
416 | break; | ||
417 | case 6: | ||
418 | default: | ||
419 | omap_revision = OMAP4430_REV_ES2_3; | ||
394 | } | 420 | } |
395 | break; | 421 | break; |
396 | case 0xb94e: | 422 | case 0xb94e: |
@@ -401,9 +427,17 @@ static void __init omap4_check_revision(void) | |||
401 | break; | 427 | break; |
402 | } | 428 | } |
403 | break; | 429 | break; |
430 | case 0xb975: | ||
431 | switch (rev) { | ||
432 | case 0: | ||
433 | default: | ||
434 | omap_revision = OMAP4470_REV_ES1_0; | ||
435 | break; | ||
436 | } | ||
437 | break; | ||
404 | default: | 438 | default: |
405 | /* Unknown default to latest silicon rev as default */ | 439 | /* Unknown default to latest silicon rev as default */ |
406 | omap_revision = OMAP4430_REV_ES2_2; | 440 | omap_revision = OMAP4430_REV_ES2_3; |
407 | } | 441 | } |
408 | 442 | ||
409 | pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, | 443 | pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, |
@@ -432,6 +466,10 @@ static void __init omap3_cpuinfo(const char *cpu_rev) | |||
432 | cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; | 466 | cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505"; |
433 | } else if (cpu_is_ti816x()) { | 467 | } else if (cpu_is_ti816x()) { |
434 | cpu_name = "TI816X"; | 468 | cpu_name = "TI816X"; |
469 | } else if (cpu_is_am335x()) { | ||
470 | cpu_name = "AM335X"; | ||
471 | } else if (cpu_is_ti814x()) { | ||
472 | cpu_name = "TI814X"; | ||
435 | } else if (omap3_has_iva() && omap3_has_sgx()) { | 473 | } else if (omap3_has_iva() && omap3_has_sgx()) { |
436 | /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ | 474 | /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ |
437 | cpu_name = "OMAP3430/3530"; | 475 | cpu_name = "OMAP3430/3530"; |
@@ -472,11 +510,11 @@ void __init omap2_check_revision(void) | |||
472 | } else if (cpu_is_omap34xx()) { | 510 | } else if (cpu_is_omap34xx()) { |
473 | omap3_check_revision(&cpu_rev); | 511 | omap3_check_revision(&cpu_rev); |
474 | 512 | ||
475 | /* TI816X doesn't have feature register */ | 513 | /* TI81XX doesn't have feature register */ |
476 | if (!cpu_is_ti816x()) | 514 | if (!cpu_is_ti81xx()) |
477 | omap3_check_features(); | 515 | omap3_check_features(); |
478 | else | 516 | else |
479 | ti816x_check_features(); | 517 | ti81xx_check_features(); |
480 | 518 | ||
481 | omap3_cpuinfo(cpu_rev); | 519 | omap3_cpuinfo(cpu_rev); |
482 | return; | 520 | return; |
diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h new file mode 100644 index 000000000000..4fa72c7cc7cd --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/barriers.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * OMAP memory barrier header. | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
6 | * Richard Woodruff <r-woodruff2@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef __MACH_BARRIERS_H | ||
23 | #define __MACH_BARRIERS_H | ||
24 | |||
25 | extern void omap_bus_sync(void); | ||
26 | |||
27 | #define rmb() dsb() | ||
28 | #define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0) | ||
29 | #define mb() wmb() | ||
30 | |||
31 | #endif /* __MACH_BARRIERS_H */ | ||
diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 13f98e59cfef..cdfc2a1f0e75 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S | |||
@@ -66,11 +66,11 @@ omap_uart_lsr: .word 0 | |||
66 | beq 34f @ configure OMAP3UART4 | 66 | beq 34f @ configure OMAP3UART4 |
67 | cmp \rp, #OMAP4UART4 @ only on 44xx | 67 | cmp \rp, #OMAP4UART4 @ only on 44xx |
68 | beq 44f @ configure OMAP4UART4 | 68 | beq 44f @ configure OMAP4UART4 |
69 | cmp \rp, #TI816XUART1 @ ti816x UART offsets different | 69 | cmp \rp, #TI81XXUART1 @ ti81Xx UART offsets different |
70 | beq 81f @ configure UART1 | 70 | beq 81f @ configure UART1 |
71 | cmp \rp, #TI816XUART2 @ ti816x UART offsets different | 71 | cmp \rp, #TI81XXUART2 @ ti81Xx UART offsets different |
72 | beq 82f @ configure UART2 | 72 | beq 82f @ configure UART2 |
73 | cmp \rp, #TI816XUART3 @ ti816x UART offsets different | 73 | cmp \rp, #TI81XXUART3 @ ti81Xx UART offsets different |
74 | beq 83f @ configure UART3 | 74 | beq 83f @ configure UART3 |
75 | cmp \rp, #ZOOM_UART @ only on zoom2/3 | 75 | cmp \rp, #ZOOM_UART @ only on zoom2/3 |
76 | beq 95f @ configure ZOOM_UART | 76 | beq 95f @ configure ZOOM_UART |
@@ -94,11 +94,11 @@ omap_uart_lsr: .word 0 | |||
94 | b 98f | 94 | b 98f |
95 | 44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) | 95 | 44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) |
96 | b 98f | 96 | b 98f |
97 | 81: mov \rp, #UART_OFFSET(TI816X_UART1_BASE) | 97 | 81: mov \rp, #UART_OFFSET(TI81XX_UART1_BASE) |
98 | b 98f | 98 | b 98f |
99 | 82: mov \rp, #UART_OFFSET(TI816X_UART2_BASE) | 99 | 82: mov \rp, #UART_OFFSET(TI81XX_UART2_BASE) |
100 | b 98f | 100 | b 98f |
101 | 83: mov \rp, #UART_OFFSET(TI816X_UART3_BASE) | 101 | 83: mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) |
102 | b 98f | 102 | b 98f |
103 | 103 | ||
104 | 95: ldr \rp, =ZOOM_UART_BASE | 104 | 95: ldr \rp, =ZOOM_UART_BASE |
diff --git a/arch/arm/mach-omap2/include/mach/omap-secure.h b/arch/arm/mach-omap2/include/mach/omap-secure.h new file mode 100644 index 000000000000..c90a43589abe --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/omap-secure.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * omap-secure.h: OMAP Secure infrastructure header. | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
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 | #ifndef OMAP_ARCH_OMAP_SECURE_H | ||
12 | #define OMAP_ARCH_OMAP_SECURE_H | ||
13 | |||
14 | /* Monitor error code */ | ||
15 | #define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE | ||
16 | #define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF | ||
17 | |||
18 | /* HAL API error codes */ | ||
19 | #define API_HAL_RET_VALUE_OK 0x00 | ||
20 | #define API_HAL_RET_VALUE_FAIL 0x01 | ||
21 | |||
22 | /* Secure HAL API flags */ | ||
23 | #define FLAG_START_CRITICAL 0x4 | ||
24 | #define FLAG_IRQFIQ_MASK 0x3 | ||
25 | #define FLAG_IRQ_ENABLE 0x2 | ||
26 | #define FLAG_FIQ_ENABLE 0x1 | ||
27 | #define NO_FLAG 0x0 | ||
28 | |||
29 | /* Maximum Secure memory storage size */ | ||
30 | #define OMAP_SECURE_RAM_STORAGE (88 * SZ_1K) | ||
31 | |||
32 | /* Secure low power HAL API index */ | ||
33 | #define OMAP4_HAL_SAVESECURERAM_INDEX 0x1a | ||
34 | #define OMAP4_HAL_SAVEHW_INDEX 0x1b | ||
35 | #define OMAP4_HAL_SAVEALL_INDEX 0x1c | ||
36 | #define OMAP4_HAL_SAVEGIC_INDEX 0x1d | ||
37 | |||
38 | /* Secure Monitor mode APIs */ | ||
39 | #define OMAP4_MON_SCU_PWR_INDEX 0x108 | ||
40 | #define OMAP4_MON_L2X0_DBG_CTRL_INDEX 0x100 | ||
41 | #define OMAP4_MON_L2X0_CTRL_INDEX 0x102 | ||
42 | #define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 | ||
43 | #define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 | ||
44 | |||
45 | /* Secure PPA(Primary Protected Application) APIs */ | ||
46 | #define OMAP4_PPA_L2_POR_INDEX 0x23 | ||
47 | #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25 | ||
48 | |||
49 | #ifndef __ASSEMBLER__ | ||
50 | |||
51 | extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, | ||
52 | u32 arg1, u32 arg2, u32 arg3, u32 arg4); | ||
53 | extern u32 omap_smc2(u32 id, u32 falg, u32 pargs); | ||
54 | extern phys_addr_t omap_secure_ram_mempool_base(void); | ||
55 | |||
56 | #endif /* __ASSEMBLER__ */ | ||
57 | #endif /* OMAP_ARCH_OMAP_SECURE_H */ | ||
diff --git a/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h new file mode 100644 index 000000000000..d79321b0f2a2 --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/omap-wakeupgen.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * OMAP WakeupGen header file | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
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 | #ifndef OMAP_ARCH_WAKEUPGEN_H | ||
12 | #define OMAP_ARCH_WAKEUPGEN_H | ||
13 | |||
14 | #define OMAP_WKG_CONTROL_0 0x00 | ||
15 | #define OMAP_WKG_ENB_A_0 0x10 | ||
16 | #define OMAP_WKG_ENB_B_0 0x14 | ||
17 | #define OMAP_WKG_ENB_C_0 0x18 | ||
18 | #define OMAP_WKG_ENB_D_0 0x1c | ||
19 | #define OMAP_WKG_ENB_SECURE_A_0 0x20 | ||
20 | #define OMAP_WKG_ENB_SECURE_B_0 0x24 | ||
21 | #define OMAP_WKG_ENB_SECURE_C_0 0x28 | ||
22 | #define OMAP_WKG_ENB_SECURE_D_0 0x2c | ||
23 | #define OMAP_WKG_ENB_A_1 0x410 | ||
24 | #define OMAP_WKG_ENB_B_1 0x414 | ||
25 | #define OMAP_WKG_ENB_C_1 0x418 | ||
26 | #define OMAP_WKG_ENB_D_1 0x41c | ||
27 | #define OMAP_WKG_ENB_SECURE_A_1 0x420 | ||
28 | #define OMAP_WKG_ENB_SECURE_B_1 0x424 | ||
29 | #define OMAP_WKG_ENB_SECURE_C_1 0x428 | ||
30 | #define OMAP_WKG_ENB_SECURE_D_1 0x42c | ||
31 | #define OMAP_AUX_CORE_BOOT_0 0x800 | ||
32 | #define OMAP_AUX_CORE_BOOT_1 0x804 | ||
33 | #define OMAP_PTMSYNCREQ_MASK 0xc00 | ||
34 | #define OMAP_PTMSYNCREQ_EN 0xc04 | ||
35 | #define OMAP_TIMESTAMPCYCLELO 0xc08 | ||
36 | #define OMAP_TIMESTAMPCYCLEHI 0xc0c | ||
37 | |||
38 | extern int __init omap_wakeupgen_init(void); | ||
39 | #endif | ||
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3f565dd2ea8d..eb50c29fb644 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -176,14 +176,31 @@ static struct map_desc omap34xx_io_desc[] __initdata = { | |||
176 | }; | 176 | }; |
177 | #endif | 177 | #endif |
178 | 178 | ||
179 | #ifdef CONFIG_SOC_OMAPTI816X | 179 | #ifdef CONFIG_SOC_OMAPTI81XX |
180 | static struct map_desc omapti816x_io_desc[] __initdata = { | 180 | static struct map_desc omapti81xx_io_desc[] __initdata = { |
181 | { | ||
182 | .virtual = L4_34XX_VIRT, | ||
183 | .pfn = __phys_to_pfn(L4_34XX_PHYS), | ||
184 | .length = L4_34XX_SIZE, | ||
185 | .type = MT_DEVICE | ||
186 | } | ||
187 | }; | ||
188 | #endif | ||
189 | |||
190 | #ifdef CONFIG_SOC_OMAPAM33XX | ||
191 | static struct map_desc omapam33xx_io_desc[] __initdata = { | ||
181 | { | 192 | { |
182 | .virtual = L4_34XX_VIRT, | 193 | .virtual = L4_34XX_VIRT, |
183 | .pfn = __phys_to_pfn(L4_34XX_PHYS), | 194 | .pfn = __phys_to_pfn(L4_34XX_PHYS), |
184 | .length = L4_34XX_SIZE, | 195 | .length = L4_34XX_SIZE, |
185 | .type = MT_DEVICE | 196 | .type = MT_DEVICE |
186 | }, | 197 | }, |
198 | { | ||
199 | .virtual = L4_WK_AM33XX_VIRT, | ||
200 | .pfn = __phys_to_pfn(L4_WK_AM33XX_PHYS), | ||
201 | .length = L4_WK_AM33XX_SIZE, | ||
202 | .type = MT_DEVICE | ||
203 | } | ||
187 | }; | 204 | }; |
188 | #endif | 205 | #endif |
189 | 206 | ||
@@ -237,6 +254,15 @@ static struct map_desc omap44xx_io_desc[] __initdata = { | |||
237 | .length = L4_EMU_44XX_SIZE, | 254 | .length = L4_EMU_44XX_SIZE, |
238 | .type = MT_DEVICE, | 255 | .type = MT_DEVICE, |
239 | }, | 256 | }, |
257 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
258 | { | ||
259 | .virtual = OMAP4_SRAM_VA, | ||
260 | .pfn = __phys_to_pfn(OMAP4_SRAM_PA), | ||
261 | .length = PAGE_SIZE, | ||
262 | .type = MT_MEMORY_SO, | ||
263 | }, | ||
264 | #endif | ||
265 | |||
240 | }; | 266 | }; |
241 | #endif | 267 | #endif |
242 | 268 | ||
@@ -263,10 +289,17 @@ void __init omap34xx_map_common_io(void) | |||
263 | } | 289 | } |
264 | #endif | 290 | #endif |
265 | 291 | ||
266 | #ifdef CONFIG_SOC_OMAPTI816X | 292 | #ifdef CONFIG_SOC_OMAPTI81XX |
267 | void __init omapti816x_map_common_io(void) | 293 | void __init omapti81xx_map_common_io(void) |
294 | { | ||
295 | iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc)); | ||
296 | } | ||
297 | #endif | ||
298 | |||
299 | #ifdef CONFIG_SOC_OMAPAM33XX | ||
300 | void __init omapam33xx_map_common_io(void) | ||
268 | { | 301 | { |
269 | iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc)); | 302 | iotable_init(omapam33xx_io_desc, ARRAY_SIZE(omapam33xx_io_desc)); |
270 | } | 303 | } |
271 | #endif | 304 | #endif |
272 | 305 | ||
@@ -355,7 +388,7 @@ static void __init omap_hwmod_init_postsetup(void) | |||
355 | omap_pm_if_early_init(); | 388 | omap_pm_if_early_init(); |
356 | } | 389 | } |
357 | 390 | ||
358 | #ifdef CONFIG_ARCH_OMAP2 | 391 | #ifdef CONFIG_SOC_OMAP2420 |
359 | void __init omap2420_init_early(void) | 392 | void __init omap2420_init_early(void) |
360 | { | 393 | { |
361 | omap2_set_globals_242x(); | 394 | omap2_set_globals_242x(); |
@@ -367,7 +400,9 @@ void __init omap2420_init_early(void) | |||
367 | omap_hwmod_init_postsetup(); | 400 | omap_hwmod_init_postsetup(); |
368 | omap2420_clk_init(); | 401 | omap2420_clk_init(); |
369 | } | 402 | } |
403 | #endif | ||
370 | 404 | ||
405 | #ifdef CONFIG_SOC_OMAP2430 | ||
371 | void __init omap2430_init_early(void) | 406 | void __init omap2430_init_early(void) |
372 | { | 407 | { |
373 | omap2_set_globals_243x(); | 408 | omap2_set_globals_243x(); |
@@ -418,9 +453,9 @@ void __init am35xx_init_early(void) | |||
418 | omap3_init_early(); | 453 | omap3_init_early(); |
419 | } | 454 | } |
420 | 455 | ||
421 | void __init ti816x_init_early(void) | 456 | void __init ti81xx_init_early(void) |
422 | { | 457 | { |
423 | omap2_set_globals_ti816x(); | 458 | omap2_set_globals_ti81xx(); |
424 | omap_common_init_early(); | 459 | omap_common_init_early(); |
425 | omap3xxx_voltagedomains_init(); | 460 | omap3xxx_voltagedomains_init(); |
426 | omap3xxx_powerdomains_init(); | 461 | omap3xxx_powerdomains_init(); |
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 42b1d6591912..1fef061f7927 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c | |||
@@ -193,7 +193,7 @@ void __init omap3_init_irq(void) | |||
193 | omap_init_irq(OMAP34XX_IC_BASE, 96); | 193 | omap_init_irq(OMAP34XX_IC_BASE, 96); |
194 | } | 194 | } |
195 | 195 | ||
196 | void __init ti816x_init_irq(void) | 196 | void __init ti81xx_init_irq(void) |
197 | { | 197 | { |
198 | omap_init_irq(OMAP34XX_IC_BASE, 128); | 198 | omap_init_irq(OMAP34XX_IC_BASE, 128); |
199 | } | 199 | } |
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 292eee3be15f..fb4bcf81a183 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -145,6 +145,9 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
145 | pdata->reg_size = 4; | 145 | pdata->reg_size = 4; |
146 | pdata->has_ccr = true; | 146 | pdata->has_ccr = true; |
147 | } | 147 | } |
148 | pdata->set_clk_src = omap2_mcbsp_set_clk_src; | ||
149 | if (id == 1) | ||
150 | pdata->mux_signal = omap2_mcbsp1_mux_rx_clk; | ||
148 | 151 | ||
149 | if (oh->class->rev == MCBSP_CONFIG_TYPE3) { | 152 | if (oh->class->rev == MCBSP_CONFIG_TYPE3) { |
150 | if (id == 2) | 153 | if (id == 2) |
@@ -153,6 +156,9 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
153 | else | 156 | else |
154 | /* The FIFO has 128 locations */ | 157 | /* The FIFO has 128 locations */ |
155 | pdata->buffer_size = 0x80; | 158 | pdata->buffer_size = 0x80; |
159 | } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) { | ||
160 | /* The FIFO has 128 locations for all instances */ | ||
161 | pdata->buffer_size = 0x80; | ||
156 | } | 162 | } |
157 | 163 | ||
158 | if (oh->class->rev >= MCBSP_CONFIG_TYPE3) | 164 | if (oh->class->rev >= MCBSP_CONFIG_TYPE3) |
@@ -174,9 +180,6 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) | |||
174 | name, oh->name); | 180 | name, oh->name); |
175 | return PTR_ERR(pdev); | 181 | return PTR_ERR(pdev); |
176 | } | 182 | } |
177 | pdata->set_clk_src = omap2_mcbsp_set_clk_src; | ||
178 | if (id == 1) | ||
179 | pdata->mux_signal = omap2_mcbsp1_mux_rx_clk; | ||
180 | omap_mcbsp_count++; | 183 | omap_mcbsp_count++; |
181 | return 0; | 184 | return 0; |
182 | } | 185 | } |
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 655e9480eb98..e1cc75d1a57a 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/debugfs.h> | 32 | #include <linux/debugfs.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | #include <linux/uaccess.h> | 34 | #include <linux/uaccess.h> |
35 | #include <linux/irq.h> | ||
36 | #include <linux/interrupt.h> | ||
35 | 37 | ||
36 | #include <asm/system.h> | 38 | #include <asm/system.h> |
37 | 39 | ||
@@ -39,6 +41,7 @@ | |||
39 | 41 | ||
40 | #include "control.h" | 42 | #include "control.h" |
41 | #include "mux.h" | 43 | #include "mux.h" |
44 | #include "prm.h" | ||
42 | 45 | ||
43 | #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ | 46 | #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ |
44 | #define OMAP_MUX_BASE_SZ 0x5ca | 47 | #define OMAP_MUX_BASE_SZ 0x5ca |
@@ -306,7 +309,8 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads) | |||
306 | pad->idle = bpad->idle; | 309 | pad->idle = bpad->idle; |
307 | pad->off = bpad->off; | 310 | pad->off = bpad->off; |
308 | 311 | ||
309 | if (pad->flags & OMAP_DEVICE_PAD_REMUX) | 312 | if (pad->flags & |
313 | (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) | ||
310 | nr_pads_dynamic++; | 314 | nr_pads_dynamic++; |
311 | 315 | ||
312 | pr_debug("%s: Initialized %s\n", __func__, pad->name); | 316 | pr_debug("%s: Initialized %s\n", __func__, pad->name); |
@@ -331,7 +335,8 @@ omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads) | |||
331 | for (i = 0; i < hmux->nr_pads; i++) { | 335 | for (i = 0; i < hmux->nr_pads; i++) { |
332 | struct omap_device_pad *pad = &hmux->pads[i]; | 336 | struct omap_device_pad *pad = &hmux->pads[i]; |
333 | 337 | ||
334 | if (pad->flags & OMAP_DEVICE_PAD_REMUX) { | 338 | if (pad->flags & |
339 | (OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP)) { | ||
335 | pr_debug("%s: pad %s tagged dynamic\n", | 340 | pr_debug("%s: pad %s tagged dynamic\n", |
336 | __func__, pad->name); | 341 | __func__, pad->name); |
337 | hmux->pads_dynamic[nr_pads_dynamic] = pad; | 342 | hmux->pads_dynamic[nr_pads_dynamic] = pad; |
@@ -351,6 +356,78 @@ err1: | |||
351 | return NULL; | 356 | return NULL; |
352 | } | 357 | } |
353 | 358 | ||
359 | /** | ||
360 | * omap_hwmod_mux_scan_wakeups - omap hwmod scan wakeup pads | ||
361 | * @hmux: Pads for a hwmod | ||
362 | * @mpu_irqs: MPU irq array for a hwmod | ||
363 | * | ||
364 | * Scans the wakeup status of pads for a single hwmod. If an irq | ||
365 | * array is defined for this mux, the parser will call the registered | ||
366 | * ISRs for corresponding pads, otherwise the parser will stop at the | ||
367 | * first wakeup active pad and return. Returns true if there is a | ||
368 | * pending and non-served wakeup event for the mux, otherwise false. | ||
369 | */ | ||
370 | static bool omap_hwmod_mux_scan_wakeups(struct omap_hwmod_mux_info *hmux, | ||
371 | struct omap_hwmod_irq_info *mpu_irqs) | ||
372 | { | ||
373 | int i, irq; | ||
374 | unsigned int val; | ||
375 | u32 handled_irqs = 0; | ||
376 | |||
377 | for (i = 0; i < hmux->nr_pads_dynamic; i++) { | ||
378 | struct omap_device_pad *pad = hmux->pads_dynamic[i]; | ||
379 | |||
380 | if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP) || | ||
381 | !(pad->idle & OMAP_WAKEUP_EN)) | ||
382 | continue; | ||
383 | |||
384 | val = omap_mux_read(pad->partition, pad->mux->reg_offset); | ||
385 | if (!(val & OMAP_WAKEUP_EVENT)) | ||
386 | continue; | ||
387 | |||
388 | if (!hmux->irqs) | ||
389 | return true; | ||
390 | |||
391 | irq = hmux->irqs[i]; | ||
392 | /* make sure we only handle each irq once */ | ||
393 | if (handled_irqs & 1 << irq) | ||
394 | continue; | ||
395 | |||
396 | handled_irqs |= 1 << irq; | ||
397 | |||
398 | generic_handle_irq(mpu_irqs[irq].irq); | ||
399 | } | ||
400 | |||
401 | return false; | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * _omap_hwmod_mux_handle_irq - Process wakeup events for a single hwmod | ||
406 | * | ||
407 | * Checks a single hwmod for every wakeup capable pad to see if there is an | ||
408 | * active wakeup event. If this is the case, call the corresponding ISR. | ||
409 | */ | ||
410 | static int _omap_hwmod_mux_handle_irq(struct omap_hwmod *oh, void *data) | ||
411 | { | ||
412 | if (!oh->mux || !oh->mux->enabled) | ||
413 | return 0; | ||
414 | if (omap_hwmod_mux_scan_wakeups(oh->mux, oh->mpu_irqs)) | ||
415 | generic_handle_irq(oh->mpu_irqs[0].irq); | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | /** | ||
420 | * omap_hwmod_mux_handle_irq - Process pad wakeup irqs. | ||
421 | * | ||
422 | * Calls a function for each registered omap_hwmod to check | ||
423 | * pad wakeup statuses. | ||
424 | */ | ||
425 | static irqreturn_t omap_hwmod_mux_handle_irq(int irq, void *unused) | ||
426 | { | ||
427 | omap_hwmod_for_each(_omap_hwmod_mux_handle_irq, NULL); | ||
428 | return IRQ_HANDLED; | ||
429 | } | ||
430 | |||
354 | /* Assumes the calling function takes care of locking */ | 431 | /* Assumes the calling function takes care of locking */ |
355 | void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) | 432 | void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state) |
356 | { | 433 | { |
@@ -715,6 +792,7 @@ static void __init omap_mux_free_names(struct omap_mux *m) | |||
715 | static int __init omap_mux_late_init(void) | 792 | static int __init omap_mux_late_init(void) |
716 | { | 793 | { |
717 | struct omap_mux_partition *partition; | 794 | struct omap_mux_partition *partition; |
795 | int ret; | ||
718 | 796 | ||
719 | list_for_each_entry(partition, &mux_partitions, node) { | 797 | list_for_each_entry(partition, &mux_partitions, node) { |
720 | struct omap_mux_entry *e, *tmp; | 798 | struct omap_mux_entry *e, *tmp; |
@@ -735,6 +813,13 @@ static int __init omap_mux_late_init(void) | |||
735 | } | 813 | } |
736 | } | 814 | } |
737 | 815 | ||
816 | ret = request_irq(omap_prcm_event_to_irq("io"), | ||
817 | omap_hwmod_mux_handle_irq, IRQF_SHARED | IRQF_NO_SUSPEND, | ||
818 | "hwmod_io", omap_mux_late_init); | ||
819 | |||
820 | if (ret) | ||
821 | pr_warning("mux: Failed to setup hwmod io irq %d\n", ret); | ||
822 | |||
738 | omap_mux_dbg_init(); | 823 | omap_mux_dbg_init(); |
739 | 824 | ||
740 | return 0; | 825 | return 0; |
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S index 4ee6aeca885a..b13ef7ef5ef4 100644 --- a/arch/arm/mach-omap2/omap-headsmp.S +++ b/arch/arm/mach-omap2/omap-headsmp.S | |||
@@ -18,11 +18,6 @@ | |||
18 | #include <linux/linkage.h> | 18 | #include <linux/linkage.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | 20 | ||
21 | /* Physical address needed since MMU not enabled yet on secondary core */ | ||
22 | #define OMAP4_AUX_CORE_BOOT1_PA 0x48281804 | ||
23 | |||
24 | __INIT | ||
25 | |||
26 | /* | 21 | /* |
27 | * OMAP4 specific entry point for secondary CPU to jump from ROM | 22 | * OMAP4 specific entry point for secondary CPU to jump from ROM |
28 | * code. This routine also provides a holding flag into which | 23 | * code. This routine also provides a holding flag into which |
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index e5a1c3f40a86..adbe4d8c7caf 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c | |||
@@ -22,6 +22,8 @@ | |||
22 | 22 | ||
23 | #include "common.h" | 23 | #include "common.h" |
24 | 24 | ||
25 | #include "powerdomain.h" | ||
26 | |||
25 | int platform_cpu_kill(unsigned int cpu) | 27 | int platform_cpu_kill(unsigned int cpu) |
26 | { | 28 | { |
27 | return 1; | 29 | return 1; |
@@ -33,6 +35,8 @@ int platform_cpu_kill(unsigned int cpu) | |||
33 | */ | 35 | */ |
34 | void platform_cpu_die(unsigned int cpu) | 36 | void platform_cpu_die(unsigned int cpu) |
35 | { | 37 | { |
38 | unsigned int this_cpu; | ||
39 | |||
36 | flush_cache_all(); | 40 | flush_cache_all(); |
37 | dsb(); | 41 | dsb(); |
38 | 42 | ||
@@ -40,15 +44,15 @@ void platform_cpu_die(unsigned int cpu) | |||
40 | * we're ready for shutdown now, so do it | 44 | * we're ready for shutdown now, so do it |
41 | */ | 45 | */ |
42 | if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) | 46 | if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) |
43 | printk(KERN_CRIT "Secure clear status failed\n"); | 47 | pr_err("Secure clear status failed\n"); |
44 | 48 | ||
45 | for (;;) { | 49 | for (;;) { |
46 | /* | 50 | /* |
47 | * Execute WFI | 51 | * Enter into low power state |
48 | */ | 52 | */ |
49 | do_wfi(); | 53 | omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF); |
50 | 54 | this_cpu = smp_processor_id(); | |
51 | if (omap_read_auxcoreboot0() == cpu) { | 55 | if (omap_read_auxcoreboot0() == this_cpu) { |
52 | /* | 56 | /* |
53 | * OK, proper wakeup, we're done | 57 | * OK, proper wakeup, we're done |
54 | */ | 58 | */ |
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c new file mode 100644 index 000000000000..1d5d01056558 --- /dev/null +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * OMAP MPUSS low power code | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
6 | * | ||
7 | * OMAP4430 MPUSS mainly consists of dual Cortex-A9 with per-CPU | ||
8 | * Local timer and Watchdog, GIC, SCU, PL310 L2 cache controller, | ||
9 | * CPU0 and CPU1 LPRM modules. | ||
10 | * CPU0, CPU1 and MPUSS each have there own power domain and | ||
11 | * hence multiple low power combinations of MPUSS are possible. | ||
12 | * | ||
13 | * The CPU0 and CPU1 can't support Closed switch Retention (CSWR) | ||
14 | * because the mode is not supported by hw constraints of dormant | ||
15 | * mode. While waking up from the dormant mode, a reset signal | ||
16 | * to the Cortex-A9 processor must be asserted by the external | ||
17 | * power controller. | ||
18 | * | ||
19 | * With architectural inputs and hardware recommendations, only | ||
20 | * below modes are supported from power gain vs latency point of view. | ||
21 | * | ||
22 | * CPU0 CPU1 MPUSS | ||
23 | * ---------------------------------------------- | ||
24 | * ON ON ON | ||
25 | * ON(Inactive) OFF ON(Inactive) | ||
26 | * OFF OFF CSWR | ||
27 | * OFF OFF OSWR | ||
28 | * OFF OFF OFF(Device OFF *TBD) | ||
29 | * ---------------------------------------------- | ||
30 | * | ||
31 | * Note: CPU0 is the master core and it is the last CPU to go down | ||
32 | * and first to wake-up when MPUSS low power states are excercised | ||
33 | * | ||
34 | * | ||
35 | * This program is free software; you can redistribute it and/or modify | ||
36 | * it under the terms of the GNU General Public License version 2 as | ||
37 | * published by the Free Software Foundation. | ||
38 | */ | ||
39 | |||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/io.h> | ||
42 | #include <linux/errno.h> | ||
43 | #include <linux/linkage.h> | ||
44 | #include <linux/smp.h> | ||
45 | |||
46 | #include <asm/cacheflush.h> | ||
47 | #include <asm/tlbflush.h> | ||
48 | #include <asm/smp_scu.h> | ||
49 | #include <asm/system.h> | ||
50 | #include <asm/pgalloc.h> | ||
51 | #include <asm/suspend.h> | ||
52 | #include <asm/hardware/cache-l2x0.h> | ||
53 | |||
54 | #include <plat/omap44xx.h> | ||
55 | |||
56 | #include "common.h" | ||
57 | #include "omap4-sar-layout.h" | ||
58 | #include "pm.h" | ||
59 | #include "prcm_mpu44xx.h" | ||
60 | #include "prminst44xx.h" | ||
61 | #include "prcm44xx.h" | ||
62 | #include "prm44xx.h" | ||
63 | #include "prm-regbits-44xx.h" | ||
64 | |||
65 | #ifdef CONFIG_SMP | ||
66 | |||
67 | struct omap4_cpu_pm_info { | ||
68 | struct powerdomain *pwrdm; | ||
69 | void __iomem *scu_sar_addr; | ||
70 | void __iomem *wkup_sar_addr; | ||
71 | void __iomem *l2x0_sar_addr; | ||
72 | }; | ||
73 | |||
74 | static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); | ||
75 | static struct powerdomain *mpuss_pd; | ||
76 | static void __iomem *sar_base; | ||
77 | |||
78 | /* | ||
79 | * Program the wakeup routine address for the CPU0 and CPU1 | ||
80 | * used for OFF or DORMANT wakeup. | ||
81 | */ | ||
82 | static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr) | ||
83 | { | ||
84 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
85 | |||
86 | __raw_writel(addr, pm_info->wkup_sar_addr); | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Set the CPUx powerdomain's previous power state | ||
91 | */ | ||
92 | static inline void set_cpu_next_pwrst(unsigned int cpu_id, | ||
93 | unsigned int power_state) | ||
94 | { | ||
95 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
96 | |||
97 | pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Read CPU's previous power state | ||
102 | */ | ||
103 | static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id) | ||
104 | { | ||
105 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
106 | |||
107 | return pwrdm_read_prev_pwrst(pm_info->pwrdm); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Clear the CPUx powerdomain's previous power state | ||
112 | */ | ||
113 | static inline void clear_cpu_prev_pwrst(unsigned int cpu_id) | ||
114 | { | ||
115 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
116 | |||
117 | pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Store the SCU power status value to scratchpad memory | ||
122 | */ | ||
123 | static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) | ||
124 | { | ||
125 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
126 | u32 scu_pwr_st; | ||
127 | |||
128 | switch (cpu_state) { | ||
129 | case PWRDM_POWER_RET: | ||
130 | scu_pwr_st = SCU_PM_DORMANT; | ||
131 | break; | ||
132 | case PWRDM_POWER_OFF: | ||
133 | scu_pwr_st = SCU_PM_POWEROFF; | ||
134 | break; | ||
135 | case PWRDM_POWER_ON: | ||
136 | case PWRDM_POWER_INACTIVE: | ||
137 | default: | ||
138 | scu_pwr_st = SCU_PM_NORMAL; | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | __raw_writel(scu_pwr_st, pm_info->scu_sar_addr); | ||
143 | } | ||
144 | |||
145 | /* Helper functions for MPUSS OSWR */ | ||
146 | static inline void mpuss_clear_prev_logic_pwrst(void) | ||
147 | { | ||
148 | u32 reg; | ||
149 | |||
150 | reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, | ||
151 | OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); | ||
152 | omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION, | ||
153 | OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); | ||
154 | } | ||
155 | |||
156 | static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id) | ||
157 | { | ||
158 | u32 reg; | ||
159 | |||
160 | if (cpu_id) { | ||
161 | reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST, | ||
162 | OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); | ||
163 | omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST, | ||
164 | OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); | ||
165 | } else { | ||
166 | reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST, | ||
167 | OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); | ||
168 | omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST, | ||
169 | OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * omap4_mpuss_read_prev_context_state: | ||
175 | * Function returns the MPUSS previous context state | ||
176 | */ | ||
177 | u32 omap4_mpuss_read_prev_context_state(void) | ||
178 | { | ||
179 | u32 reg; | ||
180 | |||
181 | reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, | ||
182 | OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); | ||
183 | reg &= OMAP4430_LOSTCONTEXT_DFF_MASK; | ||
184 | return reg; | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Store the CPU cluster state for L2X0 low power operations. | ||
189 | */ | ||
190 | static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state) | ||
191 | { | ||
192 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | ||
193 | |||
194 | __raw_writel(save_state, pm_info->l2x0_sar_addr); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to | ||
199 | * in every restore MPUSS OFF path. | ||
200 | */ | ||
201 | #ifdef CONFIG_CACHE_L2X0 | ||
202 | static void save_l2x0_context(void) | ||
203 | { | ||
204 | u32 val; | ||
205 | void __iomem *l2x0_base = omap4_get_l2cache_base(); | ||
206 | |||
207 | val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); | ||
208 | __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); | ||
209 | val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); | ||
210 | __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); | ||
211 | } | ||
212 | #else | ||
213 | static void save_l2x0_context(void) | ||
214 | {} | ||
215 | #endif | ||
216 | |||
217 | /** | ||
218 | * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function | ||
219 | * The purpose of this function is to manage low power programming | ||
220 | * of OMAP4 MPUSS subsystem | ||
221 | * @cpu : CPU ID | ||
222 | * @power_state: Low power state. | ||
223 | * | ||
224 | * MPUSS states for the context save: | ||
225 | * save_state = | ||
226 | * 0 - Nothing lost and no need to save: MPUSS INACTIVE | ||
227 | * 1 - CPUx L1 and logic lost: MPUSS CSWR | ||
228 | * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR | ||
229 | * 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF | ||
230 | */ | ||
231 | int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) | ||
232 | { | ||
233 | unsigned int save_state = 0; | ||
234 | unsigned int wakeup_cpu; | ||
235 | |||
236 | if (omap_rev() == OMAP4430_REV_ES1_0) | ||
237 | return -ENXIO; | ||
238 | |||
239 | switch (power_state) { | ||
240 | case PWRDM_POWER_ON: | ||
241 | case PWRDM_POWER_INACTIVE: | ||
242 | save_state = 0; | ||
243 | break; | ||
244 | case PWRDM_POWER_OFF: | ||
245 | save_state = 1; | ||
246 | break; | ||
247 | case PWRDM_POWER_RET: | ||
248 | default: | ||
249 | /* | ||
250 | * CPUx CSWR is invalid hardware state. Also CPUx OSWR | ||
251 | * doesn't make much scense, since logic is lost and $L1 | ||
252 | * needs to be cleaned because of coherency. This makes | ||
253 | * CPUx OSWR equivalent to CPUX OFF and hence not supported | ||
254 | */ | ||
255 | WARN_ON(1); | ||
256 | return -ENXIO; | ||
257 | } | ||
258 | |||
259 | pwrdm_pre_transition(); | ||
260 | |||
261 | /* | ||
262 | * Check MPUSS next state and save interrupt controller if needed. | ||
263 | * In MPUSS OSWR or device OFF, interrupt controller contest is lost. | ||
264 | */ | ||
265 | mpuss_clear_prev_logic_pwrst(); | ||
266 | pwrdm_clear_all_prev_pwrst(mpuss_pd); | ||
267 | if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) && | ||
268 | (pwrdm_read_logic_retst(mpuss_pd) == PWRDM_POWER_OFF)) | ||
269 | save_state = 2; | ||
270 | |||
271 | clear_cpu_prev_pwrst(cpu); | ||
272 | cpu_clear_prev_logic_pwrst(cpu); | ||
273 | set_cpu_next_pwrst(cpu, power_state); | ||
274 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume)); | ||
275 | scu_pwrst_prepare(cpu, power_state); | ||
276 | l2x0_pwrst_prepare(cpu, save_state); | ||
277 | |||
278 | /* | ||
279 | * Call low level function with targeted low power state. | ||
280 | */ | ||
281 | cpu_suspend(save_state, omap4_finish_suspend); | ||
282 | |||
283 | /* | ||
284 | * Restore the CPUx power state to ON otherwise CPUx | ||
285 | * power domain can transitions to programmed low power | ||
286 | * state while doing WFI outside the low powe code. On | ||
287 | * secure devices, CPUx does WFI which can result in | ||
288 | * domain transition | ||
289 | */ | ||
290 | wakeup_cpu = smp_processor_id(); | ||
291 | set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); | ||
292 | |||
293 | pwrdm_post_transition(); | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * omap4_hotplug_cpu: OMAP4 CPU hotplug entry | ||
300 | * @cpu : CPU ID | ||
301 | * @power_state: CPU low power state. | ||
302 | */ | ||
303 | int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state) | ||
304 | { | ||
305 | unsigned int cpu_state = 0; | ||
306 | |||
307 | if (omap_rev() == OMAP4430_REV_ES1_0) | ||
308 | return -ENXIO; | ||
309 | |||
310 | if (power_state == PWRDM_POWER_OFF) | ||
311 | cpu_state = 1; | ||
312 | |||
313 | clear_cpu_prev_pwrst(cpu); | ||
314 | set_cpu_next_pwrst(cpu, power_state); | ||
315 | set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup)); | ||
316 | scu_pwrst_prepare(cpu, power_state); | ||
317 | |||
318 | /* | ||
319 | * CPU never retuns back if targetted power state is OFF mode. | ||
320 | * CPU ONLINE follows normal CPU ONLINE ptah via | ||
321 | * omap_secondary_startup(). | ||
322 | */ | ||
323 | omap4_finish_suspend(cpu_state); | ||
324 | |||
325 | set_cpu_next_pwrst(cpu, PWRDM_POWER_ON); | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | |||
330 | /* | ||
331 | * Initialise OMAP4 MPUSS | ||
332 | */ | ||
333 | int __init omap4_mpuss_init(void) | ||
334 | { | ||
335 | struct omap4_cpu_pm_info *pm_info; | ||
336 | |||
337 | if (omap_rev() == OMAP4430_REV_ES1_0) { | ||
338 | WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); | ||
339 | return -ENODEV; | ||
340 | } | ||
341 | |||
342 | sar_base = omap4_get_sar_ram_base(); | ||
343 | |||
344 | /* Initilaise per CPU PM information */ | ||
345 | pm_info = &per_cpu(omap4_pm_info, 0x0); | ||
346 | pm_info->scu_sar_addr = sar_base + SCU_OFFSET0; | ||
347 | pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET; | ||
348 | pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0; | ||
349 | pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm"); | ||
350 | if (!pm_info->pwrdm) { | ||
351 | pr_err("Lookup failed for CPU0 pwrdm\n"); | ||
352 | return -ENODEV; | ||
353 | } | ||
354 | |||
355 | /* Clear CPU previous power domain state */ | ||
356 | pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); | ||
357 | cpu_clear_prev_logic_pwrst(0); | ||
358 | |||
359 | /* Initialise CPU0 power domain state to ON */ | ||
360 | pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); | ||
361 | |||
362 | pm_info = &per_cpu(omap4_pm_info, 0x1); | ||
363 | pm_info->scu_sar_addr = sar_base + SCU_OFFSET1; | ||
364 | pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET; | ||
365 | pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1; | ||
366 | pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm"); | ||
367 | if (!pm_info->pwrdm) { | ||
368 | pr_err("Lookup failed for CPU1 pwrdm\n"); | ||
369 | return -ENODEV; | ||
370 | } | ||
371 | |||
372 | /* Clear CPU previous power domain state */ | ||
373 | pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); | ||
374 | cpu_clear_prev_logic_pwrst(1); | ||
375 | |||
376 | /* Initialise CPU1 power domain state to ON */ | ||
377 | pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON); | ||
378 | |||
379 | mpuss_pd = pwrdm_lookup("mpu_pwrdm"); | ||
380 | if (!mpuss_pd) { | ||
381 | pr_err("Failed to lookup MPUSS power domain\n"); | ||
382 | return -ENODEV; | ||
383 | } | ||
384 | pwrdm_clear_all_prev_pwrst(mpuss_pd); | ||
385 | mpuss_clear_prev_logic_pwrst(); | ||
386 | |||
387 | /* Save device type on scratchpad for low level code to use */ | ||
388 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) | ||
389 | __raw_writel(1, sar_base + OMAP_TYPE_OFFSET); | ||
390 | else | ||
391 | __raw_writel(0, sar_base + OMAP_TYPE_OFFSET); | ||
392 | |||
393 | save_l2x0_context(); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | #endif | ||
diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c new file mode 100644 index 000000000000..d8f8ef40290f --- /dev/null +++ b/arch/arm/mach-omap2/omap-secure.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * OMAP Secure API infrastructure. | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
6 | * | ||
7 | * | ||
8 | * This program is free software,you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/memblock.h> | ||
17 | |||
18 | #include <asm/cacheflush.h> | ||
19 | #include <asm/memblock.h> | ||
20 | |||
21 | #include <mach/omap-secure.h> | ||
22 | |||
23 | static phys_addr_t omap_secure_memblock_base; | ||
24 | |||
25 | /** | ||
26 | * omap_sec_dispatcher: Routine to dispatch low power secure | ||
27 | * service routines | ||
28 | * @idx: The HAL API index | ||
29 | * @flag: The flag indicating criticality of operation | ||
30 | * @nargs: Number of valid arguments out of four. | ||
31 | * @arg1, arg2, arg3 args4: Parameters passed to secure API | ||
32 | * | ||
33 | * Return the non-zero error value on failure. | ||
34 | */ | ||
35 | u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2, | ||
36 | u32 arg3, u32 arg4) | ||
37 | { | ||
38 | u32 ret; | ||
39 | u32 param[5]; | ||
40 | |||
41 | param[0] = nargs; | ||
42 | param[1] = arg1; | ||
43 | param[2] = arg2; | ||
44 | param[3] = arg3; | ||
45 | param[4] = arg4; | ||
46 | |||
47 | /* | ||
48 | * Secure API needs physical address | ||
49 | * pointer for the parameters | ||
50 | */ | ||
51 | flush_cache_all(); | ||
52 | outer_clean_range(__pa(param), __pa(param + 5)); | ||
53 | ret = omap_smc2(idx, flag, __pa(param)); | ||
54 | |||
55 | return ret; | ||
56 | } | ||
57 | |||
58 | /* Allocate the memory to save secure ram */ | ||
59 | int __init omap_secure_ram_reserve_memblock(void) | ||
60 | { | ||
61 | u32 size = OMAP_SECURE_RAM_STORAGE; | ||
62 | |||
63 | size = ALIGN(size, SZ_1M); | ||
64 | omap_secure_memblock_base = arm_memblock_steal(size, SZ_1M); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | phys_addr_t omap_secure_ram_mempool_base(void) | ||
70 | { | ||
71 | return omap_secure_memblock_base; | ||
72 | } | ||
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap-smc.S index e69d37d95204..f6441c13cd8c 100644 --- a/arch/arm/mach-omap2/omap44xx-smc.S +++ b/arch/arm/mach-omap2/omap-smc.S | |||
@@ -31,6 +31,29 @@ ENTRY(omap_smc1) | |||
31 | ldmfd sp!, {r2-r12, pc} | 31 | ldmfd sp!, {r2-r12, pc} |
32 | ENDPROC(omap_smc1) | 32 | ENDPROC(omap_smc1) |
33 | 33 | ||
34 | /** | ||
35 | * u32 omap_smc2(u32 id, u32 falg, u32 pargs) | ||
36 | * Low level common routine for secure HAL and PPA APIs. | ||
37 | * @id: Application ID of HAL APIs | ||
38 | * @flag: Flag to indicate the criticality of operation | ||
39 | * @pargs: Physical address of parameter list starting | ||
40 | * with number of parametrs | ||
41 | */ | ||
42 | ENTRY(omap_smc2) | ||
43 | stmfd sp!, {r4-r12, lr} | ||
44 | mov r3, r2 | ||
45 | mov r2, r1 | ||
46 | mov r1, #0x0 @ Process ID | ||
47 | mov r6, #0xff | ||
48 | mov r12, #0x00 @ Secure Service ID | ||
49 | mov r7, #0 | ||
50 | mcr p15, 0, r7, c7, c5, 6 | ||
51 | dsb | ||
52 | dmb | ||
53 | smc #0 | ||
54 | ldmfd sp!, {r4-r12, pc} | ||
55 | ENDPROC(omap_smc2) | ||
56 | |||
34 | ENTRY(omap_modify_auxcoreboot0) | 57 | ENTRY(omap_modify_auxcoreboot0) |
35 | stmfd sp!, {r1-r12, lr} | 58 | stmfd sp!, {r1-r12, lr} |
36 | ldr r12, =0x104 | 59 | ldr r12, =0x104 |
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index e99bc6cd4714..c1bf3ef0ba02 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -24,17 +24,37 @@ | |||
24 | #include <asm/hardware/gic.h> | 24 | #include <asm/hardware/gic.h> |
25 | #include <asm/smp_scu.h> | 25 | #include <asm/smp_scu.h> |
26 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
27 | #include <mach/omap-secure.h> | ||
27 | 28 | ||
28 | #include "common.h" | 29 | #include "common.h" |
29 | 30 | ||
31 | #include "clockdomain.h" | ||
32 | |||
30 | /* SCU base address */ | 33 | /* SCU base address */ |
31 | static void __iomem *scu_base; | 34 | static void __iomem *scu_base; |
32 | 35 | ||
33 | static DEFINE_SPINLOCK(boot_lock); | 36 | static DEFINE_SPINLOCK(boot_lock); |
34 | 37 | ||
38 | void __iomem *omap4_get_scu_base(void) | ||
39 | { | ||
40 | return scu_base; | ||
41 | } | ||
42 | |||
35 | void __cpuinit platform_secondary_init(unsigned int cpu) | 43 | void __cpuinit platform_secondary_init(unsigned int cpu) |
36 | { | 44 | { |
37 | /* | 45 | /* |
46 | * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. | ||
47 | * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA | ||
48 | * init and for CPU1, a secure PPA API provided. CPU0 must be ON | ||
49 | * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. | ||
50 | * OMAP443X GP devices- SMP bit isn't accessible. | ||
51 | * OMAP446X GP devices - SMP bit access is enabled on both CPUs. | ||
52 | */ | ||
53 | if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) | ||
54 | omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, | ||
55 | 4, 0, 0, 0, 0, 0); | ||
56 | |||
57 | /* | ||
38 | * If any interrupts are already enabled for the primary | 58 | * If any interrupts are already enabled for the primary |
39 | * core (e.g. timer irq), then they will not have been enabled | 59 | * core (e.g. timer irq), then they will not have been enabled |
40 | * for us: do so | 60 | * for us: do so |
@@ -50,6 +70,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu) | |||
50 | 70 | ||
51 | int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | 71 | int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) |
52 | { | 72 | { |
73 | static struct clockdomain *cpu1_clkdm; | ||
74 | static bool booted; | ||
53 | /* | 75 | /* |
54 | * Set synchronisation state between this boot processor | 76 | * Set synchronisation state between this boot processor |
55 | * and the secondary one | 77 | * and the secondary one |
@@ -65,6 +87,29 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
65 | omap_modify_auxcoreboot0(0x200, 0xfffffdff); | 87 | omap_modify_auxcoreboot0(0x200, 0xfffffdff); |
66 | flush_cache_all(); | 88 | flush_cache_all(); |
67 | smp_wmb(); | 89 | smp_wmb(); |
90 | |||
91 | if (!cpu1_clkdm) | ||
92 | cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); | ||
93 | |||
94 | /* | ||
95 | * The SGI(Software Generated Interrupts) are not wakeup capable | ||
96 | * from low power states. This is known limitation on OMAP4 and | ||
97 | * needs to be worked around by using software forced clockdomain | ||
98 | * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to | ||
99 | * software force wakeup. The clockdomain is then put back to | ||
100 | * hardware supervised mode. | ||
101 | * More details can be found in OMAP4430 TRM - Version J | ||
102 | * Section : | ||
103 | * 4.3.4.2 Power States of CPU0 and CPU1 | ||
104 | */ | ||
105 | if (booted) { | ||
106 | clkdm_wakeup(cpu1_clkdm); | ||
107 | clkdm_allow_idle(cpu1_clkdm); | ||
108 | } else { | ||
109 | dsb_sev(); | ||
110 | booted = true; | ||
111 | } | ||
112 | |||
68 | gic_raise_softirq(cpumask_of(cpu), 1); | 113 | gic_raise_softirq(cpumask_of(cpu), 1); |
69 | 114 | ||
70 | /* | 115 | /* |
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c new file mode 100644 index 000000000000..d3d8971d7f30 --- /dev/null +++ b/arch/arm/mach-omap2/omap-wakeupgen.c | |||
@@ -0,0 +1,389 @@ | |||
1 | /* | ||
2 | * OMAP WakeupGen Source file | ||
3 | * | ||
4 | * OMAP WakeupGen is the interrupt controller extension used along | ||
5 | * with ARM GIC to wake the CPU out from low power states on | ||
6 | * external interrupts. It is responsible for generating wakeup | ||
7 | * event from the incoming interrupts and enable bits. It is | ||
8 | * implemented in MPU always ON power domain. During normal operation, | ||
9 | * WakeupGen delivers external interrupts directly to the GIC. | ||
10 | * | ||
11 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
12 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License version 2 as | ||
16 | * published by the Free Software Foundation. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/irq.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/cpu.h> | ||
25 | #include <linux/notifier.h> | ||
26 | #include <linux/cpu_pm.h> | ||
27 | |||
28 | #include <asm/hardware/gic.h> | ||
29 | |||
30 | #include <mach/omap-wakeupgen.h> | ||
31 | #include <mach/omap-secure.h> | ||
32 | |||
33 | #include "omap4-sar-layout.h" | ||
34 | #include "common.h" | ||
35 | |||
36 | #define NR_REG_BANKS 4 | ||
37 | #define MAX_IRQS 128 | ||
38 | #define WKG_MASK_ALL 0x00000000 | ||
39 | #define WKG_UNMASK_ALL 0xffffffff | ||
40 | #define CPU_ENA_OFFSET 0x400 | ||
41 | #define CPU0_ID 0x0 | ||
42 | #define CPU1_ID 0x1 | ||
43 | |||
44 | static void __iomem *wakeupgen_base; | ||
45 | static void __iomem *sar_base; | ||
46 | static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); | ||
47 | static DEFINE_SPINLOCK(wakeupgen_lock); | ||
48 | static unsigned int irq_target_cpu[NR_IRQS]; | ||
49 | |||
50 | /* | ||
51 | * Static helper functions. | ||
52 | */ | ||
53 | static inline u32 wakeupgen_readl(u8 idx, u32 cpu) | ||
54 | { | ||
55 | return __raw_readl(wakeupgen_base + OMAP_WKG_ENB_A_0 + | ||
56 | (cpu * CPU_ENA_OFFSET) + (idx * 4)); | ||
57 | } | ||
58 | |||
59 | static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu) | ||
60 | { | ||
61 | __raw_writel(val, wakeupgen_base + OMAP_WKG_ENB_A_0 + | ||
62 | (cpu * CPU_ENA_OFFSET) + (idx * 4)); | ||
63 | } | ||
64 | |||
65 | static inline void sar_writel(u32 val, u32 offset, u8 idx) | ||
66 | { | ||
67 | __raw_writel(val, sar_base + offset + (idx * 4)); | ||
68 | } | ||
69 | |||
70 | static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg) | ||
71 | { | ||
72 | u8 i; | ||
73 | |||
74 | for (i = 0; i < NR_REG_BANKS; i++) | ||
75 | wakeupgen_writel(reg, i, cpu); | ||
76 | } | ||
77 | |||
78 | static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index) | ||
79 | { | ||
80 | unsigned int spi_irq; | ||
81 | |||
82 | /* | ||
83 | * PPIs and SGIs are not supported. | ||
84 | */ | ||
85 | if (irq < OMAP44XX_IRQ_GIC_START) | ||
86 | return -EINVAL; | ||
87 | |||
88 | /* | ||
89 | * Subtract the GIC offset. | ||
90 | */ | ||
91 | spi_irq = irq - OMAP44XX_IRQ_GIC_START; | ||
92 | if (spi_irq > MAX_IRQS) { | ||
93 | pr_err("omap wakeupGen: Invalid IRQ%d\n", irq); | ||
94 | return -EINVAL; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Each WakeupGen register controls 32 interrupt. | ||
99 | * i.e. 1 bit per SPI IRQ | ||
100 | */ | ||
101 | *reg_index = spi_irq >> 5; | ||
102 | *bit_posn = spi_irq %= 32; | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static void _wakeupgen_clear(unsigned int irq, unsigned int cpu) | ||
108 | { | ||
109 | u32 val, bit_number; | ||
110 | u8 i; | ||
111 | |||
112 | if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) | ||
113 | return; | ||
114 | |||
115 | val = wakeupgen_readl(i, cpu); | ||
116 | val &= ~BIT(bit_number); | ||
117 | wakeupgen_writel(val, i, cpu); | ||
118 | } | ||
119 | |||
120 | static void _wakeupgen_set(unsigned int irq, unsigned int cpu) | ||
121 | { | ||
122 | u32 val, bit_number; | ||
123 | u8 i; | ||
124 | |||
125 | if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) | ||
126 | return; | ||
127 | |||
128 | val = wakeupgen_readl(i, cpu); | ||
129 | val |= BIT(bit_number); | ||
130 | wakeupgen_writel(val, i, cpu); | ||
131 | } | ||
132 | |||
133 | static void _wakeupgen_save_masks(unsigned int cpu) | ||
134 | { | ||
135 | u8 i; | ||
136 | |||
137 | for (i = 0; i < NR_REG_BANKS; i++) | ||
138 | per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu); | ||
139 | } | ||
140 | |||
141 | static void _wakeupgen_restore_masks(unsigned int cpu) | ||
142 | { | ||
143 | u8 i; | ||
144 | |||
145 | for (i = 0; i < NR_REG_BANKS; i++) | ||
146 | wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu); | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Architecture specific Mask extension | ||
151 | */ | ||
152 | static void wakeupgen_mask(struct irq_data *d) | ||
153 | { | ||
154 | unsigned long flags; | ||
155 | |||
156 | spin_lock_irqsave(&wakeupgen_lock, flags); | ||
157 | _wakeupgen_clear(d->irq, irq_target_cpu[d->irq]); | ||
158 | spin_unlock_irqrestore(&wakeupgen_lock, flags); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * Architecture specific Unmask extension | ||
163 | */ | ||
164 | static void wakeupgen_unmask(struct irq_data *d) | ||
165 | { | ||
166 | unsigned long flags; | ||
167 | |||
168 | spin_lock_irqsave(&wakeupgen_lock, flags); | ||
169 | _wakeupgen_set(d->irq, irq_target_cpu[d->irq]); | ||
170 | spin_unlock_irqrestore(&wakeupgen_lock, flags); | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Mask or unmask all interrupts on given CPU. | ||
175 | * 0 = Mask all interrupts on the 'cpu' | ||
176 | * 1 = Unmask all interrupts on the 'cpu' | ||
177 | * Ensure that the initial mask is maintained. This is faster than | ||
178 | * iterating through GIC registers to arrive at the correct masks. | ||
179 | */ | ||
180 | static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) | ||
181 | { | ||
182 | unsigned long flags; | ||
183 | |||
184 | spin_lock_irqsave(&wakeupgen_lock, flags); | ||
185 | if (set) { | ||
186 | _wakeupgen_save_masks(cpu); | ||
187 | _wakeupgen_set_all(cpu, WKG_MASK_ALL); | ||
188 | } else { | ||
189 | _wakeupgen_set_all(cpu, WKG_UNMASK_ALL); | ||
190 | _wakeupgen_restore_masks(cpu); | ||
191 | } | ||
192 | spin_unlock_irqrestore(&wakeupgen_lock, flags); | ||
193 | } | ||
194 | |||
195 | #ifdef CONFIG_CPU_PM | ||
196 | /* | ||
197 | * Save WakeupGen interrupt context in SAR BANK3. Restore is done by | ||
198 | * ROM code. WakeupGen IP is integrated along with GIC to manage the | ||
199 | * interrupt wakeups from CPU low power states. It manages | ||
200 | * masking/unmasking of Shared peripheral interrupts(SPI). So the | ||
201 | * interrupt enable/disable control should be in sync and consistent | ||
202 | * at WakeupGen and GIC so that interrupts are not lost. | ||
203 | */ | ||
204 | static void irq_save_context(void) | ||
205 | { | ||
206 | u32 i, val; | ||
207 | |||
208 | if (omap_rev() == OMAP4430_REV_ES1_0) | ||
209 | return; | ||
210 | |||
211 | if (!sar_base) | ||
212 | sar_base = omap4_get_sar_ram_base(); | ||
213 | |||
214 | for (i = 0; i < NR_REG_BANKS; i++) { | ||
215 | /* Save the CPUx interrupt mask for IRQ 0 to 127 */ | ||
216 | val = wakeupgen_readl(i, 0); | ||
217 | sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i); | ||
218 | val = wakeupgen_readl(i, 1); | ||
219 | sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i); | ||
220 | |||
221 | /* | ||
222 | * Disable the secure interrupts for CPUx. The restore | ||
223 | * code blindly restores secure and non-secure interrupt | ||
224 | * masks from SAR RAM. Secure interrupts are not suppose | ||
225 | * to be enabled from HLOS. So overwrite the SAR location | ||
226 | * so that the secure interrupt remains disabled. | ||
227 | */ | ||
228 | sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i); | ||
229 | sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i); | ||
230 | } | ||
231 | |||
232 | /* Save AuxBoot* registers */ | ||
233 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | ||
234 | __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET); | ||
235 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | ||
236 | __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET); | ||
237 | |||
238 | /* Save SyncReq generation logic */ | ||
239 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | ||
240 | __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET); | ||
241 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | ||
242 | __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET); | ||
243 | |||
244 | /* Save SyncReq generation logic */ | ||
245 | val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK); | ||
246 | __raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET); | ||
247 | val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN); | ||
248 | __raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET); | ||
249 | |||
250 | /* Set the Backup Bit Mask status */ | ||
251 | val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); | ||
252 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; | ||
253 | __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * Clear WakeupGen SAR backup status. | ||
258 | */ | ||
259 | void irq_sar_clear(void) | ||
260 | { | ||
261 | u32 val; | ||
262 | val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); | ||
263 | val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; | ||
264 | __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Save GIC and Wakeupgen interrupt context using secure API | ||
269 | * for HS/EMU devices. | ||
270 | */ | ||
271 | static void irq_save_secure_context(void) | ||
272 | { | ||
273 | u32 ret; | ||
274 | ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX, | ||
275 | FLAG_START_CRITICAL, | ||
276 | 0, 0, 0, 0, 0); | ||
277 | if (ret != API_HAL_RET_VALUE_OK) | ||
278 | pr_err("GIC and Wakeupgen context save failed\n"); | ||
279 | } | ||
280 | #endif | ||
281 | |||
282 | #ifdef CONFIG_HOTPLUG_CPU | ||
283 | static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self, | ||
284 | unsigned long action, void *hcpu) | ||
285 | { | ||
286 | unsigned int cpu = (unsigned int)hcpu; | ||
287 | |||
288 | switch (action) { | ||
289 | case CPU_ONLINE: | ||
290 | wakeupgen_irqmask_all(cpu, 0); | ||
291 | break; | ||
292 | case CPU_DEAD: | ||
293 | wakeupgen_irqmask_all(cpu, 1); | ||
294 | break; | ||
295 | } | ||
296 | return NOTIFY_OK; | ||
297 | } | ||
298 | |||
299 | static struct notifier_block __refdata irq_hotplug_notifier = { | ||
300 | .notifier_call = irq_cpu_hotplug_notify, | ||
301 | }; | ||
302 | |||
303 | static void __init irq_hotplug_init(void) | ||
304 | { | ||
305 | register_hotcpu_notifier(&irq_hotplug_notifier); | ||
306 | } | ||
307 | #else | ||
308 | static void __init irq_hotplug_init(void) | ||
309 | {} | ||
310 | #endif | ||
311 | |||
312 | #ifdef CONFIG_CPU_PM | ||
313 | static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) | ||
314 | { | ||
315 | switch (cmd) { | ||
316 | case CPU_CLUSTER_PM_ENTER: | ||
317 | if (omap_type() == OMAP2_DEVICE_TYPE_GP) | ||
318 | irq_save_context(); | ||
319 | else | ||
320 | irq_save_secure_context(); | ||
321 | break; | ||
322 | case CPU_CLUSTER_PM_EXIT: | ||
323 | if (omap_type() == OMAP2_DEVICE_TYPE_GP) | ||
324 | irq_sar_clear(); | ||
325 | break; | ||
326 | } | ||
327 | return NOTIFY_OK; | ||
328 | } | ||
329 | |||
330 | static struct notifier_block irq_notifier_block = { | ||
331 | .notifier_call = irq_notifier, | ||
332 | }; | ||
333 | |||
334 | static void __init irq_pm_init(void) | ||
335 | { | ||
336 | cpu_pm_register_notifier(&irq_notifier_block); | ||
337 | } | ||
338 | #else | ||
339 | static void __init irq_pm_init(void) | ||
340 | {} | ||
341 | #endif | ||
342 | |||
343 | /* | ||
344 | * Initialise the wakeupgen module. | ||
345 | */ | ||
346 | int __init omap_wakeupgen_init(void) | ||
347 | { | ||
348 | int i; | ||
349 | unsigned int boot_cpu = smp_processor_id(); | ||
350 | |||
351 | /* Not supported on OMAP4 ES1.0 silicon */ | ||
352 | if (omap_rev() == OMAP4430_REV_ES1_0) { | ||
353 | WARN(1, "WakeupGen: Not supported on OMAP4430 ES1.0\n"); | ||
354 | return -EPERM; | ||
355 | } | ||
356 | |||
357 | /* Static mapping, never released */ | ||
358 | wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K); | ||
359 | if (WARN_ON(!wakeupgen_base)) | ||
360 | return -ENOMEM; | ||
361 | |||
362 | /* Clear all IRQ bitmasks at wakeupGen level */ | ||
363 | for (i = 0; i < NR_REG_BANKS; i++) { | ||
364 | wakeupgen_writel(0, i, CPU0_ID); | ||
365 | wakeupgen_writel(0, i, CPU1_ID); | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * Override GIC architecture specific functions to add | ||
370 | * OMAP WakeupGen interrupt controller along with GIC | ||
371 | */ | ||
372 | gic_arch_extn.irq_mask = wakeupgen_mask; | ||
373 | gic_arch_extn.irq_unmask = wakeupgen_unmask; | ||
374 | gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; | ||
375 | |||
376 | /* | ||
377 | * FIXME: Add support to set_smp_affinity() once the core | ||
378 | * GIC code has necessary hooks in place. | ||
379 | */ | ||
380 | |||
381 | /* Associate all the IRQs to boot CPU like GIC init does. */ | ||
382 | for (i = 0; i < NR_IRQS; i++) | ||
383 | irq_target_cpu[i] = boot_cpu; | ||
384 | |||
385 | irq_hotplug_init(); | ||
386 | irq_pm_init(); | ||
387 | |||
388 | return 0; | ||
389 | } | ||
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index beecfdd56ea3..40a8fbc07e4b 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -15,18 +15,69 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/memblock.h> | ||
18 | 19 | ||
19 | #include <asm/hardware/gic.h> | 20 | #include <asm/hardware/gic.h> |
20 | #include <asm/hardware/cache-l2x0.h> | 21 | #include <asm/hardware/cache-l2x0.h> |
22 | #include <asm/mach/map.h> | ||
23 | #include <asm/memblock.h> | ||
21 | 24 | ||
22 | #include <plat/irqs.h> | 25 | #include <plat/irqs.h> |
26 | #include <plat/sram.h> | ||
23 | 27 | ||
24 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/omap-wakeupgen.h> | ||
25 | 30 | ||
26 | #include "common.h" | 31 | #include "common.h" |
32 | #include "omap4-sar-layout.h" | ||
27 | 33 | ||
28 | #ifdef CONFIG_CACHE_L2X0 | 34 | #ifdef CONFIG_CACHE_L2X0 |
29 | void __iomem *l2cache_base; | 35 | static void __iomem *l2cache_base; |
36 | #endif | ||
37 | |||
38 | static void __iomem *sar_ram_base; | ||
39 | |||
40 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
41 | /* Used to implement memory barrier on DRAM path */ | ||
42 | #define OMAP4_DRAM_BARRIER_VA 0xfe600000 | ||
43 | |||
44 | void __iomem *dram_sync, *sram_sync; | ||
45 | |||
46 | void omap_bus_sync(void) | ||
47 | { | ||
48 | if (dram_sync && sram_sync) { | ||
49 | writel_relaxed(readl_relaxed(dram_sync), dram_sync); | ||
50 | writel_relaxed(readl_relaxed(sram_sync), sram_sync); | ||
51 | isb(); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | static int __init omap_barriers_init(void) | ||
56 | { | ||
57 | struct map_desc dram_io_desc[1]; | ||
58 | phys_addr_t paddr; | ||
59 | u32 size; | ||
60 | |||
61 | if (!cpu_is_omap44xx()) | ||
62 | return -ENODEV; | ||
63 | |||
64 | size = ALIGN(PAGE_SIZE, SZ_1M); | ||
65 | paddr = arm_memblock_steal(size, SZ_1M); | ||
66 | |||
67 | dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; | ||
68 | dram_io_desc[0].pfn = __phys_to_pfn(paddr); | ||
69 | dram_io_desc[0].length = size; | ||
70 | dram_io_desc[0].type = MT_MEMORY_SO; | ||
71 | iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); | ||
72 | dram_sync = (void __iomem *) dram_io_desc[0].virtual; | ||
73 | sram_sync = (void __iomem *) OMAP4_SRAM_VA; | ||
74 | |||
75 | pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n", | ||
76 | (long long) paddr, dram_io_desc[0].virtual); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | core_initcall(omap_barriers_init); | ||
30 | #endif | 81 | #endif |
31 | 82 | ||
32 | void __init gic_init_irq(void) | 83 | void __init gic_init_irq(void) |
@@ -42,11 +93,18 @@ void __init gic_init_irq(void) | |||
42 | omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); | 93 | omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512); |
43 | BUG_ON(!omap_irq_base); | 94 | BUG_ON(!omap_irq_base); |
44 | 95 | ||
96 | omap_wakeupgen_init(); | ||
97 | |||
45 | gic_init(0, 29, gic_dist_base_addr, omap_irq_base); | 98 | gic_init(0, 29, gic_dist_base_addr, omap_irq_base); |
46 | } | 99 | } |
47 | 100 | ||
48 | #ifdef CONFIG_CACHE_L2X0 | 101 | #ifdef CONFIG_CACHE_L2X0 |
49 | 102 | ||
103 | void __iomem *omap4_get_l2cache_base(void) | ||
104 | { | ||
105 | return l2cache_base; | ||
106 | } | ||
107 | |||
50 | static void omap4_l2x0_disable(void) | 108 | static void omap4_l2x0_disable(void) |
51 | { | 109 | { |
52 | /* Disable PL310 L2 Cache controller */ | 110 | /* Disable PL310 L2 Cache controller */ |
@@ -72,7 +130,8 @@ static int __init omap_l2_cache_init(void) | |||
72 | 130 | ||
73 | /* Static mapping, never released */ | 131 | /* Static mapping, never released */ |
74 | l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); | 132 | l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K); |
75 | BUG_ON(!l2cache_base); | 133 | if (WARN_ON(!l2cache_base)) |
134 | return -ENOMEM; | ||
76 | 135 | ||
77 | /* | 136 | /* |
78 | * 16-way associativity, parity disabled | 137 | * 16-way associativity, parity disabled |
@@ -112,3 +171,30 @@ static int __init omap_l2_cache_init(void) | |||
112 | } | 171 | } |
113 | early_initcall(omap_l2_cache_init); | 172 | early_initcall(omap_l2_cache_init); |
114 | #endif | 173 | #endif |
174 | |||
175 | void __iomem *omap4_get_sar_ram_base(void) | ||
176 | { | ||
177 | return sar_ram_base; | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * SAR RAM used to save and restore the HW | ||
182 | * context in low power modes | ||
183 | */ | ||
184 | static int __init omap4_sar_ram_init(void) | ||
185 | { | ||
186 | /* | ||
187 | * To avoid code running on other OMAPs in | ||
188 | * multi-omap builds | ||
189 | */ | ||
190 | if (!cpu_is_omap44xx()) | ||
191 | return -ENOMEM; | ||
192 | |||
193 | /* Static mapping, never released */ | ||
194 | sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K); | ||
195 | if (WARN_ON(!sar_ram_base)) | ||
196 | return -ENOMEM; | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | early_initcall(omap4_sar_ram_init); | ||
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h new file mode 100644 index 000000000000..fe5b545ad443 --- /dev/null +++ b/arch/arm/mach-omap2/omap4-sar-layout.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * omap4-sar-layout.h: OMAP4 SAR RAM layout header file | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
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 | #ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H | ||
12 | #define OMAP_ARCH_OMAP4_SAR_LAYOUT_H | ||
13 | |||
14 | /* | ||
15 | * SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE | ||
16 | */ | ||
17 | #define SAR_BANK1_OFFSET 0x0000 | ||
18 | #define SAR_BANK2_OFFSET 0x1000 | ||
19 | #define SAR_BANK3_OFFSET 0x2000 | ||
20 | #define SAR_BANK4_OFFSET 0x3000 | ||
21 | |||
22 | /* Scratch pad memory offsets from SAR_BANK1 */ | ||
23 | #define SCU_OFFSET0 0xd00 | ||
24 | #define SCU_OFFSET1 0xd04 | ||
25 | #define OMAP_TYPE_OFFSET 0xd10 | ||
26 | #define L2X0_SAVE_OFFSET0 0xd14 | ||
27 | #define L2X0_SAVE_OFFSET1 0xd18 | ||
28 | #define L2X0_AUXCTRL_OFFSET 0xd1c | ||
29 | #define L2X0_PREFETCH_CTRL_OFFSET 0xd20 | ||
30 | |||
31 | /* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ | ||
32 | #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 | ||
33 | #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 | ||
34 | |||
35 | #define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500) | ||
36 | #define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504) | ||
37 | #define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) | ||
38 | |||
39 | /* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ | ||
40 | #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684) | ||
41 | #define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694) | ||
42 | #define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4) | ||
43 | #define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4) | ||
44 | #define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4) | ||
45 | #define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8) | ||
46 | #define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc) | ||
47 | #define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0) | ||
48 | #define SAR_BACKUP_STATUS_WAKEUPGEN 0x10 | ||
49 | |||
50 | #endif | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 529142aff766..5192cabb40ed 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -136,6 +136,7 @@ | |||
136 | #include <linux/list.h> | 136 | #include <linux/list.h> |
137 | #include <linux/mutex.h> | 137 | #include <linux/mutex.h> |
138 | #include <linux/spinlock.h> | 138 | #include <linux/spinlock.h> |
139 | #include <linux/slab.h> | ||
139 | 140 | ||
140 | #include "common.h" | 141 | #include "common.h" |
141 | #include <plat/cpu.h> | 142 | #include <plat/cpu.h> |
@@ -381,6 +382,51 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle, | |||
381 | } | 382 | } |
382 | 383 | ||
383 | /** | 384 | /** |
385 | * _set_idle_ioring_wakeup - enable/disable IO pad wakeup on hwmod idle for mux | ||
386 | * @oh: struct omap_hwmod * | ||
387 | * @set_wake: bool value indicating to set (true) or clear (false) wakeup enable | ||
388 | * | ||
389 | * Set or clear the I/O pad wakeup flag in the mux entries for the | ||
390 | * hwmod @oh. This function changes the @oh->mux->pads_dynamic array | ||
391 | * in memory. If the hwmod is currently idled, and the new idle | ||
392 | * values don't match the previous ones, this function will also | ||
393 | * update the SCM PADCTRL registers. Otherwise, if the hwmod is not | ||
394 | * currently idled, this function won't touch the hardware: the new | ||
395 | * mux settings are written to the SCM PADCTRL registers when the | ||
396 | * hwmod is idled. No return value. | ||
397 | */ | ||
398 | static void _set_idle_ioring_wakeup(struct omap_hwmod *oh, bool set_wake) | ||
399 | { | ||
400 | struct omap_device_pad *pad; | ||
401 | bool change = false; | ||
402 | u16 prev_idle; | ||
403 | int j; | ||
404 | |||
405 | if (!oh->mux || !oh->mux->enabled) | ||
406 | return; | ||
407 | |||
408 | for (j = 0; j < oh->mux->nr_pads_dynamic; j++) { | ||
409 | pad = oh->mux->pads_dynamic[j]; | ||
410 | |||
411 | if (!(pad->flags & OMAP_DEVICE_PAD_WAKEUP)) | ||
412 | continue; | ||
413 | |||
414 | prev_idle = pad->idle; | ||
415 | |||
416 | if (set_wake) | ||
417 | pad->idle |= OMAP_WAKEUP_EN; | ||
418 | else | ||
419 | pad->idle &= ~OMAP_WAKEUP_EN; | ||
420 | |||
421 | if (prev_idle != pad->idle) | ||
422 | change = true; | ||
423 | } | ||
424 | |||
425 | if (change && oh->_state == _HWMOD_STATE_IDLE) | ||
426 | omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE); | ||
427 | } | ||
428 | |||
429 | /** | ||
384 | * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware | 430 | * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware |
385 | * @oh: struct omap_hwmod * | 431 | * @oh: struct omap_hwmod * |
386 | * | 432 | * |
@@ -706,27 +752,65 @@ static void _enable_module(struct omap_hwmod *oh) | |||
706 | } | 752 | } |
707 | 753 | ||
708 | /** | 754 | /** |
709 | * _disable_module - enable CLKCTRL modulemode on OMAP4 | 755 | * _omap4_wait_target_disable - wait for a module to be disabled on OMAP4 |
756 | * @oh: struct omap_hwmod * | ||
757 | * | ||
758 | * Wait for a module @oh to enter slave idle. Returns 0 if the module | ||
759 | * does not have an IDLEST bit or if the module successfully enters | ||
760 | * slave idle; otherwise, pass along the return value of the | ||
761 | * appropriate *_cm*_wait_module_idle() function. | ||
762 | */ | ||
763 | static int _omap4_wait_target_disable(struct omap_hwmod *oh) | ||
764 | { | ||
765 | if (!cpu_is_omap44xx()) | ||
766 | return 0; | ||
767 | |||
768 | if (!oh) | ||
769 | return -EINVAL; | ||
770 | |||
771 | if (oh->_int_flags & _HWMOD_NO_MPU_PORT) | ||
772 | return 0; | ||
773 | |||
774 | if (oh->flags & HWMOD_NO_IDLEST) | ||
775 | return 0; | ||
776 | |||
777 | return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, | ||
778 | oh->clkdm->cm_inst, | ||
779 | oh->clkdm->clkdm_offs, | ||
780 | oh->prcm.omap4.clkctrl_offs); | ||
781 | } | ||
782 | |||
783 | /** | ||
784 | * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4 | ||
710 | * @oh: struct omap_hwmod * | 785 | * @oh: struct omap_hwmod * |
711 | * | 786 | * |
712 | * Disable the PRCM module mode related to the hwmod @oh. | 787 | * Disable the PRCM module mode related to the hwmod @oh. |
713 | * No return value. | 788 | * Return EINVAL if the modulemode is not supported and 0 in case of success. |
714 | */ | 789 | */ |
715 | static void _disable_module(struct omap_hwmod *oh) | 790 | static int _omap4_disable_module(struct omap_hwmod *oh) |
716 | { | 791 | { |
792 | int v; | ||
793 | |||
717 | /* The module mode does not exist prior OMAP4 */ | 794 | /* The module mode does not exist prior OMAP4 */ |
718 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | 795 | if (!cpu_is_omap44xx()) |
719 | return; | 796 | return -EINVAL; |
720 | 797 | ||
721 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) | 798 | if (!oh->clkdm || !oh->prcm.omap4.modulemode) |
722 | return; | 799 | return -EINVAL; |
723 | 800 | ||
724 | pr_debug("omap_hwmod: %s: _disable_module\n", oh->name); | 801 | pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__); |
725 | 802 | ||
726 | omap4_cminst_module_disable(oh->clkdm->prcm_partition, | 803 | omap4_cminst_module_disable(oh->clkdm->prcm_partition, |
727 | oh->clkdm->cm_inst, | 804 | oh->clkdm->cm_inst, |
728 | oh->clkdm->clkdm_offs, | 805 | oh->clkdm->clkdm_offs, |
729 | oh->prcm.omap4.clkctrl_offs); | 806 | oh->prcm.omap4.clkctrl_offs); |
807 | |||
808 | v = _omap4_wait_target_disable(oh); | ||
809 | if (v) | ||
810 | pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", | ||
811 | oh->name); | ||
812 | |||
813 | return 0; | ||
730 | } | 814 | } |
731 | 815 | ||
732 | /** | 816 | /** |
@@ -1153,36 +1237,6 @@ static int _wait_target_ready(struct omap_hwmod *oh) | |||
1153 | } | 1237 | } |
1154 | 1238 | ||
1155 | /** | 1239 | /** |
1156 | * _wait_target_disable - wait for a module to be disabled | ||
1157 | * @oh: struct omap_hwmod * | ||
1158 | * | ||
1159 | * Wait for a module @oh to enter slave idle. Returns 0 if the module | ||
1160 | * does not have an IDLEST bit or if the module successfully enters | ||
1161 | * slave idle; otherwise, pass along the return value of the | ||
1162 | * appropriate *_cm*_wait_module_idle() function. | ||
1163 | */ | ||
1164 | static int _wait_target_disable(struct omap_hwmod *oh) | ||
1165 | { | ||
1166 | /* TODO: For now just handle OMAP4+ */ | ||
1167 | if (cpu_is_omap24xx() || cpu_is_omap34xx()) | ||
1168 | return 0; | ||
1169 | |||
1170 | if (!oh) | ||
1171 | return -EINVAL; | ||
1172 | |||
1173 | if (oh->_int_flags & _HWMOD_NO_MPU_PORT) | ||
1174 | return 0; | ||
1175 | |||
1176 | if (oh->flags & HWMOD_NO_IDLEST) | ||
1177 | return 0; | ||
1178 | |||
1179 | return omap4_cminst_wait_module_idle(oh->clkdm->prcm_partition, | ||
1180 | oh->clkdm->cm_inst, | ||
1181 | oh->clkdm->clkdm_offs, | ||
1182 | oh->prcm.omap4.clkctrl_offs); | ||
1183 | } | ||
1184 | |||
1185 | /** | ||
1186 | * _lookup_hardreset - fill register bit info for this hwmod/reset line | 1240 | * _lookup_hardreset - fill register bit info for this hwmod/reset line |
1187 | * @oh: struct omap_hwmod * | 1241 | * @oh: struct omap_hwmod * |
1188 | * @name: name of the reset line in the context of this hwmod | 1242 | * @name: name of the reset line in the context of this hwmod |
@@ -1441,6 +1495,25 @@ static int _enable(struct omap_hwmod *oh) | |||
1441 | 1495 | ||
1442 | pr_debug("omap_hwmod: %s: enabling\n", oh->name); | 1496 | pr_debug("omap_hwmod: %s: enabling\n", oh->name); |
1443 | 1497 | ||
1498 | /* | ||
1499 | * hwmods with HWMOD_INIT_NO_IDLE flag set are left | ||
1500 | * in enabled state at init. | ||
1501 | * Now that someone is really trying to enable them, | ||
1502 | * just ensure that the hwmod mux is set. | ||
1503 | */ | ||
1504 | if (oh->_int_flags & _HWMOD_SKIP_ENABLE) { | ||
1505 | /* | ||
1506 | * If the caller has mux data populated, do the mux'ing | ||
1507 | * which wouldn't have been done as part of the _enable() | ||
1508 | * done during setup. | ||
1509 | */ | ||
1510 | if (oh->mux) | ||
1511 | omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); | ||
1512 | |||
1513 | oh->_int_flags &= ~_HWMOD_SKIP_ENABLE; | ||
1514 | return 0; | ||
1515 | } | ||
1516 | |||
1444 | if (oh->_state != _HWMOD_STATE_INITIALIZED && | 1517 | if (oh->_state != _HWMOD_STATE_INITIALIZED && |
1445 | oh->_state != _HWMOD_STATE_IDLE && | 1518 | oh->_state != _HWMOD_STATE_IDLE && |
1446 | oh->_state != _HWMOD_STATE_DISABLED) { | 1519 | oh->_state != _HWMOD_STATE_DISABLED) { |
@@ -1524,8 +1597,6 @@ static int _enable(struct omap_hwmod *oh) | |||
1524 | */ | 1597 | */ |
1525 | static int _idle(struct omap_hwmod *oh) | 1598 | static int _idle(struct omap_hwmod *oh) |
1526 | { | 1599 | { |
1527 | int ret; | ||
1528 | |||
1529 | pr_debug("omap_hwmod: %s: idling\n", oh->name); | 1600 | pr_debug("omap_hwmod: %s: idling\n", oh->name); |
1530 | 1601 | ||
1531 | if (oh->_state != _HWMOD_STATE_ENABLED) { | 1602 | if (oh->_state != _HWMOD_STATE_ENABLED) { |
@@ -1537,11 +1608,9 @@ static int _idle(struct omap_hwmod *oh) | |||
1537 | if (oh->class->sysc) | 1608 | if (oh->class->sysc) |
1538 | _idle_sysc(oh); | 1609 | _idle_sysc(oh); |
1539 | _del_initiator_dep(oh, mpu_oh); | 1610 | _del_initiator_dep(oh, mpu_oh); |
1540 | _disable_module(oh); | 1611 | |
1541 | ret = _wait_target_disable(oh); | 1612 | _omap4_disable_module(oh); |
1542 | if (ret) | 1613 | |
1543 | pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", | ||
1544 | oh->name); | ||
1545 | /* | 1614 | /* |
1546 | * The module must be in idle mode before disabling any parents | 1615 | * The module must be in idle mode before disabling any parents |
1547 | * clocks. Otherwise, the parent clock might be disabled before | 1616 | * clocks. Otherwise, the parent clock might be disabled before |
@@ -1642,11 +1711,7 @@ static int _shutdown(struct omap_hwmod *oh) | |||
1642 | if (oh->_state == _HWMOD_STATE_ENABLED) { | 1711 | if (oh->_state == _HWMOD_STATE_ENABLED) { |
1643 | _del_initiator_dep(oh, mpu_oh); | 1712 | _del_initiator_dep(oh, mpu_oh); |
1644 | /* XXX what about the other system initiators here? dma, dsp */ | 1713 | /* XXX what about the other system initiators here? dma, dsp */ |
1645 | _disable_module(oh); | 1714 | _omap4_disable_module(oh); |
1646 | ret = _wait_target_disable(oh); | ||
1647 | if (ret) | ||
1648 | pr_warn("omap_hwmod: %s: _wait_target_disable failed\n", | ||
1649 | oh->name); | ||
1650 | _disable_clocks(oh); | 1715 | _disable_clocks(oh); |
1651 | if (oh->clkdm) | 1716 | if (oh->clkdm) |
1652 | clkdm_hwmod_disable(oh->clkdm, oh); | 1717 | clkdm_hwmod_disable(oh->clkdm, oh); |
@@ -1744,8 +1809,10 @@ static int _setup(struct omap_hwmod *oh, void *data) | |||
1744 | * it should be set by the core code as a runtime flag during startup | 1809 | * it should be set by the core code as a runtime flag during startup |
1745 | */ | 1810 | */ |
1746 | if ((oh->flags & HWMOD_INIT_NO_IDLE) && | 1811 | if ((oh->flags & HWMOD_INIT_NO_IDLE) && |
1747 | (postsetup_state == _HWMOD_STATE_IDLE)) | 1812 | (postsetup_state == _HWMOD_STATE_IDLE)) { |
1813 | oh->_int_flags |= _HWMOD_SKIP_ENABLE; | ||
1748 | postsetup_state = _HWMOD_STATE_ENABLED; | 1814 | postsetup_state = _HWMOD_STATE_ENABLED; |
1815 | } | ||
1749 | 1816 | ||
1750 | if (postsetup_state == _HWMOD_STATE_IDLE) | 1817 | if (postsetup_state == _HWMOD_STATE_IDLE) |
1751 | _idle(oh); | 1818 | _idle(oh); |
@@ -2416,6 +2483,7 @@ int omap_hwmod_enable_wakeup(struct omap_hwmod *oh) | |||
2416 | v = oh->_sysc_cache; | 2483 | v = oh->_sysc_cache; |
2417 | _enable_wakeup(oh, &v); | 2484 | _enable_wakeup(oh, &v); |
2418 | _write_sysconfig(v, oh); | 2485 | _write_sysconfig(v, oh); |
2486 | _set_idle_ioring_wakeup(oh, true); | ||
2419 | spin_unlock_irqrestore(&oh->_lock, flags); | 2487 | spin_unlock_irqrestore(&oh->_lock, flags); |
2420 | 2488 | ||
2421 | return 0; | 2489 | return 0; |
@@ -2446,6 +2514,7 @@ int omap_hwmod_disable_wakeup(struct omap_hwmod *oh) | |||
2446 | v = oh->_sysc_cache; | 2514 | v = oh->_sysc_cache; |
2447 | _disable_wakeup(oh, &v); | 2515 | _disable_wakeup(oh, &v); |
2448 | _write_sysconfig(v, oh); | 2516 | _write_sysconfig(v, oh); |
2517 | _set_idle_ioring_wakeup(oh, false); | ||
2449 | spin_unlock_irqrestore(&oh->_lock, flags); | 2518 | spin_unlock_irqrestore(&oh->_lock, flags); |
2450 | 2519 | ||
2451 | return 0; | 2520 | return 0; |
@@ -2662,3 +2731,57 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh) | |||
2662 | 2731 | ||
2663 | return 0; | 2732 | return 0; |
2664 | } | 2733 | } |
2734 | |||
2735 | /** | ||
2736 | * omap_hwmod_pad_route_irq - route an I/O pad wakeup to a particular MPU IRQ | ||
2737 | * @oh: struct omap_hwmod * containing hwmod mux entries | ||
2738 | * @pad_idx: array index in oh->mux of the hwmod mux entry to route wakeup | ||
2739 | * @irq_idx: the hwmod mpu_irqs array index of the IRQ to trigger on wakeup | ||
2740 | * | ||
2741 | * When an I/O pad wakeup arrives for the dynamic or wakeup hwmod mux | ||
2742 | * entry number @pad_idx for the hwmod @oh, trigger the interrupt | ||
2743 | * service routine for the hwmod's mpu_irqs array index @irq_idx. If | ||
2744 | * this function is not called for a given pad_idx, then the ISR | ||
2745 | * associated with @oh's first MPU IRQ will be triggered when an I/O | ||
2746 | * pad wakeup occurs on that pad. Note that @pad_idx is the index of | ||
2747 | * the _dynamic or wakeup_ entry: if there are other entries not | ||
2748 | * marked with OMAP_DEVICE_PAD_WAKEUP or OMAP_DEVICE_PAD_REMUX, these | ||
2749 | * entries are NOT COUNTED in the dynamic pad index. This function | ||
2750 | * must be called separately for each pad that requires its interrupt | ||
2751 | * to be re-routed this way. Returns -EINVAL if there is an argument | ||
2752 | * problem or if @oh does not have hwmod mux entries or MPU IRQs; | ||
2753 | * returns -ENOMEM if memory cannot be allocated; or 0 upon success. | ||
2754 | * | ||
2755 | * XXX This function interface is fragile. Rather than using array | ||
2756 | * indexes, which are subject to unpredictable change, it should be | ||
2757 | * using hwmod IRQ names, and some other stable key for the hwmod mux | ||
2758 | * pad records. | ||
2759 | */ | ||
2760 | int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx) | ||
2761 | { | ||
2762 | int nr_irqs; | ||
2763 | |||
2764 | might_sleep(); | ||
2765 | |||
2766 | if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 || | ||
2767 | pad_idx >= oh->mux->nr_pads_dynamic) | ||
2768 | return -EINVAL; | ||
2769 | |||
2770 | /* Check the number of available mpu_irqs */ | ||
2771 | for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++) | ||
2772 | ; | ||
2773 | |||
2774 | if (irq_idx >= nr_irqs) | ||
2775 | return -EINVAL; | ||
2776 | |||
2777 | if (!oh->mux->irqs) { | ||
2778 | /* XXX What frees this? */ | ||
2779 | oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic, | ||
2780 | GFP_KERNEL); | ||
2781 | if (!oh->mux->irqs) | ||
2782 | return -ENOMEM; | ||
2783 | } | ||
2784 | oh->mux->irqs[pad_idx] = irq_idx; | ||
2785 | |||
2786 | return 0; | ||
2787 | } | ||
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c index c11273da5dcc..f08e442af397 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c | |||
@@ -56,27 +56,6 @@ struct omap_hwmod_class omap2_dss_hwmod_class = { | |||
56 | }; | 56 | }; |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * 'dispc' class | ||
60 | * display controller | ||
61 | */ | ||
62 | |||
63 | static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = { | ||
64 | .rev_offs = 0x0000, | ||
65 | .sysc_offs = 0x0010, | ||
66 | .syss_offs = 0x0014, | ||
67 | .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | | ||
68 | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), | ||
69 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||
70 | MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), | ||
71 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
72 | }; | ||
73 | |||
74 | struct omap_hwmod_class omap2_dispc_hwmod_class = { | ||
75 | .name = "dispc", | ||
76 | .sysc = &omap2_dispc_sysc, | ||
77 | }; | ||
78 | |||
79 | /* | ||
80 | * 'rfbi' class | 59 | * 'rfbi' class |
81 | * remote frame buffer interface | 60 | * remote frame buffer interface |
82 | */ | 61 | */ |
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 177dee20faef..2a6729741b06 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | |||
@@ -28,6 +28,28 @@ struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = { | |||
28 | { .name = "dispc", .dma_req = 5 }, | 28 | { .name = "dispc", .dma_req = 5 }, |
29 | { .dma_req = -1 } | 29 | { .dma_req = -1 } |
30 | }; | 30 | }; |
31 | |||
32 | /* | ||
33 | * 'dispc' class | ||
34 | * display controller | ||
35 | */ | ||
36 | |||
37 | static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = { | ||
38 | .rev_offs = 0x0000, | ||
39 | .sysc_offs = 0x0010, | ||
40 | .syss_offs = 0x0014, | ||
41 | .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | | ||
42 | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), | ||
43 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||
44 | MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), | ||
45 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
46 | }; | ||
47 | |||
48 | struct omap_hwmod_class omap2_dispc_hwmod_class = { | ||
49 | .name = "dispc", | ||
50 | .sysc = &omap2_dispc_sysc, | ||
51 | }; | ||
52 | |||
31 | /* OMAP2xxx Timer Common */ | 53 | /* OMAP2xxx Timer Common */ |
32 | static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = { | 54 | static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = { |
33 | .rev_offs = 0x0000, | 55 | .rev_offs = 0x0000, |
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 7f8915ad5099..3c8dd928628e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | |||
@@ -84,6 +84,8 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod; | |||
84 | static struct omap_hwmod omap3xxx_mcbsp5_hwmod; | 84 | static struct omap_hwmod omap3xxx_mcbsp5_hwmod; |
85 | static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod; | 85 | static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod; |
86 | static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod; | 86 | static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod; |
87 | static struct omap_hwmod omap3xxx_usb_host_hs_hwmod; | ||
88 | static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod; | ||
87 | 89 | ||
88 | /* L3 -> L4_CORE interface */ | 90 | /* L3 -> L4_CORE interface */ |
89 | static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { | 91 | static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { |
@@ -164,6 +166,7 @@ static struct omap_hwmod omap3xxx_uart1_hwmod; | |||
164 | static struct omap_hwmod omap3xxx_uart2_hwmod; | 166 | static struct omap_hwmod omap3xxx_uart2_hwmod; |
165 | static struct omap_hwmod omap3xxx_uart3_hwmod; | 167 | static struct omap_hwmod omap3xxx_uart3_hwmod; |
166 | static struct omap_hwmod omap3xxx_uart4_hwmod; | 168 | static struct omap_hwmod omap3xxx_uart4_hwmod; |
169 | static struct omap_hwmod am35xx_uart4_hwmod; | ||
167 | static struct omap_hwmod omap3xxx_usbhsotg_hwmod; | 170 | static struct omap_hwmod omap3xxx_usbhsotg_hwmod; |
168 | 171 | ||
169 | /* l3_core -> usbhsotg interface */ | 172 | /* l3_core -> usbhsotg interface */ |
@@ -299,6 +302,23 @@ static struct omap_hwmod_ocp_if omap3_l4_per__uart4 = { | |||
299 | .user = OCP_USER_MPU | OCP_USER_SDMA, | 302 | .user = OCP_USER_MPU | OCP_USER_SDMA, |
300 | }; | 303 | }; |
301 | 304 | ||
305 | /* AM35xx: L4 CORE -> UART4 interface */ | ||
306 | static struct omap_hwmod_addr_space am35xx_uart4_addr_space[] = { | ||
307 | { | ||
308 | .pa_start = OMAP3_UART4_AM35XX_BASE, | ||
309 | .pa_end = OMAP3_UART4_AM35XX_BASE + SZ_1K - 1, | ||
310 | .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT, | ||
311 | }, | ||
312 | }; | ||
313 | |||
314 | static struct omap_hwmod_ocp_if am35xx_l4_core__uart4 = { | ||
315 | .master = &omap3xxx_l4_core_hwmod, | ||
316 | .slave = &am35xx_uart4_hwmod, | ||
317 | .clk = "uart4_ick", | ||
318 | .addr = am35xx_uart4_addr_space, | ||
319 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
320 | }; | ||
321 | |||
302 | /* L4 CORE -> I2C1 interface */ | 322 | /* L4 CORE -> I2C1 interface */ |
303 | static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = { | 323 | static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = { |
304 | .master = &omap3xxx_l4_core_hwmod, | 324 | .master = &omap3xxx_l4_core_hwmod, |
@@ -1162,6 +1182,7 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = { | |||
1162 | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | | 1182 | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | |
1163 | SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), | 1183 | SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), |
1164 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), | 1184 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), |
1185 | .clockact = CLOCKACT_TEST_ICLK, | ||
1165 | .sysc_fields = &omap_hwmod_sysc_type1, | 1186 | .sysc_fields = &omap_hwmod_sysc_type1, |
1166 | }; | 1187 | }; |
1167 | 1188 | ||
@@ -1309,6 +1330,39 @@ static struct omap_hwmod omap3xxx_uart4_hwmod = { | |||
1309 | .class = &omap2_uart_class, | 1330 | .class = &omap2_uart_class, |
1310 | }; | 1331 | }; |
1311 | 1332 | ||
1333 | static struct omap_hwmod_irq_info am35xx_uart4_mpu_irqs[] = { | ||
1334 | { .irq = INT_35XX_UART4_IRQ, }, | ||
1335 | }; | ||
1336 | |||
1337 | static struct omap_hwmod_dma_info am35xx_uart4_sdma_reqs[] = { | ||
1338 | { .name = "rx", .dma_req = AM35XX_DMA_UART4_RX, }, | ||
1339 | { .name = "tx", .dma_req = AM35XX_DMA_UART4_TX, }, | ||
1340 | }; | ||
1341 | |||
1342 | static struct omap_hwmod_ocp_if *am35xx_uart4_slaves[] = { | ||
1343 | &am35xx_l4_core__uart4, | ||
1344 | }; | ||
1345 | |||
1346 | static struct omap_hwmod am35xx_uart4_hwmod = { | ||
1347 | .name = "uart4", | ||
1348 | .mpu_irqs = am35xx_uart4_mpu_irqs, | ||
1349 | .sdma_reqs = am35xx_uart4_sdma_reqs, | ||
1350 | .main_clk = "uart4_fck", | ||
1351 | .prcm = { | ||
1352 | .omap2 = { | ||
1353 | .module_offs = CORE_MOD, | ||
1354 | .prcm_reg_id = 1, | ||
1355 | .module_bit = OMAP3430_EN_UART4_SHIFT, | ||
1356 | .idlest_reg_id = 1, | ||
1357 | .idlest_idle_bit = OMAP3430_EN_UART4_SHIFT, | ||
1358 | }, | ||
1359 | }, | ||
1360 | .slaves = am35xx_uart4_slaves, | ||
1361 | .slaves_cnt = ARRAY_SIZE(am35xx_uart4_slaves), | ||
1362 | .class = &omap2_uart_class, | ||
1363 | }; | ||
1364 | |||
1365 | |||
1312 | static struct omap_hwmod_class i2c_class = { | 1366 | static struct omap_hwmod_class i2c_class = { |
1313 | .name = "i2c", | 1367 | .name = "i2c", |
1314 | .sysc = &i2c_sysc, | 1368 | .sysc = &i2c_sysc, |
@@ -1426,6 +1480,28 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = { | |||
1426 | .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), | 1480 | .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), |
1427 | }; | 1481 | }; |
1428 | 1482 | ||
1483 | /* | ||
1484 | * 'dispc' class | ||
1485 | * display controller | ||
1486 | */ | ||
1487 | |||
1488 | static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = { | ||
1489 | .rev_offs = 0x0000, | ||
1490 | .sysc_offs = 0x0010, | ||
1491 | .syss_offs = 0x0014, | ||
1492 | .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | | ||
1493 | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | | ||
1494 | SYSC_HAS_ENAWAKEUP), | ||
1495 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||
1496 | MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), | ||
1497 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
1498 | }; | ||
1499 | |||
1500 | static struct omap_hwmod_class omap3_dispc_hwmod_class = { | ||
1501 | .name = "dispc", | ||
1502 | .sysc = &omap3_dispc_sysc, | ||
1503 | }; | ||
1504 | |||
1429 | /* l4_core -> dss_dispc */ | 1505 | /* l4_core -> dss_dispc */ |
1430 | static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = { | 1506 | static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = { |
1431 | .master = &omap3xxx_l4_core_hwmod, | 1507 | .master = &omap3xxx_l4_core_hwmod, |
@@ -1449,7 +1525,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = { | |||
1449 | 1525 | ||
1450 | static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { | 1526 | static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { |
1451 | .name = "dss_dispc", | 1527 | .name = "dss_dispc", |
1452 | .class = &omap2_dispc_hwmod_class, | 1528 | .class = &omap3_dispc_hwmod_class, |
1453 | .mpu_irqs = omap2_dispc_irqs, | 1529 | .mpu_irqs = omap2_dispc_irqs, |
1454 | .main_clk = "dss1_alwon_fck", | 1530 | .main_clk = "dss1_alwon_fck", |
1455 | .prcm = { | 1531 | .prcm = { |
@@ -1636,7 +1712,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = { | |||
1636 | 1712 | ||
1637 | static struct omap_hwmod omap3xxx_i2c1_hwmod = { | 1713 | static struct omap_hwmod omap3xxx_i2c1_hwmod = { |
1638 | .name = "i2c1", | 1714 | .name = "i2c1", |
1639 | .flags = HWMOD_16BIT_REG, | 1715 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
1640 | .mpu_irqs = omap2_i2c1_mpu_irqs, | 1716 | .mpu_irqs = omap2_i2c1_mpu_irqs, |
1641 | .sdma_reqs = omap2_i2c1_sdma_reqs, | 1717 | .sdma_reqs = omap2_i2c1_sdma_reqs, |
1642 | .main_clk = "i2c1_fck", | 1718 | .main_clk = "i2c1_fck", |
@@ -1670,7 +1746,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = { | |||
1670 | 1746 | ||
1671 | static struct omap_hwmod omap3xxx_i2c2_hwmod = { | 1747 | static struct omap_hwmod omap3xxx_i2c2_hwmod = { |
1672 | .name = "i2c2", | 1748 | .name = "i2c2", |
1673 | .flags = HWMOD_16BIT_REG, | 1749 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
1674 | .mpu_irqs = omap2_i2c2_mpu_irqs, | 1750 | .mpu_irqs = omap2_i2c2_mpu_irqs, |
1675 | .sdma_reqs = omap2_i2c2_sdma_reqs, | 1751 | .sdma_reqs = omap2_i2c2_sdma_reqs, |
1676 | .main_clk = "i2c2_fck", | 1752 | .main_clk = "i2c2_fck", |
@@ -1715,7 +1791,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c3_slaves[] = { | |||
1715 | 1791 | ||
1716 | static struct omap_hwmod omap3xxx_i2c3_hwmod = { | 1792 | static struct omap_hwmod omap3xxx_i2c3_hwmod = { |
1717 | .name = "i2c3", | 1793 | .name = "i2c3", |
1718 | .flags = HWMOD_16BIT_REG, | 1794 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
1719 | .mpu_irqs = i2c3_mpu_irqs, | 1795 | .mpu_irqs = i2c3_mpu_irqs, |
1720 | .sdma_reqs = i2c3_sdma_reqs, | 1796 | .sdma_reqs = i2c3_sdma_reqs, |
1721 | .main_clk = "i2c3_fck", | 1797 | .main_clk = "i2c3_fck", |
@@ -3072,7 +3148,35 @@ static struct omap_mmc_dev_attr mmc1_dev_attr = { | |||
3072 | .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, | 3148 | .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, |
3073 | }; | 3149 | }; |
3074 | 3150 | ||
3075 | static struct omap_hwmod omap3xxx_mmc1_hwmod = { | 3151 | /* See 35xx errata 2.1.1.128 in SPRZ278F */ |
3152 | static struct omap_mmc_dev_attr mmc1_pre_es3_dev_attr = { | ||
3153 | .flags = (OMAP_HSMMC_SUPPORTS_DUAL_VOLT | | ||
3154 | OMAP_HSMMC_BROKEN_MULTIBLOCK_READ), | ||
3155 | }; | ||
3156 | |||
3157 | static struct omap_hwmod omap3xxx_pre_es3_mmc1_hwmod = { | ||
3158 | .name = "mmc1", | ||
3159 | .mpu_irqs = omap34xx_mmc1_mpu_irqs, | ||
3160 | .sdma_reqs = omap34xx_mmc1_sdma_reqs, | ||
3161 | .opt_clks = omap34xx_mmc1_opt_clks, | ||
3162 | .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks), | ||
3163 | .main_clk = "mmchs1_fck", | ||
3164 | .prcm = { | ||
3165 | .omap2 = { | ||
3166 | .module_offs = CORE_MOD, | ||
3167 | .prcm_reg_id = 1, | ||
3168 | .module_bit = OMAP3430_EN_MMC1_SHIFT, | ||
3169 | .idlest_reg_id = 1, | ||
3170 | .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT, | ||
3171 | }, | ||
3172 | }, | ||
3173 | .dev_attr = &mmc1_pre_es3_dev_attr, | ||
3174 | .slaves = omap3xxx_mmc1_slaves, | ||
3175 | .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc1_slaves), | ||
3176 | .class = &omap34xx_mmc_class, | ||
3177 | }; | ||
3178 | |||
3179 | static struct omap_hwmod omap3xxx_es3plus_mmc1_hwmod = { | ||
3076 | .name = "mmc1", | 3180 | .name = "mmc1", |
3077 | .mpu_irqs = omap34xx_mmc1_mpu_irqs, | 3181 | .mpu_irqs = omap34xx_mmc1_mpu_irqs, |
3078 | .sdma_reqs = omap34xx_mmc1_sdma_reqs, | 3182 | .sdma_reqs = omap34xx_mmc1_sdma_reqs, |
@@ -3115,7 +3219,34 @@ static struct omap_hwmod_ocp_if *omap3xxx_mmc2_slaves[] = { | |||
3115 | &omap3xxx_l4_core__mmc2, | 3219 | &omap3xxx_l4_core__mmc2, |
3116 | }; | 3220 | }; |
3117 | 3221 | ||
3118 | static struct omap_hwmod omap3xxx_mmc2_hwmod = { | 3222 | /* See 35xx errata 2.1.1.128 in SPRZ278F */ |
3223 | static struct omap_mmc_dev_attr mmc2_pre_es3_dev_attr = { | ||
3224 | .flags = OMAP_HSMMC_BROKEN_MULTIBLOCK_READ, | ||
3225 | }; | ||
3226 | |||
3227 | static struct omap_hwmod omap3xxx_pre_es3_mmc2_hwmod = { | ||
3228 | .name = "mmc2", | ||
3229 | .mpu_irqs = omap34xx_mmc2_mpu_irqs, | ||
3230 | .sdma_reqs = omap34xx_mmc2_sdma_reqs, | ||
3231 | .opt_clks = omap34xx_mmc2_opt_clks, | ||
3232 | .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks), | ||
3233 | .main_clk = "mmchs2_fck", | ||
3234 | .prcm = { | ||
3235 | .omap2 = { | ||
3236 | .module_offs = CORE_MOD, | ||
3237 | .prcm_reg_id = 1, | ||
3238 | .module_bit = OMAP3430_EN_MMC2_SHIFT, | ||
3239 | .idlest_reg_id = 1, | ||
3240 | .idlest_idle_bit = OMAP3430_ST_MMC2_SHIFT, | ||
3241 | }, | ||
3242 | }, | ||
3243 | .dev_attr = &mmc2_pre_es3_dev_attr, | ||
3244 | .slaves = omap3xxx_mmc2_slaves, | ||
3245 | .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc2_slaves), | ||
3246 | .class = &omap34xx_mmc_class, | ||
3247 | }; | ||
3248 | |||
3249 | static struct omap_hwmod omap3xxx_es3plus_mmc2_hwmod = { | ||
3119 | .name = "mmc2", | 3250 | .name = "mmc2", |
3120 | .mpu_irqs = omap34xx_mmc2_mpu_irqs, | 3251 | .mpu_irqs = omap34xx_mmc2_mpu_irqs, |
3121 | .sdma_reqs = omap34xx_mmc2_sdma_reqs, | 3252 | .sdma_reqs = omap34xx_mmc2_sdma_reqs, |
@@ -3177,13 +3308,223 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = { | |||
3177 | .class = &omap34xx_mmc_class, | 3308 | .class = &omap34xx_mmc_class, |
3178 | }; | 3309 | }; |
3179 | 3310 | ||
3311 | /* | ||
3312 | * 'usb_host_hs' class | ||
3313 | * high-speed multi-port usb host controller | ||
3314 | */ | ||
3315 | static struct omap_hwmod_ocp_if omap3xxx_usb_host_hs__l3_main_2 = { | ||
3316 | .master = &omap3xxx_usb_host_hs_hwmod, | ||
3317 | .slave = &omap3xxx_l3_main_hwmod, | ||
3318 | .clk = "core_l3_ick", | ||
3319 | .user = OCP_USER_MPU, | ||
3320 | }; | ||
3321 | |||
3322 | static struct omap_hwmod_class_sysconfig omap3xxx_usb_host_hs_sysc = { | ||
3323 | .rev_offs = 0x0000, | ||
3324 | .sysc_offs = 0x0010, | ||
3325 | .syss_offs = 0x0014, | ||
3326 | .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY | | ||
3327 | SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | | ||
3328 | SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), | ||
3329 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||
3330 | MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), | ||
3331 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
3332 | }; | ||
3333 | |||
3334 | static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = { | ||
3335 | .name = "usb_host_hs", | ||
3336 | .sysc = &omap3xxx_usb_host_hs_sysc, | ||
3337 | }; | ||
3338 | |||
3339 | static struct omap_hwmod_ocp_if *omap3xxx_usb_host_hs_masters[] = { | ||
3340 | &omap3xxx_usb_host_hs__l3_main_2, | ||
3341 | }; | ||
3342 | |||
3343 | static struct omap_hwmod_addr_space omap3xxx_usb_host_hs_addrs[] = { | ||
3344 | { | ||
3345 | .name = "uhh", | ||
3346 | .pa_start = 0x48064000, | ||
3347 | .pa_end = 0x480643ff, | ||
3348 | .flags = ADDR_TYPE_RT | ||
3349 | }, | ||
3350 | { | ||
3351 | .name = "ohci", | ||
3352 | .pa_start = 0x48064400, | ||
3353 | .pa_end = 0x480647ff, | ||
3354 | }, | ||
3355 | { | ||
3356 | .name = "ehci", | ||
3357 | .pa_start = 0x48064800, | ||
3358 | .pa_end = 0x48064cff, | ||
3359 | }, | ||
3360 | {} | ||
3361 | }; | ||
3362 | |||
3363 | static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_host_hs = { | ||
3364 | .master = &omap3xxx_l4_core_hwmod, | ||
3365 | .slave = &omap3xxx_usb_host_hs_hwmod, | ||
3366 | .clk = "usbhost_ick", | ||
3367 | .addr = omap3xxx_usb_host_hs_addrs, | ||
3368 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
3369 | }; | ||
3370 | |||
3371 | static struct omap_hwmod_ocp_if *omap3xxx_usb_host_hs_slaves[] = { | ||
3372 | &omap3xxx_l4_core__usb_host_hs, | ||
3373 | }; | ||
3374 | |||
3375 | static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = { | ||
3376 | { .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", }, | ||
3377 | }; | ||
3378 | |||
3379 | static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = { | ||
3380 | { .name = "ohci-irq", .irq = 76 }, | ||
3381 | { .name = "ehci-irq", .irq = 77 }, | ||
3382 | { .irq = -1 } | ||
3383 | }; | ||
3384 | |||
3385 | static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = { | ||
3386 | .name = "usb_host_hs", | ||
3387 | .class = &omap3xxx_usb_host_hs_hwmod_class, | ||
3388 | .clkdm_name = "l3_init_clkdm", | ||
3389 | .mpu_irqs = omap3xxx_usb_host_hs_irqs, | ||
3390 | .main_clk = "usbhost_48m_fck", | ||
3391 | .prcm = { | ||
3392 | .omap2 = { | ||
3393 | .module_offs = OMAP3430ES2_USBHOST_MOD, | ||
3394 | .prcm_reg_id = 1, | ||
3395 | .module_bit = OMAP3430ES2_EN_USBHOST1_SHIFT, | ||
3396 | .idlest_reg_id = 1, | ||
3397 | .idlest_idle_bit = OMAP3430ES2_ST_USBHOST_IDLE_SHIFT, | ||
3398 | .idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT, | ||
3399 | }, | ||
3400 | }, | ||
3401 | .opt_clks = omap3xxx_usb_host_hs_opt_clks, | ||
3402 | .opt_clks_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks), | ||
3403 | .slaves = omap3xxx_usb_host_hs_slaves, | ||
3404 | .slaves_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_slaves), | ||
3405 | .masters = omap3xxx_usb_host_hs_masters, | ||
3406 | .masters_cnt = ARRAY_SIZE(omap3xxx_usb_host_hs_masters), | ||
3407 | |||
3408 | /* | ||
3409 | * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock | ||
3410 | * id: i660 | ||
3411 | * | ||
3412 | * Description: | ||
3413 | * In the following configuration : | ||
3414 | * - USBHOST module is set to smart-idle mode | ||
3415 | * - PRCM asserts idle_req to the USBHOST module ( This typically | ||
3416 | * happens when the system is going to a low power mode : all ports | ||
3417 | * have been suspended, the master part of the USBHOST module has | ||
3418 | * entered the standby state, and SW has cut the functional clocks) | ||
3419 | * - an USBHOST interrupt occurs before the module is able to answer | ||
3420 | * idle_ack, typically a remote wakeup IRQ. | ||
3421 | * Then the USB HOST module will enter a deadlock situation where it | ||
3422 | * is no more accessible nor functional. | ||
3423 | * | ||
3424 | * Workaround: | ||
3425 | * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE | ||
3426 | */ | ||
3427 | |||
3428 | /* | ||
3429 | * Errata: USB host EHCI may stall when entering smart-standby mode | ||
3430 | * Id: i571 | ||
3431 | * | ||
3432 | * Description: | ||
3433 | * When the USBHOST module is set to smart-standby mode, and when it is | ||
3434 | * ready to enter the standby state (i.e. all ports are suspended and | ||
3435 | * all attached devices are in suspend mode), then it can wrongly assert | ||
3436 | * the Mstandby signal too early while there are still some residual OCP | ||
3437 | * transactions ongoing. If this condition occurs, the internal state | ||
3438 | * machine may go to an undefined state and the USB link may be stuck | ||
3439 | * upon the next resume. | ||
3440 | * | ||
3441 | * Workaround: | ||
3442 | * Don't use smart standby; use only force standby, | ||
3443 | * hence HWMOD_SWSUP_MSTANDBY | ||
3444 | */ | ||
3445 | |||
3446 | /* | ||
3447 | * During system boot; If the hwmod framework resets the module | ||
3448 | * the module will have smart idle settings; which can lead to deadlock | ||
3449 | * (above Errata Id:i660); so, dont reset the module during boot; | ||
3450 | * Use HWMOD_INIT_NO_RESET. | ||
3451 | */ | ||
3452 | |||
3453 | .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | | ||
3454 | HWMOD_INIT_NO_RESET, | ||
3455 | }; | ||
3456 | |||
3457 | /* | ||
3458 | * 'usb_tll_hs' class | ||
3459 | * usb_tll_hs module is the adapter on the usb_host_hs ports | ||
3460 | */ | ||
3461 | static struct omap_hwmod_class_sysconfig omap3xxx_usb_tll_hs_sysc = { | ||
3462 | .rev_offs = 0x0000, | ||
3463 | .sysc_offs = 0x0010, | ||
3464 | .syss_offs = 0x0014, | ||
3465 | .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | | ||
3466 | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | | ||
3467 | SYSC_HAS_AUTOIDLE), | ||
3468 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), | ||
3469 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
3470 | }; | ||
3471 | |||
3472 | static struct omap_hwmod_class omap3xxx_usb_tll_hs_hwmod_class = { | ||
3473 | .name = "usb_tll_hs", | ||
3474 | .sysc = &omap3xxx_usb_tll_hs_sysc, | ||
3475 | }; | ||
3476 | |||
3477 | static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = { | ||
3478 | { .name = "tll-irq", .irq = 78 }, | ||
3479 | { .irq = -1 } | ||
3480 | }; | ||
3481 | |||
3482 | static struct omap_hwmod_addr_space omap3xxx_usb_tll_hs_addrs[] = { | ||
3483 | { | ||
3484 | .name = "tll", | ||
3485 | .pa_start = 0x48062000, | ||
3486 | .pa_end = 0x48062fff, | ||
3487 | .flags = ADDR_TYPE_RT | ||
3488 | }, | ||
3489 | {} | ||
3490 | }; | ||
3491 | |||
3492 | static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_tll_hs = { | ||
3493 | .master = &omap3xxx_l4_core_hwmod, | ||
3494 | .slave = &omap3xxx_usb_tll_hs_hwmod, | ||
3495 | .clk = "usbtll_ick", | ||
3496 | .addr = omap3xxx_usb_tll_hs_addrs, | ||
3497 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
3498 | }; | ||
3499 | |||
3500 | static struct omap_hwmod_ocp_if *omap3xxx_usb_tll_hs_slaves[] = { | ||
3501 | &omap3xxx_l4_core__usb_tll_hs, | ||
3502 | }; | ||
3503 | |||
3504 | static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = { | ||
3505 | .name = "usb_tll_hs", | ||
3506 | .class = &omap3xxx_usb_tll_hs_hwmod_class, | ||
3507 | .clkdm_name = "l3_init_clkdm", | ||
3508 | .mpu_irqs = omap3xxx_usb_tll_hs_irqs, | ||
3509 | .main_clk = "usbtll_fck", | ||
3510 | .prcm = { | ||
3511 | .omap2 = { | ||
3512 | .module_offs = CORE_MOD, | ||
3513 | .prcm_reg_id = 3, | ||
3514 | .module_bit = OMAP3430ES2_EN_USBTLL_SHIFT, | ||
3515 | .idlest_reg_id = 3, | ||
3516 | .idlest_idle_bit = OMAP3430ES2_ST_USBTLL_SHIFT, | ||
3517 | }, | ||
3518 | }, | ||
3519 | .slaves = omap3xxx_usb_tll_hs_slaves, | ||
3520 | .slaves_cnt = ARRAY_SIZE(omap3xxx_usb_tll_hs_slaves), | ||
3521 | }; | ||
3522 | |||
3180 | static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { | 3523 | static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { |
3181 | &omap3xxx_l3_main_hwmod, | 3524 | &omap3xxx_l3_main_hwmod, |
3182 | &omap3xxx_l4_core_hwmod, | 3525 | &omap3xxx_l4_core_hwmod, |
3183 | &omap3xxx_l4_per_hwmod, | 3526 | &omap3xxx_l4_per_hwmod, |
3184 | &omap3xxx_l4_wkup_hwmod, | 3527 | &omap3xxx_l4_wkup_hwmod, |
3185 | &omap3xxx_mmc1_hwmod, | ||
3186 | &omap3xxx_mmc2_hwmod, | ||
3187 | &omap3xxx_mmc3_hwmod, | 3528 | &omap3xxx_mmc3_hwmod, |
3188 | &omap3xxx_mpu_hwmod, | 3529 | &omap3xxx_mpu_hwmod, |
3189 | 3530 | ||
@@ -3198,17 +3539,11 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { | |||
3198 | &omap3xxx_timer9_hwmod, | 3539 | &omap3xxx_timer9_hwmod, |
3199 | &omap3xxx_timer10_hwmod, | 3540 | &omap3xxx_timer10_hwmod, |
3200 | &omap3xxx_timer11_hwmod, | 3541 | &omap3xxx_timer11_hwmod, |
3201 | &omap3xxx_timer12_hwmod, | ||
3202 | 3542 | ||
3203 | &omap3xxx_wd_timer2_hwmod, | 3543 | &omap3xxx_wd_timer2_hwmod, |
3204 | &omap3xxx_uart1_hwmod, | 3544 | &omap3xxx_uart1_hwmod, |
3205 | &omap3xxx_uart2_hwmod, | 3545 | &omap3xxx_uart2_hwmod, |
3206 | &omap3xxx_uart3_hwmod, | 3546 | &omap3xxx_uart3_hwmod, |
3207 | /* dss class */ | ||
3208 | &omap3xxx_dss_dispc_hwmod, | ||
3209 | &omap3xxx_dss_dsi1_hwmod, | ||
3210 | &omap3xxx_dss_rfbi_hwmod, | ||
3211 | &omap3xxx_dss_venc_hwmod, | ||
3212 | 3547 | ||
3213 | /* i2c class */ | 3548 | /* i2c class */ |
3214 | &omap3xxx_i2c1_hwmod, | 3549 | &omap3xxx_i2c1_hwmod, |
@@ -3245,20 +3580,38 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { | |||
3245 | NULL, | 3580 | NULL, |
3246 | }; | 3581 | }; |
3247 | 3582 | ||
3583 | /* GP-only hwmods */ | ||
3584 | static __initdata struct omap_hwmod *omap3xxx_gp_hwmods[] = { | ||
3585 | &omap3xxx_timer12_hwmod, | ||
3586 | NULL | ||
3587 | }; | ||
3588 | |||
3248 | /* 3430ES1-only hwmods */ | 3589 | /* 3430ES1-only hwmods */ |
3249 | static __initdata struct omap_hwmod *omap3430es1_hwmods[] = { | 3590 | static __initdata struct omap_hwmod *omap3430es1_hwmods[] = { |
3250 | &omap3xxx_iva_hwmod, | ||
3251 | &omap3430es1_dss_core_hwmod, | 3591 | &omap3430es1_dss_core_hwmod, |
3252 | &omap3xxx_mailbox_hwmod, | ||
3253 | NULL | 3592 | NULL |
3254 | }; | 3593 | }; |
3255 | 3594 | ||
3256 | /* 3430ES2+-only hwmods */ | 3595 | /* 3430ES2+-only hwmods */ |
3257 | static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = { | 3596 | static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = { |
3258 | &omap3xxx_iva_hwmod, | ||
3259 | &omap3xxx_dss_core_hwmod, | 3597 | &omap3xxx_dss_core_hwmod, |
3260 | &omap3xxx_usbhsotg_hwmod, | 3598 | &omap3xxx_usbhsotg_hwmod, |
3261 | &omap3xxx_mailbox_hwmod, | 3599 | &omap3xxx_usb_host_hs_hwmod, |
3600 | &omap3xxx_usb_tll_hs_hwmod, | ||
3601 | NULL | ||
3602 | }; | ||
3603 | |||
3604 | /* <= 3430ES3-only hwmods */ | ||
3605 | static struct omap_hwmod *omap3430_pre_es3_hwmods[] __initdata = { | ||
3606 | &omap3xxx_pre_es3_mmc1_hwmod, | ||
3607 | &omap3xxx_pre_es3_mmc2_hwmod, | ||
3608 | NULL | ||
3609 | }; | ||
3610 | |||
3611 | /* 3430ES3+-only hwmods */ | ||
3612 | static struct omap_hwmod *omap3430_es3plus_hwmods[] __initdata = { | ||
3613 | &omap3xxx_es3plus_mmc1_hwmod, | ||
3614 | &omap3xxx_es3plus_mmc2_hwmod, | ||
3262 | NULL | 3615 | NULL |
3263 | }; | 3616 | }; |
3264 | 3617 | ||
@@ -3280,12 +3633,30 @@ static __initdata struct omap_hwmod *omap36xx_hwmods[] = { | |||
3280 | &omap36xx_sr2_hwmod, | 3633 | &omap36xx_sr2_hwmod, |
3281 | &omap3xxx_usbhsotg_hwmod, | 3634 | &omap3xxx_usbhsotg_hwmod, |
3282 | &omap3xxx_mailbox_hwmod, | 3635 | &omap3xxx_mailbox_hwmod, |
3636 | &omap3xxx_usb_host_hs_hwmod, | ||
3637 | &omap3xxx_usb_tll_hs_hwmod, | ||
3638 | &omap3xxx_es3plus_mmc1_hwmod, | ||
3639 | &omap3xxx_es3plus_mmc2_hwmod, | ||
3283 | NULL | 3640 | NULL |
3284 | }; | 3641 | }; |
3285 | 3642 | ||
3286 | static __initdata struct omap_hwmod *am35xx_hwmods[] = { | 3643 | static __initdata struct omap_hwmod *am35xx_hwmods[] = { |
3287 | &omap3xxx_dss_core_hwmod, /* XXX ??? */ | 3644 | &omap3xxx_dss_core_hwmod, /* XXX ??? */ |
3288 | &am35xx_usbhsotg_hwmod, | 3645 | &am35xx_usbhsotg_hwmod, |
3646 | &am35xx_uart4_hwmod, | ||
3647 | &omap3xxx_usb_host_hs_hwmod, | ||
3648 | &omap3xxx_usb_tll_hs_hwmod, | ||
3649 | &omap3xxx_es3plus_mmc1_hwmod, | ||
3650 | &omap3xxx_es3plus_mmc2_hwmod, | ||
3651 | NULL | ||
3652 | }; | ||
3653 | |||
3654 | static __initdata struct omap_hwmod *omap3xxx_dss_hwmods[] = { | ||
3655 | /* dss class */ | ||
3656 | &omap3xxx_dss_dispc_hwmod, | ||
3657 | &omap3xxx_dss_dsi1_hwmod, | ||
3658 | &omap3xxx_dss_rfbi_hwmod, | ||
3659 | &omap3xxx_dss_venc_hwmod, | ||
3289 | NULL | 3660 | NULL |
3290 | }; | 3661 | }; |
3291 | 3662 | ||
@@ -3300,6 +3671,13 @@ int __init omap3xxx_hwmod_init(void) | |||
3300 | if (r < 0) | 3671 | if (r < 0) |
3301 | return r; | 3672 | return r; |
3302 | 3673 | ||
3674 | /* Register GP-only hwmods. */ | ||
3675 | if (omap_type() == OMAP2_DEVICE_TYPE_GP) { | ||
3676 | r = omap_hwmod_register(omap3xxx_gp_hwmods); | ||
3677 | if (r < 0) | ||
3678 | return r; | ||
3679 | } | ||
3680 | |||
3303 | rev = omap_rev(); | 3681 | rev = omap_rev(); |
3304 | 3682 | ||
3305 | /* | 3683 | /* |
@@ -3338,8 +3716,38 @@ int __init omap3xxx_hwmod_init(void) | |||
3338 | h = omap3430es2plus_hwmods; | 3716 | h = omap3430es2plus_hwmods; |
3339 | }; | 3717 | }; |
3340 | 3718 | ||
3719 | if (h) { | ||
3720 | r = omap_hwmod_register(h); | ||
3721 | if (r < 0) | ||
3722 | return r; | ||
3723 | } | ||
3724 | |||
3725 | h = NULL; | ||
3726 | if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 || | ||
3727 | rev == OMAP3430_REV_ES2_1) { | ||
3728 | h = omap3430_pre_es3_hwmods; | ||
3729 | } else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 || | ||
3730 | rev == OMAP3430_REV_ES3_1_2) { | ||
3731 | h = omap3430_es3plus_hwmods; | ||
3732 | }; | ||
3733 | |||
3341 | if (h) | 3734 | if (h) |
3342 | r = omap_hwmod_register(h); | 3735 | r = omap_hwmod_register(h); |
3736 | if (r < 0) | ||
3737 | return r; | ||
3738 | |||
3739 | /* | ||
3740 | * DSS code presumes that dss_core hwmod is handled first, | ||
3741 | * _before_ any other DSS related hwmods so register common | ||
3742 | * DSS hwmods last to ensure that dss_core is already registered. | ||
3743 | * Otherwise some change things may happen, for ex. if dispc | ||
3744 | * is handled before dss_core and DSS is enabled in bootloader | ||
3745 | * DIPSC will be reset with outputs enabled which sometimes leads | ||
3746 | * to unrecoverable L3 error. | ||
3747 | * XXX The long-term fix to this is to ensure modules are set up | ||
3748 | * in dependency order in the hwmod core code. | ||
3749 | */ | ||
3750 | r = omap_hwmod_register(omap3xxx_dss_hwmods); | ||
3343 | 3751 | ||
3344 | return r; | 3752 | return r; |
3345 | } | 3753 | } |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index daaf165af696..ef0524c10a84 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c | |||
@@ -70,6 +70,8 @@ static struct omap_hwmod omap44xx_mmc2_hwmod; | |||
70 | static struct omap_hwmod omap44xx_mpu_hwmod; | 70 | static struct omap_hwmod omap44xx_mpu_hwmod; |
71 | static struct omap_hwmod omap44xx_mpu_private_hwmod; | 71 | static struct omap_hwmod omap44xx_mpu_private_hwmod; |
72 | static struct omap_hwmod omap44xx_usb_otg_hs_hwmod; | 72 | static struct omap_hwmod omap44xx_usb_otg_hs_hwmod; |
73 | static struct omap_hwmod omap44xx_usb_host_hs_hwmod; | ||
74 | static struct omap_hwmod omap44xx_usb_tll_hs_hwmod; | ||
73 | 75 | ||
74 | /* | 76 | /* |
75 | * Interconnects omap_hwmod structures | 77 | * Interconnects omap_hwmod structures |
@@ -1029,6 +1031,7 @@ static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = { | |||
1029 | 1031 | ||
1030 | static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = { | 1032 | static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = { |
1031 | { | 1033 | { |
1034 | .name = "mpu", | ||
1032 | .pa_start = 0x4012e000, | 1035 | .pa_start = 0x4012e000, |
1033 | .pa_end = 0x4012e07f, | 1036 | .pa_end = 0x4012e07f, |
1034 | .flags = ADDR_TYPE_RT | 1037 | .flags = ADDR_TYPE_RT |
@@ -1047,6 +1050,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = { | |||
1047 | 1050 | ||
1048 | static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = { | 1051 | static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = { |
1049 | { | 1052 | { |
1053 | .name = "dma", | ||
1050 | .pa_start = 0x4902e000, | 1054 | .pa_start = 0x4902e000, |
1051 | .pa_end = 0x4902e07f, | 1055 | .pa_end = 0x4902e07f, |
1052 | .flags = ADDR_TYPE_RT | 1056 | .flags = ADDR_TYPE_RT |
@@ -2246,6 +2250,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { | |||
2246 | SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), | 2250 | SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), |
2247 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | 2251 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | |
2248 | SIDLE_SMART_WKUP), | 2252 | SIDLE_SMART_WKUP), |
2253 | .clockact = CLOCKACT_TEST_ICLK, | ||
2249 | .sysc_fields = &omap_hwmod_sysc_type1, | 2254 | .sysc_fields = &omap_hwmod_sysc_type1, |
2250 | }; | 2255 | }; |
2251 | 2256 | ||
@@ -2300,7 +2305,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = { | |||
2300 | .name = "i2c1", | 2305 | .name = "i2c1", |
2301 | .class = &omap44xx_i2c_hwmod_class, | 2306 | .class = &omap44xx_i2c_hwmod_class, |
2302 | .clkdm_name = "l4_per_clkdm", | 2307 | .clkdm_name = "l4_per_clkdm", |
2303 | .flags = HWMOD_16BIT_REG, | 2308 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
2304 | .mpu_irqs = omap44xx_i2c1_irqs, | 2309 | .mpu_irqs = omap44xx_i2c1_irqs, |
2305 | .sdma_reqs = omap44xx_i2c1_sdma_reqs, | 2310 | .sdma_reqs = omap44xx_i2c1_sdma_reqs, |
2306 | .main_clk = "i2c1_fck", | 2311 | .main_clk = "i2c1_fck", |
@@ -2356,7 +2361,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = { | |||
2356 | .name = "i2c2", | 2361 | .name = "i2c2", |
2357 | .class = &omap44xx_i2c_hwmod_class, | 2362 | .class = &omap44xx_i2c_hwmod_class, |
2358 | .clkdm_name = "l4_per_clkdm", | 2363 | .clkdm_name = "l4_per_clkdm", |
2359 | .flags = HWMOD_16BIT_REG, | 2364 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
2360 | .mpu_irqs = omap44xx_i2c2_irqs, | 2365 | .mpu_irqs = omap44xx_i2c2_irqs, |
2361 | .sdma_reqs = omap44xx_i2c2_sdma_reqs, | 2366 | .sdma_reqs = omap44xx_i2c2_sdma_reqs, |
2362 | .main_clk = "i2c2_fck", | 2367 | .main_clk = "i2c2_fck", |
@@ -2412,7 +2417,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = { | |||
2412 | .name = "i2c3", | 2417 | .name = "i2c3", |
2413 | .class = &omap44xx_i2c_hwmod_class, | 2418 | .class = &omap44xx_i2c_hwmod_class, |
2414 | .clkdm_name = "l4_per_clkdm", | 2419 | .clkdm_name = "l4_per_clkdm", |
2415 | .flags = HWMOD_16BIT_REG, | 2420 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
2416 | .mpu_irqs = omap44xx_i2c3_irqs, | 2421 | .mpu_irqs = omap44xx_i2c3_irqs, |
2417 | .sdma_reqs = omap44xx_i2c3_sdma_reqs, | 2422 | .sdma_reqs = omap44xx_i2c3_sdma_reqs, |
2418 | .main_clk = "i2c3_fck", | 2423 | .main_clk = "i2c3_fck", |
@@ -2468,7 +2473,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = { | |||
2468 | .name = "i2c4", | 2473 | .name = "i2c4", |
2469 | .class = &omap44xx_i2c_hwmod_class, | 2474 | .class = &omap44xx_i2c_hwmod_class, |
2470 | .clkdm_name = "l4_per_clkdm", | 2475 | .clkdm_name = "l4_per_clkdm", |
2471 | .flags = HWMOD_16BIT_REG, | 2476 | .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, |
2472 | .mpu_irqs = omap44xx_i2c4_irqs, | 2477 | .mpu_irqs = omap44xx_i2c4_irqs, |
2473 | .sdma_reqs = omap44xx_i2c4_sdma_reqs, | 2478 | .sdma_reqs = omap44xx_i2c4_sdma_reqs, |
2474 | .main_clk = "i2c4_fck", | 2479 | .main_clk = "i2c4_fck", |
@@ -5276,6 +5281,207 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = { | |||
5276 | .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves), | 5281 | .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves), |
5277 | }; | 5282 | }; |
5278 | 5283 | ||
5284 | /* | ||
5285 | * 'usb_host_hs' class | ||
5286 | * high-speed multi-port usb host controller | ||
5287 | */ | ||
5288 | static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = { | ||
5289 | .master = &omap44xx_usb_host_hs_hwmod, | ||
5290 | .slave = &omap44xx_l3_main_2_hwmod, | ||
5291 | .clk = "l3_div_ck", | ||
5292 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
5293 | }; | ||
5294 | |||
5295 | static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = { | ||
5296 | .rev_offs = 0x0000, | ||
5297 | .sysc_offs = 0x0010, | ||
5298 | .syss_offs = 0x0014, | ||
5299 | .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | | ||
5300 | SYSC_HAS_SOFTRESET), | ||
5301 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | | ||
5302 | SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | | ||
5303 | MSTANDBY_SMART | MSTANDBY_SMART_WKUP), | ||
5304 | .sysc_fields = &omap_hwmod_sysc_type2, | ||
5305 | }; | ||
5306 | |||
5307 | static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = { | ||
5308 | .name = "usb_host_hs", | ||
5309 | .sysc = &omap44xx_usb_host_hs_sysc, | ||
5310 | }; | ||
5311 | |||
5312 | static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_masters[] = { | ||
5313 | &omap44xx_usb_host_hs__l3_main_2, | ||
5314 | }; | ||
5315 | |||
5316 | static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = { | ||
5317 | { | ||
5318 | .name = "uhh", | ||
5319 | .pa_start = 0x4a064000, | ||
5320 | .pa_end = 0x4a0647ff, | ||
5321 | .flags = ADDR_TYPE_RT | ||
5322 | }, | ||
5323 | { | ||
5324 | .name = "ohci", | ||
5325 | .pa_start = 0x4a064800, | ||
5326 | .pa_end = 0x4a064bff, | ||
5327 | }, | ||
5328 | { | ||
5329 | .name = "ehci", | ||
5330 | .pa_start = 0x4a064c00, | ||
5331 | .pa_end = 0x4a064fff, | ||
5332 | }, | ||
5333 | {} | ||
5334 | }; | ||
5335 | |||
5336 | static struct omap_hwmod_irq_info omap44xx_usb_host_hs_irqs[] = { | ||
5337 | { .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START }, | ||
5338 | { .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START }, | ||
5339 | { .irq = -1 } | ||
5340 | }; | ||
5341 | |||
5342 | static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = { | ||
5343 | .master = &omap44xx_l4_cfg_hwmod, | ||
5344 | .slave = &omap44xx_usb_host_hs_hwmod, | ||
5345 | .clk = "l4_div_ck", | ||
5346 | .addr = omap44xx_usb_host_hs_addrs, | ||
5347 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
5348 | }; | ||
5349 | |||
5350 | static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_slaves[] = { | ||
5351 | &omap44xx_l4_cfg__usb_host_hs, | ||
5352 | }; | ||
5353 | |||
5354 | static struct omap_hwmod omap44xx_usb_host_hs_hwmod = { | ||
5355 | .name = "usb_host_hs", | ||
5356 | .class = &omap44xx_usb_host_hs_hwmod_class, | ||
5357 | .clkdm_name = "l3_init_clkdm", | ||
5358 | .main_clk = "usb_host_hs_fck", | ||
5359 | .prcm = { | ||
5360 | .omap4 = { | ||
5361 | .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET, | ||
5362 | .context_offs = OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET, | ||
5363 | .modulemode = MODULEMODE_SWCTRL, | ||
5364 | }, | ||
5365 | }, | ||
5366 | .mpu_irqs = omap44xx_usb_host_hs_irqs, | ||
5367 | .slaves = omap44xx_usb_host_hs_slaves, | ||
5368 | .slaves_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_slaves), | ||
5369 | .masters = omap44xx_usb_host_hs_masters, | ||
5370 | .masters_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_masters), | ||
5371 | |||
5372 | /* | ||
5373 | * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock | ||
5374 | * id: i660 | ||
5375 | * | ||
5376 | * Description: | ||
5377 | * In the following configuration : | ||
5378 | * - USBHOST module is set to smart-idle mode | ||
5379 | * - PRCM asserts idle_req to the USBHOST module ( This typically | ||
5380 | * happens when the system is going to a low power mode : all ports | ||
5381 | * have been suspended, the master part of the USBHOST module has | ||
5382 | * entered the standby state, and SW has cut the functional clocks) | ||
5383 | * - an USBHOST interrupt occurs before the module is able to answer | ||
5384 | * idle_ack, typically a remote wakeup IRQ. | ||
5385 | * Then the USB HOST module will enter a deadlock situation where it | ||
5386 | * is no more accessible nor functional. | ||
5387 | * | ||
5388 | * Workaround: | ||
5389 | * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE | ||
5390 | */ | ||
5391 | |||
5392 | /* | ||
5393 | * Errata: USB host EHCI may stall when entering smart-standby mode | ||
5394 | * Id: i571 | ||
5395 | * | ||
5396 | * Description: | ||
5397 | * When the USBHOST module is set to smart-standby mode, and when it is | ||
5398 | * ready to enter the standby state (i.e. all ports are suspended and | ||
5399 | * all attached devices are in suspend mode), then it can wrongly assert | ||
5400 | * the Mstandby signal too early while there are still some residual OCP | ||
5401 | * transactions ongoing. If this condition occurs, the internal state | ||
5402 | * machine may go to an undefined state and the USB link may be stuck | ||
5403 | * upon the next resume. | ||
5404 | * | ||
5405 | * Workaround: | ||
5406 | * Don't use smart standby; use only force standby, | ||
5407 | * hence HWMOD_SWSUP_MSTANDBY | ||
5408 | */ | ||
5409 | |||
5410 | /* | ||
5411 | * During system boot; If the hwmod framework resets the module | ||
5412 | * the module will have smart idle settings; which can lead to deadlock | ||
5413 | * (above Errata Id:i660); so, dont reset the module during boot; | ||
5414 | * Use HWMOD_INIT_NO_RESET. | ||
5415 | */ | ||
5416 | |||
5417 | .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | | ||
5418 | HWMOD_INIT_NO_RESET, | ||
5419 | }; | ||
5420 | |||
5421 | /* | ||
5422 | * 'usb_tll_hs' class | ||
5423 | * usb_tll_hs module is the adapter on the usb_host_hs ports | ||
5424 | */ | ||
5425 | static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_sysc = { | ||
5426 | .rev_offs = 0x0000, | ||
5427 | .sysc_offs = 0x0010, | ||
5428 | .syss_offs = 0x0014, | ||
5429 | .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | | ||
5430 | SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | | ||
5431 | SYSC_HAS_AUTOIDLE), | ||
5432 | .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), | ||
5433 | .sysc_fields = &omap_hwmod_sysc_type1, | ||
5434 | }; | ||
5435 | |||
5436 | static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = { | ||
5437 | .name = "usb_tll_hs", | ||
5438 | .sysc = &omap44xx_usb_tll_hs_sysc, | ||
5439 | }; | ||
5440 | |||
5441 | static struct omap_hwmod_irq_info omap44xx_usb_tll_hs_irqs[] = { | ||
5442 | { .name = "tll-irq", .irq = 78 + OMAP44XX_IRQ_GIC_START }, | ||
5443 | { .irq = -1 } | ||
5444 | }; | ||
5445 | |||
5446 | static struct omap_hwmod_addr_space omap44xx_usb_tll_hs_addrs[] = { | ||
5447 | { | ||
5448 | .name = "tll", | ||
5449 | .pa_start = 0x4a062000, | ||
5450 | .pa_end = 0x4a063fff, | ||
5451 | .flags = ADDR_TYPE_RT | ||
5452 | }, | ||
5453 | {} | ||
5454 | }; | ||
5455 | |||
5456 | static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = { | ||
5457 | .master = &omap44xx_l4_cfg_hwmod, | ||
5458 | .slave = &omap44xx_usb_tll_hs_hwmod, | ||
5459 | .clk = "l4_div_ck", | ||
5460 | .addr = omap44xx_usb_tll_hs_addrs, | ||
5461 | .user = OCP_USER_MPU | OCP_USER_SDMA, | ||
5462 | }; | ||
5463 | |||
5464 | static struct omap_hwmod_ocp_if *omap44xx_usb_tll_hs_slaves[] = { | ||
5465 | &omap44xx_l4_cfg__usb_tll_hs, | ||
5466 | }; | ||
5467 | |||
5468 | static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = { | ||
5469 | .name = "usb_tll_hs", | ||
5470 | .class = &omap44xx_usb_tll_hs_hwmod_class, | ||
5471 | .clkdm_name = "l3_init_clkdm", | ||
5472 | .main_clk = "usb_tll_hs_ick", | ||
5473 | .prcm = { | ||
5474 | .omap4 = { | ||
5475 | .clkctrl_offs = OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET, | ||
5476 | .context_offs = OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET, | ||
5477 | .modulemode = MODULEMODE_HWCTRL, | ||
5478 | }, | ||
5479 | }, | ||
5480 | .mpu_irqs = omap44xx_usb_tll_hs_irqs, | ||
5481 | .slaves = omap44xx_usb_tll_hs_slaves, | ||
5482 | .slaves_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_slaves), | ||
5483 | }; | ||
5484 | |||
5279 | static __initdata struct omap_hwmod *omap44xx_hwmods[] = { | 5485 | static __initdata struct omap_hwmod *omap44xx_hwmods[] = { |
5280 | 5486 | ||
5281 | /* dmm class */ | 5487 | /* dmm class */ |
@@ -5415,13 +5621,16 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { | |||
5415 | &omap44xx_uart3_hwmod, | 5621 | &omap44xx_uart3_hwmod, |
5416 | &omap44xx_uart4_hwmod, | 5622 | &omap44xx_uart4_hwmod, |
5417 | 5623 | ||
5624 | /* usb host class */ | ||
5625 | &omap44xx_usb_host_hs_hwmod, | ||
5626 | &omap44xx_usb_tll_hs_hwmod, | ||
5627 | |||
5418 | /* usb_otg_hs class */ | 5628 | /* usb_otg_hs class */ |
5419 | &omap44xx_usb_otg_hs_hwmod, | 5629 | &omap44xx_usb_otg_hs_hwmod, |
5420 | 5630 | ||
5421 | /* wd_timer class */ | 5631 | /* wd_timer class */ |
5422 | &omap44xx_wd_timer2_hwmod, | 5632 | &omap44xx_wd_timer2_hwmod, |
5423 | &omap44xx_wd_timer3_hwmod, | 5633 | &omap44xx_wd_timer3_hwmod, |
5424 | |||
5425 | NULL, | 5634 | NULL, |
5426 | }; | 5635 | }; |
5427 | 5636 | ||
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index 58775e3c8476..4c90477e6f82 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c | |||
@@ -260,3 +260,38 @@ void am35x_set_mode(u8 musb_mode) | |||
260 | 260 | ||
261 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); | 261 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); |
262 | } | 262 | } |
263 | |||
264 | void ti81xx_musb_phy_power(u8 on) | ||
265 | { | ||
266 | void __iomem *scm_base = NULL; | ||
267 | u32 usbphycfg; | ||
268 | |||
269 | scm_base = ioremap(TI81XX_SCM_BASE, SZ_2K); | ||
270 | if (!scm_base) { | ||
271 | pr_err("system control module ioremap failed\n"); | ||
272 | return; | ||
273 | } | ||
274 | |||
275 | usbphycfg = __raw_readl(scm_base + USBCTRL0); | ||
276 | |||
277 | if (on) { | ||
278 | if (cpu_is_ti816x()) { | ||
279 | usbphycfg |= TI816X_USBPHY0_NORMAL_MODE; | ||
280 | usbphycfg &= ~TI816X_USBPHY_REFCLK_OSC; | ||
281 | } else if (cpu_is_ti814x()) { | ||
282 | usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN | ||
283 | | USBPHY_DPINPUT | USBPHY_DMINPUT); | ||
284 | usbphycfg |= (USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN | ||
285 | | USBPHY_DPOPBUFCTL | USBPHY_DMOPBUFCTL); | ||
286 | } | ||
287 | } else { | ||
288 | if (cpu_is_ti816x()) | ||
289 | usbphycfg &= ~TI816X_USBPHY0_NORMAL_MODE; | ||
290 | else if (cpu_is_ti814x()) | ||
291 | usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; | ||
292 | |||
293 | } | ||
294 | __raw_writel(usbphycfg, scm_base + USBCTRL0); | ||
295 | |||
296 | iounmap(scm_base); | ||
297 | } | ||
diff --git a/arch/arm/mach-omap2/opp2xxx.h b/arch/arm/mach-omap2/opp2xxx.h index 8affc66a92c2..8fae534eb157 100644 --- a/arch/arm/mach-omap2/opp2xxx.h +++ b/arch/arm/mach-omap2/opp2xxx.h | |||
@@ -51,7 +51,7 @@ struct prcm_config { | |||
51 | unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ | 51 | unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */ |
52 | unsigned long cm_clksel_mdm; /* modem dividers 2430 only */ | 52 | unsigned long cm_clksel_mdm; /* modem dividers 2430 only */ |
53 | unsigned long base_sdrc_rfr; /* base refresh timing for a set */ | 53 | unsigned long base_sdrc_rfr; /* base refresh timing for a set */ |
54 | unsigned char flags; | 54 | unsigned short flags; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | 57 | ||
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 1881fe915149..ad4f69394166 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -227,6 +227,14 @@ postcore_initcall(omap2_common_pm_init); | |||
227 | 227 | ||
228 | static int __init omap2_common_pm_late_init(void) | 228 | static int __init omap2_common_pm_late_init(void) |
229 | { | 229 | { |
230 | /* | ||
231 | * In the case of DT, the PMIC and SR initialization will be done using | ||
232 | * a completely different mechanism. | ||
233 | * Disable this part if a DT blob is available. | ||
234 | */ | ||
235 | if (of_have_populated_dt()) | ||
236 | return 0; | ||
237 | |||
230 | /* Init the voltage layer */ | 238 | /* Init the voltage layer */ |
231 | omap_pmic_late_init(); | 239 | omap_pmic_late_init(); |
232 | omap_voltage_late_init(); | 240 | omap_voltage_late_init(); |
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 4e166add2f35..b737b11e4499 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -21,6 +21,7 @@ extern void omap_sram_idle(void); | |||
21 | extern int omap3_can_sleep(void); | 21 | extern int omap3_can_sleep(void); |
22 | extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); | 22 | extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); |
23 | extern int omap3_idle_init(void); | 23 | extern int omap3_idle_init(void); |
24 | extern int omap4_idle_init(void); | ||
24 | 25 | ||
25 | #if defined(CONFIG_PM_OPP) | 26 | #if defined(CONFIG_PM_OPP) |
26 | extern int omap3_opp_init(void); | 27 | extern int omap3_opp_init(void); |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index ef8595c80296..b8822f8b2891 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/time.h> | 31 | #include <linux/time.h> |
32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
33 | #include <linux/console.h> | ||
34 | 33 | ||
35 | #include <asm/mach/time.h> | 34 | #include <asm/mach/time.h> |
36 | #include <asm/mach/irq.h> | 35 | #include <asm/mach/irq.h> |
@@ -127,27 +126,11 @@ static void omap2_enter_full_retention(void) | |||
127 | if (omap_irq_pending()) | 126 | if (omap_irq_pending()) |
128 | goto no_sleep; | 127 | goto no_sleep; |
129 | 128 | ||
130 | /* Block console output in case it is on one of the OMAP UARTs */ | ||
131 | if (!is_suspending()) | ||
132 | if (!console_trylock()) | ||
133 | goto no_sleep; | ||
134 | |||
135 | omap_uart_prepare_idle(0); | ||
136 | omap_uart_prepare_idle(1); | ||
137 | omap_uart_prepare_idle(2); | ||
138 | |||
139 | /* Jump to SRAM suspend code */ | 129 | /* Jump to SRAM suspend code */ |
140 | omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), | 130 | omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), |
141 | OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), | 131 | OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), |
142 | OMAP_SDRC_REGADDR(SDRC_POWER)); | 132 | OMAP_SDRC_REGADDR(SDRC_POWER)); |
143 | 133 | ||
144 | omap_uart_resume_idle(2); | ||
145 | omap_uart_resume_idle(1); | ||
146 | omap_uart_resume_idle(0); | ||
147 | |||
148 | if (!is_suspending()) | ||
149 | console_unlock(); | ||
150 | |||
151 | no_sleep: | 134 | no_sleep: |
152 | omap2_gpio_resume_after_idle(); | 135 | omap2_gpio_resume_after_idle(); |
153 | 136 | ||
@@ -239,8 +222,6 @@ static int omap2_can_sleep(void) | |||
239 | { | 222 | { |
240 | if (omap2_fclks_active()) | 223 | if (omap2_fclks_active()) |
241 | return 0; | 224 | return 0; |
242 | if (!omap_uart_can_sleep()) | ||
243 | return 0; | ||
244 | if (osc_ck->usecount > 1) | 225 | if (osc_ck->usecount > 1) |
245 | return 0; | 226 | return 0; |
246 | if (omap_dma_running()) | 227 | if (omap_dma_running()) |
@@ -291,7 +272,6 @@ static int omap2_pm_suspend(void) | |||
291 | mir1 = omap_readl(0x480fe0a4); | 272 | mir1 = omap_readl(0x480fe0a4); |
292 | omap_writel(1 << 5, 0x480fe0ac); | 273 | omap_writel(1 << 5, 0x480fe0ac); |
293 | 274 | ||
294 | omap_uart_prepare_suspend(); | ||
295 | omap2_enter_full_retention(); | 275 | omap2_enter_full_retention(); |
296 | 276 | ||
297 | omap_writel(mir1, 0x480fe0a4); | 277 | omap_writel(mir1, 0x480fe0a4); |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fa637dfdda53..fc6987578920 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/console.h> | ||
32 | #include <trace/events/power.h> | 31 | #include <trace/events/power.h> |
33 | 32 | ||
34 | #include <asm/suspend.h> | 33 | #include <asm/suspend.h> |
@@ -36,7 +35,6 @@ | |||
36 | #include <plat/sram.h> | 35 | #include <plat/sram.h> |
37 | #include "clockdomain.h" | 36 | #include "clockdomain.h" |
38 | #include "powerdomain.h" | 37 | #include "powerdomain.h" |
39 | #include <plat/serial.h> | ||
40 | #include <plat/sdrc.h> | 38 | #include <plat/sdrc.h> |
41 | #include <plat/prcm.h> | 39 | #include <plat/prcm.h> |
42 | #include <plat/gpmc.h> | 40 | #include <plat/gpmc.h> |
@@ -54,15 +52,6 @@ | |||
54 | 52 | ||
55 | #ifdef CONFIG_SUSPEND | 53 | #ifdef CONFIG_SUSPEND |
56 | static suspend_state_t suspend_state = PM_SUSPEND_ON; | 54 | static suspend_state_t suspend_state = PM_SUSPEND_ON; |
57 | static inline bool is_suspending(void) | ||
58 | { | ||
59 | return (suspend_state != PM_SUSPEND_ON) && console_suspend_enabled; | ||
60 | } | ||
61 | #else | ||
62 | static inline bool is_suspending(void) | ||
63 | { | ||
64 | return false; | ||
65 | } | ||
66 | #endif | 55 | #endif |
67 | 56 | ||
68 | /* pm34xx errata defined in pm.h */ | 57 | /* pm34xx errata defined in pm.h */ |
@@ -195,7 +184,7 @@ static void omap3_save_secure_ram_context(void) | |||
195 | * that any peripheral wake-up events occurring while attempting to | 184 | * that any peripheral wake-up events occurring while attempting to |
196 | * clear the PM_WKST_x are detected and cleared. | 185 | * clear the PM_WKST_x are detected and cleared. |
197 | */ | 186 | */ |
198 | static int prcm_clear_mod_irqs(s16 module, u8 regs) | 187 | static int prcm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits) |
199 | { | 188 | { |
200 | u32 wkst, fclk, iclk, clken; | 189 | u32 wkst, fclk, iclk, clken; |
201 | u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; | 190 | u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; |
@@ -207,6 +196,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs) | |||
207 | 196 | ||
208 | wkst = omap2_prm_read_mod_reg(module, wkst_off); | 197 | wkst = omap2_prm_read_mod_reg(module, wkst_off); |
209 | wkst &= omap2_prm_read_mod_reg(module, grpsel_off); | 198 | wkst &= omap2_prm_read_mod_reg(module, grpsel_off); |
199 | wkst &= ~ignore_bits; | ||
210 | if (wkst) { | 200 | if (wkst) { |
211 | iclk = omap2_cm_read_mod_reg(module, iclk_off); | 201 | iclk = omap2_cm_read_mod_reg(module, iclk_off); |
212 | fclk = omap2_cm_read_mod_reg(module, fclk_off); | 202 | fclk = omap2_cm_read_mod_reg(module, fclk_off); |
@@ -222,6 +212,7 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs) | |||
222 | omap2_cm_set_mod_reg_bits(clken, module, fclk_off); | 212 | omap2_cm_set_mod_reg_bits(clken, module, fclk_off); |
223 | omap2_prm_write_mod_reg(wkst, module, wkst_off); | 213 | omap2_prm_write_mod_reg(wkst, module, wkst_off); |
224 | wkst = omap2_prm_read_mod_reg(module, wkst_off); | 214 | wkst = omap2_prm_read_mod_reg(module, wkst_off); |
215 | wkst &= ~ignore_bits; | ||
225 | c++; | 216 | c++; |
226 | } | 217 | } |
227 | omap2_cm_write_mod_reg(iclk, module, iclk_off); | 218 | omap2_cm_write_mod_reg(iclk, module, iclk_off); |
@@ -231,76 +222,35 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs) | |||
231 | return c; | 222 | return c; |
232 | } | 223 | } |
233 | 224 | ||
234 | static int _prcm_int_handle_wakeup(void) | 225 | static irqreturn_t _prcm_int_handle_io(int irq, void *unused) |
235 | { | 226 | { |
236 | int c; | 227 | int c; |
237 | 228 | ||
238 | c = prcm_clear_mod_irqs(WKUP_MOD, 1); | 229 | c = prcm_clear_mod_irqs(WKUP_MOD, 1, |
239 | c += prcm_clear_mod_irqs(CORE_MOD, 1); | 230 | ~(OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK)); |
240 | c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1); | ||
241 | if (omap_rev() > OMAP3430_REV_ES1_0) { | ||
242 | c += prcm_clear_mod_irqs(CORE_MOD, 3); | ||
243 | c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1); | ||
244 | } | ||
245 | 231 | ||
246 | return c; | 232 | return c ? IRQ_HANDLED : IRQ_NONE; |
247 | } | 233 | } |
248 | 234 | ||
249 | /* | 235 | static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused) |
250 | * PRCM Interrupt Handler | ||
251 | * | ||
252 | * The PRM_IRQSTATUS_MPU register indicates if there are any pending | ||
253 | * interrupts from the PRCM for the MPU. These bits must be cleared in | ||
254 | * order to clear the PRCM interrupt. The PRCM interrupt handler is | ||
255 | * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear | ||
256 | * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU | ||
257 | * register indicates that a wake-up event is pending for the MPU and | ||
258 | * this bit can only be cleared if the all the wake-up events latched | ||
259 | * in the various PM_WKST_x registers have been cleared. The interrupt | ||
260 | * handler is implemented using a do-while loop so that if a wake-up | ||
261 | * event occurred during the processing of the prcm interrupt handler | ||
262 | * (setting a bit in the corresponding PM_WKST_x register and thus | ||
263 | * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register) | ||
264 | * this would be handled. | ||
265 | */ | ||
266 | static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) | ||
267 | { | 236 | { |
268 | u32 irqenable_mpu, irqstatus_mpu; | 237 | int c; |
269 | int c = 0; | ||
270 | |||
271 | irqenable_mpu = omap2_prm_read_mod_reg(OCP_MOD, | ||
272 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); | ||
273 | irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD, | ||
274 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
275 | irqstatus_mpu &= irqenable_mpu; | ||
276 | |||
277 | do { | ||
278 | if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK | | ||
279 | OMAP3430_IO_ST_MASK)) { | ||
280 | c = _prcm_int_handle_wakeup(); | ||
281 | |||
282 | /* | ||
283 | * Is the MPU PRCM interrupt handler racing with the | ||
284 | * IVA2 PRCM interrupt handler ? | ||
285 | */ | ||
286 | WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup " | ||
287 | "but no wakeup sources are marked\n"); | ||
288 | } else { | ||
289 | /* XXX we need to expand our PRCM interrupt handler */ | ||
290 | WARN(1, "prcm: WARNING: PRCM interrupt received, but " | ||
291 | "no code to handle it (%08x)\n", irqstatus_mpu); | ||
292 | } | ||
293 | |||
294 | omap2_prm_write_mod_reg(irqstatus_mpu, OCP_MOD, | ||
295 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
296 | |||
297 | irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD, | ||
298 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
299 | irqstatus_mpu &= irqenable_mpu; | ||
300 | 238 | ||
301 | } while (irqstatus_mpu); | 239 | /* |
240 | * Clear all except ST_IO and ST_IO_CHAIN for wkup module, | ||
241 | * these are handled in a separate handler to avoid acking | ||
242 | * IO events before parsing in mux code | ||
243 | */ | ||
244 | c = prcm_clear_mod_irqs(WKUP_MOD, 1, | ||
245 | OMAP3430_ST_IO_MASK | OMAP3430_ST_IO_CHAIN_MASK); | ||
246 | c += prcm_clear_mod_irqs(CORE_MOD, 1, 0); | ||
247 | c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1, 0); | ||
248 | if (omap_rev() > OMAP3430_REV_ES1_0) { | ||
249 | c += prcm_clear_mod_irqs(CORE_MOD, 3, 0); | ||
250 | c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, 0); | ||
251 | } | ||
302 | 252 | ||
303 | return IRQ_HANDLED; | 253 | return c ? IRQ_HANDLED : IRQ_NONE; |
304 | } | 254 | } |
305 | 255 | ||
306 | static void omap34xx_save_context(u32 *save) | 256 | static void omap34xx_save_context(u32 *save) |
@@ -376,20 +326,11 @@ void omap_sram_idle(void) | |||
376 | omap3_enable_io_chain(); | 326 | omap3_enable_io_chain(); |
377 | } | 327 | } |
378 | 328 | ||
379 | /* Block console output in case it is on one of the OMAP UARTs */ | ||
380 | if (!is_suspending()) | ||
381 | if (per_next_state < PWRDM_POWER_ON || | ||
382 | core_next_state < PWRDM_POWER_ON) | ||
383 | if (!console_trylock()) | ||
384 | goto console_still_active; | ||
385 | |||
386 | pwrdm_pre_transition(); | 329 | pwrdm_pre_transition(); |
387 | 330 | ||
388 | /* PER */ | 331 | /* PER */ |
389 | if (per_next_state < PWRDM_POWER_ON) { | 332 | if (per_next_state < PWRDM_POWER_ON) { |
390 | per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; | 333 | per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0; |
391 | omap_uart_prepare_idle(2); | ||
392 | omap_uart_prepare_idle(3); | ||
393 | omap2_gpio_prepare_for_idle(per_going_off); | 334 | omap2_gpio_prepare_for_idle(per_going_off); |
394 | if (per_next_state == PWRDM_POWER_OFF) | 335 | if (per_next_state == PWRDM_POWER_OFF) |
395 | omap3_per_save_context(); | 336 | omap3_per_save_context(); |
@@ -397,8 +338,6 @@ void omap_sram_idle(void) | |||
397 | 338 | ||
398 | /* CORE */ | 339 | /* CORE */ |
399 | if (core_next_state < PWRDM_POWER_ON) { | 340 | if (core_next_state < PWRDM_POWER_ON) { |
400 | omap_uart_prepare_idle(0); | ||
401 | omap_uart_prepare_idle(1); | ||
402 | if (core_next_state == PWRDM_POWER_OFF) { | 341 | if (core_next_state == PWRDM_POWER_OFF) { |
403 | omap3_core_save_context(); | 342 | omap3_core_save_context(); |
404 | omap3_cm_save_context(); | 343 | omap3_cm_save_context(); |
@@ -447,8 +386,6 @@ void omap_sram_idle(void) | |||
447 | omap3_sram_restore_context(); | 386 | omap3_sram_restore_context(); |
448 | omap2_sms_restore_context(); | 387 | omap2_sms_restore_context(); |
449 | } | 388 | } |
450 | omap_uart_resume_idle(0); | ||
451 | omap_uart_resume_idle(1); | ||
452 | if (core_next_state == PWRDM_POWER_OFF) | 389 | if (core_next_state == PWRDM_POWER_OFF) |
453 | omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, | 390 | omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, |
454 | OMAP3430_GR_MOD, | 391 | OMAP3430_GR_MOD, |
@@ -464,14 +401,8 @@ void omap_sram_idle(void) | |||
464 | omap2_gpio_resume_after_idle(); | 401 | omap2_gpio_resume_after_idle(); |
465 | if (per_prev_state == PWRDM_POWER_OFF) | 402 | if (per_prev_state == PWRDM_POWER_OFF) |
466 | omap3_per_restore_context(); | 403 | omap3_per_restore_context(); |
467 | omap_uart_resume_idle(2); | ||
468 | omap_uart_resume_idle(3); | ||
469 | } | 404 | } |
470 | 405 | ||
471 | if (!is_suspending()) | ||
472 | console_unlock(); | ||
473 | |||
474 | console_still_active: | ||
475 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 406 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
476 | if (omap3_has_io_wakeup() && | 407 | if (omap3_has_io_wakeup() && |
477 | (per_next_state < PWRDM_POWER_ON || | 408 | (per_next_state < PWRDM_POWER_ON || |
@@ -485,21 +416,11 @@ console_still_active: | |||
485 | clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); | 416 | clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); |
486 | } | 417 | } |
487 | 418 | ||
488 | int omap3_can_sleep(void) | ||
489 | { | ||
490 | if (!omap_uart_can_sleep()) | ||
491 | return 0; | ||
492 | return 1; | ||
493 | } | ||
494 | |||
495 | static void omap3_pm_idle(void) | 419 | static void omap3_pm_idle(void) |
496 | { | 420 | { |
497 | local_irq_disable(); | 421 | local_irq_disable(); |
498 | local_fiq_disable(); | 422 | local_fiq_disable(); |
499 | 423 | ||
500 | if (!omap3_can_sleep()) | ||
501 | goto out; | ||
502 | |||
503 | if (omap_irq_pending() || need_resched()) | 424 | if (omap_irq_pending() || need_resched()) |
504 | goto out; | 425 | goto out; |
505 | 426 | ||
@@ -533,7 +454,6 @@ static int omap3_pm_suspend(void) | |||
533 | goto restore; | 454 | goto restore; |
534 | } | 455 | } |
535 | 456 | ||
536 | omap_uart_prepare_suspend(); | ||
537 | omap3_intc_suspend(); | 457 | omap3_intc_suspend(); |
538 | 458 | ||
539 | omap_sram_idle(); | 459 | omap_sram_idle(); |
@@ -580,22 +500,27 @@ static int omap3_pm_begin(suspend_state_t state) | |||
580 | { | 500 | { |
581 | disable_hlt(); | 501 | disable_hlt(); |
582 | suspend_state = state; | 502 | suspend_state = state; |
583 | omap_uart_enable_irqs(0); | 503 | omap_prcm_irq_prepare(); |
584 | return 0; | 504 | return 0; |
585 | } | 505 | } |
586 | 506 | ||
587 | static void omap3_pm_end(void) | 507 | static void omap3_pm_end(void) |
588 | { | 508 | { |
589 | suspend_state = PM_SUSPEND_ON; | 509 | suspend_state = PM_SUSPEND_ON; |
590 | omap_uart_enable_irqs(1); | ||
591 | enable_hlt(); | 510 | enable_hlt(); |
592 | return; | 511 | return; |
593 | } | 512 | } |
594 | 513 | ||
514 | static void omap3_pm_finish(void) | ||
515 | { | ||
516 | omap_prcm_irq_complete(); | ||
517 | } | ||
518 | |||
595 | static const struct platform_suspend_ops omap_pm_ops = { | 519 | static const struct platform_suspend_ops omap_pm_ops = { |
596 | .begin = omap3_pm_begin, | 520 | .begin = omap3_pm_begin, |
597 | .end = omap3_pm_end, | 521 | .end = omap3_pm_end, |
598 | .enter = omap3_pm_enter, | 522 | .enter = omap3_pm_enter, |
523 | .finish = omap3_pm_finish, | ||
599 | .valid = suspend_valid_only_mem, | 524 | .valid = suspend_valid_only_mem, |
600 | }; | 525 | }; |
601 | #endif /* CONFIG_SUSPEND */ | 526 | #endif /* CONFIG_SUSPEND */ |
@@ -701,10 +626,6 @@ static void __init prcm_setup_regs(void) | |||
701 | OMAP3430_GRPSEL_GPT1_MASK | | 626 | OMAP3430_GRPSEL_GPT1_MASK | |
702 | OMAP3430_GRPSEL_GPT12_MASK, | 627 | OMAP3430_GRPSEL_GPT12_MASK, |
703 | WKUP_MOD, OMAP3430_PM_MPUGRPSEL); | 628 | WKUP_MOD, OMAP3430_PM_MPUGRPSEL); |
704 | /* For some reason IO doesn't generate wakeup event even if | ||
705 | * it is selected to mpu wakeup goup */ | ||
706 | omap2_prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK, | ||
707 | OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); | ||
708 | 629 | ||
709 | /* Enable PM_WKEN to support DSS LPR */ | 630 | /* Enable PM_WKEN to support DSS LPR */ |
710 | omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, | 631 | omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK, |
@@ -881,12 +802,21 @@ static int __init omap3_pm_init(void) | |||
881 | * supervised mode for powerdomains */ | 802 | * supervised mode for powerdomains */ |
882 | prcm_setup_regs(); | 803 | prcm_setup_regs(); |
883 | 804 | ||
884 | ret = request_irq(INT_34XX_PRCM_MPU_IRQ, | 805 | ret = request_irq(omap_prcm_event_to_irq("wkup"), |
885 | (irq_handler_t)prcm_interrupt_handler, | 806 | _prcm_int_handle_wakeup, IRQF_NO_SUSPEND, "pm_wkup", NULL); |
886 | IRQF_DISABLED, "prcm", NULL); | 807 | |
808 | if (ret) { | ||
809 | pr_err("pm: Failed to request pm_wkup irq\n"); | ||
810 | goto err1; | ||
811 | } | ||
812 | |||
813 | /* IO interrupt is shared with mux code */ | ||
814 | ret = request_irq(omap_prcm_event_to_irq("io"), | ||
815 | _prcm_int_handle_io, IRQF_SHARED | IRQF_NO_SUSPEND, "pm_io", | ||
816 | omap3_pm_init); | ||
817 | |||
887 | if (ret) { | 818 | if (ret) { |
888 | printk(KERN_ERR "request_irq failed to register for 0x%x\n", | 819 | pr_err("pm: Failed to request pm_io irq\n"); |
889 | INT_34XX_PRCM_MPU_IRQ); | ||
890 | goto err1; | 820 | goto err1; |
891 | } | 821 | } |
892 | 822 | ||
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 8edb015f5618..c264ef7219c1 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP4 Power Management Routines | 2 | * OMAP4 Power Management Routines |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments, Inc. | 4 | * Copyright (C) 2010-2011 Texas Instruments, Inc. |
5 | * Rajendra Nayak <rnayak@ti.com> | 5 | * Rajendra Nayak <rnayak@ti.com> |
6 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * 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 | * it under the terms of the GNU General Public License version 2 as |
@@ -17,13 +18,16 @@ | |||
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | 19 | ||
19 | #include "common.h" | 20 | #include "common.h" |
21 | #include "clockdomain.h" | ||
20 | #include "powerdomain.h" | 22 | #include "powerdomain.h" |
23 | #include "pm.h" | ||
21 | 24 | ||
22 | struct power_state { | 25 | struct power_state { |
23 | struct powerdomain *pwrdm; | 26 | struct powerdomain *pwrdm; |
24 | u32 next_state; | 27 | u32 next_state; |
25 | #ifdef CONFIG_SUSPEND | 28 | #ifdef CONFIG_SUSPEND |
26 | u32 saved_state; | 29 | u32 saved_state; |
30 | u32 saved_logic_state; | ||
27 | #endif | 31 | #endif |
28 | struct list_head node; | 32 | struct list_head node; |
29 | }; | 33 | }; |
@@ -33,7 +37,50 @@ static LIST_HEAD(pwrst_list); | |||
33 | #ifdef CONFIG_SUSPEND | 37 | #ifdef CONFIG_SUSPEND |
34 | static int omap4_pm_suspend(void) | 38 | static int omap4_pm_suspend(void) |
35 | { | 39 | { |
36 | do_wfi(); | 40 | struct power_state *pwrst; |
41 | int state, ret = 0; | ||
42 | u32 cpu_id = smp_processor_id(); | ||
43 | |||
44 | /* Save current powerdomain state */ | ||
45 | list_for_each_entry(pwrst, &pwrst_list, node) { | ||
46 | pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); | ||
47 | pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm); | ||
48 | } | ||
49 | |||
50 | /* Set targeted power domain states by suspend */ | ||
51 | list_for_each_entry(pwrst, &pwrst_list, node) { | ||
52 | omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); | ||
53 | pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF); | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * For MPUSS to hit power domain retention(CSWR or OSWR), | ||
58 | * CPU0 and CPU1 power domains need to be in OFF or DORMANT state, | ||
59 | * since CPU power domain CSWR is not supported by hardware | ||
60 | * Only master CPU follows suspend path. All other CPUs follow | ||
61 | * CPU hotplug path in system wide suspend. On OMAP4, CPU power | ||
62 | * domain CSWR is not supported by hardware. | ||
63 | * More details can be found in OMAP4430 TRM section 4.3.4.2. | ||
64 | */ | ||
65 | omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF); | ||
66 | |||
67 | /* Restore next powerdomain state */ | ||
68 | list_for_each_entry(pwrst, &pwrst_list, node) { | ||
69 | state = pwrdm_read_prev_pwrst(pwrst->pwrdm); | ||
70 | if (state > pwrst->next_state) { | ||
71 | pr_info("Powerdomain (%s) didn't enter " | ||
72 | "target state %d\n", | ||
73 | pwrst->pwrdm->name, pwrst->next_state); | ||
74 | ret = -1; | ||
75 | } | ||
76 | omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); | ||
77 | pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state); | ||
78 | } | ||
79 | if (ret) | ||
80 | pr_crit("Could not enter target state in pm_suspend\n"); | ||
81 | else | ||
82 | pr_info("Successfully put all powerdomains to target state\n"); | ||
83 | |||
37 | return 0; | 84 | return 0; |
38 | } | 85 | } |
39 | 86 | ||
@@ -73,6 +120,22 @@ static const struct platform_suspend_ops omap_pm_ops = { | |||
73 | }; | 120 | }; |
74 | #endif /* CONFIG_SUSPEND */ | 121 | #endif /* CONFIG_SUSPEND */ |
75 | 122 | ||
123 | /* | ||
124 | * Enable hardware supervised mode for all clockdomains if it's | ||
125 | * supported. Initiate sleep transition for other clockdomains, if | ||
126 | * they are not used | ||
127 | */ | ||
128 | static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) | ||
129 | { | ||
130 | if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO) | ||
131 | clkdm_allow_idle(clkdm); | ||
132 | else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && | ||
133 | atomic_read(&clkdm->usecount) == 0) | ||
134 | clkdm_sleep(clkdm); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
76 | static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) | 139 | static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) |
77 | { | 140 | { |
78 | struct power_state *pwrst; | 141 | struct power_state *pwrst; |
@@ -80,14 +143,48 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) | |||
80 | if (!pwrdm->pwrsts) | 143 | if (!pwrdm->pwrsts) |
81 | return 0; | 144 | return 0; |
82 | 145 | ||
146 | /* | ||
147 | * Skip CPU0 and CPU1 power domains. CPU1 is programmed | ||
148 | * through hotplug path and CPU0 explicitly programmed | ||
149 | * further down in the code path | ||
150 | */ | ||
151 | if (!strncmp(pwrdm->name, "cpu", 3)) | ||
152 | return 0; | ||
153 | |||
154 | /* | ||
155 | * FIXME: Remove this check when core retention is supported | ||
156 | * Only MPUSS power domain is added in the list. | ||
157 | */ | ||
158 | if (strcmp(pwrdm->name, "mpu_pwrdm")) | ||
159 | return 0; | ||
160 | |||
83 | pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); | 161 | pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); |
84 | if (!pwrst) | 162 | if (!pwrst) |
85 | return -ENOMEM; | 163 | return -ENOMEM; |
164 | |||
86 | pwrst->pwrdm = pwrdm; | 165 | pwrst->pwrdm = pwrdm; |
87 | pwrst->next_state = PWRDM_POWER_ON; | 166 | pwrst->next_state = PWRDM_POWER_RET; |
88 | list_add(&pwrst->node, &pwrst_list); | 167 | list_add(&pwrst->node, &pwrst_list); |
89 | 168 | ||
90 | return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state); | 169 | return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); |
170 | } | ||
171 | |||
172 | /** | ||
173 | * omap_default_idle - OMAP4 default ilde routine.' | ||
174 | * | ||
175 | * Implements OMAP4 memory, IO ordering requirements which can't be addressed | ||
176 | * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and | ||
177 | * by secondary CPU with CONFIG_CPUIDLE. | ||
178 | */ | ||
179 | static void omap_default_idle(void) | ||
180 | { | ||
181 | local_irq_disable(); | ||
182 | local_fiq_disable(); | ||
183 | |||
184 | omap_do_wfi(); | ||
185 | |||
186 | local_fiq_enable(); | ||
187 | local_irq_enable(); | ||
91 | } | 188 | } |
92 | 189 | ||
93 | /** | 190 | /** |
@@ -99,10 +196,17 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) | |||
99 | static int __init omap4_pm_init(void) | 196 | static int __init omap4_pm_init(void) |
100 | { | 197 | { |
101 | int ret; | 198 | int ret; |
199 | struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; | ||
200 | struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; | ||
102 | 201 | ||
103 | if (!cpu_is_omap44xx()) | 202 | if (!cpu_is_omap44xx()) |
104 | return -ENODEV; | 203 | return -ENODEV; |
105 | 204 | ||
205 | if (omap_rev() == OMAP4430_REV_ES1_0) { | ||
206 | WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); | ||
207 | return -ENODEV; | ||
208 | } | ||
209 | |||
106 | pr_err("Power Management for TI OMAP4.\n"); | 210 | pr_err("Power Management for TI OMAP4.\n"); |
107 | 211 | ||
108 | ret = pwrdm_for_each(pwrdms_setup, NULL); | 212 | ret = pwrdm_for_each(pwrdms_setup, NULL); |
@@ -111,10 +215,51 @@ static int __init omap4_pm_init(void) | |||
111 | goto err2; | 215 | goto err2; |
112 | } | 216 | } |
113 | 217 | ||
218 | /* | ||
219 | * The dynamic dependency between MPUSS -> MEMIF and | ||
220 | * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as | ||
221 | * expected. The hardware recommendation is to enable static | ||
222 | * dependencies for these to avoid system lock ups or random crashes. | ||
223 | */ | ||
224 | mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); | ||
225 | emif_clkdm = clkdm_lookup("l3_emif_clkdm"); | ||
226 | l3_1_clkdm = clkdm_lookup("l3_1_clkdm"); | ||
227 | l3_2_clkdm = clkdm_lookup("l3_2_clkdm"); | ||
228 | l4_per_clkdm = clkdm_lookup("l4_per_clkdm"); | ||
229 | ducati_clkdm = clkdm_lookup("ducati_clkdm"); | ||
230 | if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || | ||
231 | (!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm)) | ||
232 | goto err2; | ||
233 | |||
234 | ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); | ||
235 | ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); | ||
236 | ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm); | ||
237 | ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm); | ||
238 | ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm); | ||
239 | ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); | ||
240 | if (ret) { | ||
241 | pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 " | ||
242 | "wakeup dependency\n"); | ||
243 | goto err2; | ||
244 | } | ||
245 | |||
246 | ret = omap4_mpuss_init(); | ||
247 | if (ret) { | ||
248 | pr_err("Failed to initialise OMAP4 MPUSS\n"); | ||
249 | goto err2; | ||
250 | } | ||
251 | |||
252 | (void) clkdm_for_each(clkdms_setup, NULL); | ||
253 | |||
114 | #ifdef CONFIG_SUSPEND | 254 | #ifdef CONFIG_SUSPEND |
115 | suspend_set_ops(&omap_pm_ops); | 255 | suspend_set_ops(&omap_pm_ops); |
116 | #endif /* CONFIG_SUSPEND */ | 256 | #endif /* CONFIG_SUSPEND */ |
117 | 257 | ||
258 | /* Overwrite the default arch_idle() */ | ||
259 | pm_idle = omap_default_idle; | ||
260 | |||
261 | omap4_idle_init(); | ||
262 | |||
118 | err2: | 263 | err2: |
119 | return ret; | 264 | return ret; |
120 | } | 265 | } |
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 0363dcb0ef93..5aa5435e3ff1 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h | |||
@@ -4,7 +4,7 @@ | |||
4 | /* | 4 | /* |
5 | * OMAP2/3 PRCM base and module definitions | 5 | * OMAP2/3 PRCM base and module definitions |
6 | * | 6 | * |
7 | * Copyright (C) 2007-2009 Texas Instruments, Inc. | 7 | * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc. |
8 | * Copyright (C) 2007-2009 Nokia Corporation | 8 | * Copyright (C) 2007-2009 Nokia Corporation |
9 | * | 9 | * |
10 | * Written by Paul Walmsley | 10 | * Written by Paul Walmsley |
@@ -201,6 +201,8 @@ | |||
201 | #define OMAP3430_EN_MMC2_SHIFT 25 | 201 | #define OMAP3430_EN_MMC2_SHIFT 25 |
202 | #define OMAP3430_EN_MMC1_MASK (1 << 24) | 202 | #define OMAP3430_EN_MMC1_MASK (1 << 24) |
203 | #define OMAP3430_EN_MMC1_SHIFT 24 | 203 | #define OMAP3430_EN_MMC1_SHIFT 24 |
204 | #define OMAP3430_EN_UART4_MASK (1 << 23) | ||
205 | #define OMAP3430_EN_UART4_SHIFT 23 | ||
204 | #define OMAP3430_EN_MCSPI4_MASK (1 << 21) | 206 | #define OMAP3430_EN_MCSPI4_MASK (1 << 21) |
205 | #define OMAP3430_EN_MCSPI4_SHIFT 21 | 207 | #define OMAP3430_EN_MCSPI4_SHIFT 21 |
206 | #define OMAP3430_EN_MCSPI3_MASK (1 << 20) | 208 | #define OMAP3430_EN_MCSPI3_MASK (1 << 20) |
@@ -408,6 +410,79 @@ | |||
408 | extern void __iomem *prm_base; | 410 | extern void __iomem *prm_base; |
409 | extern void __iomem *cm_base; | 411 | extern void __iomem *cm_base; |
410 | extern void __iomem *cm2_base; | 412 | extern void __iomem *cm2_base; |
413 | |||
414 | /** | ||
415 | * struct omap_prcm_irq - describes a PRCM interrupt bit | ||
416 | * @name: a short name describing the interrupt type, e.g. "wkup" or "io" | ||
417 | * @offset: the bit shift of the interrupt inside the IRQ{ENABLE,STATUS} regs | ||
418 | * @priority: should this interrupt be handled before @priority=false IRQs? | ||
419 | * | ||
420 | * Describes interrupt bits inside the PRM_IRQ{ENABLE,STATUS}_MPU* registers. | ||
421 | * On systems with multiple PRM MPU IRQ registers, the bitfields read from | ||
422 | * the registers are concatenated, so @offset could be > 31 on these systems - | ||
423 | * see omap_prm_irq_handler() for more details. I/O ring interrupts should | ||
424 | * have @priority set to true. | ||
425 | */ | ||
426 | struct omap_prcm_irq { | ||
427 | const char *name; | ||
428 | unsigned int offset; | ||
429 | bool priority; | ||
430 | }; | ||
431 | |||
432 | /** | ||
433 | * struct omap_prcm_irq_setup - PRCM interrupt controller details | ||
434 | * @ack: PRM register offset for the first PRM_IRQSTATUS_MPU register | ||
435 | * @mask: PRM register offset for the first PRM_IRQENABLE_MPU register | ||
436 | * @nr_regs: number of PRM_IRQ{STATUS,ENABLE}_MPU* registers | ||
437 | * @nr_irqs: number of entries in the @irqs array | ||
438 | * @irqs: ptr to an array of PRCM interrupt bits (see @nr_irqs) | ||
439 | * @irq: MPU IRQ asserted when a PRCM interrupt arrives | ||
440 | * @read_pending_irqs: fn ptr to determine if any PRCM IRQs are pending | ||
441 | * @ocp_barrier: fn ptr to force buffered PRM writes to complete | ||
442 | * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs | ||
443 | * @restore_irqen: fn ptr to save and clear IRQENABLE regs | ||
444 | * @saved_mask: IRQENABLE regs are saved here during suspend | ||
445 | * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true | ||
446 | * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init | ||
447 | * @suspended: set to true after Linux suspend code has called our ->prepare() | ||
448 | * @suspend_save_flag: set to true after IRQ masks have been saved and disabled | ||
449 | * | ||
450 | * @saved_mask, @priority_mask, @base_irq, @suspended, and | ||
451 | * @suspend_save_flag are populated dynamically, and are not to be | ||
452 | * specified in static initializers. | ||
453 | */ | ||
454 | struct omap_prcm_irq_setup { | ||
455 | u16 ack; | ||
456 | u16 mask; | ||
457 | u8 nr_regs; | ||
458 | u8 nr_irqs; | ||
459 | const struct omap_prcm_irq *irqs; | ||
460 | int irq; | ||
461 | void (*read_pending_irqs)(unsigned long *events); | ||
462 | void (*ocp_barrier)(void); | ||
463 | void (*save_and_clear_irqen)(u32 *saved_mask); | ||
464 | void (*restore_irqen)(u32 *saved_mask); | ||
465 | u32 *saved_mask; | ||
466 | u32 *priority_mask; | ||
467 | int base_irq; | ||
468 | bool suspended; | ||
469 | bool suspend_save_flag; | ||
470 | }; | ||
471 | |||
472 | /* OMAP_PRCM_IRQ: convenience macro for creating struct omap_prcm_irq records */ | ||
473 | #define OMAP_PRCM_IRQ(_name, _offset, _priority) { \ | ||
474 | .name = _name, \ | ||
475 | .offset = _offset, \ | ||
476 | .priority = _priority \ | ||
477 | } | ||
478 | |||
479 | extern void omap_prcm_irq_cleanup(void); | ||
480 | extern int omap_prcm_register_chain_handler( | ||
481 | struct omap_prcm_irq_setup *irq_setup); | ||
482 | extern int omap_prcm_event_to_irq(const char *event); | ||
483 | extern void omap_prcm_irq_prepare(void); | ||
484 | extern void omap_prcm_irq_complete(void); | ||
485 | |||
411 | # endif | 486 | # endif |
412 | 487 | ||
413 | #endif | 488 | #endif |
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index c35e5cea9f8f..626acfad7190 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/export.h> | 26 | #include <linux/export.h> |
27 | 27 | ||
28 | #include <mach/system.h> | ||
29 | #include "common.h" | 28 | #include "common.h" |
30 | #include <plat/prcm.h> | 29 | #include <plat/prcm.h> |
31 | #include <plat/irqs.h> | 30 | #include <plat/irqs.h> |
@@ -59,7 +58,7 @@ u32 omap_prcm_get_reset_sources(void) | |||
59 | EXPORT_SYMBOL(omap_prcm_get_reset_sources); | 58 | EXPORT_SYMBOL(omap_prcm_get_reset_sources); |
60 | 59 | ||
61 | /* Resets clock rates and reboots the system. Only called from system.h */ | 60 | /* Resets clock rates and reboots the system. Only called from system.h */ |
62 | static void omap_prcm_arch_reset(char mode, const char *cmd) | 61 | void omap_prcm_restart(char mode, const char *cmd) |
63 | { | 62 | { |
64 | s16 prcm_offs = 0; | 63 | s16 prcm_offs = 0; |
65 | 64 | ||
@@ -110,8 +109,6 @@ static void omap_prcm_arch_reset(char mode, const char *cmd) | |||
110 | omap2_prm_read_mod_reg(prcm_offs, OMAP2_RM_RSTCTRL); /* OCP barrier */ | 109 | omap2_prm_read_mod_reg(prcm_offs, OMAP2_RM_RSTCTRL); /* OCP barrier */ |
111 | } | 110 | } |
112 | 111 | ||
113 | void (*arch_reset)(char, const char *) = omap_prcm_arch_reset; | ||
114 | |||
115 | /** | 112 | /** |
116 | * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness | 113 | * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness |
117 | * @reg: physical address of module IDLEST register | 114 | * @reg: physical address of module IDLEST register |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index 9a08ba397327..9ce765407ad5 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP2/3 PRM module functions | 2 | * OMAP2/3 PRM module functions |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Texas Instruments, Inc. | 4 | * Copyright (C) 2010-2011 Texas Instruments, Inc. |
5 | * Copyright (C) 2010 Nokia Corporation | 5 | * Copyright (C) 2010 Nokia Corporation |
6 | * Benoît Cousson | 6 | * Benoît Cousson |
7 | * Paul Walmsley | 7 | * Paul Walmsley |
@@ -19,6 +19,7 @@ | |||
19 | #include "common.h" | 19 | #include "common.h" |
20 | #include <plat/cpu.h> | 20 | #include <plat/cpu.h> |
21 | #include <plat/prcm.h> | 21 | #include <plat/prcm.h> |
22 | #include <plat/irqs.h> | ||
22 | 23 | ||
23 | #include "vp.h" | 24 | #include "vp.h" |
24 | 25 | ||
@@ -27,6 +28,24 @@ | |||
27 | #include "prm-regbits-24xx.h" | 28 | #include "prm-regbits-24xx.h" |
28 | #include "prm-regbits-34xx.h" | 29 | #include "prm-regbits-34xx.h" |
29 | 30 | ||
31 | static const struct omap_prcm_irq omap3_prcm_irqs[] = { | ||
32 | OMAP_PRCM_IRQ("wkup", 0, 0), | ||
33 | OMAP_PRCM_IRQ("io", 9, 1), | ||
34 | }; | ||
35 | |||
36 | static struct omap_prcm_irq_setup omap3_prcm_irq_setup = { | ||
37 | .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET, | ||
38 | .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET, | ||
39 | .nr_regs = 1, | ||
40 | .irqs = omap3_prcm_irqs, | ||
41 | .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs), | ||
42 | .irq = INT_34XX_PRCM_MPU_IRQ, | ||
43 | .read_pending_irqs = &omap3xxx_prm_read_pending_irqs, | ||
44 | .ocp_barrier = &omap3xxx_prm_ocp_barrier, | ||
45 | .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen, | ||
46 | .restore_irqen = &omap3xxx_prm_restore_irqen, | ||
47 | }; | ||
48 | |||
30 | u32 omap2_prm_read_mod_reg(s16 module, u16 idx) | 49 | u32 omap2_prm_read_mod_reg(s16 module, u16 idx) |
31 | { | 50 | { |
32 | return __raw_readl(prm_base + module + idx); | 51 | return __raw_readl(prm_base + module + idx); |
@@ -212,3 +231,80 @@ u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) | |||
212 | { | 231 | { |
213 | return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset); | 232 | return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset); |
214 | } | 233 | } |
234 | |||
235 | /** | ||
236 | * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events | ||
237 | * @events: ptr to a u32, preallocated by caller | ||
238 | * | ||
239 | * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM | ||
240 | * MPU IRQs, and store the result into the u32 pointed to by @events. | ||
241 | * No return value. | ||
242 | */ | ||
243 | void omap3xxx_prm_read_pending_irqs(unsigned long *events) | ||
244 | { | ||
245 | u32 mask, st; | ||
246 | |||
247 | /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */ | ||
248 | mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); | ||
249 | st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
250 | |||
251 | events[0] = mask & st; | ||
252 | } | ||
253 | |||
254 | /** | ||
255 | * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete | ||
256 | * | ||
257 | * Force any buffered writes to the PRM IP block to complete. Needed | ||
258 | * by the PRM IRQ handler, which reads and writes directly to the IP | ||
259 | * block, to avoid race conditions after acknowledging or clearing IRQ | ||
260 | * bits. No return value. | ||
261 | */ | ||
262 | void omap3xxx_prm_ocp_barrier(void) | ||
263 | { | ||
264 | omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); | ||
265 | } | ||
266 | |||
267 | /** | ||
268 | * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg | ||
269 | * @saved_mask: ptr to a u32 array to save IRQENABLE bits | ||
270 | * | ||
271 | * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask | ||
272 | * must be allocated by the caller. Intended to be used in the PRM | ||
273 | * interrupt handler suspend callback. The OCP barrier is needed to | ||
274 | * ensure the write to disable PRM interrupts reaches the PRM before | ||
275 | * returning; otherwise, spurious interrupts might occur. No return | ||
276 | * value. | ||
277 | */ | ||
278 | void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask) | ||
279 | { | ||
280 | saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD, | ||
281 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); | ||
282 | omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); | ||
283 | |||
284 | /* OCP barrier */ | ||
285 | omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET); | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args | ||
290 | * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously | ||
291 | * | ||
292 | * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended | ||
293 | * to be used in the PRM interrupt handler resume callback to restore | ||
294 | * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP | ||
295 | * barrier should be needed here; any pending PRM interrupts will fire | ||
296 | * once the writes reach the PRM. No return value. | ||
297 | */ | ||
298 | void omap3xxx_prm_restore_irqen(u32 *saved_mask) | ||
299 | { | ||
300 | omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD, | ||
301 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); | ||
302 | } | ||
303 | |||
304 | static int __init omap3xxx_prcm_init(void) | ||
305 | { | ||
306 | if (cpu_is_omap34xx()) | ||
307 | return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); | ||
308 | return 0; | ||
309 | } | ||
310 | subsys_initcall(omap3xxx_prcm_init); | ||
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index cef533df0861..70ac2a19dc5f 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP2/3 Power/Reset Management (PRM) register definitions | 2 | * OMAP2/3 Power/Reset Management (PRM) register definitions |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2009 Texas Instruments, Inc. | 4 | * Copyright (C) 2007-2009, 2011 Texas Instruments, Inc. |
5 | * Copyright (C) 2008-2010 Nokia Corporation | 5 | * Copyright (C) 2008-2010 Nokia Corporation |
6 | * Paul Walmsley | 6 | * Paul Walmsley |
7 | * | 7 | * |
@@ -314,6 +314,13 @@ void omap3_prm_vp_clear_txdone(u8 vp_id); | |||
314 | extern u32 omap3_prm_vcvp_read(u8 offset); | 314 | extern u32 omap3_prm_vcvp_read(u8 offset); |
315 | extern void omap3_prm_vcvp_write(u32 val, u8 offset); | 315 | extern void omap3_prm_vcvp_write(u32 val, u8 offset); |
316 | extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); | 316 | extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); |
317 | |||
318 | /* PRM interrupt-related functions */ | ||
319 | extern void omap3xxx_prm_read_pending_irqs(unsigned long *events); | ||
320 | extern void omap3xxx_prm_ocp_barrier(void); | ||
321 | extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask); | ||
322 | extern void omap3xxx_prm_restore_irqen(u32 *saved_mask); | ||
323 | |||
317 | #endif /* CONFIG_ARCH_OMAP4 */ | 324 | #endif /* CONFIG_ARCH_OMAP4 */ |
318 | 325 | ||
319 | #endif | 326 | #endif |
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index dd885eecf22a..33dd655e6aab 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c | |||
@@ -27,6 +27,24 @@ | |||
27 | #include "prcm44xx.h" | 27 | #include "prcm44xx.h" |
28 | #include "prminst44xx.h" | 28 | #include "prminst44xx.h" |
29 | 29 | ||
30 | static const struct omap_prcm_irq omap4_prcm_irqs[] = { | ||
31 | OMAP_PRCM_IRQ("wkup", 0, 0), | ||
32 | OMAP_PRCM_IRQ("io", 9, 1), | ||
33 | }; | ||
34 | |||
35 | static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { | ||
36 | .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, | ||
37 | .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET, | ||
38 | .nr_regs = 2, | ||
39 | .irqs = omap4_prcm_irqs, | ||
40 | .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs), | ||
41 | .irq = OMAP44XX_IRQ_PRCM, | ||
42 | .read_pending_irqs = &omap44xx_prm_read_pending_irqs, | ||
43 | .ocp_barrier = &omap44xx_prm_ocp_barrier, | ||
44 | .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, | ||
45 | .restore_irqen = &omap44xx_prm_restore_irqen, | ||
46 | }; | ||
47 | |||
30 | /* PRM low-level functions */ | 48 | /* PRM low-level functions */ |
31 | 49 | ||
32 | /* Read a register in a CM/PRM instance in the PRM module */ | 50 | /* Read a register in a CM/PRM instance in the PRM module */ |
@@ -121,3 +139,101 @@ u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset) | |||
121 | OMAP4430_PRM_DEVICE_INST, | 139 | OMAP4430_PRM_DEVICE_INST, |
122 | offset); | 140 | offset); |
123 | } | 141 | } |
142 | |||
143 | static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) | ||
144 | { | ||
145 | u32 mask, st; | ||
146 | |||
147 | /* XXX read mask from RAM? */ | ||
148 | mask = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqen_offs); | ||
149 | st = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, irqst_offs); | ||
150 | |||
151 | return mask & st; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events | ||
156 | * @events: ptr to two consecutive u32s, preallocated by caller | ||
157 | * | ||
158 | * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM | ||
159 | * MPU IRQs, and store the result into the two u32s pointed to by @events. | ||
160 | * No return value. | ||
161 | */ | ||
162 | void omap44xx_prm_read_pending_irqs(unsigned long *events) | ||
163 | { | ||
164 | events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, | ||
165 | OMAP4_PRM_IRQSTATUS_MPU_OFFSET); | ||
166 | |||
167 | events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET, | ||
168 | OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete | ||
173 | * | ||
174 | * Force any buffered writes to the PRM IP block to complete. Needed | ||
175 | * by the PRM IRQ handler, which reads and writes directly to the IP | ||
176 | * block, to avoid race conditions after acknowledging or clearing IRQ | ||
177 | * bits. No return value. | ||
178 | */ | ||
179 | void omap44xx_prm_ocp_barrier(void) | ||
180 | { | ||
181 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
182 | OMAP4_REVISION_PRM_OFFSET); | ||
183 | } | ||
184 | |||
185 | /** | ||
186 | * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs | ||
187 | * @saved_mask: ptr to a u32 array to save IRQENABLE bits | ||
188 | * | ||
189 | * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to | ||
190 | * @saved_mask. @saved_mask must be allocated by the caller. | ||
191 | * Intended to be used in the PRM interrupt handler suspend callback. | ||
192 | * The OCP barrier is needed to ensure the write to disable PRM | ||
193 | * interrupts reaches the PRM before returning; otherwise, spurious | ||
194 | * interrupts might occur. No return value. | ||
195 | */ | ||
196 | void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) | ||
197 | { | ||
198 | saved_mask[0] = | ||
199 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
200 | OMAP4_PRM_IRQSTATUS_MPU_OFFSET); | ||
201 | saved_mask[1] = | ||
202 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
203 | OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); | ||
204 | |||
205 | omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, | ||
206 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); | ||
207 | omap4_prm_write_inst_reg(0, OMAP4430_PRM_DEVICE_INST, | ||
208 | OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); | ||
209 | |||
210 | /* OCP barrier */ | ||
211 | omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST, | ||
212 | OMAP4_REVISION_PRM_OFFSET); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args | ||
217 | * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously | ||
218 | * | ||
219 | * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from | ||
220 | * @saved_mask. Intended to be used in the PRM interrupt handler resume | ||
221 | * callback to restore values saved by omap44xx_prm_save_and_clear_irqen(). | ||
222 | * No OCP barrier should be needed here; any pending PRM interrupts will fire | ||
223 | * once the writes reach the PRM. No return value. | ||
224 | */ | ||
225 | void omap44xx_prm_restore_irqen(u32 *saved_mask) | ||
226 | { | ||
227 | omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_DEVICE_INST, | ||
228 | OMAP4_PRM_IRQENABLE_MPU_OFFSET); | ||
229 | omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_DEVICE_INST, | ||
230 | OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); | ||
231 | } | ||
232 | |||
233 | static int __init omap4xxx_prcm_init(void) | ||
234 | { | ||
235 | if (cpu_is_omap44xx()) | ||
236 | return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); | ||
237 | return 0; | ||
238 | } | ||
239 | subsys_initcall(omap4xxx_prcm_init); | ||
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h index 3d66ccd849d2..7978092946db 100644 --- a/arch/arm/mach-omap2/prm44xx.h +++ b/arch/arm/mach-omap2/prm44xx.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP44xx PRM instance offset macros | 2 | * OMAP44xx PRM instance offset macros |
3 | * | 3 | * |
4 | * Copyright (C) 2009-2010 Texas Instruments, Inc. | 4 | * Copyright (C) 2009-2011 Texas Instruments, Inc. |
5 | * Copyright (C) 2009-2010 Nokia Corporation | 5 | * Copyright (C) 2009-2010 Nokia Corporation |
6 | * | 6 | * |
7 | * Paul Walmsley (paul@pwsan.com) | 7 | * Paul Walmsley (paul@pwsan.com) |
@@ -763,6 +763,12 @@ extern u32 omap4_prm_vcvp_read(u8 offset); | |||
763 | extern void omap4_prm_vcvp_write(u32 val, u8 offset); | 763 | extern void omap4_prm_vcvp_write(u32 val, u8 offset); |
764 | extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); | 764 | extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset); |
765 | 765 | ||
766 | /* PRM interrupt-related functions */ | ||
767 | extern void omap44xx_prm_read_pending_irqs(unsigned long *events); | ||
768 | extern void omap44xx_prm_ocp_barrier(void); | ||
769 | extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); | ||
770 | extern void omap44xx_prm_restore_irqen(u32 *saved_mask); | ||
771 | |||
766 | # endif | 772 | # endif |
767 | 773 | ||
768 | #endif | 774 | #endif |
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c new file mode 100644 index 000000000000..860118ab43e2 --- /dev/null +++ b/arch/arm/mach-omap2/prm_common.c | |||
@@ -0,0 +1,320 @@ | |||
1 | /* | ||
2 | * OMAP2+ common Power & Reset Management (PRM) IP block functions | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Tero Kristo <t-kristo@ti.com> | ||
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 | * For historical purposes, the API used to configure the PRM | ||
13 | * interrupt handler refers to it as the "PRCM interrupt." The | ||
14 | * underlying registers are located in the PRM on OMAP3/4. | ||
15 | * | ||
16 | * XXX This code should eventually be moved to a PRM driver. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/irq.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/slab.h> | ||
26 | |||
27 | #include <mach/system.h> | ||
28 | #include <plat/common.h> | ||
29 | #include <plat/prcm.h> | ||
30 | #include <plat/irqs.h> | ||
31 | |||
32 | #include "prm2xxx_3xxx.h" | ||
33 | #include "prm44xx.h" | ||
34 | |||
35 | /* | ||
36 | * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs | ||
37 | * XXX this is technically not needed, since | ||
38 | * omap_prcm_register_chain_handler() could allocate this based on the | ||
39 | * actual amount of memory needed for the SoC | ||
40 | */ | ||
41 | #define OMAP_PRCM_MAX_NR_PENDING_REG 2 | ||
42 | |||
43 | /* | ||
44 | * prcm_irq_chips: an array of all of the "generic IRQ chips" in use | ||
45 | * by the PRCM interrupt handler code. There will be one 'chip' per | ||
46 | * PRM_{IRQSTATUS,IRQENABLE}_MPU register pair. (So OMAP3 will have | ||
47 | * one "chip" and OMAP4 will have two.) | ||
48 | */ | ||
49 | static struct irq_chip_generic **prcm_irq_chips; | ||
50 | |||
51 | /* | ||
52 | * prcm_irq_setup: the PRCM IRQ parameters for the hardware the code | ||
53 | * is currently running on. Defined and passed by initialization code | ||
54 | * that calls omap_prcm_register_chain_handler(). | ||
55 | */ | ||
56 | static struct omap_prcm_irq_setup *prcm_irq_setup; | ||
57 | |||
58 | /* Private functions */ | ||
59 | |||
60 | /* | ||
61 | * Move priority events from events to priority_events array | ||
62 | */ | ||
63 | static void omap_prcm_events_filter_priority(unsigned long *events, | ||
64 | unsigned long *priority_events) | ||
65 | { | ||
66 | int i; | ||
67 | |||
68 | for (i = 0; i < prcm_irq_setup->nr_regs; i++) { | ||
69 | priority_events[i] = | ||
70 | events[i] & prcm_irq_setup->priority_mask[i]; | ||
71 | events[i] ^= priority_events[i]; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * PRCM Interrupt Handler | ||
77 | * | ||
78 | * This is a common handler for the OMAP PRCM interrupts. Pending | ||
79 | * interrupts are detected by a call to prcm_pending_events and | ||
80 | * dispatched accordingly. Clearing of the wakeup events should be | ||
81 | * done by the SoC specific individual handlers. | ||
82 | */ | ||
83 | static void omap_prcm_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
84 | { | ||
85 | unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG]; | ||
86 | unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG]; | ||
87 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
88 | unsigned int virtirq; | ||
89 | int nr_irqs = prcm_irq_setup->nr_regs * 32; | ||
90 | |||
91 | /* | ||
92 | * If we are suspended, mask all interrupts from PRCM level, | ||
93 | * this does not ack them, and they will be pending until we | ||
94 | * re-enable the interrupts, at which point the | ||
95 | * omap_prcm_irq_handler will be executed again. The | ||
96 | * _save_and_clear_irqen() function must ensure that the PRM | ||
97 | * write to disable all IRQs has reached the PRM before | ||
98 | * returning, or spurious PRCM interrupts may occur during | ||
99 | * suspend. | ||
100 | */ | ||
101 | if (prcm_irq_setup->suspended) { | ||
102 | prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask); | ||
103 | prcm_irq_setup->suspend_save_flag = true; | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Loop until all pending irqs are handled, since | ||
108 | * generic_handle_irq() can cause new irqs to come | ||
109 | */ | ||
110 | while (!prcm_irq_setup->suspended) { | ||
111 | prcm_irq_setup->read_pending_irqs(pending); | ||
112 | |||
113 | /* No bit set, then all IRQs are handled */ | ||
114 | if (find_first_bit(pending, nr_irqs) >= nr_irqs) | ||
115 | break; | ||
116 | |||
117 | omap_prcm_events_filter_priority(pending, priority_pending); | ||
118 | |||
119 | /* | ||
120 | * Loop on all currently pending irqs so that new irqs | ||
121 | * cannot starve previously pending irqs | ||
122 | */ | ||
123 | |||
124 | /* Serve priority events first */ | ||
125 | for_each_set_bit(virtirq, priority_pending, nr_irqs) | ||
126 | generic_handle_irq(prcm_irq_setup->base_irq + virtirq); | ||
127 | |||
128 | /* Serve normal events next */ | ||
129 | for_each_set_bit(virtirq, pending, nr_irqs) | ||
130 | generic_handle_irq(prcm_irq_setup->base_irq + virtirq); | ||
131 | } | ||
132 | if (chip->irq_ack) | ||
133 | chip->irq_ack(&desc->irq_data); | ||
134 | if (chip->irq_eoi) | ||
135 | chip->irq_eoi(&desc->irq_data); | ||
136 | chip->irq_unmask(&desc->irq_data); | ||
137 | |||
138 | prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */ | ||
139 | } | ||
140 | |||
141 | /* Public functions */ | ||
142 | |||
143 | /** | ||
144 | * omap_prcm_event_to_irq - given a PRCM event name, returns the | ||
145 | * corresponding IRQ on which the handler should be registered | ||
146 | * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq | ||
147 | * | ||
148 | * Returns the Linux internal IRQ ID corresponding to @name upon success, | ||
149 | * or -ENOENT upon failure. | ||
150 | */ | ||
151 | int omap_prcm_event_to_irq(const char *name) | ||
152 | { | ||
153 | int i; | ||
154 | |||
155 | if (!prcm_irq_setup || !name) | ||
156 | return -ENOENT; | ||
157 | |||
158 | for (i = 0; i < prcm_irq_setup->nr_irqs; i++) | ||
159 | if (!strcmp(prcm_irq_setup->irqs[i].name, name)) | ||
160 | return prcm_irq_setup->base_irq + | ||
161 | prcm_irq_setup->irqs[i].offset; | ||
162 | |||
163 | return -ENOENT; | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * omap_prcm_irq_cleanup - reverses memory allocated and other steps | ||
168 | * done by omap_prcm_register_chain_handler() | ||
169 | * | ||
170 | * No return value. | ||
171 | */ | ||
172 | void omap_prcm_irq_cleanup(void) | ||
173 | { | ||
174 | int i; | ||
175 | |||
176 | if (!prcm_irq_setup) { | ||
177 | pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n"); | ||
178 | return; | ||
179 | } | ||
180 | |||
181 | if (prcm_irq_chips) { | ||
182 | for (i = 0; i < prcm_irq_setup->nr_regs; i++) { | ||
183 | if (prcm_irq_chips[i]) | ||
184 | irq_remove_generic_chip(prcm_irq_chips[i], | ||
185 | 0xffffffff, 0, 0); | ||
186 | prcm_irq_chips[i] = NULL; | ||
187 | } | ||
188 | kfree(prcm_irq_chips); | ||
189 | prcm_irq_chips = NULL; | ||
190 | } | ||
191 | |||
192 | kfree(prcm_irq_setup->saved_mask); | ||
193 | prcm_irq_setup->saved_mask = NULL; | ||
194 | |||
195 | kfree(prcm_irq_setup->priority_mask); | ||
196 | prcm_irq_setup->priority_mask = NULL; | ||
197 | |||
198 | irq_set_chained_handler(prcm_irq_setup->irq, NULL); | ||
199 | |||
200 | if (prcm_irq_setup->base_irq > 0) | ||
201 | irq_free_descs(prcm_irq_setup->base_irq, | ||
202 | prcm_irq_setup->nr_regs * 32); | ||
203 | prcm_irq_setup->base_irq = 0; | ||
204 | } | ||
205 | |||
206 | void omap_prcm_irq_prepare(void) | ||
207 | { | ||
208 | prcm_irq_setup->suspended = true; | ||
209 | } | ||
210 | |||
211 | void omap_prcm_irq_complete(void) | ||
212 | { | ||
213 | prcm_irq_setup->suspended = false; | ||
214 | |||
215 | /* If we have not saved the masks, do not attempt to restore */ | ||
216 | if (!prcm_irq_setup->suspend_save_flag) | ||
217 | return; | ||
218 | |||
219 | prcm_irq_setup->suspend_save_flag = false; | ||
220 | |||
221 | /* | ||
222 | * Re-enable all masked PRCM irq sources, this causes the PRCM | ||
223 | * interrupt to fire immediately if the events were masked | ||
224 | * previously in the chain handler | ||
225 | */ | ||
226 | prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask); | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * omap_prcm_register_chain_handler - initializes the prcm chained interrupt | ||
231 | * handler based on provided parameters | ||
232 | * @irq_setup: hardware data about the underlying PRM/PRCM | ||
233 | * | ||
234 | * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up | ||
235 | * one generic IRQ chip per PRM interrupt status/enable register pair. | ||
236 | * Returns 0 upon success, -EINVAL if called twice or if invalid | ||
237 | * arguments are passed, or -ENOMEM on any other error. | ||
238 | */ | ||
239 | int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) | ||
240 | { | ||
241 | int nr_regs = irq_setup->nr_regs; | ||
242 | u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG]; | ||
243 | int offset, i; | ||
244 | struct irq_chip_generic *gc; | ||
245 | struct irq_chip_type *ct; | ||
246 | |||
247 | if (!irq_setup) | ||
248 | return -EINVAL; | ||
249 | |||
250 | if (prcm_irq_setup) { | ||
251 | pr_err("PRCM: already initialized; won't reinitialize\n"); | ||
252 | return -EINVAL; | ||
253 | } | ||
254 | |||
255 | if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) { | ||
256 | pr_err("PRCM: nr_regs too large\n"); | ||
257 | return -EINVAL; | ||
258 | } | ||
259 | |||
260 | prcm_irq_setup = irq_setup; | ||
261 | |||
262 | prcm_irq_chips = kzalloc(sizeof(void *) * nr_regs, GFP_KERNEL); | ||
263 | prcm_irq_setup->saved_mask = kzalloc(sizeof(u32) * nr_regs, GFP_KERNEL); | ||
264 | prcm_irq_setup->priority_mask = kzalloc(sizeof(u32) * nr_regs, | ||
265 | GFP_KERNEL); | ||
266 | |||
267 | if (!prcm_irq_chips || !prcm_irq_setup->saved_mask || | ||
268 | !prcm_irq_setup->priority_mask) { | ||
269 | pr_err("PRCM: kzalloc failed\n"); | ||
270 | goto err; | ||
271 | } | ||
272 | |||
273 | memset(mask, 0, sizeof(mask)); | ||
274 | |||
275 | for (i = 0; i < irq_setup->nr_irqs; i++) { | ||
276 | offset = irq_setup->irqs[i].offset; | ||
277 | mask[offset >> 5] |= 1 << (offset & 0x1f); | ||
278 | if (irq_setup->irqs[i].priority) | ||
279 | irq_setup->priority_mask[offset >> 5] |= | ||
280 | 1 << (offset & 0x1f); | ||
281 | } | ||
282 | |||
283 | irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler); | ||
284 | |||
285 | irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32, | ||
286 | 0); | ||
287 | |||
288 | if (irq_setup->base_irq < 0) { | ||
289 | pr_err("PRCM: failed to allocate irq descs: %d\n", | ||
290 | irq_setup->base_irq); | ||
291 | goto err; | ||
292 | } | ||
293 | |||
294 | for (i = 0; i <= irq_setup->nr_regs; i++) { | ||
295 | gc = irq_alloc_generic_chip("PRCM", 1, | ||
296 | irq_setup->base_irq + i * 32, prm_base, | ||
297 | handle_level_irq); | ||
298 | |||
299 | if (!gc) { | ||
300 | pr_err("PRCM: failed to allocate generic chip\n"); | ||
301 | goto err; | ||
302 | } | ||
303 | ct = gc->chip_types; | ||
304 | ct->chip.irq_ack = irq_gc_ack_set_bit; | ||
305 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | ||
306 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | ||
307 | |||
308 | ct->regs.ack = irq_setup->ack + i * 4; | ||
309 | ct->regs.mask = irq_setup->mask + i * 4; | ||
310 | |||
311 | irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0); | ||
312 | prcm_irq_chips[i] = gc; | ||
313 | } | ||
314 | |||
315 | return 0; | ||
316 | |||
317 | err: | ||
318 | omap_prcm_irq_cleanup(); | ||
319 | return -ENOMEM; | ||
320 | } | ||
diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index ee3a8ad304cb..7479d7ea1379 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * SDRC register values for Nokia boards | 2 | * SDRC register values for Nokia boards |
3 | * | 3 | * |
4 | * Copyright (C) 2008, 2010 Nokia Corporation | 4 | * Copyright (C) 2008, 2010-2011 Nokia Corporation |
5 | * | 5 | * |
6 | * Lauri Leukkunen <lauri.leukkunen@nokia.com> | 6 | * Lauri Leukkunen <lauri.leukkunen@nokia.com> |
7 | * | 7 | * |
@@ -107,14 +107,37 @@ static const struct sdram_timings nokia_195dot2mhz_timings[] = { | |||
107 | }, | 107 | }, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static const struct sdram_timings nokia_200mhz_timings[] = { | ||
111 | { | ||
112 | .casl = 3, | ||
113 | .tDAL = 30000, | ||
114 | .tDPL = 15000, | ||
115 | .tRRD = 10000, | ||
116 | .tRCD = 20000, | ||
117 | .tRP = 15000, | ||
118 | .tRAS = 40000, | ||
119 | .tRC = 55000, | ||
120 | .tRFC = 140000, | ||
121 | .tXSR = 200000, | ||
122 | |||
123 | .tREF = 7800, | ||
124 | |||
125 | .tXP = 2, | ||
126 | .tCKE = 4, | ||
127 | .tWTR = 2 | ||
128 | }, | ||
129 | }; | ||
130 | |||
110 | static const struct { | 131 | static const struct { |
111 | long rate; | 132 | long rate; |
112 | struct sdram_timings const *data; | 133 | struct sdram_timings const *data; |
113 | } nokia_timings[] = { | 134 | } nokia_timings[] = { |
114 | { 83000000, nokia_166mhz_timings }, | 135 | { 83000000, nokia_166mhz_timings }, |
115 | { 97600000, nokia_97dot6mhz_timings }, | 136 | { 97600000, nokia_97dot6mhz_timings }, |
137 | { 100000000, nokia_200mhz_timings }, | ||
116 | { 166000000, nokia_166mhz_timings }, | 138 | { 166000000, nokia_166mhz_timings }, |
117 | { 195200000, nokia_195dot2mhz_timings }, | 139 | { 195200000, nokia_195dot2mhz_timings }, |
140 | { 200000000, nokia_200mhz_timings }, | ||
118 | }; | 141 | }; |
119 | static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; | 142 | static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; |
120 | 143 | ||
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 42c326732a29..247d89478f24 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -19,26 +19,21 @@ | |||
19 | */ | 19 | */ |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/serial_reg.h> | ||
23 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
24 | #include <linux/io.h> | 23 | #include <linux/io.h> |
25 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
26 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
28 | #include <linux/serial_8250.h> | ||
29 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
30 | #include <linux/console.h> | 28 | #include <linux/console.h> |
31 | 29 | ||
32 | #ifdef CONFIG_SERIAL_OMAP | ||
33 | #include <plat/omap-serial.h> | 30 | #include <plat/omap-serial.h> |
34 | #endif | ||
35 | |||
36 | #include "common.h" | 31 | #include "common.h" |
37 | #include <plat/board.h> | 32 | #include <plat/board.h> |
38 | #include <plat/clock.h> | ||
39 | #include <plat/dma.h> | 33 | #include <plat/dma.h> |
40 | #include <plat/omap_hwmod.h> | 34 | #include <plat/omap_hwmod.h> |
41 | #include <plat/omap_device.h> | 35 | #include <plat/omap_device.h> |
36 | #include <plat/omap-pm.h> | ||
42 | 37 | ||
43 | #include "prm2xxx_3xxx.h" | 38 | #include "prm2xxx_3xxx.h" |
44 | #include "pm.h" | 39 | #include "pm.h" |
@@ -47,603 +42,226 @@ | |||
47 | #include "control.h" | 42 | #include "control.h" |
48 | #include "mux.h" | 43 | #include "mux.h" |
49 | 44 | ||
50 | #define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 | ||
51 | #define UART_OMAP_WER 0x17 /* Wake-up enable register */ | ||
52 | |||
53 | #define UART_ERRATA_FIFO_FULL_ABORT (0x1 << 0) | ||
54 | #define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1) | ||
55 | |||
56 | /* | 45 | /* |
57 | * NOTE: By default the serial timeout is disabled as it causes lost characters | 46 | * NOTE: By default the serial auto_suspend timeout is disabled as it causes |
58 | * over the serial ports. This means that the UART clocks will stay on until | 47 | * lost characters over the serial ports. This means that the UART clocks will |
59 | * disabled via sysfs. This also causes that any deeper omap sleep states are | 48 | * stay on until power/autosuspend_delay is set for the uart from sysfs. |
60 | * blocked. | 49 | * This also causes that any deeper omap sleep states are blocked. |
61 | */ | 50 | */ |
62 | #define DEFAULT_TIMEOUT 0 | 51 | #define DEFAULT_AUTOSUSPEND_DELAY -1 |
63 | 52 | ||
64 | #define MAX_UART_HWMOD_NAME_LEN 16 | 53 | #define MAX_UART_HWMOD_NAME_LEN 16 |
65 | 54 | ||
66 | struct omap_uart_state { | 55 | struct omap_uart_state { |
67 | int num; | 56 | int num; |
68 | int can_sleep; | 57 | int can_sleep; |
69 | struct timer_list timer; | ||
70 | u32 timeout; | ||
71 | |||
72 | void __iomem *wk_st; | ||
73 | void __iomem *wk_en; | ||
74 | u32 wk_mask; | ||
75 | u32 padconf; | ||
76 | u32 dma_enabled; | ||
77 | |||
78 | struct clk *ick; | ||
79 | struct clk *fck; | ||
80 | int clocked; | ||
81 | |||
82 | int irq; | ||
83 | int regshift; | ||
84 | int irqflags; | ||
85 | void __iomem *membase; | ||
86 | resource_size_t mapbase; | ||
87 | 58 | ||
88 | struct list_head node; | 59 | struct list_head node; |
89 | struct omap_hwmod *oh; | 60 | struct omap_hwmod *oh; |
90 | struct platform_device *pdev; | 61 | struct platform_device *pdev; |
91 | |||
92 | u32 errata; | ||
93 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | ||
94 | int context_valid; | ||
95 | |||
96 | /* Registers to be saved/restored for OFF-mode */ | ||
97 | u16 dll; | ||
98 | u16 dlh; | ||
99 | u16 ier; | ||
100 | u16 sysc; | ||
101 | u16 scr; | ||
102 | u16 wer; | ||
103 | u16 mcr; | ||
104 | #endif | ||
105 | }; | 62 | }; |
106 | 63 | ||
107 | static LIST_HEAD(uart_list); | 64 | static LIST_HEAD(uart_list); |
108 | static u8 num_uarts; | 65 | static u8 num_uarts; |
66 | static u8 console_uart_id = -1; | ||
67 | static u8 no_console_suspend; | ||
68 | static u8 uart_debug; | ||
69 | |||
70 | #define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ | ||
71 | #define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ | ||
72 | #define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */ | ||
73 | |||
74 | static struct omap_uart_port_info omap_serial_default_info[] __initdata = { | ||
75 | { | ||
76 | .dma_enabled = false, | ||
77 | .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, | ||
78 | .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, | ||
79 | .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, | ||
80 | .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY, | ||
81 | }, | ||
82 | }; | ||
109 | 83 | ||
110 | static inline unsigned int __serial_read_reg(struct uart_port *up, | 84 | #ifdef CONFIG_PM |
111 | int offset) | 85 | static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) |
112 | { | ||
113 | offset <<= up->regshift; | ||
114 | return (unsigned int)__raw_readb(up->membase + offset); | ||
115 | } | ||
116 | |||
117 | static inline unsigned int serial_read_reg(struct omap_uart_state *uart, | ||
118 | int offset) | ||
119 | { | 86 | { |
120 | offset <<= uart->regshift; | 87 | struct omap_device *od = to_omap_device(pdev); |
121 | return (unsigned int)__raw_readb(uart->membase + offset); | ||
122 | } | ||
123 | 88 | ||
124 | static inline void __serial_write_reg(struct uart_port *up, int offset, | 89 | if (!od) |
125 | int value) | 90 | return; |
126 | { | ||
127 | offset <<= up->regshift; | ||
128 | __raw_writeb(value, up->membase + offset); | ||
129 | } | ||
130 | 91 | ||
131 | static inline void serial_write_reg(struct omap_uart_state *uart, int offset, | 92 | if (enable) |
132 | int value) | 93 | omap_hwmod_enable_wakeup(od->hwmods[0]); |
133 | { | 94 | else |
134 | offset <<= uart->regshift; | 95 | omap_hwmod_disable_wakeup(od->hwmods[0]); |
135 | __raw_writeb(value, uart->membase + offset); | ||
136 | } | 96 | } |
137 | 97 | ||
138 | /* | 98 | /* |
139 | * Internal UARTs need to be initialized for the 8250 autoconfig to work | 99 | * Errata i291: [UART]:Cannot Acknowledge Idle Requests |
140 | * properly. Note that the TX watermark initialization may not be needed | 100 | * in Smartidle Mode When Configured for DMA Operations. |
141 | * once the 8250.c watermark handling code is merged. | 101 | * WA: configure uart in force idle mode. |
142 | */ | 102 | */ |
143 | 103 | static void omap_uart_set_noidle(struct platform_device *pdev) | |
144 | static inline void __init omap_uart_reset(struct omap_uart_state *uart) | ||
145 | { | 104 | { |
146 | serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); | 105 | struct omap_device *od = to_omap_device(pdev); |
147 | serial_write_reg(uart, UART_OMAP_SCR, 0x08); | ||
148 | serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE); | ||
149 | } | ||
150 | |||
151 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) | ||
152 | 106 | ||
153 | /* | 107 | omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); |
154 | * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6) | ||
155 | * The access to uart register after MDR1 Access | ||
156 | * causes UART to corrupt data. | ||
157 | * | ||
158 | * Need a delay = | ||
159 | * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS) | ||
160 | * give 10 times as much | ||
161 | */ | ||
162 | static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val, | ||
163 | u8 fcr_val) | ||
164 | { | ||
165 | u8 timeout = 255; | ||
166 | |||
167 | serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val); | ||
168 | udelay(2); | ||
169 | serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT | | ||
170 | UART_FCR_CLEAR_RCVR); | ||
171 | /* | ||
172 | * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and | ||
173 | * TX_FIFO_E bit is 1. | ||
174 | */ | ||
175 | while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) & | ||
176 | (UART_LSR_THRE | UART_LSR_DR))) { | ||
177 | timeout--; | ||
178 | if (!timeout) { | ||
179 | /* Should *never* happen. we warn and carry on */ | ||
180 | dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n", | ||
181 | serial_read_reg(uart, UART_LSR)); | ||
182 | break; | ||
183 | } | ||
184 | udelay(1); | ||
185 | } | ||
186 | } | 108 | } |
187 | 109 | ||
188 | static void omap_uart_save_context(struct omap_uart_state *uart) | 110 | static void omap_uart_set_forceidle(struct platform_device *pdev) |
189 | { | 111 | { |
190 | u16 lcr = 0; | 112 | struct omap_device *od = to_omap_device(pdev); |
191 | 113 | ||
192 | if (!enable_off_mode) | 114 | omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE); |
193 | return; | ||
194 | |||
195 | lcr = serial_read_reg(uart, UART_LCR); | ||
196 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
197 | uart->dll = serial_read_reg(uart, UART_DLL); | ||
198 | uart->dlh = serial_read_reg(uart, UART_DLM); | ||
199 | serial_write_reg(uart, UART_LCR, lcr); | ||
200 | uart->ier = serial_read_reg(uart, UART_IER); | ||
201 | uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC); | ||
202 | uart->scr = serial_read_reg(uart, UART_OMAP_SCR); | ||
203 | uart->wer = serial_read_reg(uart, UART_OMAP_WER); | ||
204 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A); | ||
205 | uart->mcr = serial_read_reg(uart, UART_MCR); | ||
206 | serial_write_reg(uart, UART_LCR, lcr); | ||
207 | |||
208 | uart->context_valid = 1; | ||
209 | } | 115 | } |
210 | 116 | ||
211 | static void omap_uart_restore_context(struct omap_uart_state *uart) | ||
212 | { | ||
213 | u16 efr = 0; | ||
214 | |||
215 | if (!enable_off_mode) | ||
216 | return; | ||
217 | |||
218 | if (!uart->context_valid) | ||
219 | return; | ||
220 | |||
221 | uart->context_valid = 0; | ||
222 | |||
223 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | ||
224 | omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0); | ||
225 | else | ||
226 | serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); | ||
227 | |||
228 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
229 | efr = serial_read_reg(uart, UART_EFR); | ||
230 | serial_write_reg(uart, UART_EFR, UART_EFR_ECB); | ||
231 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ | ||
232 | serial_write_reg(uart, UART_IER, 0x0); | ||
233 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
234 | serial_write_reg(uart, UART_DLL, uart->dll); | ||
235 | serial_write_reg(uart, UART_DLM, uart->dlh); | ||
236 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ | ||
237 | serial_write_reg(uart, UART_IER, uart->ier); | ||
238 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A); | ||
239 | serial_write_reg(uart, UART_MCR, uart->mcr); | ||
240 | serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B); | ||
241 | serial_write_reg(uart, UART_EFR, efr); | ||
242 | serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8); | ||
243 | serial_write_reg(uart, UART_OMAP_SCR, uart->scr); | ||
244 | serial_write_reg(uart, UART_OMAP_WER, uart->wer); | ||
245 | serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc); | ||
246 | |||
247 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | ||
248 | omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1); | ||
249 | else | ||
250 | /* UART 16x mode */ | ||
251 | serial_write_reg(uart, UART_OMAP_MDR1, | ||
252 | UART_OMAP_MDR1_16X_MODE); | ||
253 | } | ||
254 | #else | 117 | #else |
255 | static inline void omap_uart_save_context(struct omap_uart_state *uart) {} | 118 | static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) |
256 | static inline void omap_uart_restore_context(struct omap_uart_state *uart) {} | 119 | {} |
257 | #endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */ | 120 | static void omap_uart_set_noidle(struct platform_device *pdev) {} |
258 | 121 | static void omap_uart_set_forceidle(struct platform_device *pdev) {} | |
259 | static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) | 122 | #endif /* CONFIG_PM */ |
260 | { | ||
261 | if (uart->clocked) | ||
262 | return; | ||
263 | |||
264 | omap_device_enable(uart->pdev); | ||
265 | uart->clocked = 1; | ||
266 | omap_uart_restore_context(uart); | ||
267 | } | ||
268 | |||
269 | #ifdef CONFIG_PM | ||
270 | |||
271 | static inline void omap_uart_disable_clocks(struct omap_uart_state *uart) | ||
272 | { | ||
273 | if (!uart->clocked) | ||
274 | return; | ||
275 | |||
276 | omap_uart_save_context(uart); | ||
277 | uart->clocked = 0; | ||
278 | omap_device_idle(uart->pdev); | ||
279 | } | ||
280 | |||
281 | static void omap_uart_enable_wakeup(struct omap_uart_state *uart) | ||
282 | { | ||
283 | /* Set wake-enable bit */ | ||
284 | if (uart->wk_en && uart->wk_mask) { | ||
285 | u32 v = __raw_readl(uart->wk_en); | ||
286 | v |= uart->wk_mask; | ||
287 | __raw_writel(v, uart->wk_en); | ||
288 | } | ||
289 | |||
290 | /* Ensure IOPAD wake-enables are set */ | ||
291 | if (cpu_is_omap34xx() && uart->padconf) { | ||
292 | u16 v = omap_ctrl_readw(uart->padconf); | ||
293 | v |= OMAP3_PADCONF_WAKEUPENABLE0; | ||
294 | omap_ctrl_writew(v, uart->padconf); | ||
295 | } | ||
296 | } | ||
297 | |||
298 | static void omap_uart_disable_wakeup(struct omap_uart_state *uart) | ||
299 | { | ||
300 | /* Clear wake-enable bit */ | ||
301 | if (uart->wk_en && uart->wk_mask) { | ||
302 | u32 v = __raw_readl(uart->wk_en); | ||
303 | v &= ~uart->wk_mask; | ||
304 | __raw_writel(v, uart->wk_en); | ||
305 | } | ||
306 | |||
307 | /* Ensure IOPAD wake-enables are cleared */ | ||
308 | if (cpu_is_omap34xx() && uart->padconf) { | ||
309 | u16 v = omap_ctrl_readw(uart->padconf); | ||
310 | v &= ~OMAP3_PADCONF_WAKEUPENABLE0; | ||
311 | omap_ctrl_writew(v, uart->padconf); | ||
312 | } | ||
313 | } | ||
314 | |||
315 | static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, | ||
316 | int enable) | ||
317 | { | ||
318 | u8 idlemode; | ||
319 | |||
320 | if (enable) { | ||
321 | /** | ||
322 | * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests | ||
323 | * in Smartidle Mode When Configured for DMA Operations. | ||
324 | */ | ||
325 | if (uart->dma_enabled) | ||
326 | idlemode = HWMOD_IDLEMODE_FORCE; | ||
327 | else | ||
328 | idlemode = HWMOD_IDLEMODE_SMART; | ||
329 | } else { | ||
330 | idlemode = HWMOD_IDLEMODE_NO; | ||
331 | } | ||
332 | |||
333 | omap_hwmod_set_slave_idlemode(uart->oh, idlemode); | ||
334 | } | ||
335 | |||
336 | static void omap_uart_block_sleep(struct omap_uart_state *uart) | ||
337 | { | ||
338 | omap_uart_enable_clocks(uart); | ||
339 | |||
340 | omap_uart_smart_idle_enable(uart, 0); | ||
341 | uart->can_sleep = 0; | ||
342 | if (uart->timeout) | ||
343 | mod_timer(&uart->timer, jiffies + uart->timeout); | ||
344 | else | ||
345 | del_timer(&uart->timer); | ||
346 | } | ||
347 | |||
348 | static void omap_uart_allow_sleep(struct omap_uart_state *uart) | ||
349 | { | ||
350 | if (device_may_wakeup(&uart->pdev->dev)) | ||
351 | omap_uart_enable_wakeup(uart); | ||
352 | else | ||
353 | omap_uart_disable_wakeup(uart); | ||
354 | |||
355 | if (!uart->clocked) | ||
356 | return; | ||
357 | |||
358 | omap_uart_smart_idle_enable(uart, 1); | ||
359 | uart->can_sleep = 1; | ||
360 | del_timer(&uart->timer); | ||
361 | } | ||
362 | |||
363 | static void omap_uart_idle_timer(unsigned long data) | ||
364 | { | ||
365 | struct omap_uart_state *uart = (struct omap_uart_state *)data; | ||
366 | |||
367 | omap_uart_allow_sleep(uart); | ||
368 | } | ||
369 | |||
370 | void omap_uart_prepare_idle(int num) | ||
371 | { | ||
372 | struct omap_uart_state *uart; | ||
373 | |||
374 | list_for_each_entry(uart, &uart_list, node) { | ||
375 | if (num == uart->num && uart->can_sleep) { | ||
376 | omap_uart_disable_clocks(uart); | ||
377 | return; | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | |||
382 | void omap_uart_resume_idle(int num) | ||
383 | { | ||
384 | struct omap_uart_state *uart; | ||
385 | |||
386 | list_for_each_entry(uart, &uart_list, node) { | ||
387 | if (num == uart->num && uart->can_sleep) { | ||
388 | omap_uart_enable_clocks(uart); | ||
389 | |||
390 | /* Check for IO pad wakeup */ | ||
391 | if (cpu_is_omap34xx() && uart->padconf) { | ||
392 | u16 p = omap_ctrl_readw(uart->padconf); | ||
393 | |||
394 | if (p & OMAP3_PADCONF_WAKEUPEVENT0) | ||
395 | omap_uart_block_sleep(uart); | ||
396 | } | ||
397 | |||
398 | /* Check for normal UART wakeup */ | ||
399 | if (__raw_readl(uart->wk_st) & uart->wk_mask) | ||
400 | omap_uart_block_sleep(uart); | ||
401 | return; | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | |||
406 | void omap_uart_prepare_suspend(void) | ||
407 | { | ||
408 | struct omap_uart_state *uart; | ||
409 | |||
410 | list_for_each_entry(uart, &uart_list, node) { | ||
411 | omap_uart_allow_sleep(uart); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | int omap_uart_can_sleep(void) | ||
416 | { | ||
417 | struct omap_uart_state *uart; | ||
418 | int can_sleep = 1; | ||
419 | |||
420 | list_for_each_entry(uart, &uart_list, node) { | ||
421 | if (!uart->clocked) | ||
422 | continue; | ||
423 | |||
424 | if (!uart->can_sleep) { | ||
425 | can_sleep = 0; | ||
426 | continue; | ||
427 | } | ||
428 | |||
429 | /* This UART can now safely sleep. */ | ||
430 | omap_uart_allow_sleep(uart); | ||
431 | } | ||
432 | |||
433 | return can_sleep; | ||
434 | } | ||
435 | 123 | ||
436 | /** | 124 | #ifdef CONFIG_OMAP_MUX |
437 | * omap_uart_interrupt() | 125 | static struct omap_device_pad default_uart1_pads[] __initdata = { |
438 | * | 126 | { |
439 | * This handler is used only to detect that *any* UART interrupt has | 127 | .name = "uart1_cts.uart1_cts", |
440 | * occurred. It does _nothing_ to handle the interrupt. Rather, | 128 | .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, |
441 | * any UART interrupt will trigger the inactivity timer so the | 129 | }, |
442 | * UART will not idle or sleep for its timeout period. | 130 | { |
443 | * | 131 | .name = "uart1_rts.uart1_rts", |
444 | **/ | 132 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
445 | /* static int first_interrupt; */ | 133 | }, |
446 | static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) | 134 | { |
447 | { | 135 | .name = "uart1_tx.uart1_tx", |
448 | struct omap_uart_state *uart = dev_id; | 136 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
137 | }, | ||
138 | { | ||
139 | .name = "uart1_rx.uart1_rx", | ||
140 | .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, | ||
141 | .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, | ||
142 | .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, | ||
143 | }, | ||
144 | }; | ||
449 | 145 | ||
450 | omap_uart_block_sleep(uart); | 146 | static struct omap_device_pad default_uart2_pads[] __initdata = { |
147 | { | ||
148 | .name = "uart2_cts.uart2_cts", | ||
149 | .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, | ||
150 | }, | ||
151 | { | ||
152 | .name = "uart2_rts.uart2_rts", | ||
153 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, | ||
154 | }, | ||
155 | { | ||
156 | .name = "uart2_tx.uart2_tx", | ||
157 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, | ||
158 | }, | ||
159 | { | ||
160 | .name = "uart2_rx.uart2_rx", | ||
161 | .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, | ||
162 | .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, | ||
163 | .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, | ||
164 | }, | ||
165 | }; | ||
451 | 166 | ||
452 | return IRQ_NONE; | 167 | static struct omap_device_pad default_uart3_pads[] __initdata = { |
453 | } | 168 | { |
169 | .name = "uart3_cts_rctx.uart3_cts_rctx", | ||
170 | .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, | ||
171 | }, | ||
172 | { | ||
173 | .name = "uart3_rts_sd.uart3_rts_sd", | ||
174 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, | ||
175 | }, | ||
176 | { | ||
177 | .name = "uart3_tx_irtx.uart3_tx_irtx", | ||
178 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, | ||
179 | }, | ||
180 | { | ||
181 | .name = "uart3_rx_irrx.uart3_rx_irrx", | ||
182 | .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, | ||
183 | .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, | ||
184 | .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, | ||
185 | }, | ||
186 | }; | ||
454 | 187 | ||
455 | static void omap_uart_idle_init(struct omap_uart_state *uart) | 188 | static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = { |
456 | { | 189 | { |
457 | int ret; | 190 | .name = "gpmc_wait2.uart4_tx", |
458 | 191 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, | |
459 | uart->can_sleep = 0; | 192 | }, |
460 | uart->timeout = DEFAULT_TIMEOUT; | 193 | { |
461 | setup_timer(&uart->timer, omap_uart_idle_timer, | 194 | .name = "gpmc_wait3.uart4_rx", |
462 | (unsigned long) uart); | 195 | .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, |
463 | if (uart->timeout) | 196 | .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2, |
464 | mod_timer(&uart->timer, jiffies + uart->timeout); | 197 | .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2, |
465 | omap_uart_smart_idle_enable(uart, 0); | 198 | }, |
466 | 199 | }; | |
467 | if (cpu_is_omap34xx() && !cpu_is_ti816x()) { | ||
468 | u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; | ||
469 | u32 wk_mask = 0; | ||
470 | u32 padconf = 0; | ||
471 | |||
472 | /* XXX These PRM accesses do not belong here */ | ||
473 | uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1); | ||
474 | uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1); | ||
475 | switch (uart->num) { | ||
476 | case 0: | ||
477 | wk_mask = OMAP3430_ST_UART1_MASK; | ||
478 | padconf = 0x182; | ||
479 | break; | ||
480 | case 1: | ||
481 | wk_mask = OMAP3430_ST_UART2_MASK; | ||
482 | padconf = 0x17a; | ||
483 | break; | ||
484 | case 2: | ||
485 | wk_mask = OMAP3430_ST_UART3_MASK; | ||
486 | padconf = 0x19e; | ||
487 | break; | ||
488 | case 3: | ||
489 | wk_mask = OMAP3630_ST_UART4_MASK; | ||
490 | padconf = 0x0d2; | ||
491 | break; | ||
492 | } | ||
493 | uart->wk_mask = wk_mask; | ||
494 | uart->padconf = padconf; | ||
495 | } else if (cpu_is_omap24xx()) { | ||
496 | u32 wk_mask = 0; | ||
497 | u32 wk_en = PM_WKEN1, wk_st = PM_WKST1; | ||
498 | |||
499 | switch (uart->num) { | ||
500 | case 0: | ||
501 | wk_mask = OMAP24XX_ST_UART1_MASK; | ||
502 | break; | ||
503 | case 1: | ||
504 | wk_mask = OMAP24XX_ST_UART2_MASK; | ||
505 | break; | ||
506 | case 2: | ||
507 | wk_en = OMAP24XX_PM_WKEN2; | ||
508 | wk_st = OMAP24XX_PM_WKST2; | ||
509 | wk_mask = OMAP24XX_ST_UART3_MASK; | ||
510 | break; | ||
511 | } | ||
512 | uart->wk_mask = wk_mask; | ||
513 | if (cpu_is_omap2430()) { | ||
514 | uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en); | ||
515 | uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st); | ||
516 | } else if (cpu_is_omap2420()) { | ||
517 | uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en); | ||
518 | uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st); | ||
519 | } | ||
520 | } else { | ||
521 | uart->wk_en = NULL; | ||
522 | uart->wk_st = NULL; | ||
523 | uart->wk_mask = 0; | ||
524 | uart->padconf = 0; | ||
525 | } | ||
526 | 200 | ||
527 | uart->irqflags |= IRQF_SHARED; | 201 | static struct omap_device_pad default_omap4_uart4_pads[] __initdata = { |
528 | ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt, | 202 | { |
529 | IRQF_SHARED, "serial idle", (void *)uart); | 203 | .name = "uart4_tx.uart4_tx", |
530 | WARN_ON(ret); | 204 | .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, |
531 | } | 205 | }, |
206 | { | ||
207 | .name = "uart4_rx.uart4_rx", | ||
208 | .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, | ||
209 | .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, | ||
210 | .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, | ||
211 | }, | ||
212 | }; | ||
532 | 213 | ||
533 | void omap_uart_enable_irqs(int enable) | 214 | static void omap_serial_fill_default_pads(struct omap_board_data *bdata) |
534 | { | 215 | { |
535 | int ret; | 216 | switch (bdata->id) { |
536 | struct omap_uart_state *uart; | 217 | case 0: |
537 | 218 | bdata->pads = default_uart1_pads; | |
538 | list_for_each_entry(uart, &uart_list, node) { | 219 | bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads); |
539 | if (enable) { | 220 | break; |
540 | pm_runtime_put_sync(&uart->pdev->dev); | 221 | case 1: |
541 | ret = request_threaded_irq(uart->irq, NULL, | 222 | bdata->pads = default_uart2_pads; |
542 | omap_uart_interrupt, | 223 | bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads); |
543 | IRQF_SHARED, | 224 | break; |
544 | "serial idle", | 225 | case 2: |
545 | (void *)uart); | 226 | bdata->pads = default_uart3_pads; |
546 | } else { | 227 | bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads); |
547 | pm_runtime_get_noresume(&uart->pdev->dev); | 228 | break; |
548 | free_irq(uart->irq, (void *)uart); | 229 | case 3: |
230 | if (cpu_is_omap44xx()) { | ||
231 | bdata->pads = default_omap4_uart4_pads; | ||
232 | bdata->pads_cnt = | ||
233 | ARRAY_SIZE(default_omap4_uart4_pads); | ||
234 | } else if (cpu_is_omap3630()) { | ||
235 | bdata->pads = default_omap36xx_uart4_pads; | ||
236 | bdata->pads_cnt = | ||
237 | ARRAY_SIZE(default_omap36xx_uart4_pads); | ||
549 | } | 238 | } |
239 | break; | ||
240 | default: | ||
241 | break; | ||
550 | } | 242 | } |
551 | } | 243 | } |
552 | |||
553 | static ssize_t sleep_timeout_show(struct device *dev, | ||
554 | struct device_attribute *attr, | ||
555 | char *buf) | ||
556 | { | ||
557 | struct platform_device *pdev = to_platform_device(dev); | ||
558 | struct omap_device *odev = to_omap_device(pdev); | ||
559 | struct omap_uart_state *uart = odev->hwmods[0]->dev_attr; | ||
560 | |||
561 | return sprintf(buf, "%u\n", uart->timeout / HZ); | ||
562 | } | ||
563 | |||
564 | static ssize_t sleep_timeout_store(struct device *dev, | ||
565 | struct device_attribute *attr, | ||
566 | const char *buf, size_t n) | ||
567 | { | ||
568 | struct platform_device *pdev = to_platform_device(dev); | ||
569 | struct omap_device *odev = to_omap_device(pdev); | ||
570 | struct omap_uart_state *uart = odev->hwmods[0]->dev_attr; | ||
571 | unsigned int value; | ||
572 | |||
573 | if (sscanf(buf, "%u", &value) != 1) { | ||
574 | dev_err(dev, "sleep_timeout_store: Invalid value\n"); | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | |||
578 | uart->timeout = value * HZ; | ||
579 | if (uart->timeout) | ||
580 | mod_timer(&uart->timer, jiffies + uart->timeout); | ||
581 | else | ||
582 | /* A zero value means disable timeout feature */ | ||
583 | omap_uart_block_sleep(uart); | ||
584 | |||
585 | return n; | ||
586 | } | ||
587 | |||
588 | static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show, | ||
589 | sleep_timeout_store); | ||
590 | #define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr)) | ||
591 | #else | 244 | #else |
592 | static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} | 245 | static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} |
593 | static void omap_uart_block_sleep(struct omap_uart_state *uart) | 246 | #endif |
594 | { | ||
595 | /* Needed to enable UART clocks when built without CONFIG_PM */ | ||
596 | omap_uart_enable_clocks(uart); | ||
597 | } | ||
598 | #define DEV_CREATE_FILE(dev, attr) | ||
599 | #endif /* CONFIG_PM */ | ||
600 | |||
601 | #ifndef CONFIG_SERIAL_OMAP | ||
602 | /* | ||
603 | * Override the default 8250 read handler: mem_serial_in() | ||
604 | * Empty RX fifo read causes an abort on omap3630 and omap4 | ||
605 | * This function makes sure that an empty rx fifo is not read on these silicons | ||
606 | * (OMAP1/2/3430 are not affected) | ||
607 | */ | ||
608 | static unsigned int serial_in_override(struct uart_port *up, int offset) | ||
609 | { | ||
610 | if (UART_RX == offset) { | ||
611 | unsigned int lsr; | ||
612 | lsr = __serial_read_reg(up, UART_LSR); | ||
613 | if (!(lsr & UART_LSR_DR)) | ||
614 | return -EPERM; | ||
615 | } | ||
616 | |||
617 | return __serial_read_reg(up, offset); | ||
618 | } | ||
619 | 247 | ||
620 | static void serial_out_override(struct uart_port *up, int offset, int value) | 248 | char *cmdline_find_option(char *str) |
621 | { | 249 | { |
622 | unsigned int status, tmout = 10000; | 250 | extern char *saved_command_line; |
623 | 251 | ||
624 | status = __serial_read_reg(up, UART_LSR); | 252 | return strstr(saved_command_line, str); |
625 | while (!(status & UART_LSR_THRE)) { | ||
626 | /* Wait up to 10ms for the character(s) to be sent. */ | ||
627 | if (--tmout == 0) | ||
628 | break; | ||
629 | udelay(1); | ||
630 | status = __serial_read_reg(up, UART_LSR); | ||
631 | } | ||
632 | __serial_write_reg(up, offset, value); | ||
633 | } | 253 | } |
634 | #endif | ||
635 | 254 | ||
636 | static int __init omap_serial_early_init(void) | 255 | static int __init omap_serial_early_init(void) |
637 | { | 256 | { |
638 | int i = 0; | ||
639 | |||
640 | do { | 257 | do { |
641 | char oh_name[MAX_UART_HWMOD_NAME_LEN]; | 258 | char oh_name[MAX_UART_HWMOD_NAME_LEN]; |
642 | struct omap_hwmod *oh; | 259 | struct omap_hwmod *oh; |
643 | struct omap_uart_state *uart; | 260 | struct omap_uart_state *uart; |
261 | char uart_name[MAX_UART_HWMOD_NAME_LEN]; | ||
644 | 262 | ||
645 | snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, | 263 | snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, |
646 | "uart%d", i + 1); | 264 | "uart%d", num_uarts + 1); |
647 | oh = omap_hwmod_lookup(oh_name); | 265 | oh = omap_hwmod_lookup(oh_name); |
648 | if (!oh) | 266 | if (!oh) |
649 | break; | 267 | break; |
@@ -653,21 +271,35 @@ static int __init omap_serial_early_init(void) | |||
653 | return -ENODEV; | 271 | return -ENODEV; |
654 | 272 | ||
655 | uart->oh = oh; | 273 | uart->oh = oh; |
656 | uart->num = i++; | 274 | uart->num = num_uarts++; |
657 | list_add_tail(&uart->node, &uart_list); | 275 | list_add_tail(&uart->node, &uart_list); |
658 | num_uarts++; | 276 | snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN, |
659 | 277 | "%s%d", OMAP_SERIAL_NAME, uart->num); | |
660 | /* | 278 | |
661 | * NOTE: omap_hwmod_setup*() has not yet been called, | 279 | if (cmdline_find_option(uart_name)) { |
662 | * so no hwmod functions will work yet. | 280 | console_uart_id = uart->num; |
663 | */ | 281 | |
664 | 282 | if (console_loglevel >= 10) { | |
665 | /* | 283 | uart_debug = true; |
666 | * During UART early init, device need to be probed | 284 | pr_info("%s used as console in debug mode" |
667 | * to determine SoC specific init before omap_device | 285 | " uart%d clocks will not be" |
668 | * is ready. Therefore, don't allow idle here | 286 | " gated", uart_name, uart->num); |
669 | */ | 287 | } |
670 | uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; | 288 | |
289 | if (cmdline_find_option("no_console_suspend")) | ||
290 | no_console_suspend = true; | ||
291 | |||
292 | /* | ||
293 | * omap-uart can be used for earlyprintk logs | ||
294 | * So if omap-uart is used as console then prevent | ||
295 | * uart reset and idle to get logs from omap-uart | ||
296 | * until uart console driver is available to take | ||
297 | * care for console messages. | ||
298 | * Idling or resetting omap-uart while printing logs | ||
299 | * early boot logs can stall the boot-up. | ||
300 | */ | ||
301 | oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; | ||
302 | } | ||
671 | } while (1); | 303 | } while (1); |
672 | 304 | ||
673 | return 0; | 305 | return 0; |
@@ -677,6 +309,7 @@ core_initcall(omap_serial_early_init); | |||
677 | /** | 309 | /** |
678 | * omap_serial_init_port() - initialize single serial port | 310 | * omap_serial_init_port() - initialize single serial port |
679 | * @bdata: port specific board data pointer | 311 | * @bdata: port specific board data pointer |
312 | * @info: platform specific data pointer | ||
680 | * | 313 | * |
681 | * This function initialies serial driver for given port only. | 314 | * This function initialies serial driver for given port only. |
682 | * Platforms can call this function instead of omap_serial_init() | 315 | * Platforms can call this function instead of omap_serial_init() |
@@ -685,7 +318,8 @@ core_initcall(omap_serial_early_init); | |||
685 | * Don't mix calls to omap_serial_init_port() and omap_serial_init(), | 318 | * Don't mix calls to omap_serial_init_port() and omap_serial_init(), |
686 | * use only one of the two. | 319 | * use only one of the two. |
687 | */ | 320 | */ |
688 | void __init omap_serial_init_port(struct omap_board_data *bdata) | 321 | void __init omap_serial_init_port(struct omap_board_data *bdata, |
322 | struct omap_uart_port_info *info) | ||
689 | { | 323 | { |
690 | struct omap_uart_state *uart; | 324 | struct omap_uart_state *uart; |
691 | struct omap_hwmod *oh; | 325 | struct omap_hwmod *oh; |
@@ -693,15 +327,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) | |||
693 | void *pdata = NULL; | 327 | void *pdata = NULL; |
694 | u32 pdata_size = 0; | 328 | u32 pdata_size = 0; |
695 | char *name; | 329 | char *name; |
696 | #ifndef CONFIG_SERIAL_OMAP | ||
697 | struct plat_serial8250_port ports[2] = { | ||
698 | {}, | ||
699 | {.flags = 0}, | ||
700 | }; | ||
701 | struct plat_serial8250_port *p = &ports[0]; | ||
702 | #else | ||
703 | struct omap_uart_port_info omap_up; | 330 | struct omap_uart_port_info omap_up; |
704 | #endif | ||
705 | 331 | ||
706 | if (WARN_ON(!bdata)) | 332 | if (WARN_ON(!bdata)) |
707 | return; | 333 | return; |
@@ -713,66 +339,34 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) | |||
713 | list_for_each_entry(uart, &uart_list, node) | 339 | list_for_each_entry(uart, &uart_list, node) |
714 | if (bdata->id == uart->num) | 340 | if (bdata->id == uart->num) |
715 | break; | 341 | break; |
342 | if (!info) | ||
343 | info = omap_serial_default_info; | ||
716 | 344 | ||
717 | oh = uart->oh; | 345 | oh = uart->oh; |
718 | uart->dma_enabled = 0; | ||
719 | #ifndef CONFIG_SERIAL_OMAP | ||
720 | name = "serial8250"; | ||
721 | |||
722 | /* | ||
723 | * !! 8250 driver does not use standard IORESOURCE* It | ||
724 | * has it's own custom pdata that can be taken from | ||
725 | * the hwmod resource data. But, this needs to be | ||
726 | * done after the build. | ||
727 | * | ||
728 | * ?? does it have to be done before the register ?? | ||
729 | * YES, because platform_device_data_add() copies | ||
730 | * pdata, it does not use a pointer. | ||
731 | */ | ||
732 | p->flags = UPF_BOOT_AUTOCONF; | ||
733 | p->iotype = UPIO_MEM; | ||
734 | p->regshift = 2; | ||
735 | p->uartclk = OMAP24XX_BASE_BAUD * 16; | ||
736 | p->irq = oh->mpu_irqs[0].irq; | ||
737 | p->mapbase = oh->slaves[0]->addr->pa_start; | ||
738 | p->membase = omap_hwmod_get_mpu_rt_va(oh); | ||
739 | p->irqflags = IRQF_SHARED; | ||
740 | p->private_data = uart; | ||
741 | |||
742 | /* | ||
743 | * omap44xx, ti816x: Never read empty UART fifo | ||
744 | * omap3xxx: Never read empty UART fifo on UARTs | ||
745 | * with IP rev >=0x52 | ||
746 | */ | ||
747 | uart->regshift = p->regshift; | ||
748 | uart->membase = p->membase; | ||
749 | if (cpu_is_omap44xx() || cpu_is_ti816x()) | ||
750 | uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; | ||
751 | else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF) | ||
752 | >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) | ||
753 | uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; | ||
754 | |||
755 | if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) { | ||
756 | p->serial_in = serial_in_override; | ||
757 | p->serial_out = serial_out_override; | ||
758 | } | ||
759 | |||
760 | pdata = &ports[0]; | ||
761 | pdata_size = 2 * sizeof(struct plat_serial8250_port); | ||
762 | #else | ||
763 | |||
764 | name = DRIVER_NAME; | 346 | name = DRIVER_NAME; |
765 | 347 | ||
766 | omap_up.dma_enabled = uart->dma_enabled; | 348 | omap_up.dma_enabled = info->dma_enabled; |
767 | omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; | 349 | omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; |
768 | omap_up.mapbase = oh->slaves[0]->addr->pa_start; | 350 | omap_up.flags = UPF_BOOT_AUTOCONF; |
769 | omap_up.membase = omap_hwmod_get_mpu_rt_va(oh); | 351 | omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; |
770 | omap_up.irqflags = IRQF_SHARED; | 352 | omap_up.set_forceidle = omap_uart_set_forceidle; |
771 | omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | 353 | omap_up.set_noidle = omap_uart_set_noidle; |
354 | omap_up.enable_wakeup = omap_uart_enable_wakeup; | ||
355 | omap_up.dma_rx_buf_size = info->dma_rx_buf_size; | ||
356 | omap_up.dma_rx_timeout = info->dma_rx_timeout; | ||
357 | omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate; | ||
358 | omap_up.autosuspend_timeout = info->autosuspend_timeout; | ||
359 | |||
360 | /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ | ||
361 | if (!cpu_is_omap2420() && !cpu_is_ti816x()) | ||
362 | omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS; | ||
363 | |||
364 | /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */ | ||
365 | if (cpu_is_omap34xx() || cpu_is_omap3630()) | ||
366 | omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE; | ||
772 | 367 | ||
773 | pdata = &omap_up; | 368 | pdata = &omap_up; |
774 | pdata_size = sizeof(struct omap_uart_port_info); | 369 | pdata_size = sizeof(struct omap_uart_port_info); |
775 | #endif | ||
776 | 370 | ||
777 | if (WARN_ON(!oh)) | 371 | if (WARN_ON(!oh)) |
778 | return; | 372 | return; |
@@ -782,64 +376,29 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) | |||
782 | WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", | 376 | WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", |
783 | name, oh->name); | 377 | name, oh->name); |
784 | 378 | ||
785 | omap_device_disable_idle_on_suspend(pdev); | 379 | if ((console_uart_id == bdata->id) && no_console_suspend) |
380 | omap_device_disable_idle_on_suspend(pdev); | ||
381 | |||
786 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); | 382 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); |
787 | 383 | ||
788 | uart->irq = oh->mpu_irqs[0].irq; | ||
789 | uart->regshift = 2; | ||
790 | uart->mapbase = oh->slaves[0]->addr->pa_start; | ||
791 | uart->membase = omap_hwmod_get_mpu_rt_va(oh); | ||
792 | uart->pdev = pdev; | 384 | uart->pdev = pdev; |
793 | 385 | ||
794 | oh->dev_attr = uart; | 386 | oh->dev_attr = uart; |
795 | 387 | ||
796 | console_lock(); /* in case the earlycon is on the UART */ | 388 | if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) |
797 | 389 | && !uart_debug) | |
798 | /* | ||
799 | * Because of early UART probing, UART did not get idled | ||
800 | * on init. Now that omap_device is ready, ensure full idle | ||
801 | * before doing omap_device_enable(). | ||
802 | */ | ||
803 | omap_hwmod_idle(uart->oh); | ||
804 | |||
805 | omap_device_enable(uart->pdev); | ||
806 | omap_uart_idle_init(uart); | ||
807 | omap_uart_reset(uart); | ||
808 | omap_hwmod_enable_wakeup(uart->oh); | ||
809 | omap_device_idle(uart->pdev); | ||
810 | |||
811 | /* | ||
812 | * Need to block sleep long enough for interrupt driven | ||
813 | * driver to start. Console driver is in polling mode | ||
814 | * so device needs to be kept enabled while polling driver | ||
815 | * is in use. | ||
816 | */ | ||
817 | if (uart->timeout) | ||
818 | uart->timeout = (30 * HZ); | ||
819 | omap_uart_block_sleep(uart); | ||
820 | uart->timeout = DEFAULT_TIMEOUT; | ||
821 | |||
822 | console_unlock(); | ||
823 | |||
824 | if ((cpu_is_omap34xx() && uart->padconf) || | ||
825 | (uart->wk_en && uart->wk_mask)) { | ||
826 | device_init_wakeup(&pdev->dev, true); | 390 | device_init_wakeup(&pdev->dev, true); |
827 | DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout); | ||
828 | } | ||
829 | |||
830 | /* Enable the MDR1 errata for OMAP3 */ | ||
831 | if (cpu_is_omap34xx() && !cpu_is_ti816x()) | ||
832 | uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; | ||
833 | } | 391 | } |
834 | 392 | ||
835 | /** | 393 | /** |
836 | * omap_serial_init() - initialize all supported serial ports | 394 | * omap_serial_board_init() - initialize all supported serial ports |
395 | * @info: platform specific data pointer | ||
837 | * | 396 | * |
838 | * Initializes all available UARTs as serial ports. Platforms | 397 | * Initializes all available UARTs as serial ports. Platforms |
839 | * can call this function when they want to have default behaviour | 398 | * can call this function when they want to have default behaviour |
840 | * for serial ports (e.g initialize them all as serial ports). | 399 | * for serial ports (e.g initialize them all as serial ports). |
841 | */ | 400 | */ |
842 | void __init omap_serial_init(void) | 401 | void __init omap_serial_board_init(struct omap_uart_port_info *info) |
843 | { | 402 | { |
844 | struct omap_uart_state *uart; | 403 | struct omap_uart_state *uart; |
845 | struct omap_board_data bdata; | 404 | struct omap_board_data bdata; |
@@ -849,7 +408,25 @@ void __init omap_serial_init(void) | |||
849 | bdata.flags = 0; | 408 | bdata.flags = 0; |
850 | bdata.pads = NULL; | 409 | bdata.pads = NULL; |
851 | bdata.pads_cnt = 0; | 410 | bdata.pads_cnt = 0; |
852 | omap_serial_init_port(&bdata); | ||
853 | 411 | ||
412 | if (cpu_is_omap44xx() || cpu_is_omap34xx()) | ||
413 | omap_serial_fill_default_pads(&bdata); | ||
414 | |||
415 | if (!info) | ||
416 | omap_serial_init_port(&bdata, NULL); | ||
417 | else | ||
418 | omap_serial_init_port(&bdata, &info[uart->num]); | ||
854 | } | 419 | } |
855 | } | 420 | } |
421 | |||
422 | /** | ||
423 | * omap_serial_init() - initialize all supported serial ports | ||
424 | * | ||
425 | * Initializes all available UARTs. | ||
426 | * Platforms can call this function when they want to have default behaviour | ||
427 | * for serial ports (e.g initialize them all as serial ports). | ||
428 | */ | ||
429 | void __init omap_serial_init(void) | ||
430 | { | ||
431 | omap_serial_board_init(NULL); | ||
432 | } | ||
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S new file mode 100644 index 000000000000..abd283400490 --- /dev/null +++ b/arch/arm/mach-omap2/sleep44xx.S | |||
@@ -0,0 +1,379 @@ | |||
1 | /* | ||
2 | * OMAP44xx sleep code. | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
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/linkage.h> | ||
13 | #include <asm/system.h> | ||
14 | #include <asm/smp_scu.h> | ||
15 | #include <asm/memory.h> | ||
16 | #include <asm/hardware/cache-l2x0.h> | ||
17 | |||
18 | #include <plat/omap44xx.h> | ||
19 | #include <mach/omap-secure.h> | ||
20 | |||
21 | #include "common.h" | ||
22 | #include "omap4-sar-layout.h" | ||
23 | |||
24 | #if defined(CONFIG_SMP) && defined(CONFIG_PM) | ||
25 | |||
26 | .macro DO_SMC | ||
27 | dsb | ||
28 | smc #0 | ||
29 | dsb | ||
30 | .endm | ||
31 | |||
32 | ppa_zero_params: | ||
33 | .word 0x0 | ||
34 | |||
35 | ppa_por_params: | ||
36 | .word 1, 0 | ||
37 | |||
38 | /* | ||
39 | * ============================= | ||
40 | * == CPU suspend finisher == | ||
41 | * ============================= | ||
42 | * | ||
43 | * void omap4_finish_suspend(unsigned long cpu_state) | ||
44 | * | ||
45 | * This function code saves the CPU context and performs the CPU | ||
46 | * power down sequence. Calling WFI effectively changes the CPU | ||
47 | * power domains states to the desired target power state. | ||
48 | * | ||
49 | * @cpu_state : contains context save state (r0) | ||
50 | * 0 - No context lost | ||
51 | * 1 - CPUx L1 and logic lost: MPUSS CSWR | ||
52 | * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR | ||
53 | * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF | ||
54 | * @return: This function never returns for CPU OFF and DORMANT power states. | ||
55 | * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up | ||
56 | * from this follows a full CPU reset path via ROM code to CPU restore code. | ||
57 | * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. | ||
58 | * It returns to the caller for CPU INACTIVE and ON power states or in case | ||
59 | * CPU failed to transition to targeted OFF/DORMANT state. | ||
60 | */ | ||
61 | ENTRY(omap4_finish_suspend) | ||
62 | stmfd sp!, {lr} | ||
63 | cmp r0, #0x0 | ||
64 | beq do_WFI @ No lowpower state, jump to WFI | ||
65 | |||
66 | /* | ||
67 | * Flush all data from the L1 data cache before disabling | ||
68 | * SCTLR.C bit. | ||
69 | */ | ||
70 | bl omap4_get_sar_ram_base | ||
71 | ldr r9, [r0, #OMAP_TYPE_OFFSET] | ||
72 | cmp r9, #0x1 @ Check for HS device | ||
73 | bne skip_secure_l1_clean | ||
74 | mov r0, #SCU_PM_NORMAL | ||
75 | mov r1, #0xFF @ clean seucre L1 | ||
76 | stmfd r13!, {r4-r12, r14} | ||
77 | ldr r12, =OMAP4_MON_SCU_PWR_INDEX | ||
78 | DO_SMC | ||
79 | ldmfd r13!, {r4-r12, r14} | ||
80 | skip_secure_l1_clean: | ||
81 | bl v7_flush_dcache_all | ||
82 | |||
83 | /* | ||
84 | * Clear the SCTLR.C bit to prevent further data cache | ||
85 | * allocation. Clearing SCTLR.C would make all the data accesses | ||
86 | * strongly ordered and would not hit the cache. | ||
87 | */ | ||
88 | mrc p15, 0, r0, c1, c0, 0 | ||
89 | bic r0, r0, #(1 << 2) @ Disable the C bit | ||
90 | mcr p15, 0, r0, c1, c0, 0 | ||
91 | isb | ||
92 | |||
93 | /* | ||
94 | * Invalidate L1 data cache. Even though only invalidate is | ||
95 | * necessary exported flush API is used here. Doing clean | ||
96 | * on already clean cache would be almost NOP. | ||
97 | */ | ||
98 | bl v7_flush_dcache_all | ||
99 | |||
100 | /* | ||
101 | * Switch the CPU from Symmetric Multiprocessing (SMP) mode | ||
102 | * to AsymmetricMultiprocessing (AMP) mode by programming | ||
103 | * the SCU power status to DORMANT or OFF mode. | ||
104 | * This enables the CPU to be taken out of coherency by | ||
105 | * preventing the CPU from receiving cache, TLB, or BTB | ||
106 | * maintenance operations broadcast by other CPUs in the cluster. | ||
107 | */ | ||
108 | bl omap4_get_sar_ram_base | ||
109 | mov r8, r0 | ||
110 | ldr r9, [r8, #OMAP_TYPE_OFFSET] | ||
111 | cmp r9, #0x1 @ Check for HS device | ||
112 | bne scu_gp_set | ||
113 | mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR | ||
114 | ands r0, r0, #0x0f | ||
115 | ldreq r0, [r8, #SCU_OFFSET0] | ||
116 | ldrne r0, [r8, #SCU_OFFSET1] | ||
117 | mov r1, #0x00 | ||
118 | stmfd r13!, {r4-r12, r14} | ||
119 | ldr r12, =OMAP4_MON_SCU_PWR_INDEX | ||
120 | DO_SMC | ||
121 | ldmfd r13!, {r4-r12, r14} | ||
122 | b skip_scu_gp_set | ||
123 | scu_gp_set: | ||
124 | mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR | ||
125 | ands r0, r0, #0x0f | ||
126 | ldreq r1, [r8, #SCU_OFFSET0] | ||
127 | ldrne r1, [r8, #SCU_OFFSET1] | ||
128 | bl omap4_get_scu_base | ||
129 | bl scu_power_mode | ||
130 | skip_scu_gp_set: | ||
131 | mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data | ||
132 | tst r0, #(1 << 18) | ||
133 | mrcne p15, 0, r0, c1, c0, 1 | ||
134 | bicne r0, r0, #(1 << 6) @ Disable SMP bit | ||
135 | mcrne p15, 0, r0, c1, c0, 1 | ||
136 | isb | ||
137 | dsb | ||
138 | #ifdef CONFIG_CACHE_L2X0 | ||
139 | /* | ||
140 | * Clean and invalidate the L2 cache. | ||
141 | * Common cache-l2x0.c functions can't be used here since it | ||
142 | * uses spinlocks. We are out of coherency here with data cache | ||
143 | * disabled. The spinlock implementation uses exclusive load/store | ||
144 | * instruction which can fail without data cache being enabled. | ||
145 | * OMAP4 hardware doesn't support exclusive monitor which can | ||
146 | * overcome exclusive access issue. Because of this, CPU can | ||
147 | * lead to deadlock. | ||
148 | */ | ||
149 | bl omap4_get_sar_ram_base | ||
150 | mov r8, r0 | ||
151 | mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR | ||
152 | ands r5, r5, #0x0f | ||
153 | ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR | ||
154 | ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory. | ||
155 | cmp r0, #3 | ||
156 | bne do_WFI | ||
157 | #ifdef CONFIG_PL310_ERRATA_727915 | ||
158 | mov r0, #0x03 | ||
159 | mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX | ||
160 | DO_SMC | ||
161 | #endif | ||
162 | bl omap4_get_l2cache_base | ||
163 | mov r2, r0 | ||
164 | ldr r0, =0xffff | ||
165 | str r0, [r2, #L2X0_CLEAN_INV_WAY] | ||
166 | wait: | ||
167 | ldr r0, [r2, #L2X0_CLEAN_INV_WAY] | ||
168 | ldr r1, =0xffff | ||
169 | ands r0, r0, r1 | ||
170 | bne wait | ||
171 | #ifdef CONFIG_PL310_ERRATA_727915 | ||
172 | mov r0, #0x00 | ||
173 | mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX | ||
174 | DO_SMC | ||
175 | #endif | ||
176 | l2x_sync: | ||
177 | bl omap4_get_l2cache_base | ||
178 | mov r2, r0 | ||
179 | mov r0, #0x0 | ||
180 | str r0, [r2, #L2X0_CACHE_SYNC] | ||
181 | sync: | ||
182 | ldr r0, [r2, #L2X0_CACHE_SYNC] | ||
183 | ands r0, r0, #0x1 | ||
184 | bne sync | ||
185 | #endif | ||
186 | |||
187 | do_WFI: | ||
188 | bl omap_do_wfi | ||
189 | |||
190 | /* | ||
191 | * CPU is here when it failed to enter OFF/DORMANT or | ||
192 | * no low power state was attempted. | ||
193 | */ | ||
194 | mrc p15, 0, r0, c1, c0, 0 | ||
195 | tst r0, #(1 << 2) @ Check C bit enabled? | ||
196 | orreq r0, r0, #(1 << 2) @ Enable the C bit | ||
197 | mcreq p15, 0, r0, c1, c0, 0 | ||
198 | isb | ||
199 | |||
200 | /* | ||
201 | * Ensure the CPU power state is set to NORMAL in | ||
202 | * SCU power state so that CPU is back in coherency. | ||
203 | * In non-coherent mode CPU can lock-up and lead to | ||
204 | * system deadlock. | ||
205 | */ | ||
206 | mrc p15, 0, r0, c1, c0, 1 | ||
207 | tst r0, #(1 << 6) @ Check SMP bit enabled? | ||
208 | orreq r0, r0, #(1 << 6) | ||
209 | mcreq p15, 0, r0, c1, c0, 1 | ||
210 | isb | ||
211 | bl omap4_get_sar_ram_base | ||
212 | mov r8, r0 | ||
213 | ldr r9, [r8, #OMAP_TYPE_OFFSET] | ||
214 | cmp r9, #0x1 @ Check for HS device | ||
215 | bne scu_gp_clear | ||
216 | mov r0, #SCU_PM_NORMAL | ||
217 | mov r1, #0x00 | ||
218 | stmfd r13!, {r4-r12, r14} | ||
219 | ldr r12, =OMAP4_MON_SCU_PWR_INDEX | ||
220 | DO_SMC | ||
221 | ldmfd r13!, {r4-r12, r14} | ||
222 | b skip_scu_gp_clear | ||
223 | scu_gp_clear: | ||
224 | bl omap4_get_scu_base | ||
225 | mov r1, #SCU_PM_NORMAL | ||
226 | bl scu_power_mode | ||
227 | skip_scu_gp_clear: | ||
228 | isb | ||
229 | dsb | ||
230 | ldmfd sp!, {pc} | ||
231 | ENDPROC(omap4_finish_suspend) | ||
232 | |||
233 | /* | ||
234 | * ============================ | ||
235 | * == CPU resume entry point == | ||
236 | * ============================ | ||
237 | * | ||
238 | * void omap4_cpu_resume(void) | ||
239 | * | ||
240 | * ROM code jumps to this function while waking up from CPU | ||
241 | * OFF or DORMANT state. Physical address of the function is | ||
242 | * stored in the SAR RAM while entering to OFF or DORMANT mode. | ||
243 | * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. | ||
244 | */ | ||
245 | ENTRY(omap4_cpu_resume) | ||
246 | /* | ||
247 | * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. | ||
248 | * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA | ||
249 | * init and for CPU1, a secure PPA API provided. CPU0 must be ON | ||
250 | * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. | ||
251 | * OMAP443X GP devices- SMP bit isn't accessible. | ||
252 | * OMAP446X GP devices - SMP bit access is enabled on both CPUs. | ||
253 | */ | ||
254 | ldr r8, =OMAP44XX_SAR_RAM_BASE | ||
255 | ldr r9, [r8, #OMAP_TYPE_OFFSET] | ||
256 | cmp r9, #0x1 @ Skip if GP device | ||
257 | bne skip_ns_smp_enable | ||
258 | mrc p15, 0, r0, c0, c0, 5 | ||
259 | ands r0, r0, #0x0f | ||
260 | beq skip_ns_smp_enable | ||
261 | ppa_actrl_retry: | ||
262 | mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX | ||
263 | adr r3, ppa_zero_params @ Pointer to parameters | ||
264 | mov r1, #0x0 @ Process ID | ||
265 | mov r2, #0x4 @ Flag | ||
266 | mov r6, #0xff | ||
267 | mov r12, #0x00 @ Secure Service ID | ||
268 | DO_SMC | ||
269 | cmp r0, #0x0 @ API returns 0 on success. | ||
270 | beq enable_smp_bit | ||
271 | b ppa_actrl_retry | ||
272 | enable_smp_bit: | ||
273 | mrc p15, 0, r0, c1, c0, 1 | ||
274 | tst r0, #(1 << 6) @ Check SMP bit enabled? | ||
275 | orreq r0, r0, #(1 << 6) | ||
276 | mcreq p15, 0, r0, c1, c0, 1 | ||
277 | isb | ||
278 | skip_ns_smp_enable: | ||
279 | #ifdef CONFIG_CACHE_L2X0 | ||
280 | /* | ||
281 | * Restore the L2 AUXCTRL and enable the L2 cache. | ||
282 | * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL | ||
283 | * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL | ||
284 | * register r0 contains value to be programmed. | ||
285 | * L2 cache is already invalidate by ROM code as part | ||
286 | * of MPUSS OFF wakeup path. | ||
287 | */ | ||
288 | ldr r2, =OMAP44XX_L2CACHE_BASE | ||
289 | ldr r0, [r2, #L2X0_CTRL] | ||
290 | and r0, #0x0f | ||
291 | cmp r0, #1 | ||
292 | beq skip_l2en @ Skip if already enabled | ||
293 | ldr r3, =OMAP44XX_SAR_RAM_BASE | ||
294 | ldr r1, [r3, #OMAP_TYPE_OFFSET] | ||
295 | cmp r1, #0x1 @ Check for HS device | ||
296 | bne set_gp_por | ||
297 | ldr r0, =OMAP4_PPA_L2_POR_INDEX | ||
298 | ldr r1, =OMAP44XX_SAR_RAM_BASE | ||
299 | ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET] | ||
300 | adr r3, ppa_por_params | ||
301 | str r4, [r3, #0x04] | ||
302 | mov r1, #0x0 @ Process ID | ||
303 | mov r2, #0x4 @ Flag | ||
304 | mov r6, #0xff | ||
305 | mov r12, #0x00 @ Secure Service ID | ||
306 | DO_SMC | ||
307 | b set_aux_ctrl | ||
308 | set_gp_por: | ||
309 | ldr r1, =OMAP44XX_SAR_RAM_BASE | ||
310 | ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET] | ||
311 | ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH | ||
312 | DO_SMC | ||
313 | set_aux_ctrl: | ||
314 | ldr r1, =OMAP44XX_SAR_RAM_BASE | ||
315 | ldr r0, [r1, #L2X0_AUXCTRL_OFFSET] | ||
316 | ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL | ||
317 | DO_SMC | ||
318 | mov r0, #0x1 | ||
319 | ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache | ||
320 | DO_SMC | ||
321 | skip_l2en: | ||
322 | #endif | ||
323 | |||
324 | b cpu_resume @ Jump to generic resume | ||
325 | ENDPROC(omap4_cpu_resume) | ||
326 | #endif | ||
327 | |||
328 | #ifndef CONFIG_OMAP4_ERRATA_I688 | ||
329 | ENTRY(omap_bus_sync) | ||
330 | mov pc, lr | ||
331 | ENDPROC(omap_bus_sync) | ||
332 | #endif | ||
333 | |||
334 | ENTRY(omap_do_wfi) | ||
335 | stmfd sp!, {lr} | ||
336 | /* Drain interconnect write buffers. */ | ||
337 | bl omap_bus_sync | ||
338 | |||
339 | /* | ||
340 | * Execute an ISB instruction to ensure that all of the | ||
341 | * CP15 register changes have been committed. | ||
342 | */ | ||
343 | isb | ||
344 | |||
345 | /* | ||
346 | * Execute a barrier instruction to ensure that all cache, | ||
347 | * TLB and branch predictor maintenance operations issued | ||
348 | * by any CPU in the cluster have completed. | ||
349 | */ | ||
350 | dsb | ||
351 | dmb | ||
352 | |||
353 | /* | ||
354 | * Execute a WFI instruction and wait until the | ||
355 | * STANDBYWFI output is asserted to indicate that the | ||
356 | * CPU is in idle and low power state. CPU can specualatively | ||
357 | * prefetch the instructions so add NOPs after WFI. Sixteen | ||
358 | * NOPs as per Cortex-A9 pipeline. | ||
359 | */ | ||
360 | wfi @ Wait For Interrupt | ||
361 | nop | ||
362 | nop | ||
363 | nop | ||
364 | nop | ||
365 | nop | ||
366 | nop | ||
367 | nop | ||
368 | nop | ||
369 | nop | ||
370 | nop | ||
371 | nop | ||
372 | nop | ||
373 | nop | ||
374 | nop | ||
375 | nop | ||
376 | nop | ||
377 | |||
378 | ldmfd sp!, {pc} | ||
379 | ENDPROC(omap_do_wfi) | ||
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c index 9dd93453e563..7e755bb0ffc4 100644 --- a/arch/arm/mach-omap2/smartreflex.c +++ b/arch/arm/mach-omap2/smartreflex.c | |||
@@ -897,7 +897,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) | |||
897 | ret = sr_late_init(sr_info); | 897 | ret = sr_late_init(sr_info); |
898 | if (ret) { | 898 | if (ret) { |
899 | pr_warning("%s: Error in SR late init\n", __func__); | 899 | pr_warning("%s: Error in SR late init\n", __func__); |
900 | return ret; | 900 | goto err_iounmap; |
901 | } | 901 | } |
902 | } | 902 | } |
903 | 903 | ||
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 9edcd520510f..5c9acea95761 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -254,7 +254,6 @@ static struct omap_dm_timer clksrc; | |||
254 | /* | 254 | /* |
255 | * clocksource | 255 | * clocksource |
256 | */ | 256 | */ |
257 | static DEFINE_CLOCK_DATA(cd); | ||
258 | static cycle_t clocksource_read_cycles(struct clocksource *cs) | 257 | static cycle_t clocksource_read_cycles(struct clocksource *cs) |
259 | { | 258 | { |
260 | return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1); | 259 | return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1); |
@@ -268,23 +267,12 @@ static struct clocksource clocksource_gpt = { | |||
268 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 267 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
269 | }; | 268 | }; |
270 | 269 | ||
271 | static void notrace dmtimer_update_sched_clock(void) | 270 | static u32 notrace dmtimer_read_sched_clock(void) |
272 | { | 271 | { |
273 | u32 cyc; | ||
274 | |||
275 | cyc = __omap_dm_timer_read_counter(&clksrc, 1); | ||
276 | |||
277 | update_sched_clock(&cd, cyc, (u32)~0); | ||
278 | } | ||
279 | |||
280 | unsigned long long notrace sched_clock(void) | ||
281 | { | ||
282 | u32 cyc = 0; | ||
283 | |||
284 | if (clksrc.reserved) | 272 | if (clksrc.reserved) |
285 | cyc = __omap_dm_timer_read_counter(&clksrc, 1); | 273 | return __omap_dm_timer_read_counter(&clksrc, 1); |
286 | 274 | ||
287 | return cyc_to_sched_clock(&cd, cyc, (u32)~0); | 275 | return 0; |
288 | } | 276 | } |
289 | 277 | ||
290 | /* Setup free-running counter for clocksource */ | 278 | /* Setup free-running counter for clocksource */ |
@@ -301,7 +289,7 @@ static void __init omap2_gp_clocksource_init(int gptimer_id, | |||
301 | 289 | ||
302 | __omap_dm_timer_load_start(&clksrc, | 290 | __omap_dm_timer_load_start(&clksrc, |
303 | OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); | 291 | OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); |
304 | init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); | 292 | setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate); |
305 | 293 | ||
306 | if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) | 294 | if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) |
307 | pr_err("Could not register clocksource %s\n", | 295 | pr_err("Could not register clocksource %s\n", |
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 89ae29847c59..771dc781b746 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c | |||
@@ -28,51 +28,28 @@ | |||
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/irqs.h> | 29 | #include <mach/irqs.h> |
30 | #include <plat/usb.h> | 30 | #include <plat/usb.h> |
31 | #include <plat/omap_device.h> | ||
31 | 32 | ||
32 | #include "mux.h" | 33 | #include "mux.h" |
33 | 34 | ||
34 | #ifdef CONFIG_MFD_OMAP_USB_HOST | 35 | #ifdef CONFIG_MFD_OMAP_USB_HOST |
35 | 36 | ||
36 | #define OMAP_USBHS_DEVICE "usbhs-omap" | 37 | #define OMAP_USBHS_DEVICE "usbhs_omap" |
37 | 38 | #define USBHS_UHH_HWMODNAME "usb_host_hs" | |
38 | static struct resource usbhs_resources[] = { | 39 | #define USBHS_TLL_HWMODNAME "usb_tll_hs" |
39 | { | ||
40 | .name = "uhh", | ||
41 | .flags = IORESOURCE_MEM, | ||
42 | }, | ||
43 | { | ||
44 | .name = "tll", | ||
45 | .flags = IORESOURCE_MEM, | ||
46 | }, | ||
47 | { | ||
48 | .name = "ehci", | ||
49 | .flags = IORESOURCE_MEM, | ||
50 | }, | ||
51 | { | ||
52 | .name = "ehci-irq", | ||
53 | .flags = IORESOURCE_IRQ, | ||
54 | }, | ||
55 | { | ||
56 | .name = "ohci", | ||
57 | .flags = IORESOURCE_MEM, | ||
58 | }, | ||
59 | { | ||
60 | .name = "ohci-irq", | ||
61 | .flags = IORESOURCE_IRQ, | ||
62 | } | ||
63 | }; | ||
64 | |||
65 | static struct platform_device usbhs_device = { | ||
66 | .name = OMAP_USBHS_DEVICE, | ||
67 | .id = 0, | ||
68 | .num_resources = ARRAY_SIZE(usbhs_resources), | ||
69 | .resource = usbhs_resources, | ||
70 | }; | ||
71 | 40 | ||
72 | static struct usbhs_omap_platform_data usbhs_data; | 41 | static struct usbhs_omap_platform_data usbhs_data; |
73 | static struct ehci_hcd_omap_platform_data ehci_data; | 42 | static struct ehci_hcd_omap_platform_data ehci_data; |
74 | static struct ohci_hcd_omap_platform_data ohci_data; | 43 | static struct ohci_hcd_omap_platform_data ohci_data; |
75 | 44 | ||
45 | static struct omap_device_pm_latency omap_uhhtll_latency[] = { | ||
46 | { | ||
47 | .deactivate_func = omap_device_idle_hwmods, | ||
48 | .activate_func = omap_device_enable_hwmods, | ||
49 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
50 | }, | ||
51 | }; | ||
52 | |||
76 | /* MUX settings for EHCI pins */ | 53 | /* MUX settings for EHCI pins */ |
77 | /* | 54 | /* |
78 | * setup_ehci_io_mux - initialize IO pad mux for USBHOST | 55 | * setup_ehci_io_mux - initialize IO pad mux for USBHOST |
@@ -508,7 +485,10 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) | |||
508 | 485 | ||
509 | void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | 486 | void __init usbhs_init(const struct usbhs_omap_board_data *pdata) |
510 | { | 487 | { |
511 | int i; | 488 | struct omap_hwmod *oh[2]; |
489 | struct omap_device *od; | ||
490 | int bus_id = -1; | ||
491 | int i; | ||
512 | 492 | ||
513 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) { | 493 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) { |
514 | usbhs_data.port_mode[i] = pdata->port_mode[i]; | 494 | usbhs_data.port_mode[i] = pdata->port_mode[i]; |
@@ -523,44 +503,34 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | |||
523 | usbhs_data.ohci_data = &ohci_data; | 503 | usbhs_data.ohci_data = &ohci_data; |
524 | 504 | ||
525 | if (cpu_is_omap34xx()) { | 505 | if (cpu_is_omap34xx()) { |
526 | usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE; | ||
527 | usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1; | ||
528 | usbhs_resources[1].start = OMAP34XX_USBTLL_BASE; | ||
529 | usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1; | ||
530 | usbhs_resources[2].start = OMAP34XX_EHCI_BASE; | ||
531 | usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1; | ||
532 | usbhs_resources[3].start = INT_34XX_EHCI_IRQ; | ||
533 | usbhs_resources[4].start = OMAP34XX_OHCI_BASE; | ||
534 | usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1; | ||
535 | usbhs_resources[5].start = INT_34XX_OHCI_IRQ; | ||
536 | setup_ehci_io_mux(pdata->port_mode); | 506 | setup_ehci_io_mux(pdata->port_mode); |
537 | setup_ohci_io_mux(pdata->port_mode); | 507 | setup_ohci_io_mux(pdata->port_mode); |
538 | } else if (cpu_is_omap44xx()) { | 508 | } else if (cpu_is_omap44xx()) { |
539 | usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE; | ||
540 | usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1; | ||
541 | usbhs_resources[1].start = OMAP44XX_USBTLL_BASE; | ||
542 | usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1; | ||
543 | usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE; | ||
544 | usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1; | ||
545 | usbhs_resources[3].start = OMAP44XX_IRQ_EHCI; | ||
546 | usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE; | ||
547 | usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1; | ||
548 | usbhs_resources[5].start = OMAP44XX_IRQ_OHCI; | ||
549 | setup_4430ehci_io_mux(pdata->port_mode); | 509 | setup_4430ehci_io_mux(pdata->port_mode); |
550 | setup_4430ohci_io_mux(pdata->port_mode); | 510 | setup_4430ohci_io_mux(pdata->port_mode); |
551 | } | 511 | } |
552 | 512 | ||
553 | if (platform_device_add_data(&usbhs_device, | 513 | oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME); |
554 | &usbhs_data, sizeof(usbhs_data)) < 0) { | 514 | if (!oh[0]) { |
555 | printk(KERN_ERR "USBHS platform_device_add_data failed\n"); | 515 | pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME); |
556 | goto init_end; | 516 | return; |
557 | } | 517 | } |
558 | 518 | ||
559 | if (platform_device_register(&usbhs_device) < 0) | 519 | oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME); |
560 | printk(KERN_ERR "USBHS platform_device_register failed\n"); | 520 | if (!oh[1]) { |
521 | pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME); | ||
522 | return; | ||
523 | } | ||
561 | 524 | ||
562 | init_end: | 525 | od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2, |
563 | return; | 526 | (void *)&usbhs_data, sizeof(usbhs_data), |
527 | omap_uhhtll_latency, | ||
528 | ARRAY_SIZE(omap_uhhtll_latency), false); | ||
529 | if (IS_ERR(od)) { | ||
530 | pr_err("Could not build hwmod devices %s,%s\n", | ||
531 | USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME); | ||
532 | return; | ||
533 | } | ||
564 | } | 534 | } |
565 | 535 | ||
566 | #else | 536 | #else |
@@ -570,5 +540,3 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) | |||
570 | } | 540 | } |
571 | 541 | ||
572 | #endif | 542 | #endif |
573 | |||
574 | |||
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 267975086a7b..8d5ed775dd56 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c | |||
@@ -93,6 +93,9 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) | |||
93 | if (cpu_is_omap3517() || cpu_is_omap3505()) { | 93 | if (cpu_is_omap3517() || cpu_is_omap3505()) { |
94 | oh_name = "am35x_otg_hs"; | 94 | oh_name = "am35x_otg_hs"; |
95 | name = "musb-am35x"; | 95 | name = "musb-am35x"; |
96 | } else if (cpu_is_ti81xx()) { | ||
97 | oh_name = "usb_otg_hs"; | ||
98 | name = "musb-ti81xx"; | ||
96 | } else { | 99 | } else { |
97 | oh_name = "usb_otg_hs"; | 100 | oh_name = "usb_otg_hs"; |
98 | name = "musb-omap2430"; | 101 | name = "musb-omap2430"; |
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c index 474559d5b072..c005e2f5e383 100644 --- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c +++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c | |||
@@ -31,6 +31,14 @@ | |||
31 | * VDD data | 31 | * VDD data |
32 | */ | 32 | */ |
33 | 33 | ||
34 | /* OMAP3-common voltagedomain data */ | ||
35 | |||
36 | static struct voltagedomain omap3_voltdm_wkup = { | ||
37 | .name = "wakeup", | ||
38 | }; | ||
39 | |||
40 | /* 34xx/36xx voltagedomain data */ | ||
41 | |||
34 | static const struct omap_vfsm_instance omap3_vdd1_vfsm = { | 42 | static const struct omap_vfsm_instance omap3_vdd1_vfsm = { |
35 | .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET, | 43 | .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET, |
36 | .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK, | 44 | .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK, |
@@ -63,10 +71,6 @@ static struct voltagedomain omap3_voltdm_core = { | |||
63 | .vp = &omap3_vp_core, | 71 | .vp = &omap3_vp_core, |
64 | }; | 72 | }; |
65 | 73 | ||
66 | static struct voltagedomain omap3_voltdm_wkup = { | ||
67 | .name = "wakeup", | ||
68 | }; | ||
69 | |||
70 | static struct voltagedomain *voltagedomains_omap3[] __initdata = { | 74 | static struct voltagedomain *voltagedomains_omap3[] __initdata = { |
71 | &omap3_voltdm_mpu, | 75 | &omap3_voltdm_mpu, |
72 | &omap3_voltdm_core, | 76 | &omap3_voltdm_core, |
@@ -74,11 +78,30 @@ static struct voltagedomain *voltagedomains_omap3[] __initdata = { | |||
74 | NULL, | 78 | NULL, |
75 | }; | 79 | }; |
76 | 80 | ||
81 | /* AM35xx voltagedomain data */ | ||
82 | |||
83 | static struct voltagedomain am35xx_voltdm_mpu = { | ||
84 | .name = "mpu_iva", | ||
85 | }; | ||
86 | |||
87 | static struct voltagedomain am35xx_voltdm_core = { | ||
88 | .name = "core", | ||
89 | }; | ||
90 | |||
91 | static struct voltagedomain *voltagedomains_am35xx[] __initdata = { | ||
92 | &am35xx_voltdm_mpu, | ||
93 | &am35xx_voltdm_core, | ||
94 | &omap3_voltdm_wkup, | ||
95 | NULL, | ||
96 | }; | ||
97 | |||
98 | |||
77 | static const char *sys_clk_name __initdata = "sys_ck"; | 99 | static const char *sys_clk_name __initdata = "sys_ck"; |
78 | 100 | ||
79 | void __init omap3xxx_voltagedomains_init(void) | 101 | void __init omap3xxx_voltagedomains_init(void) |
80 | { | 102 | { |
81 | struct voltagedomain *voltdm; | 103 | struct voltagedomain *voltdm; |
104 | struct voltagedomain **voltdms; | ||
82 | int i; | 105 | int i; |
83 | 106 | ||
84 | /* | 107 | /* |
@@ -93,8 +116,13 @@ void __init omap3xxx_voltagedomains_init(void) | |||
93 | omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data; | 116 | omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data; |
94 | } | 117 | } |
95 | 118 | ||
96 | for (i = 0; voltdm = voltagedomains_omap3[i], voltdm; i++) | 119 | if (cpu_is_omap3517() || cpu_is_omap3505()) |
120 | voltdms = voltagedomains_am35xx; | ||
121 | else | ||
122 | voltdms = voltagedomains_omap3; | ||
123 | |||
124 | for (i = 0; voltdm = voltdms[i], voltdm; i++) | ||
97 | voltdm->sys_clk.name = sys_clk_name; | 125 | voltdm->sys_clk.name = sys_clk_name; |
98 | 126 | ||
99 | voltdm_init(voltagedomains_omap3); | 127 | voltdm_init(voltdms); |
100 | }; | 128 | }; |