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/module.h> 17 #include <linux/kobject.h> 18 #include <linux/completion.h> 19 20 #define CPUIDLE_STATE_MAX 8 21 #define CPUIDLE_NAME_LEN 16 22 #define CPUIDLE_DESC_LEN 32 23 24 struct cpuidle_device; 25 26 27 /**************************** 28 * CPUIDLE DEVICE INTERFACE * 29 ****************************/ 30 31 struct cpuidle_state { 32 char name[CPUIDLE_NAME_LEN]; 33 char desc[CPUIDLE_DESC_LEN]; 34 void *driver_data; 35 36 unsigned int flags; 37 unsigned int exit_latency; /* in US */ 38 unsigned int power_usage; /* in mW */ 39 unsigned int target_residency; /* in US */ 40 41 unsigned long long usage; 42 unsigned long long time; /* in US */ 43 44 int (*enter) (struct cpuidle_device *dev, 45 struct cpuidle_state *state); 46 }; 47 48 /* Idle State Flags */ 49 #define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ 50 #define CPUIDLE_FLAG_CHECK_BM (0x02) /* BM activity will exit state */ 51 #define CPUIDLE_FLAG_POLL (0x10) /* no latency, no savings */ 52 #define CPUIDLE_FLAG_SHALLOW (0x20) /* low latency, minimal savings */ 53 #define CPUIDLE_FLAG_BALANCED (0x40) /* medium latency, moderate savings */ 54 #define CPUIDLE_FLAG_DEEP (0x80) /* high latency, large savings */ 55 #define CPUIDLE_FLAG_IGNORE (0x100) /* ignore during this idle period */ 56 #define CPUIDLE_FLAG_TLB_FLUSHED (0x200) /* tlb will be flushed */ 57 58 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) 59 60 /** 61 * cpuidle_get_statedata - retrieves private driver state data 62 * @state: the state 63 */ 64 static inline void * cpuidle_get_statedata(struct cpuidle_state *state) 65 { 66 return state->driver_data; 67 } 68 69 /** 70 * cpuidle_set_statedata - stores private driver state data 71 * @state: the state 72 * @data: the private data 73 */ 74 static inline void 75 cpuidle_set_statedata(struct cpuidle_state *state, void *data) 76 { 77 state->driver_data = data; 78 } 79 80 struct cpuidle_state_kobj { 81 struct cpuidle_state *state; 82 struct completion kobj_unregister; 83 struct kobject kobj; 84 }; 85 86 struct cpuidle_device { 87 unsigned int registered:1; 88 unsigned int enabled:1; 89 unsigned int power_specified:1; 90 unsigned int cpu; 91 92 int last_residency; 93 int state_count; 94 struct cpuidle_state states[CPUIDLE_STATE_MAX]; 95 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; 96 struct cpuidle_state *last_state; 97 98 struct list_head device_list; 99 struct kobject kobj; 100 struct completion kobj_unregister; 101 void *governor_data; 102 struct cpuidle_state *safe_state; 103 104 int (*prepare) (struct cpuidle_device *dev); 105 }; 106 107 DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); 108 109 /** 110 * cpuidle_get_last_residency - retrieves the last state's residency time 111 * @dev: the target CPU 112 * 113 * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set 114 */ 115 static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) 116 { 117 return dev->last_residency; 118 } 119 120 121 /**************************** 122 * CPUIDLE DRIVER INTERFACE * 123 ****************************/ 124 125 struct cpuidle_driver { 126 char name[CPUIDLE_NAME_LEN]; 127 struct module *owner; 128 }; 129 130 #ifdef CONFIG_CPU_IDLE 131 132 extern int cpuidle_register_driver(struct cpuidle_driver *drv); 133 struct cpuidle_driver *cpuidle_get_driver(void); 134 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); 135 extern int cpuidle_register_device(struct cpuidle_device *dev); 136 extern void cpuidle_unregister_device(struct cpuidle_device *dev); 137 138 extern void cpuidle_pause_and_lock(void); 139 extern void cpuidle_resume_and_unlock(void); 140 extern int cpuidle_enable_device(struct cpuidle_device *dev); 141 extern void cpuidle_disable_device(struct cpuidle_device *dev); 142 143 #else 144 145 static inline int cpuidle_register_driver(struct cpuidle_driver *drv) 146 {return -ENODEV; } 147 static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } 148 static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } 149 static inline int cpuidle_register_device(struct cpuidle_device *dev) 150 {return -ENODEV; } 151 static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } 152 153 static inline void cpuidle_pause_and_lock(void) { } 154 static inline void cpuidle_resume_and_unlock(void) { } 155 static inline int cpuidle_enable_device(struct cpuidle_device *dev) 156 {return -ENODEV; } 157 static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } 158 159 #endif 160 161 /****************************** 162 * CPUIDLE GOVERNOR INTERFACE * 163 ******************************/ 164 165 struct cpuidle_governor { 166 char name[CPUIDLE_NAME_LEN]; 167 struct list_head governor_list; 168 unsigned int rating; 169 170 int (*enable) (struct cpuidle_device *dev); 171 void (*disable) (struct cpuidle_device *dev); 172 173 int (*select) (struct cpuidle_device *dev); 174 void (*reflect) (struct cpuidle_device *dev); 175 176 struct module *owner; 177 }; 178 179 #ifdef CONFIG_CPU_IDLE 180 181 extern int cpuidle_register_governor(struct cpuidle_governor *gov); 182 extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); 183 184 #else 185 186 static inline int cpuidle_register_governor(struct cpuidle_governor *gov) 187 {return 0;} 188 static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { } 189 190 #endif 191 192 #ifdef CONFIG_ARCH_HAS_CPU_RELAX 193 #define CPUIDLE_DRIVER_STATE_START 1 194 #else 195 #define CPUIDLE_DRIVER_STATE_START 0 196 #endif 197 198 #endif /* _LINUX_CPUIDLE_H */ 199