diff options
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r-- | drivers/cpuidle/cpuidle.c | 62 |
1 files changed, 32 insertions, 30 deletions
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 4deed977f209..d78c6d89272f 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -42,8 +42,6 @@ void disable_cpuidle(void) | |||
42 | off = 1; | 42 | off = 1; |
43 | } | 43 | } |
44 | 44 | ||
45 | static int __cpuidle_register_device(struct cpuidle_device *dev); | ||
46 | |||
47 | /** | 45 | /** |
48 | * cpuidle_play_dead - cpu off-lining | 46 | * cpuidle_play_dead - cpu off-lining |
49 | * | 47 | * |
@@ -357,6 +355,15 @@ void cpuidle_disable_device(struct cpuidle_device *dev) | |||
357 | 355 | ||
358 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); | 356 | EXPORT_SYMBOL_GPL(cpuidle_disable_device); |
359 | 357 | ||
358 | static void __cpuidle_unregister_device(struct cpuidle_device *dev) | ||
359 | { | ||
360 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); | ||
361 | |||
362 | list_del(&dev->device_list); | ||
363 | per_cpu(cpuidle_devices, dev->cpu) = NULL; | ||
364 | module_put(drv->owner); | ||
365 | } | ||
366 | |||
360 | /** | 367 | /** |
361 | * __cpuidle_register_device - internal register function called before register | 368 | * __cpuidle_register_device - internal register function called before register |
362 | * and enable routines | 369 | * and enable routines |
@@ -374,24 +381,15 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) | |||
374 | 381 | ||
375 | per_cpu(cpuidle_devices, dev->cpu) = dev; | 382 | per_cpu(cpuidle_devices, dev->cpu) = dev; |
376 | list_add(&dev->device_list, &cpuidle_detected_devices); | 383 | list_add(&dev->device_list, &cpuidle_detected_devices); |
377 | ret = cpuidle_add_sysfs(dev); | ||
378 | if (ret) | ||
379 | goto err_sysfs; | ||
380 | 384 | ||
381 | ret = cpuidle_coupled_register_device(dev); | 385 | ret = cpuidle_coupled_register_device(dev); |
382 | if (ret) | 386 | if (ret) { |
383 | goto err_coupled; | 387 | __cpuidle_unregister_device(dev); |
388 | return ret; | ||
389 | } | ||
384 | 390 | ||
385 | dev->registered = 1; | 391 | dev->registered = 1; |
386 | return 0; | 392 | return 0; |
387 | |||
388 | err_coupled: | ||
389 | cpuidle_remove_sysfs(dev); | ||
390 | err_sysfs: | ||
391 | list_del(&dev->device_list); | ||
392 | per_cpu(cpuidle_devices, dev->cpu) = NULL; | ||
393 | module_put(drv->owner); | ||
394 | return ret; | ||
395 | } | 393 | } |
396 | 394 | ||
397 | /** | 395 | /** |
@@ -407,22 +405,30 @@ int cpuidle_register_device(struct cpuidle_device *dev) | |||
407 | 405 | ||
408 | mutex_lock(&cpuidle_lock); | 406 | mutex_lock(&cpuidle_lock); |
409 | 407 | ||
410 | if ((ret = __cpuidle_register_device(dev))) { | 408 | ret = __cpuidle_register_device(dev); |
411 | mutex_unlock(&cpuidle_lock); | 409 | if (ret) |
412 | return ret; | 410 | goto out_unlock; |
413 | } | 411 | |
412 | ret = cpuidle_add_sysfs(dev); | ||
413 | if (ret) | ||
414 | goto out_unregister; | ||
414 | 415 | ||
415 | ret = cpuidle_enable_device(dev); | 416 | ret = cpuidle_enable_device(dev); |
416 | if (ret) { | 417 | if (ret) |
417 | mutex_unlock(&cpuidle_lock); | 418 | goto out_sysfs; |
418 | return ret; | ||
419 | } | ||
420 | 419 | ||
421 | cpuidle_install_idle_handler(); | 420 | cpuidle_install_idle_handler(); |
422 | 421 | ||
422 | out_unlock: | ||
423 | mutex_unlock(&cpuidle_lock); | 423 | mutex_unlock(&cpuidle_lock); |
424 | 424 | ||
425 | return 0; | 425 | return ret; |
426 | |||
427 | out_sysfs: | ||
428 | cpuidle_remove_sysfs(dev); | ||
429 | out_unregister: | ||
430 | __cpuidle_unregister_device(dev); | ||
431 | goto out_unlock; | ||
426 | } | 432 | } |
427 | 433 | ||
428 | EXPORT_SYMBOL_GPL(cpuidle_register_device); | 434 | EXPORT_SYMBOL_GPL(cpuidle_register_device); |
@@ -433,8 +439,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); | |||
433 | */ | 439 | */ |
434 | void cpuidle_unregister_device(struct cpuidle_device *dev) | 440 | void cpuidle_unregister_device(struct cpuidle_device *dev) |
435 | { | 441 | { |
436 | struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); | ||
437 | |||
438 | if (dev->registered == 0) | 442 | if (dev->registered == 0) |
439 | return; | 443 | return; |
440 | 444 | ||
@@ -443,14 +447,12 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) | |||
443 | cpuidle_disable_device(dev); | 447 | cpuidle_disable_device(dev); |
444 | 448 | ||
445 | cpuidle_remove_sysfs(dev); | 449 | cpuidle_remove_sysfs(dev); |
446 | list_del(&dev->device_list); | 450 | |
447 | per_cpu(cpuidle_devices, dev->cpu) = NULL; | 451 | __cpuidle_unregister_device(dev); |
448 | 452 | ||
449 | cpuidle_coupled_unregister_device(dev); | 453 | cpuidle_coupled_unregister_device(dev); |
450 | 454 | ||
451 | cpuidle_resume_and_unlock(); | 455 | cpuidle_resume_and_unlock(); |
452 | |||
453 | module_put(drv->owner); | ||
454 | } | 456 | } |
455 | 457 | ||
456 | EXPORT_SYMBOL_GPL(cpuidle_unregister_device); | 458 | EXPORT_SYMBOL_GPL(cpuidle_unregister_device); |