From 9d63ba29502b2fade968d9ae00e3d328d758eb41 Mon Sep 17 00:00:00 2001 From: Scott Williams Date: Wed, 29 Jun 2011 14:24:31 -0700 Subject: ARM: tegra: power: Restore tegra_cpuidle_pm_notifier registration Restore the registration of the CPU idle power management notifier callback that was removed when porting to Linux 2.6.39. There is no reason why individual CPUs should be trying to go into the LP2 state when the system is suspending. Change-Id: I227948a60fa958b464ceb889d3369fbba2e8c8fd Reviewed-on: http://git-master/r/40462 Tested-by: Daniel Willemsen Reviewed-by: Scott Williams Reviewed-by: Daniel Willemsen Rebase-Id: R27753c83d40b0407204090e94e6948cdc6449e5b --- arch/arm/mach-tegra/cpuidle.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-tegra/cpuidle.c') diff --git a/arch/arm/mach-tegra/cpuidle.c b/arch/arm/mach-tegra/cpuidle.c index 465b8aa1fbc1..3ac61373e186 100644 --- a/arch/arm/mach-tegra/cpuidle.c +++ b/arch/arm/mach-tegra/cpuidle.c @@ -45,6 +45,7 @@ static bool lp2_in_idle __read_mostly = true; module_param(lp2_in_idle, bool, 0644); +static bool lp2_disabled_by_suspend; static struct { unsigned int cpu_ready_count[2]; @@ -99,6 +100,9 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev, ktime_t enter, exit; s64 us; + if (lp2_disabled_by_suspend) + return tegra_idle_enter_lp3(dev, state); + local_irq_disable(); enter = ktime_get(); @@ -135,7 +139,7 @@ static int tegra_idle_prepare(struct cpuidle_device *dev) return 0; } -static int tegra_idle_enter(unsigned int cpu) +static int tegra_cpuidle_register_device(unsigned int cpu) { struct cpuidle_device *dev; struct cpuidle_state *state; @@ -187,26 +191,42 @@ static int tegra_idle_enter(unsigned int cpu) return 0; } +static int tegra_cpuidle_pm_notify(struct notifier_block *nb, + unsigned long event, void *dummy) +{ + if (event == PM_SUSPEND_PREPARE) + lp2_disabled_by_suspend = true; + else if (event == PM_POST_SUSPEND) + lp2_disabled_by_suspend = false; + + return NOTIFY_OK; +} + +static struct notifier_block tegra_cpuidle_pm_notifier = { + .notifier_call = tegra_cpuidle_pm_notify, +}; + static int __init tegra_cpuidle_init(void) { unsigned int cpu; int ret; ret = cpuidle_register_driver(&tegra_idle); - if (ret) return ret; for_each_possible_cpu(cpu) { - if (tegra_idle_enter(cpu)) + if (tegra_cpuidle_register_device(cpu)) pr_err("CPU%u: error initializing idle loop\n", cpu); } + register_pm_notifier(&tegra_cpuidle_pm_notifier); return 0; } static void __exit tegra_cpuidle_exit(void) { + unregister_pm_notifier(&tegra_cpuidle_pm_notifier); cpuidle_unregister_driver(&tegra_idle); } -- cgit v1.2.3