From 8e2efde9f1ba2fb918245f9419246e4e59b42a11 Mon Sep 17 00:00:00 2001 From: Ari Kauppi Date: Tue, 23 Mar 2010 09:04:59 +0200 Subject: [PATCH] OMAP3: PM: Add milliseconds interface to suspend wakeup timer Millisecond resolution is possible and there are use cases for it (automatic testing). Seconds-based interface is preserved for compatibility. Signed-off-by: Ari Kauppi Reviewed-by: Phil Carmody Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm-debug.c | 3 +++ arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm34xx.c | 17 ++++++++++------- 3 files changed, 14 insertions(+), 7 deletions(-) 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) { u32 *option = data; + if (option == &wakeup_timer_milliseconds && val >= 1000) + return -EINVAL; + *option = val; 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); extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); extern u32 wakeup_timer_seconds; +extern u32 wakeup_timer_milliseconds; extern struct omap_dm_timer *gptimer_wakeup; #ifdef CONFIG_PM_DEBUG diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index a15aa92d384e..e76af5b532a0 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -58,6 +58,7 @@ u32 enable_off_mode; u32 sleep_while_idle; u32 wakeup_timer_seconds; +u32 wakeup_timer_milliseconds; struct power_state { struct powerdomain *pwrdm; @@ -555,20 +556,21 @@ out: #ifdef CONFIG_SUSPEND static suspend_state_t suspend_state; -static void omap2_pm_wakeup_on_timer(u32 seconds) +static void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) { u32 tick_rate, cycles; - if (!seconds) + if (!seconds && !milliseconds) return; tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); - cycles = tick_rate * seconds; + cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; omap_dm_timer_stop(gptimer_wakeup); omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); - pr_info("PM: Resume timer in %d secs (%d ticks at %d ticks/sec.)\n", - seconds, cycles, tick_rate); + pr_info("PM: Resume timer in %u.%03u secs" + " (%d ticks at %d ticks/sec.)\n", + seconds, milliseconds, cycles, tick_rate); } static int omap3_pm_prepare(void) @@ -582,8 +584,9 @@ static int omap3_pm_suspend(void) struct power_state *pwrst; int state, ret = 0; - if (wakeup_timer_seconds) - omap2_pm_wakeup_on_timer(wakeup_timer_seconds); + if (wakeup_timer_seconds || wakeup_timer_milliseconds) + omap2_pm_wakeup_on_timer(wakeup_timer_seconds, + wakeup_timer_milliseconds); /* Read current next_pwrsts */ list_for_each_entry(pwrst, &pwrst_list, node) -- 2.11.0