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 #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */ 62 63 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) 64 65 /** 66 * cpuidle_get_statedata - retrieves private driver state data 67 * @st_usage: the state usage statistics 68 */ 69 static inline void *cpuidle_get_statedata(struct cpuidle_state_usage *st_usage) 70 { 71 return st_usage->driver_data; 72 } 73 74 /** 75 * cpuidle_set_statedata - stores private driver state data 76 * @st_usage: the state usage statistics 77 * @data: the private data 78 */ 79 static inline void 80 cpuidle_set_statedata(struct cpuidle_state_usage *st_usage, void *data) 81 { 82 st_usage->driver_data = data; 83 } 84 85 struct cpuidle_state_kobj { 86 struct cpuidle_state *state; 87 struct cpuidle_state_usage *state_usage; 88 struct completion kobj_unregister; 89 struct kobject kobj; 90 }; 91 92 struct cpuidle_device { 93 unsigned int registered:1; 94 unsigned int enabled:1; 95 unsigned int cpu; 96 97 int last_residency; 98 int state_count; 99 struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; 100 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; 101 102 struct list_head device_list; 103 struct kobject kobj; 104 struct completion kobj_unregister; 105 106 #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED 107 int safe_state_index; 108 cpumask_t coupled_cpus; 109 struct cpuidle_coupled *coupled; 110 #endif 111 }; 112 113 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); 114 115 /** 116 * cpuidle_get_last_residency - retrieves the last state's residency time 117 * @dev: the target CPU 118 * 119 * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set 120 */ 121 static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) 122 { 123 return dev->last_residency; 124 } 125 126 127 /**************************** 128 * CPUIDLE DRIVER INTERFACE * 129 ****************************/ 130 131 struct cpuidle_driver { 132 const char *name; 133 struct module *owner; 134 135 unsigned int power_specified:1; 136 /* set to 1 to use the core cpuidle time keeping (for all states). */ 137 unsigned int en_core_tk_irqen:1; 138 struct cpuidle_state states[CPUIDLE_STATE_MAX]; 139 int state_count; 140 int safe_state_index; 141 }; 142 143 #ifdef CONFIG_CPU_IDLE 144 extern void disable_cpuidle(void); 145 extern int cpuidle_idle_call(void); 146 extern int cpuidle_register_driver(struct cpuidle_driver *drv); 147 extern struct cpuidle_driver *cpuidle_get_driver(void); 148 extern struct cpuidle_driver *cpuidle_driver_ref(void); 149 extern void cpuidle_driver_unref(void); 150 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); 151 extern int cpuidle_register_device(struct cpuidle_device *dev); 152 extern void cpuidle_unregister_device(struct cpuidle_device *dev); 153 154 extern void cpuidle_pause_and_lock(void); 155 extern void cpuidle_resume_and_unlock(void); 156 extern void cpuidle_pause(void); 157 extern void cpuidle_resume(void); 158 extern int cpuidle_enable_device(struct cpuidle_device *dev); 159 extern void cpuidle_disable_device(struct cpuidle_device *dev); 160 extern int cpuidle_wrap_enter(struct cpuidle_device *dev, 161 struct cpuidle_driver *drv, int index, 162 int (*enter)(struct cpuidle_device *dev, 163 struct cpuidle_driver *drv, int index)); 164 extern int cpuidle_play_dead(void); 165 166 #else 167 static inline void disable_cpuidle(void) { } 168 static inline int cpuidle_idle_call(void) { return -ENODEV; } 169 static inline int cpuidle_register_driver(struct cpuidle_driver *drv) 170 {return -ENODEV; } 171 static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } 172 static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; } 173 static inline void cpuidle_driver_unref(void) {} 174 static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } 175 static inline int cpuidle_register_device(struct cpuidle_device *dev) 176 {return -ENODEV; } 177 static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } 178 179 static inline void cpuidle_pause_and_lock(void) { } 180 static inline void cpuidle_resume_and_unlock(void) { } 181 static inline void cpuidle_pause(void) { } 182 static inline void cpuidle_resume(void) { } 183 static inline int cpuidle_enable_device(struct cpuidle_device *dev) 184 {return -ENODEV; } 185 static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } 186 static inline int cpuidle_wrap_enter(struct cpuidle_device *dev, 187 struct cpuidle_driver *drv, int index, 188 int (*enter)(struct cpuidle_device *dev, 189 struct cpuidle_driver *drv, int index)) 190 { return -ENODEV; } 191 static inline int cpuidle_play_dead(void) {return -ENODEV; } 192 193 #endif 194 195 #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED 196 void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a); 197 #else 198 static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a) 199 { 200 } 201 #endif 202 203 /****************************** 204 * CPUIDLE GOVERNOR INTERFACE * 205 ******************************/ 206 207 struct cpuidle_governor { 208 char name[CPUIDLE_NAME_LEN]; 209 struct list_head governor_list; 210 unsigned int rating; 211 212 int (*enable) (struct cpuidle_driver *drv, 213 struct cpuidle_device *dev); 214 void (*disable) (struct cpuidle_driver *drv, 215 struct cpuidle_device *dev); 216 217 int (*select) (struct cpuidle_driver *drv, 218 struct cpuidle_device *dev); 219 void (*reflect) (struct cpuidle_device *dev, int index); 220 221 struct module *owner; 222 }; 223 224 #ifdef CONFIG_CPU_IDLE 225 226 extern int cpuidle_register_governor(struct cpuidle_governor *gov); 227 extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); 228 229 #else 230 231 static inline int cpuidle_register_governor(struct cpuidle_governor *gov) 232 {return 0;} 233 static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { } 234 235 #endif 236 237 #ifdef CONFIG_ARCH_HAS_CPU_RELAX 238 #define CPUIDLE_DRIVER_STATE_START 1 239 #else 240 #define CPUIDLE_DRIVER_STATE_START 0 241 #endif 242 243 #endif /* _LINUX_CPUIDLE_H */ 244