diff options
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/common.h | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cpuidle34xx.c | 52 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cpuidle44xx.c | 84 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-mpuss-lowpower.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 9 |
5 files changed, 47 insertions, 117 deletions
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index d6ba13e1c540..14522d077c88 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h | |||
@@ -249,7 +249,6 @@ extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state); | |||
249 | extern int omap4_finish_suspend(unsigned long cpu_state); | 249 | extern int omap4_finish_suspend(unsigned long cpu_state); |
250 | extern void omap4_cpu_resume(void); | 250 | extern void omap4_cpu_resume(void); |
251 | extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); | 251 | extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state); |
252 | extern u32 omap4_mpuss_read_prev_context_state(void); | ||
253 | #else | 252 | #else |
254 | static inline int omap4_enter_lowpower(unsigned int cpu, | 253 | static inline int omap4_enter_lowpower(unsigned int cpu, |
255 | unsigned int power_state) | 254 | unsigned int power_state) |
@@ -277,10 +276,6 @@ static inline int omap4_finish_suspend(unsigned long cpu_state) | |||
277 | static inline void omap4_cpu_resume(void) | 276 | static inline void omap4_cpu_resume(void) |
278 | {} | 277 | {} |
279 | 278 | ||
280 | static inline u32 omap4_mpuss_read_prev_context_state(void) | ||
281 | { | ||
282 | return 0; | ||
283 | } | ||
284 | #endif | 279 | #endif |
285 | 280 | ||
286 | struct omap_sdrc_params; | 281 | struct omap_sdrc_params; |
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 80392fca86c6..cca045c95fbf 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/cpuidle.h> | 26 | #include <linux/cpuidle.h> |
27 | #include <linux/export.h> | 27 | #include <linux/export.h> |
28 | #include <linux/cpu_pm.h> | 28 | #include <linux/cpu_pm.h> |
29 | #include <asm/cpuidle.h> | ||
29 | 30 | ||
30 | #include "powerdomain.h" | 31 | #include "powerdomain.h" |
31 | #include "clockdomain.h" | 32 | #include "clockdomain.h" |
@@ -99,11 +100,15 @@ static struct omap3_idle_statedata omap3_idle_data[] = { | |||
99 | }, | 100 | }, |
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* Private functions */ | 103 | /** |
103 | 104 | * omap3_enter_idle - Programs OMAP3 to enter the specified state | |
104 | static int __omap3_enter_idle(struct cpuidle_device *dev, | 105 | * @dev: cpuidle device |
105 | struct cpuidle_driver *drv, | 106 | * @drv: cpuidle driver |
106 | int index) | 107 | * @index: the index of state to be entered |
108 | */ | ||
109 | static int omap3_enter_idle(struct cpuidle_device *dev, | ||
110 | struct cpuidle_driver *drv, | ||
111 | int index) | ||
107 | { | 112 | { |
108 | struct omap3_idle_statedata *cx = &omap3_idle_data[index]; | 113 | struct omap3_idle_statedata *cx = &omap3_idle_data[index]; |
109 | 114 | ||
@@ -149,22 +154,6 @@ return_sleep_time: | |||
149 | } | 154 | } |
150 | 155 | ||
151 | /** | 156 | /** |
152 | * omap3_enter_idle - Programs OMAP3 to enter the specified state | ||
153 | * @dev: cpuidle device | ||
154 | * @drv: cpuidle driver | ||
155 | * @index: the index of state to be entered | ||
156 | * | ||
157 | * Called from the CPUidle framework to program the device to the | ||
158 | * specified target state selected by the governor. | ||
159 | */ | ||
160 | static inline int omap3_enter_idle(struct cpuidle_device *dev, | ||
161 | struct cpuidle_driver *drv, | ||
162 | int index) | ||
163 | { | ||
164 | return cpuidle_wrap_enter(dev, drv, index, __omap3_enter_idle); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * next_valid_state - Find next valid C-state | 157 | * next_valid_state - Find next valid C-state |
169 | * @dev: cpuidle device | 158 | * @dev: cpuidle device |
170 | * @drv: cpuidle driver | 159 | * @drv: cpuidle driver |
@@ -271,11 +260,9 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, | |||
271 | return ret; | 260 | return ret; |
272 | } | 261 | } |
273 | 262 | ||
274 | static DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev); | ||
275 | |||
276 | static struct cpuidle_driver omap3_idle_driver = { | 263 | static struct cpuidle_driver omap3_idle_driver = { |
277 | .name = "omap3_idle", | 264 | .name = "omap3_idle", |
278 | .owner = THIS_MODULE, | 265 | .owner = THIS_MODULE, |
279 | .states = { | 266 | .states = { |
280 | { | 267 | { |
281 | .enter = omap3_enter_idle_bm, | 268 | .enter = omap3_enter_idle_bm, |
@@ -348,8 +335,6 @@ static struct cpuidle_driver omap3_idle_driver = { | |||
348 | */ | 335 | */ |
349 | int __init omap3_idle_init(void) | 336 | int __init omap3_idle_init(void) |
350 | { | 337 | { |
351 | struct cpuidle_device *dev; | ||
352 | |||
353 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); | 338 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); |
354 | core_pd = pwrdm_lookup("core_pwrdm"); | 339 | core_pd = pwrdm_lookup("core_pwrdm"); |
355 | per_pd = pwrdm_lookup("per_pwrdm"); | 340 | per_pd = pwrdm_lookup("per_pwrdm"); |
@@ -358,16 +343,5 @@ int __init omap3_idle_init(void) | |||
358 | if (!mpu_pd || !core_pd || !per_pd || !cam_pd) | 343 | if (!mpu_pd || !core_pd || !per_pd || !cam_pd) |
359 | return -ENODEV; | 344 | return -ENODEV; |
360 | 345 | ||
361 | cpuidle_register_driver(&omap3_idle_driver); | 346 | return cpuidle_register(&omap3_idle_driver, NULL); |
362 | |||
363 | dev = &per_cpu(omap3_idle_dev, smp_processor_id()); | ||
364 | dev->cpu = 0; | ||
365 | |||
366 | if (cpuidle_register_device(dev)) { | ||
367 | printk(KERN_ERR "%s: CPUidle register device failed\n", | ||
368 | __func__); | ||
369 | return -EIO; | ||
370 | } | ||
371 | |||
372 | return 0; | ||
373 | } | 347 | } |
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index d639aef0deda..5a286b56205e 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP4 CPU idle Routines | 2 | * OMAP4+ CPU idle Routines |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Texas Instruments, Inc. | 4 | * Copyright (C) 2011-2013 Texas Instruments, Inc. |
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | 5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
6 | * Rajendra Nayak <rnayak@ti.com> | 6 | * Rajendra Nayak <rnayak@ti.com> |
7 | * | 7 | * |
@@ -14,8 +14,8 @@ | |||
14 | #include <linux/cpuidle.h> | 14 | #include <linux/cpuidle.h> |
15 | #include <linux/cpu_pm.h> | 15 | #include <linux/cpu_pm.h> |
16 | #include <linux/export.h> | 16 | #include <linux/export.h> |
17 | #include <linux/clockchips.h> | ||
18 | 17 | ||
18 | #include <asm/cpuidle.h> | ||
19 | #include <asm/proc-fns.h> | 19 | #include <asm/proc-fns.h> |
20 | 20 | ||
21 | #include "common.h" | 21 | #include "common.h" |
@@ -24,13 +24,13 @@ | |||
24 | #include "clockdomain.h" | 24 | #include "clockdomain.h" |
25 | 25 | ||
26 | /* Machine specific information */ | 26 | /* Machine specific information */ |
27 | struct omap4_idle_statedata { | 27 | struct idle_statedata { |
28 | u32 cpu_state; | 28 | u32 cpu_state; |
29 | u32 mpu_logic_state; | 29 | u32 mpu_logic_state; |
30 | u32 mpu_state; | 30 | u32 mpu_state; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static struct omap4_idle_statedata omap4_idle_data[] = { | 33 | static struct idle_statedata omap4_idle_data[] = { |
34 | { | 34 | { |
35 | .cpu_state = PWRDM_POWER_ON, | 35 | .cpu_state = PWRDM_POWER_ON, |
36 | .mpu_state = PWRDM_POWER_ON, | 36 | .mpu_state = PWRDM_POWER_ON, |
@@ -53,11 +53,12 @@ static struct clockdomain *cpu_clkdm[NR_CPUS]; | |||
53 | 53 | ||
54 | static atomic_t abort_barrier; | 54 | static atomic_t abort_barrier; |
55 | static bool cpu_done[NR_CPUS]; | 55 | static bool cpu_done[NR_CPUS]; |
56 | static struct idle_statedata *state_ptr = &omap4_idle_data[0]; | ||
56 | 57 | ||
57 | /* Private functions */ | 58 | /* Private functions */ |
58 | 59 | ||
59 | /** | 60 | /** |
60 | * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions | 61 | * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions |
61 | * @dev: cpuidle device | 62 | * @dev: cpuidle device |
62 | * @drv: cpuidle driver | 63 | * @drv: cpuidle driver |
63 | * @index: the index of state to be entered | 64 | * @index: the index of state to be entered |
@@ -66,7 +67,7 @@ static bool cpu_done[NR_CPUS]; | |||
66 | * specified low power state selected by the governor. | 67 | * specified low power state selected by the governor. |
67 | * Returns the amount of time spent in the low power state. | 68 | * Returns the amount of time spent in the low power state. |
68 | */ | 69 | */ |
69 | static int omap4_enter_idle_simple(struct cpuidle_device *dev, | 70 | static int omap_enter_idle_simple(struct cpuidle_device *dev, |
70 | struct cpuidle_driver *drv, | 71 | struct cpuidle_driver *drv, |
71 | int index) | 72 | int index) |
72 | { | 73 | { |
@@ -77,12 +78,11 @@ static int omap4_enter_idle_simple(struct cpuidle_device *dev, | |||
77 | return index; | 78 | return index; |
78 | } | 79 | } |
79 | 80 | ||
80 | static int omap4_enter_idle_coupled(struct cpuidle_device *dev, | 81 | static int omap_enter_idle_coupled(struct cpuidle_device *dev, |
81 | struct cpuidle_driver *drv, | 82 | struct cpuidle_driver *drv, |
82 | int index) | 83 | int index) |
83 | { | 84 | { |
84 | struct omap4_idle_statedata *cx = &omap4_idle_data[index]; | 85 | struct idle_statedata *cx = state_ptr + index; |
85 | int cpu_id = smp_processor_id(); | ||
86 | 86 | ||
87 | local_fiq_disable(); | 87 | local_fiq_disable(); |
88 | 88 | ||
@@ -109,8 +109,6 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev, | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); | ||
113 | |||
114 | /* | 112 | /* |
115 | * Call idle CPU PM enter notifier chain so that | 113 | * Call idle CPU PM enter notifier chain so that |
116 | * VFP and per CPU interrupt context is saved. | 114 | * VFP and per CPU interrupt context is saved. |
@@ -149,11 +147,10 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev, | |||
149 | * Call idle CPU cluster PM exit notifier chain | 147 | * Call idle CPU cluster PM exit notifier chain |
150 | * to restore GIC and wakeupgen context. | 148 | * to restore GIC and wakeupgen context. |
151 | */ | 149 | */ |
152 | if (omap4_mpuss_read_prev_context_state()) | 150 | if ((cx->mpu_state == PWRDM_POWER_RET) && |
151 | (cx->mpu_logic_state == PWRDM_POWER_OFF)) | ||
153 | cpu_cluster_pm_exit(); | 152 | cpu_cluster_pm_exit(); |
154 | 153 | ||
155 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); | ||
156 | |||
157 | fail: | 154 | fail: |
158 | cpuidle_coupled_parallel_barrier(dev, &abort_barrier); | 155 | cpuidle_coupled_parallel_barrier(dev, &abort_barrier); |
159 | cpu_done[dev->cpu] = false; | 156 | cpu_done[dev->cpu] = false; |
@@ -163,49 +160,38 @@ fail: | |||
163 | return index; | 160 | return index; |
164 | } | 161 | } |
165 | 162 | ||
166 | /* | ||
167 | * For each cpu, setup the broadcast timer because local timers | ||
168 | * stops for the states above C1. | ||
169 | */ | ||
170 | static void omap_setup_broadcast_timer(void *arg) | ||
171 | { | ||
172 | int cpu = smp_processor_id(); | ||
173 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); | ||
174 | } | ||
175 | |||
176 | static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev); | ||
177 | |||
178 | static struct cpuidle_driver omap4_idle_driver = { | 163 | static struct cpuidle_driver omap4_idle_driver = { |
179 | .name = "omap4_idle", | 164 | .name = "omap4_idle", |
180 | .owner = THIS_MODULE, | 165 | .owner = THIS_MODULE, |
181 | .en_core_tk_irqen = 1, | ||
182 | .states = { | 166 | .states = { |
183 | { | 167 | { |
184 | /* C1 - CPU0 ON + CPU1 ON + MPU ON */ | 168 | /* C1 - CPU0 ON + CPU1 ON + MPU ON */ |
185 | .exit_latency = 2 + 2, | 169 | .exit_latency = 2 + 2, |
186 | .target_residency = 5, | 170 | .target_residency = 5, |
187 | .flags = CPUIDLE_FLAG_TIME_VALID, | 171 | .flags = CPUIDLE_FLAG_TIME_VALID, |
188 | .enter = omap4_enter_idle_simple, | 172 | .enter = omap_enter_idle_simple, |
189 | .name = "C1", | 173 | .name = "C1", |
190 | .desc = "MPUSS ON" | 174 | .desc = "CPUx ON, MPUSS ON" |
191 | }, | 175 | }, |
192 | { | 176 | { |
193 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ | 177 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ |
194 | .exit_latency = 328 + 440, | 178 | .exit_latency = 328 + 440, |
195 | .target_residency = 960, | 179 | .target_residency = 960, |
196 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, | 180 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED | |
197 | .enter = omap4_enter_idle_coupled, | 181 | CPUIDLE_FLAG_TIMER_STOP, |
182 | .enter = omap_enter_idle_coupled, | ||
198 | .name = "C2", | 183 | .name = "C2", |
199 | .desc = "MPUSS CSWR", | 184 | .desc = "CPUx OFF, MPUSS CSWR", |
200 | }, | 185 | }, |
201 | { | 186 | { |
202 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | 187 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ |
203 | .exit_latency = 460 + 518, | 188 | .exit_latency = 460 + 518, |
204 | .target_residency = 1100, | 189 | .target_residency = 1100, |
205 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, | 190 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED | |
206 | .enter = omap4_enter_idle_coupled, | 191 | CPUIDLE_FLAG_TIMER_STOP, |
192 | .enter = omap_enter_idle_coupled, | ||
207 | .name = "C3", | 193 | .name = "C3", |
208 | .desc = "MPUSS OSWR", | 194 | .desc = "CPUx OFF, MPUSS OSWR", |
209 | }, | 195 | }, |
210 | }, | 196 | }, |
211 | .state_count = ARRAY_SIZE(omap4_idle_data), | 197 | .state_count = ARRAY_SIZE(omap4_idle_data), |
@@ -215,16 +201,13 @@ static struct cpuidle_driver omap4_idle_driver = { | |||
215 | /* Public functions */ | 201 | /* Public functions */ |
216 | 202 | ||
217 | /** | 203 | /** |
218 | * omap4_idle_init - Init routine for OMAP4 idle | 204 | * omap4_idle_init - Init routine for OMAP4+ idle |
219 | * | 205 | * |
220 | * Registers the OMAP4 specific cpuidle driver to the cpuidle | 206 | * Registers the OMAP4+ specific cpuidle driver to the cpuidle |
221 | * framework with the valid set of states. | 207 | * framework with the valid set of states. |
222 | */ | 208 | */ |
223 | int __init omap4_idle_init(void) | 209 | int __init omap4_idle_init(void) |
224 | { | 210 | { |
225 | struct cpuidle_device *dev; | ||
226 | unsigned int cpu_id = 0; | ||
227 | |||
228 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); | 211 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); |
229 | cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); | 212 | cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); |
230 | cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); | 213 | cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); |
@@ -236,22 +219,5 @@ int __init omap4_idle_init(void) | |||
236 | if (!cpu_clkdm[0] || !cpu_clkdm[1]) | 219 | if (!cpu_clkdm[0] || !cpu_clkdm[1]) |
237 | return -ENODEV; | 220 | return -ENODEV; |
238 | 221 | ||
239 | /* Configure the broadcast timer on each cpu */ | 222 | return cpuidle_register(&omap4_idle_driver, cpu_online_mask); |
240 | on_each_cpu(omap_setup_broadcast_timer, NULL, 1); | ||
241 | |||
242 | for_each_cpu(cpu_id, cpu_online_mask) { | ||
243 | dev = &per_cpu(omap4_idle_dev, cpu_id); | ||
244 | dev->cpu = cpu_id; | ||
245 | #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED | ||
246 | dev->coupled_cpus = *cpu_online_mask; | ||
247 | #endif | ||
248 | cpuidle_register_driver(&omap4_idle_driver); | ||
249 | |||
250 | if (cpuidle_register_device(dev)) { | ||
251 | pr_err("%s: CPUidle register failed\n", __func__); | ||
252 | return -EIO; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | } | 223 | } |
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 8bcb64bcdcdb..e80327b6c81f 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c | |||
@@ -139,20 +139,6 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id) | |||
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
142 | /** | ||
143 | * omap4_mpuss_read_prev_context_state: | ||
144 | * Function returns the MPUSS previous context state | ||
145 | */ | ||
146 | u32 omap4_mpuss_read_prev_context_state(void) | ||
147 | { | ||
148 | u32 reg; | ||
149 | |||
150 | reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, | ||
151 | OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); | ||
152 | reg &= OMAP4430_LOSTCONTEXT_DFF_MASK; | ||
153 | return reg; | ||
154 | } | ||
155 | |||
156 | /* | 142 | /* |
157 | * Store the CPU cluster state for L2X0 low power operations. | 143 | * Store the CPU cluster state for L2X0 low power operations. |
158 | */ | 144 | */ |
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index dec553349ae2..e742118fcfd2 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -264,6 +264,12 @@ static void __init omap4_init_voltages(void) | |||
264 | omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva"); | 264 | omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva"); |
265 | } | 265 | } |
266 | 266 | ||
267 | static inline void omap_init_cpufreq(void) | ||
268 | { | ||
269 | struct platform_device_info devinfo = { .name = "omap-cpufreq", }; | ||
270 | platform_device_register_full(&devinfo); | ||
271 | } | ||
272 | |||
267 | static int __init omap2_common_pm_init(void) | 273 | static int __init omap2_common_pm_init(void) |
268 | { | 274 | { |
269 | if (!of_have_populated_dt()) | 275 | if (!of_have_populated_dt()) |
@@ -293,6 +299,9 @@ int __init omap2_common_pm_late_init(void) | |||
293 | 299 | ||
294 | /* Smartreflex device init */ | 300 | /* Smartreflex device init */ |
295 | omap_devinit_smartreflex(); | 301 | omap_devinit_smartreflex(); |
302 | |||
303 | /* cpufreq dummy device instantiation */ | ||
304 | omap_init_cpufreq(); | ||
296 | } | 305 | } |
297 | 306 | ||
298 | #ifdef CONFIG_SUSPEND | 307 | #ifdef CONFIG_SUSPEND |