aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpuidle
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpuidle')
-rw-r--r--drivers/cpuidle/cpuidle.c62
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
45static 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
358EXPORT_SYMBOL_GPL(cpuidle_disable_device); 356EXPORT_SYMBOL_GPL(cpuidle_disable_device);
359 357
358static 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
388err_coupled:
389 cpuidle_remove_sysfs(dev);
390err_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
422out_unlock:
423 mutex_unlock(&cpuidle_lock); 423 mutex_unlock(&cpuidle_lock);
424 424
425 return 0; 425 return ret;
426
427out_sysfs:
428 cpuidle_remove_sysfs(dev);
429out_unregister:
430 __cpuidle_unregister_device(dev);
431 goto out_unlock;
426} 432}
427 433
428EXPORT_SYMBOL_GPL(cpuidle_register_device); 434EXPORT_SYMBOL_GPL(cpuidle_register_device);
@@ -433,8 +439,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device);
433 */ 439 */
434void cpuidle_unregister_device(struct cpuidle_device *dev) 440void 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
456EXPORT_SYMBOL_GPL(cpuidle_unregister_device); 458EXPORT_SYMBOL_GPL(cpuidle_unregister_device);