diff options
author | Kevin Hilman <khilman@deeprootsystems.com> | 2009-10-06 17:30:23 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-11-11 17:42:28 -0500 |
commit | d7814e4df6e9c54680a30de3f439c66a2a55ce94 (patch) | |
tree | d516729e2ec5203adf9325ca77a4a00672adfd85 /arch | |
parent | c40552bc82166adb21a1a7fcb1dc4e76352b1b79 (diff) |
PM debug: allow configurable wakeup from suspend on OMAP GPtimer
Using debugfs, export a configurable wakeup timer to be used to
wakeup system from suspend.
If a non-zero value is written to
/debug/pm_debug/wakeup_timer_seconds, A timer wakeup event will wake
the system and resume after the configured number of seconds.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/pm-debug.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer-gp.c | 2 |
4 files changed, 28 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 1725da3f4e18..8baa30d2acfb 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -596,6 +596,8 @@ static int __init pm_dbg_init(void) | |||
596 | &enable_off_mode, &pm_dbg_option_fops); | 596 | &enable_off_mode, &pm_dbg_option_fops); |
597 | (void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUGO, d, | 597 | (void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUGO, d, |
598 | &sleep_while_idle, &pm_dbg_option_fops); | 598 | &sleep_while_idle, &pm_dbg_option_fops); |
599 | (void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUGO, d, | ||
600 | &wakeup_timer_seconds, &pm_dbg_option_fops); | ||
599 | pm_dbg_init_done = 1; | 601 | pm_dbg_init_done = 1; |
600 | 602 | ||
601 | return 0; | 603 | return 0; |
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 9582793ce82d..7eb769f4ef30 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -22,6 +22,9 @@ extern void omap3_pm_off_mode_enable(int); | |||
22 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); | 22 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); |
23 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); | 23 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); |
24 | 24 | ||
25 | extern u32 wakeup_timer_seconds; | ||
26 | extern struct omap_dm_timer *gptimer_wakeup; | ||
27 | |||
25 | #ifdef CONFIG_PM_DEBUG | 28 | #ifdef CONFIG_PM_DEBUG |
26 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); | 29 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); |
27 | extern int omap2_pm_debug; | 30 | extern int omap2_pm_debug; |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index ade2e4a6bb7d..ff818aaec6c5 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <plat/prcm.h> | 36 | #include <plat/prcm.h> |
37 | #include <plat/gpmc.h> | 37 | #include <plat/gpmc.h> |
38 | #include <plat/dma.h> | 38 | #include <plat/dma.h> |
39 | #include <plat/dmtimer.h> | ||
39 | 40 | ||
40 | #include <asm/tlbflush.h> | 41 | #include <asm/tlbflush.h> |
41 | 42 | ||
@@ -60,6 +61,7 @@ | |||
60 | 61 | ||
61 | u32 enable_off_mode; | 62 | u32 enable_off_mode; |
62 | u32 sleep_while_idle; | 63 | u32 sleep_while_idle; |
64 | u32 wakeup_timer_seconds; | ||
63 | 65 | ||
64 | struct power_state { | 66 | struct power_state { |
65 | struct powerdomain *pwrdm; | 67 | struct powerdomain *pwrdm; |
@@ -535,6 +537,22 @@ out: | |||
535 | #ifdef CONFIG_SUSPEND | 537 | #ifdef CONFIG_SUSPEND |
536 | static suspend_state_t suspend_state; | 538 | static suspend_state_t suspend_state; |
537 | 539 | ||
540 | static void omap2_pm_wakeup_on_timer(u32 seconds) | ||
541 | { | ||
542 | u32 tick_rate, cycles; | ||
543 | |||
544 | if (!seconds) | ||
545 | return; | ||
546 | |||
547 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
548 | cycles = tick_rate * seconds; | ||
549 | omap_dm_timer_stop(gptimer_wakeup); | ||
550 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
551 | |||
552 | pr_info("PM: Resume timer in %d secs (%d ticks at %d ticks/sec.)\n", | ||
553 | seconds, cycles, tick_rate); | ||
554 | } | ||
555 | |||
538 | static int omap3_pm_prepare(void) | 556 | static int omap3_pm_prepare(void) |
539 | { | 557 | { |
540 | disable_hlt(); | 558 | disable_hlt(); |
@@ -546,6 +564,9 @@ static int omap3_pm_suspend(void) | |||
546 | struct power_state *pwrst; | 564 | struct power_state *pwrst; |
547 | int state, ret = 0; | 565 | int state, ret = 0; |
548 | 566 | ||
567 | if (wakeup_timer_seconds) | ||
568 | omap2_pm_wakeup_on_timer(wakeup_timer_seconds); | ||
569 | |||
549 | /* Read current next_pwrsts */ | 570 | /* Read current next_pwrsts */ |
550 | list_for_each_entry(pwrst, &pwrst_list, node) | 571 | list_for_each_entry(pwrst, &pwrst_list, node) |
551 | pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); | 572 | pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); |
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index df2b7094de98..cd04deaa88c5 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -47,6 +47,7 @@ static struct omap_dm_timer *gptimer; | |||
47 | static struct clock_event_device clockevent_gpt; | 47 | static struct clock_event_device clockevent_gpt; |
48 | static u8 __initdata gptimer_id = 1; | 48 | static u8 __initdata gptimer_id = 1; |
49 | static u8 __initdata inited; | 49 | static u8 __initdata inited; |
50 | struct omap_dm_timer *gptimer_wakeup; | ||
50 | 51 | ||
51 | static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) | 52 | static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) |
52 | { | 53 | { |
@@ -134,6 +135,7 @@ static void __init omap2_gp_clockevent_init(void) | |||
134 | 135 | ||
135 | gptimer = omap_dm_timer_request_specific(gptimer_id); | 136 | gptimer = omap_dm_timer_request_specific(gptimer_id); |
136 | BUG_ON(gptimer == NULL); | 137 | BUG_ON(gptimer == NULL); |
138 | gptimer_wakeup = gptimer; | ||
137 | 139 | ||
138 | #if defined(CONFIG_OMAP_32K_TIMER) | 140 | #if defined(CONFIG_OMAP_32K_TIMER) |
139 | src = OMAP_TIMER_SRC_32_KHZ; | 141 | src = OMAP_TIMER_SRC_32_KHZ; |