at v3.2-rc1 96 lines 2.2 kB view raw
1/* 2 * driver.c - driver support 3 * 4 * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> 5 * Shaohua Li <shaohua.li@intel.com> 6 * Adam Belay <abelay@novell.com> 7 * 8 * This code is licenced under the GPL. 9 */ 10 11#include <linux/mutex.h> 12#include <linux/module.h> 13#include <linux/cpuidle.h> 14 15#include "cpuidle.h" 16 17static struct cpuidle_driver *cpuidle_curr_driver; 18DEFINE_SPINLOCK(cpuidle_driver_lock); 19 20static void __cpuidle_register_driver(struct cpuidle_driver *drv) 21{ 22 int i; 23 /* 24 * cpuidle driver should set the drv->power_specified bit 25 * before registering if the driver provides 26 * power_usage numbers. 27 * 28 * If power_specified is not set, 29 * we fill in power_usage with decreasing values as the 30 * cpuidle code has an implicit assumption that state Cn 31 * uses less power than C(n-1). 32 * 33 * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned 34 * an power value of -1. So we use -2, -3, etc, for other 35 * c-states. 36 */ 37 if (!drv->power_specified) { 38 for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) 39 drv->states[i].power_usage = -1 - i; 40 } 41} 42 43 44/** 45 * cpuidle_register_driver - registers a driver 46 * @drv: the driver 47 */ 48int cpuidle_register_driver(struct cpuidle_driver *drv) 49{ 50 if (!drv) 51 return -EINVAL; 52 53 if (cpuidle_disabled()) 54 return -ENODEV; 55 56 spin_lock(&cpuidle_driver_lock); 57 if (cpuidle_curr_driver) { 58 spin_unlock(&cpuidle_driver_lock); 59 return -EBUSY; 60 } 61 __cpuidle_register_driver(drv); 62 cpuidle_curr_driver = drv; 63 spin_unlock(&cpuidle_driver_lock); 64 65 return 0; 66} 67 68EXPORT_SYMBOL_GPL(cpuidle_register_driver); 69 70/** 71 * cpuidle_get_driver - return the current driver 72 */ 73struct cpuidle_driver *cpuidle_get_driver(void) 74{ 75 return cpuidle_curr_driver; 76} 77EXPORT_SYMBOL_GPL(cpuidle_get_driver); 78 79/** 80 * cpuidle_unregister_driver - unregisters a driver 81 * @drv: the driver 82 */ 83void cpuidle_unregister_driver(struct cpuidle_driver *drv) 84{ 85 if (drv != cpuidle_curr_driver) { 86 WARN(1, "invalid cpuidle_unregister_driver(%s)\n", 87 drv->name); 88 return; 89 } 90 91 spin_lock(&cpuidle_driver_lock); 92 cpuidle_curr_driver = NULL; 93 spin_unlock(&cpuidle_driver_lock); 94} 95 96EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);