diff options
-rw-r--r-- | drivers/cpuidle/cpuidle-pseries.c | 78 |
1 files changed, 11 insertions, 67 deletions
diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c index 21154782402a..32d86bc5d3f7 100644 --- a/drivers/cpuidle/cpuidle-pseries.c +++ b/drivers/cpuidle/cpuidle-pseries.c | |||
@@ -27,7 +27,6 @@ struct cpuidle_driver pseries_idle_driver = { | |||
27 | #define MAX_IDLE_STATE_COUNT 2 | 27 | #define MAX_IDLE_STATE_COUNT 2 |
28 | 28 | ||
29 | static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; | 29 | static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; |
30 | static struct cpuidle_device __percpu *pseries_cpuidle_devices; | ||
31 | static struct cpuidle_state *cpuidle_state_table; | 30 | static struct cpuidle_state *cpuidle_state_table; |
32 | 31 | ||
33 | static inline void idle_loop_prolog(unsigned long *in_purr) | 32 | static inline void idle_loop_prolog(unsigned long *in_purr) |
@@ -55,13 +54,12 @@ static int snooze_loop(struct cpuidle_device *dev, | |||
55 | int index) | 54 | int index) |
56 | { | 55 | { |
57 | unsigned long in_purr; | 56 | unsigned long in_purr; |
58 | int cpu = dev->cpu; | ||
59 | 57 | ||
60 | idle_loop_prolog(&in_purr); | 58 | idle_loop_prolog(&in_purr); |
61 | local_irq_enable(); | 59 | local_irq_enable(); |
62 | set_thread_flag(TIF_POLLING_NRFLAG); | 60 | set_thread_flag(TIF_POLLING_NRFLAG); |
63 | 61 | ||
64 | while ((!need_resched()) && cpu_online(cpu)) { | 62 | while (!need_resched()) { |
65 | HMT_low(); | 63 | HMT_low(); |
66 | HMT_very_low(); | 64 | HMT_very_low(); |
67 | } | 65 | } |
@@ -188,7 +186,7 @@ static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, | |||
188 | { | 186 | { |
189 | int hotcpu = (unsigned long)hcpu; | 187 | int hotcpu = (unsigned long)hcpu; |
190 | struct cpuidle_device *dev = | 188 | struct cpuidle_device *dev = |
191 | per_cpu_ptr(pseries_cpuidle_devices, hotcpu); | 189 | per_cpu(cpuidle_devices, hotcpu); |
192 | 190 | ||
193 | if (dev && cpuidle_get_driver()) { | 191 | if (dev && cpuidle_get_driver()) { |
194 | switch (action) { | 192 | switch (action) { |
@@ -245,50 +243,6 @@ static int pseries_cpuidle_driver_init(void) | |||
245 | return 0; | 243 | return 0; |
246 | } | 244 | } |
247 | 245 | ||
248 | /* pseries_idle_devices_uninit(void) | ||
249 | * unregister cpuidle devices and de-allocate memory | ||
250 | */ | ||
251 | static void pseries_idle_devices_uninit(void) | ||
252 | { | ||
253 | int i; | ||
254 | struct cpuidle_device *dev; | ||
255 | |||
256 | for_each_possible_cpu(i) { | ||
257 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
258 | cpuidle_unregister_device(dev); | ||
259 | } | ||
260 | |||
261 | free_percpu(pseries_cpuidle_devices); | ||
262 | return; | ||
263 | } | ||
264 | |||
265 | /* pseries_idle_devices_init() | ||
266 | * allocate, initialize and register cpuidle device | ||
267 | */ | ||
268 | static int pseries_idle_devices_init(void) | ||
269 | { | ||
270 | int i; | ||
271 | struct cpuidle_driver *drv = &pseries_idle_driver; | ||
272 | struct cpuidle_device *dev; | ||
273 | |||
274 | pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device); | ||
275 | if (pseries_cpuidle_devices == NULL) | ||
276 | return -ENOMEM; | ||
277 | |||
278 | for_each_possible_cpu(i) { | ||
279 | dev = per_cpu_ptr(pseries_cpuidle_devices, i); | ||
280 | dev->state_count = drv->state_count; | ||
281 | dev->cpu = i; | ||
282 | if (cpuidle_register_device(dev)) { | ||
283 | printk(KERN_DEBUG \ | ||
284 | "cpuidle_register_device %d failed!\n", i); | ||
285 | return -EIO; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | /* | 246 | /* |
293 | * pseries_idle_probe() | 247 | * pseries_idle_probe() |
294 | * Choose state table for shared versus dedicated partition | 248 | * Choose state table for shared versus dedicated partition |
@@ -296,9 +250,6 @@ static int pseries_idle_devices_init(void) | |||
296 | static int pseries_idle_probe(void) | 250 | static int pseries_idle_probe(void) |
297 | { | 251 | { |
298 | 252 | ||
299 | if (!firmware_has_feature(FW_FEATURE_SPLPAR)) | ||
300 | return -ENODEV; | ||
301 | |||
302 | if (cpuidle_disable != IDLE_NO_OVERRIDE) | 253 | if (cpuidle_disable != IDLE_NO_OVERRIDE) |
303 | return -ENODEV; | 254 | return -ENODEV; |
304 | 255 | ||
@@ -307,10 +258,13 @@ static int pseries_idle_probe(void) | |||
307 | return -EPERM; | 258 | return -EPERM; |
308 | } | 259 | } |
309 | 260 | ||
310 | if (lppaca_shared_proc(get_lppaca())) | 261 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { |
311 | cpuidle_state_table = shared_states; | 262 | if (lppaca_shared_proc(get_lppaca())) |
312 | else | 263 | cpuidle_state_table = shared_states; |
313 | cpuidle_state_table = dedicated_states; | 264 | else |
265 | cpuidle_state_table = dedicated_states; | ||
266 | } else | ||
267 | return -ENODEV; | ||
314 | 268 | ||
315 | return 0; | 269 | return 0; |
316 | } | 270 | } |
@@ -324,22 +278,14 @@ static int __init pseries_processor_idle_init(void) | |||
324 | return retval; | 278 | return retval; |
325 | 279 | ||
326 | pseries_cpuidle_driver_init(); | 280 | pseries_cpuidle_driver_init(); |
327 | retval = cpuidle_register_driver(&pseries_idle_driver); | 281 | retval = cpuidle_register(&pseries_idle_driver, NULL); |
328 | if (retval) { | 282 | if (retval) { |
329 | printk(KERN_DEBUG "Registration of pseries driver failed.\n"); | 283 | printk(KERN_DEBUG "Registration of pseries driver failed.\n"); |
330 | return retval; | 284 | return retval; |
331 | } | 285 | } |
332 | 286 | ||
333 | retval = pseries_idle_devices_init(); | ||
334 | if (retval) { | ||
335 | pseries_idle_devices_uninit(); | ||
336 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
337 | return retval; | ||
338 | } | ||
339 | |||
340 | register_cpu_notifier(&setup_hotplug_notifier); | 287 | register_cpu_notifier(&setup_hotplug_notifier); |
341 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); | 288 | printk(KERN_DEBUG "pseries_idle_driver registered\n"); |
342 | |||
343 | return 0; | 289 | return 0; |
344 | } | 290 | } |
345 | 291 | ||
@@ -347,9 +293,7 @@ static void __exit pseries_processor_idle_exit(void) | |||
347 | { | 293 | { |
348 | 294 | ||
349 | unregister_cpu_notifier(&setup_hotplug_notifier); | 295 | unregister_cpu_notifier(&setup_hotplug_notifier); |
350 | pseries_idle_devices_uninit(); | 296 | cpuidle_unregister(&pseries_idle_driver); |
351 | cpuidle_unregister_driver(&pseries_idle_driver); | ||
352 | |||
353 | return; | 297 | return; |
354 | } | 298 | } |
355 | 299 | ||