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