diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-omap2/board-3430sdp.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-omap3evm.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm-debug.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 58 |
5 files changed, 41 insertions, 28 deletions
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 5822bcf7b15f..e7d629b3c76a 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c | |||
@@ -150,6 +150,7 @@ static int ads7846_get_pendown_state(void) | |||
150 | static struct ads7846_platform_data tsc2046_config __initdata = { | 150 | static struct ads7846_platform_data tsc2046_config __initdata = { |
151 | .get_pendown_state = ads7846_get_pendown_state, | 151 | .get_pendown_state = ads7846_get_pendown_state, |
152 | .keep_vref_on = 1, | 152 | .keep_vref_on = 1, |
153 | .wakeup = true, | ||
153 | }; | 154 | }; |
154 | 155 | ||
155 | 156 | ||
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c index 017bb2f4f7d2..cfbe695103d0 100644 --- a/arch/arm/mach-omap2/board-omap3evm.c +++ b/arch/arm/mach-omap2/board-omap3evm.c | |||
@@ -600,6 +600,7 @@ struct ads7846_platform_data ads7846_config = { | |||
600 | .get_pendown_state = ads7846_get_pendown_state, | 600 | .get_pendown_state = ads7846_get_pendown_state, |
601 | .keep_vref_on = 1, | 601 | .keep_vref_on = 1, |
602 | .settle_delay_usecs = 150, | 602 | .settle_delay_usecs = 150, |
603 | .wakeup = true, | ||
603 | }; | 604 | }; |
604 | 605 | ||
605 | static struct omap2_mcspi_device_config ads7846_mcspi_config = { | 606 | static struct omap2_mcspi_device_config ads7846_mcspi_config = { |
@@ -651,11 +652,10 @@ static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { | |||
651 | #ifdef CONFIG_OMAP_MUX | 652 | #ifdef CONFIG_OMAP_MUX |
652 | static struct omap_board_mux board_mux[] __initdata = { | 653 | static struct omap_board_mux board_mux[] __initdata = { |
653 | OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | | 654 | OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | |
654 | OMAP_PIN_OFF_INPUT_PULLUP | | 655 | OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | |
655 | OMAP_PIN_OFF_WAKEUPENABLE), | 656 | OMAP_PIN_OFF_WAKEUPENABLE), |
656 | OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | | 657 | OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | |
657 | OMAP_PIN_OFF_INPUT_PULLUP | | 658 | OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW), |
658 | OMAP_PIN_OFF_WAKEUPENABLE), | ||
659 | { .reg_offset = OMAP_MUX_TERMINATOR }, | 659 | { .reg_offset = OMAP_MUX_TERMINATOR }, |
660 | }; | 660 | }; |
661 | #else | 661 | #else |
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 6cac9817c243..723b44e252fd 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -548,6 +548,9 @@ static int option_set(void *data, u64 val) | |||
548 | { | 548 | { |
549 | u32 *option = data; | 549 | u32 *option = data; |
550 | 550 | ||
551 | if (option == &wakeup_timer_milliseconds && val >= 1000) | ||
552 | return -EINVAL; | ||
553 | |||
551 | *option = val; | 554 | *option = val; |
552 | 555 | ||
553 | if (option == &enable_off_mode) | 556 | if (option == &enable_off_mode) |
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index bd6466a2b039..3de6ece23fc8 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -43,6 +43,7 @@ extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); | |||
43 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); | 43 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); |
44 | 44 | ||
45 | extern u32 wakeup_timer_seconds; | 45 | extern u32 wakeup_timer_seconds; |
46 | extern u32 wakeup_timer_milliseconds; | ||
46 | extern struct omap_dm_timer *gptimer_wakeup; | 47 | extern struct omap_dm_timer *gptimer_wakeup; |
47 | 48 | ||
48 | #ifdef CONFIG_PM_DEBUG | 49 | #ifdef CONFIG_PM_DEBUG |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 468e1e3321e0..24c1966f935e 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -58,6 +58,7 @@ | |||
58 | u32 enable_off_mode; | 58 | u32 enable_off_mode; |
59 | u32 sleep_while_idle; | 59 | u32 sleep_while_idle; |
60 | u32 wakeup_timer_seconds; | 60 | u32 wakeup_timer_seconds; |
61 | u32 wakeup_timer_milliseconds; | ||
61 | 62 | ||
62 | struct power_state { | 63 | struct power_state { |
63 | struct powerdomain *pwrdm; | 64 | struct powerdomain *pwrdm; |
@@ -267,13 +268,16 @@ static int _prcm_int_handle_wakeup(void) | |||
267 | */ | 268 | */ |
268 | static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) | 269 | static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) |
269 | { | 270 | { |
270 | u32 irqstatus_mpu; | 271 | u32 irqenable_mpu, irqstatus_mpu; |
271 | int c = 0; | 272 | int c = 0; |
272 | 273 | ||
273 | do { | 274 | irqenable_mpu = prm_read_mod_reg(OCP_MOD, |
274 | irqstatus_mpu = prm_read_mod_reg(OCP_MOD, | 275 | OMAP3_PRM_IRQENABLE_MPU_OFFSET); |
275 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | 276 | irqstatus_mpu = prm_read_mod_reg(OCP_MOD, |
277 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
278 | irqstatus_mpu &= irqenable_mpu; | ||
276 | 279 | ||
280 | do { | ||
277 | if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) { | 281 | if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) { |
278 | c = _prcm_int_handle_wakeup(); | 282 | c = _prcm_int_handle_wakeup(); |
279 | 283 | ||
@@ -292,7 +296,11 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) | |||
292 | prm_write_mod_reg(irqstatus_mpu, OCP_MOD, | 296 | prm_write_mod_reg(irqstatus_mpu, OCP_MOD, |
293 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | 297 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); |
294 | 298 | ||
295 | } while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET)); | 299 | irqstatus_mpu = prm_read_mod_reg(OCP_MOD, |
300 | OMAP3_PRM_IRQSTATUS_MPU_OFFSET); | ||
301 | irqstatus_mpu &= irqenable_mpu; | ||
302 | |||
303 | } while (irqstatus_mpu); | ||
296 | 304 | ||
297 | return IRQ_HANDLED; | 305 | return IRQ_HANDLED; |
298 | } | 306 | } |
@@ -371,9 +379,16 @@ void omap_sram_idle(void) | |||
371 | if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON) | 379 | if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON) |
372 | pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state); | 380 | pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state); |
373 | 381 | ||
374 | /* PER */ | 382 | /* Enable IO-PAD and IO-CHAIN wakeups */ |
375 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); | 383 | per_next_state = pwrdm_read_next_pwrst(per_pwrdm); |
376 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); | 384 | core_next_state = pwrdm_read_next_pwrst(core_pwrdm); |
385 | if (per_next_state < PWRDM_POWER_ON || | ||
386 | core_next_state < PWRDM_POWER_ON) { | ||
387 | prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); | ||
388 | omap3_enable_io_chain(); | ||
389 | } | ||
390 | |||
391 | /* PER */ | ||
377 | if (per_next_state < PWRDM_POWER_ON) { | 392 | if (per_next_state < PWRDM_POWER_ON) { |
378 | omap_uart_prepare_idle(2); | 393 | omap_uart_prepare_idle(2); |
379 | omap2_gpio_prepare_for_idle(per_next_state); | 394 | omap2_gpio_prepare_for_idle(per_next_state); |
@@ -398,10 +413,8 @@ void omap_sram_idle(void) | |||
398 | omap3_core_save_context(); | 413 | omap3_core_save_context(); |
399 | omap3_prcm_save_context(); | 414 | omap3_prcm_save_context(); |
400 | } | 415 | } |
401 | /* Enable IO-PAD and IO-CHAIN wakeups */ | ||
402 | prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); | ||
403 | omap3_enable_io_chain(); | ||
404 | } | 416 | } |
417 | |||
405 | omap3_intc_prepare_idle(); | 418 | omap3_intc_prepare_idle(); |
406 | 419 | ||
407 | /* | 420 | /* |
@@ -463,7 +476,8 @@ void omap_sram_idle(void) | |||
463 | } | 476 | } |
464 | 477 | ||
465 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 478 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
466 | if (core_next_state < PWRDM_POWER_ON) { | 479 | if (per_next_state < PWRDM_POWER_ON || |
480 | core_next_state < PWRDM_POWER_ON) { | ||
467 | prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); | 481 | prm_clear_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); |
468 | omap3_disable_io_chain(); | 482 | omap3_disable_io_chain(); |
469 | } | 483 | } |
@@ -548,20 +562,21 @@ out: | |||
548 | #ifdef CONFIG_SUSPEND | 562 | #ifdef CONFIG_SUSPEND |
549 | static suspend_state_t suspend_state; | 563 | static suspend_state_t suspend_state; |
550 | 564 | ||
551 | static void omap2_pm_wakeup_on_timer(u32 seconds) | 565 | static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) |
552 | { | 566 | { |
553 | u32 tick_rate, cycles; | 567 | u32 tick_rate, cycles; |
554 | 568 | ||
555 | if (!seconds) | 569 | if (!seconds && !milliseconds) |
556 | return; | 570 | return; |
557 | 571 | ||
558 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | 572 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); |
559 | cycles = tick_rate * seconds; | 573 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; |
560 | omap_dm_timer_stop(gptimer_wakeup); | 574 | omap_dm_timer_stop(gptimer_wakeup); |
561 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | 575 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); |
562 | 576 | ||
563 | pr_info("PM: Resume timer in %d secs (%d ticks at %d ticks/sec.)\n", | 577 | pr_info("PM: Resume timer in %u.%03u secs" |
564 | seconds, cycles, tick_rate); | 578 | " (%d ticks at %d ticks/sec.)\n", |
579 | seconds, milliseconds, cycles, tick_rate); | ||
565 | } | 580 | } |
566 | 581 | ||
567 | static int omap3_pm_prepare(void) | 582 | static int omap3_pm_prepare(void) |
@@ -575,8 +590,9 @@ static int omap3_pm_suspend(void) | |||
575 | struct power_state *pwrst; | 590 | struct power_state *pwrst; |
576 | int state, ret = 0; | 591 | int state, ret = 0; |
577 | 592 | ||
578 | if (wakeup_timer_seconds) | 593 | if (wakeup_timer_seconds || wakeup_timer_milliseconds) |
579 | omap2_pm_wakeup_on_timer(wakeup_timer_seconds); | 594 | omap2_pm_wakeup_on_timer(wakeup_timer_seconds, |
595 | wakeup_timer_milliseconds); | ||
580 | 596 | ||
581 | /* Read current next_pwrsts */ | 597 | /* Read current next_pwrsts */ |
582 | list_for_each_entry(pwrst, &pwrst_list, node) | 598 | list_for_each_entry(pwrst, &pwrst_list, node) |
@@ -1080,14 +1096,6 @@ static int __init omap3_pm_init(void) | |||
1080 | omap3_idle_init(); | 1096 | omap3_idle_init(); |
1081 | 1097 | ||
1082 | clkdm_add_wkdep(neon_clkdm, mpu_clkdm); | 1098 | clkdm_add_wkdep(neon_clkdm, mpu_clkdm); |
1083 | /* | ||
1084 | * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for | ||
1085 | * IO-pad wakeup. Otherwise it will unnecessarily waste power | ||
1086 | * waking up PER with every CORE wakeup - see | ||
1087 | * http://marc.info/?l=linux-omap&m=121852150710062&w=2 | ||
1088 | */ | ||
1089 | clkdm_add_wkdep(per_clkdm, core_clkdm); | ||
1090 | |||
1091 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { | 1099 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { |
1092 | omap3_secure_ram_storage = | 1100 | omap3_secure_ram_storage = |
1093 | kmalloc(0x803F, GFP_KERNEL); | 1101 | kmalloc(0x803F, GFP_KERNEL); |