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 57 #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) 58 59 /** 60 * cpuidle_get_statedata - retrieves private driver state data 61 * @state: the state 62 */ 63 static inline void * cpuidle_get_statedata(struct cpuidle_state *state) 64 { 65 return state->driver_data; 66 } 67 68 /** 69 * cpuidle_set_statedata - stores private driver state data 70 * @state: the state 71 * @data: the private data 72 */ 73 static inline void 74 cpuidle_set_statedata(struct cpuidle_state *state, void *data) 75 { 76 state->driver_data = data; 77 } 78 79 struct cpuidle_state_kobj { 80 struct cpuidle_state *state; 81 struct completion kobj_unregister; 82 struct kobject kobj; 83 }; 84 85 struct cpuidle_device { 86 unsigned int registered:1; 87 unsigned int enabled:1; 88 unsigned int power_specified:1; 89 unsigned int cpu; 90 91 int last_residency; 92 int state_count; 93 struct cpuidle_state states[CPUIDLE_STATE_MAX]; 94 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; 95 struct cpuidle_state *last_state; 96 97 struct list_head device_list; 98 struct kobject kobj; 99 struct completion kobj_unregister; 100 void *governor_data; 101 struct cpuidle_state *safe_state; 102 103 int (*prepare) (struct cpuidle_device *dev); 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 char name[CPUIDLE_NAME_LEN]; 126 struct module *owner; 127 }; 128 129 #ifdef CONFIG_CPU_IDLE 130 131 extern int cpuidle_register_driver(struct cpuidle_driver *drv); 132 struct cpuidle_driver *cpuidle_get_driver(void); 133 extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); 134 extern int cpuidle_register_device(struct cpuidle_device *dev); 135 extern void cpuidle_unregister_device(struct cpuidle_device *dev); 136 137 extern void cpuidle_pause_and_lock(void); 138 extern void cpuidle_resume_and_unlock(void); 139 extern int cpuidle_enable_device(struct cpuidle_device *dev); 140 extern void cpuidle_disable_device(struct cpuidle_device *dev); 141 142 #else 143 144 static inline int cpuidle_register_driver(struct cpuidle_driver *drv) 145 {return -ENODEV; } 146 static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } 147 static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } 148 static inline int cpuidle_register_device(struct cpuidle_device *dev) 149 {return -ENODEV; } 150 static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } 151 152 static inline void cpuidle_pause_and_lock(void) { } 153 static inline void cpuidle_resume_and_unlock(void) { } 154 static inline int cpuidle_enable_device(struct cpuidle_device *dev) 155 {return -ENODEV; } 156 static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } 157 158 #endif 159 160 /****************************** 161 * CPUIDLE GOVERNOR INTERFACE * 162 ******************************/ 163 164 struct cpuidle_governor { 165 char name[CPUIDLE_NAME_LEN]; 166 struct list_head governor_list; 167 unsigned int rating; 168 169 int (*enable) (struct cpuidle_device *dev); 170 void (*disable) (struct cpuidle_device *dev); 171 172 int (*select) (struct cpuidle_device *dev); 173 void (*reflect) (struct cpuidle_device *dev); 174 175 struct module *owner; 176 }; 177 178 #ifdef CONFIG_CPU_IDLE 179 180 extern int cpuidle_register_governor(struct cpuidle_governor *gov); 181 extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); 182 183 #else 184 185 static inline int cpuidle_register_governor(struct cpuidle_governor *gov) 186 {return 0;} 187 static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { } 188 189 #endif 190 191 #ifdef CONFIG_ARCH_HAS_CPU_RELAX 192 #define CPUIDLE_DRIVER_STATE_START 1 193 #else 194 #define CPUIDLE_DRIVER_STATE_START 0 195 #endif 196 197 #endif /* _LINUX_CPUIDLE_H */ 198