aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/cpuidle-tegra30.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/cpuidle-tegra30.c')
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra30.c39
1 files changed, 2 insertions, 37 deletions
diff --git a/arch/arm/mach-tegra/cpuidle-tegra30.c b/arch/arm/mach-tegra/cpuidle-tegra30.c
index 8b50cf4ddd6f..3cf9aca5f3ea 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra30.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra30.c
@@ -43,7 +43,6 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev,
43static struct cpuidle_driver tegra_idle_driver = { 43static struct cpuidle_driver tegra_idle_driver = {
44 .name = "tegra_idle", 44 .name = "tegra_idle",
45 .owner = THIS_MODULE, 45 .owner = THIS_MODULE,
46 .en_core_tk_irqen = 1,
47#ifdef CONFIG_PM_SLEEP 46#ifdef CONFIG_PM_SLEEP
48 .state_count = 2, 47 .state_count = 2,
49#else 48#else
@@ -65,17 +64,11 @@ static struct cpuidle_driver tegra_idle_driver = {
65 }, 64 },
66}; 65};
67 66
68static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
69
70#ifdef CONFIG_PM_SLEEP 67#ifdef CONFIG_PM_SLEEP
71static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev, 68static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
72 struct cpuidle_driver *drv, 69 struct cpuidle_driver *drv,
73 int index) 70 int index)
74{ 71{
75 struct cpuidle_state *state = &drv->states[index];
76 u32 cpu_on_time = state->exit_latency;
77 u32 cpu_off_time = state->target_residency - state->exit_latency;
78
79 /* All CPUs entering LP2 is not working. 72 /* All CPUs entering LP2 is not working.
80 * Don't let CPU0 enter LP2 when any secondary CPU is online. 73 * Don't let CPU0 enter LP2 when any secondary CPU is online.
81 */ 74 */
@@ -86,7 +79,7 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
86 79
87 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); 80 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
88 81
89 tegra_idle_lp2_last(cpu_on_time, cpu_off_time); 82 tegra_idle_lp2_last();
90 83
91 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); 84 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
92 85
@@ -102,12 +95,8 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
102 95
103 smp_wmb(); 96 smp_wmb();
104 97
105 save_cpu_arch_register();
106
107 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); 98 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
108 99
109 restore_cpu_arch_register();
110
111 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); 100 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
112 101
113 return true; 102 return true;
@@ -157,32 +146,8 @@ static int tegra30_idle_lp2(struct cpuidle_device *dev,
157 146
158int __init tegra30_cpuidle_init(void) 147int __init tegra30_cpuidle_init(void)
159{ 148{
160 int ret;
161 unsigned int cpu;
162 struct cpuidle_device *dev;
163 struct cpuidle_driver *drv = &tegra_idle_driver;
164
165#ifdef CONFIG_PM_SLEEP 149#ifdef CONFIG_PM_SLEEP
166 tegra_tear_down_cpu = tegra30_tear_down_cpu; 150 tegra_tear_down_cpu = tegra30_tear_down_cpu;
167#endif 151#endif
168 152 return cpuidle_register(&tegra_idle_driver, NULL);
169 ret = cpuidle_register_driver(&tegra_idle_driver);
170 if (ret) {
171 pr_err("CPUidle driver registration failed\n");
172 return ret;
173 }
174
175 for_each_possible_cpu(cpu) {
176 dev = &per_cpu(tegra_idle_device, cpu);
177 dev->cpu = cpu;
178
179 dev->state_count = drv->state_count;
180 ret = cpuidle_register_device(dev);
181 if (ret) {
182 pr_err("CPU%u: CPUidle device registration failed\n",
183 cpu);
184 return ret;
185 }
186 }
187 return 0;
188} 153}