summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorScott Williams <scwilliams@nvidia.com>2011-07-21 17:26:07 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:46:51 -0800
commit9ca84c0c18f9e0435b8e7bd241a2662484165271 (patch)
treebcc17a5976978a7a4e1df0eb2a1a83ac9dc4b200 /arch
parentf16ace672ec41b4abcf605c3be4cf0dbdc235acb (diff)
ARM: tegra: Prevent LP2 if request is less than target residency
Change-Id: Icc7409b611439ba94ec504579c00ab9227c9a857 Signed-off-by: Scott Williams <scwilliams@nvidia.com> DW: Split into logical changes Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com> Rebase-Id: R4b56e98c821627de480a67c241363608ebfc2f07
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/cpuidle-t2.c19
-rw-r--r--arch/arm/mach-tegra/cpuidle.c3
-rw-r--r--arch/arm/mach-tegra/cpuidle.h10
3 files changed, 31 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/cpuidle-t2.c b/arch/arm/mach-tegra/cpuidle-t2.c
index 7eba1ab4bee9..446dea09479e 100644
--- a/arch/arm/mach-tegra/cpuidle-t2.c
+++ b/arch/arm/mach-tegra/cpuidle-t2.c
@@ -135,6 +135,19 @@ static int tegra2_reset_other_cpus(int cpu)
}
#endif
+bool tegra2_lp2_is_allowed(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ s64 request = ktime_to_us(tick_nohz_get_sleep_length());
+
+ if (request < state->target_residency) {
+ /* Not enough time left to enter LP2 */
+ return false;
+ }
+
+ return true;
+}
+
static int tegra2_idle_lp2_last(struct cpuidle_device *dev,
struct cpuidle_state *state, s64 request)
{
@@ -146,6 +159,12 @@ static int tegra2_idle_lp2_last(struct cpuidle_device *dev,
if (tegra2_reset_other_cpus(dev->cpu))
return -EBUSY;
+ if (request < state->target_residency) {
+ /* Not enough time left to enter LP2 */
+ tegra_cpu_wfi();
+ return -EBUSY;
+ }
+
tegra_idle_lp2_last(request, 0);
for_each_online_cpu(i) {
diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c
index d1061fb850ef..712ac003224f 100644
--- a/arch/arm/mach-tegra/cpuidle.c
+++ b/arch/arm/mach-tegra/cpuidle.c
@@ -99,7 +99,8 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
ktime_t enter, exit;
s64 us;
- if (!lp2_in_idle || lp2_disabled_by_suspend)
+ if (!lp2_in_idle || lp2_disabled_by_suspend ||
+ !tegra_lp2_is_allowed(dev, state))
return tegra_idle_enter_lp3(dev, state);
local_irq_disable();
diff --git a/arch/arm/mach-tegra/cpuidle.h b/arch/arm/mach-tegra/cpuidle.h
index c0fbb45a0f38..8f17ba66aa85 100644
--- a/arch/arm/mach-tegra/cpuidle.h
+++ b/arch/arm/mach-tegra/cpuidle.h
@@ -27,6 +27,8 @@
void tegra2_idle_lp2(struct cpuidle_device *dev, struct cpuidle_state *state);
void tegra2_cpu_idle_stats_lp2_ready(unsigned int cpu);
void tegra2_cpu_idle_stats_lp2_time(unsigned int cpu, s64 us);
+bool tegra2_lp2_is_allowed(struct cpuidle_device *dev,
+ struct cpuidle_state *state);
#ifdef CONFIG_DEBUG_FS
int tegra2_lp2_debug_show(struct seq_file *s, void *data);
#endif
@@ -54,6 +56,14 @@ static inline void tegra_idle_lp2(struct cpuidle_device *dev,
#endif
}
+static inline bool tegra_lp2_is_allowed(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ return tegra2_lp2_is_allowed(dev, state);
+#endif
+}
+
#ifdef CONFIG_DEBUG_FS
static inline int tegra_lp2_debug_show(struct seq_file *s, void *data)
{