aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu.vizoso@collabora.com>2015-05-19 10:49:12 -0400
committerThierry Reding <treding@nvidia.com>2015-08-13 10:53:38 -0400
commit1ec0e115f8604940491861d207cc1e1478db97b3 (patch)
tree3397eabff039b80e150d86fcf48993ffa3f08512
parentfc0cf1773434c153a831067a29935e4627803583 (diff)
ARM: tegra: cpuidle: implement cpuidle_state.enter_freeze()
This callback is expected to do the same as enter() but it has to guarantee that interrupts aren't enabled at any point in its execution, as the tick is frozen. It will be called when the system goes to suspend-to-idle and will reduce power usage because CPUs won't be awaken for unnecessary IRQs. By setting the CPUIDLE_FLAG_TIMER_STOP flag, we can reuse the same code for both the enter() and enter_freeze() callbacks. Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index bc00dd4a6fb2..9157546fe68c 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -45,16 +45,12 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
45 tegra_set_cpu_in_lp2(); 45 tegra_set_cpu_in_lp2();
46 cpu_pm_enter(); 46 cpu_pm_enter();
47 47
48 tick_broadcast_enter();
49
50 call_firmware_op(prepare_idle); 48 call_firmware_op(prepare_idle);
51 49
52 /* Do suspend by ourselves if the firmware does not implement it */ 50 /* Do suspend by ourselves if the firmware does not implement it */
53 if (call_firmware_op(do_idle, 0) == -ENOSYS) 51 if (call_firmware_op(do_idle, 0) == -ENOSYS)
54 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); 52 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
55 53
56 tick_broadcast_exit();
57
58 cpu_pm_exit(); 54 cpu_pm_exit();
59 tegra_clear_cpu_in_lp2(); 55 tegra_clear_cpu_in_lp2();
60 56
@@ -62,6 +58,13 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
62 58
63 return index; 59 return index;
64} 60}
61
62static void tegra114_idle_enter_freeze(struct cpuidle_device *dev,
63 struct cpuidle_driver *drv,
64 int index)
65{
66 tegra114_idle_power_down(dev, drv, index);
67}
65#endif 68#endif
66 69
67static struct cpuidle_driver tegra_idle_driver = { 70static struct cpuidle_driver tegra_idle_driver = {
@@ -73,8 +76,10 @@ static struct cpuidle_driver tegra_idle_driver = {
73#ifdef CONFIG_PM_SLEEP 76#ifdef CONFIG_PM_SLEEP
74 [1] = { 77 [1] = {
75 .enter = tegra114_idle_power_down, 78 .enter = tegra114_idle_power_down,
79 .enter_freeze = tegra114_idle_enter_freeze,
76 .exit_latency = 500, 80 .exit_latency = 500,
77 .target_residency = 1000, 81 .target_residency = 1000,
82 .flags = CPUIDLE_FLAG_TIMER_STOP,
78 .power_usage = 0, 83 .power_usage = 0,
79 .name = "powered-down", 84 .name = "powered-down",
80 .desc = "CPU power gated", 85 .desc = "CPU power gated",