1 /* 2 * cpuidle.h - a generic framework for CPU idle power management 3 * 4 * (C) 2007 Venkatesh Pallipadi <[email protected]> 5 * Shaohua Li <[email protected]> 6 * Adam Belay <[email protected]> 7 * 8 * This code is licenced under the GPL. 9 */ 10 11 #ifndef _LINUX_CPUIDLE_H 12 #define _LINUX_CPUIDLE_H 13 14 #include <linux/percpu.h> 15 #include <linux/list.h> 16 #include <linux/kobject.h> 17 #include <linux/completion.h> 18 #include <linux/hrtimer.h> 19 20 #define CPUIDLE_STATE_MAX 8 21 #define CPUIDLE_NAME_LEN 16 22 #define CPUIDLE_DESC_LEN 32 23 24 struct module; 25 26 struct cpuidle_device; 27 struct cpuidle_driver; 28 29 30 /**************************** 31 * CPUIDLE DEVICE INTERFACE * 32 ****************************/ 33 34 struct cpuidle_state_usage { 35 void *driver_data; 36 37 unsigned long long disable; 38 unsigned long long usage; 39 unsigned long long time; /* in US */ 40 }; 41 42 struct cpuidle_state { 43 char name[CPUIDLE_NAME_LEN]; 44 char desc[CPUIDLE_DESC_LEN]; 45 46 unsigned int flags; 47 unsigned int exit_latency; /* in US */ 48 int power_usage; /* in mW */ 49 unsigned int target_residency; /* in US */ 50 bool disabled; /* disabled on all CPUs */ 51 52 int (*enter) (struct cpuidle_device *dev, 53 struct cpuidle_driver *drv, 54 int index); 55 56 int (*enter_dead) (struct cpuidle_device *dev, int index); 57 }; 58 59 /* Idle State Flags */ 60 #define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ 61 62 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) 63 64 /** 65 * cpuidle_get_statedata - retrieves private driver state data 66 * @st_usage: the state usage statistics 67 */ 68 static inline void *cpuidle_get_statedata(struct cpuidle_state_usage *st_usage) 69 { 70 return st_usage->driver_data; 71 } 72 73 /** 74 * cpuidle_set_statedata - stores private driver state data 75 * @st_usage: the state usage statistics 76 * @data: the private data 77 */ 78 static inline void 79 cpuidle_set_statedata(struct cpuidle_state_usage *st_usage, void *data) 80 { 81 st_usage->driver_data = data; 82 } 83 84 struct cpuidle_state_kobj { 85 struct cpuidle_state *state; 86 struct cpuidle_state_usage *state_usage; 87 struct completion kobj_unregister; 88 struct kobject kobj; 89 }; 90 91 struct cpuidle_device { 92 unsigned int registered:1; 93 unsigned int enabled:1; 94 unsigned int cpu; 95 96 int last_residency; 97 int state_count; 98 struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; 99 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; 100 101 struct list_head device_list; 102 struct kobject kobj; 103 struct completion kobj_unregister; 104 }; 105 106 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); 107 108 /** 109 * cpuidle_get_last_residency - retrieves the last state's residency time 110 * @dev: the target CPU 111 * 112 * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set 113 */ 114 static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) 115 { 116 return dev->last_residency; 117 } 118 119 120 /**************************** 121 * CPUIDLE DRIVER INTERFACE * 122 ****************************/ 123 124 struct cpuidle_driver { 125 const char *name; 126 struct module *owner; 127 128 unsigned int power_specified:1; 129 /* set to 1 to use the core cpuidle time keeping (for all states). */ 130 unsigned int en_core_tk_irqen:1; 131 struct cpuidle_state states[CPUIDLE_STATE_MAX]; 132 int state_count; 133 int safe_state_index; 134 }; 135 136 #ifdef CONFIG_CPU_IDLE 137 extern void disable_cpuidle(void); 138 extern int cpuidle_idle_call(void); 139 extern int cpuidle_register_driver(struct cpuidle_driver *drv); 140 extern struct cpuidle_driver *cpuidle_get_driver(void); 141 extern struct cpuidle_driver *cpuidle_driver_ref(void); 142 extern void cpuidle_driver_unref(void); 143 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); 144 extern int cpuidle_register_device(struct cpuidle_device *dev); 145 extern void cpuidle_unregister_device(struct cpuidle_device *dev); 146 147 extern void cpuidle_pause_and_lock(void); 148 extern void cpuidle_resume_and_unlock(void); 149 extern void cpuidle_pause(void); 150 extern void cpuidle_resume(void); 151 extern int cpuidle_enable_device(struct cpuidle_device *dev); 152 extern void cpuidle_disable_device(struct cpuidle_device *dev); 153 extern int cpuidle_wrap_enter(struct cpuidle_device *dev, 154 struct cpuidle_driver *drv, int index, 155 int (*enter)(struct cpuidle_device *dev, 156 struct cpuidle_driver *drv, int index)); 157 extern int cpuidle_play_dead(void); 158 159 #else 160 static inline void disable_cpuidle(void) { } 161 static inline int cpuidle_idle_call(void) { return -ENODEV; } 162 static inline int cpuidle_register_driver(struct cpuidle_driver *drv) 163 {return -ENODEV; } 164 static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } 165 static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; } 166 static inline void cpuidle_driver_unref(void) {} 167 static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } 168 static inline int cpuidle_register_device(struct cpuidle_device *dev) 169 {return -ENODEV; } 170 static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } 171 172 static inline void cpuidle_pause_and_lock(void) { } 173 static inline void cpuidle_resume_and_unlock(void) { } 174 static inline void cpuidle_pause(void) { } 175 static inline void cpuidle_resume(void) { } 176 static inline int cpuidle_enable_device(struct cpuidle_device *dev) 177 {return -ENODEV; } 178 static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } 179 static inline int cpuidle_wrap_enter(struct cpuidle_device *dev, 180 struct cpuidle_driver *drv, int index, 181 int (*enter)(struct cpuidle_device *dev, 182 struct cpuidle_driver *drv, int index)) 183 { return -ENODEV; } 184 static inline int cpuidle_play_dead(void) {return -ENODEV; } 185 186 #endif 187 188 /****************************** 189 * CPUIDLE GOVERNOR INTERFACE * 190 ******************************/ 191 192 struct cpuidle_governor { 193 char name[CPUIDLE_NAME_LEN]; 194 struct list_head governor_list; 195 unsigned int rating; 196 197 int (*enable) (struct cpuidle_driver *drv, 198 struct cpuidle_device *dev); 199 void (*disable) (struct cpuidle_driver *drv, 200 struct cpuidle_device *dev); 201 202 int (*select) (struct cpuidle_driver *drv, 203 struct cpuidle_device *dev); 204 void (*reflect) (struct cpuidle_device *dev, int index); 205 206 struct module *owner; 207 }; 208 209 #ifdef CONFIG_CPU_IDLE 210 211 extern int cpuidle_register_governor(struct cpuidle_governor *gov); 212 extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); 213 214 #else 215 216 static inline int cpuidle_register_governor(struct cpuidle_governor *gov) 217 {return 0;} 218 static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { } 219 220 #endif 221 222 #ifdef CONFIG_ARCH_HAS_CPU_RELAX 223 #define CPUIDLE_DRIVER_STATE_START 1 224 #else 225 #define CPUIDLE_DRIVER_STATE_START 0 226 #endif 227 228 #endif /* _LINUX_CPUIDLE_H */ 229