From 3f4bac202b1c826de3ca9fe599e46f045e04147b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 30 May 2012 10:03:13 -0700 Subject: [PATCH] msm: pm: Add API to get deep idle latency Previously a driver could grab an idle wakelock and prevent the deep idle sleep states associated with remote processor assisted power collapse (either via the modem or the RPM). With the removal of idle wakelocks we must replace them with equivalent upstream compatabile APIs. Since the drivers are actually expressing their desire to prevent certain CPU latencys add an API to expose the latency of deep idle sleep to drivers. It's expected that this API will be removed once drivers properly specify their latency requirements. Change-Id: Iebeb17009fca1486fddda4f78f4952080096234a Signed-off-by: Stephen Boyd --- arch/arm/mach-msm/include/mach/cpuidle.h | 5 +++-- arch/arm/mach-msm/lpm_levels.c | 23 +++++++++++++++++++++++ arch/arm/mach-msm/pm2.c | 6 ++++++ arch/arm/mach-msm/rpm_resources.c | 23 +++++++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-msm/include/mach/cpuidle.h b/arch/arm/mach-msm/include/mach/cpuidle.h index 654121f244e..2a5aa975e65 100644 --- a/arch/arm/mach-msm/include/mach/cpuidle.h +++ b/arch/arm/mach-msm/include/mach/cpuidle.h @@ -26,10 +26,11 @@ struct msm_cpuidle_state { }; #ifdef CONFIG_CPU_IDLE +s32 msm_cpuidle_get_deep_idle_latency(void); int msm_cpuidle_init(void); #else -static inline int msm_cpuidle_init(void) -{ return -ENOSYS; } +static inline int msm_cpuidle_init(void) { return -ENOSYS; } +static inline s32 msm_cpuidle_get_deep_idle_latency(void) { return 0; } #endif #ifdef CONFIG_MSM_SLEEP_STATS diff --git a/arch/arm/mach-msm/lpm_levels.c b/arch/arm/mach-msm/lpm_levels.c index 80b82cbcf62..a1f5ff5595e 100644 --- a/arch/arm/mach-msm/lpm_levels.c +++ b/arch/arm/mach-msm/lpm_levels.c @@ -51,6 +51,29 @@ void msm_rpmrs_show_resources(void) return; } +s32 msm_cpuidle_get_deep_idle_latency(void) +{ + int i; + struct msm_rpmrs_level *level = msm_lpm_levels, *best = level; + + if (!level) + return 0; + + for (i = 0; i < msm_lpm_level_count; i++, level++) { + if (!level->available) + continue; + if (level->sleep_mode != MSM_PM_SLEEP_MODE_POWER_COLLAPSE) + continue; + /* Pick the first power collapse mode by default */ + if (best->sleep_mode != MSM_PM_SLEEP_MODE_POWER_COLLAPSE) + best = level; + /* Find the lowest latency for power collapse */ + if (level->latency_us < best->latency_us) + best = level; + } + return best->latency_us - 1; +} + static void *msm_lpm_lowest_limits(bool from_idle, enum msm_pm_sleep_mode sleep_mode, uint32_t latency_us, uint32_t sleep_us, uint32_t *power) diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c index bac6ef8e4bd..748d6124129 100644 --- a/arch/arm/mach-msm/pm2.c +++ b/arch/arm/mach-msm/pm2.c @@ -394,6 +394,12 @@ mode_sysfs_add_exit: return ret; } +s32 msm_cpuidle_get_deep_idle_latency(void) +{ + int i = MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN); + return msm_pm_modes[i].latency - 1; +} + void __init msm_pm_set_platform_data( struct msm_pm_platform_data *data, int count) { diff --git a/arch/arm/mach-msm/rpm_resources.c b/arch/arm/mach-msm/rpm_resources.c index 5314cee6d16..c86da6a7347 100644 --- a/arch/arm/mach-msm/rpm_resources.c +++ b/arch/arm/mach-msm/rpm_resources.c @@ -867,6 +867,29 @@ void msm_rpmrs_show_resources(void) spin_unlock_irqrestore(&msm_rpmrs_lock, flags); } +s32 msm_cpuidle_get_deep_idle_latency(void) +{ + int i; + struct msm_rpmrs_level *level = msm_rpmrs_levels, *best = level; + + if (!level) + return 0; + + for (i = 0; i < msm_rpmrs_level_count; i++, level++) { + if (!level->available) + continue; + if (level->sleep_mode != MSM_PM_SLEEP_MODE_POWER_COLLAPSE) + continue; + /* Pick the first power collapse mode by default */ + if (best->sleep_mode != MSM_PM_SLEEP_MODE_POWER_COLLAPSE) + best = level; + /* Find the lowest latency for power collapse */ + if (level->latency_us < best->latency_us) + best = level; + } + return best->latency_us - 1; +} + static void *msm_rpmrs_lowest_limits(bool from_idle, enum msm_pm_sleep_mode sleep_mode, uint32_t latency_us, uint32_t sleep_us, uint32_t *power)