PCI: pnv_php: Add missing of_node_put()
[linux-2.6-block.git] / include / linux / cpuidle.h
CommitLineData
4f86d3a8
LB
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>
e1689795 16#include <linux/hrtimer.h>
4f86d3a8 17
86239ceb 18#define CPUIDLE_STATE_MAX 10
4f86d3a8 19#define CPUIDLE_NAME_LEN 16
4fcb2fcd 20#define CPUIDLE_DESC_LEN 32
4f86d3a8 21
de477254
PG
22struct module;
23
4f86d3a8 24struct cpuidle_device;
46bcfad7 25struct cpuidle_driver;
4f86d3a8
LB
26
27
28/****************************
29 * CPUIDLE DEVICE INTERFACE *
30 ****************************/
31
4202735e 32struct cpuidle_state_usage {
dc7fd275 33 unsigned long long disable;
4202735e
DD
34 unsigned long long usage;
35 unsigned long long time; /* in US */
64bdff69
RW
36#ifdef CONFIG_SUSPEND
37 unsigned long long s2idle_usage;
38 unsigned long long s2idle_time; /* in US */
39#endif
4202735e
DD
40};
41
4f86d3a8
LB
42struct cpuidle_state {
43 char name[CPUIDLE_NAME_LEN];
4fcb2fcd 44 char desc[CPUIDLE_DESC_LEN];
4f86d3a8
LB
45
46 unsigned int flags;
47 unsigned int exit_latency; /* in US */
02401c06 48 int power_usage; /* in mW */
4f86d3a8 49 unsigned int target_residency; /* in US */
cbc9ef02 50 bool disabled; /* disabled on all CPUs */
4f86d3a8 51
4f86d3a8 52 int (*enter) (struct cpuidle_device *dev,
46bcfad7 53 struct cpuidle_driver *drv,
e978aa7d 54 int index);
1a022e3f
BO
55
56 int (*enter_dead) (struct cpuidle_device *dev, int index);
124cf911
RW
57
58 /*
28ba086e 59 * CPUs execute ->enter_s2idle with the local tick or entire timekeeping
124cf911
RW
60 * suspended, so it must not re-enable interrupts at any point (even
61 * temporarily) or attempt to change states of clock event devices.
62 */
28ba086e 63 void (*enter_s2idle) (struct cpuidle_device *dev,
124cf911
RW
64 struct cpuidle_driver *drv,
65 int index);
4f86d3a8
LB
66};
67
68/* Idle State Flags */
9e9fc6f0 69#define CPUIDLE_FLAG_NONE (0x00)
dc2251bf 70#define CPUIDLE_FLAG_POLLING (0x01) /* polling state */
4126c019 71#define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */
b60e6a0e 72#define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */
4f86d3a8
LB
73
74#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
75
728ce22b 76struct cpuidle_device_kobj;
1a706438
DL
77struct cpuidle_state_kobj;
78struct cpuidle_driver_kobj;
728ce22b 79
4f86d3a8 80struct cpuidle_device {
dcb84f33 81 unsigned int registered:1;
b5556a67 82 unsigned int enabled:1;
bb8313b6 83 unsigned int use_deepest_state:1;
4f86d3a8
LB
84 unsigned int cpu;
85
86 int last_residency;
4202735e 87 struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX];
4f86d3a8 88 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
bf4d1b5d 89 struct cpuidle_driver_kobj *kobj_driver;
728ce22b 90 struct cpuidle_device_kobj *kobj_dev;
4f86d3a8 91 struct list_head device_list;
4126c019
CC
92
93#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
4126c019
CC
94 cpumask_t coupled_cpus;
95 struct cpuidle_coupled *coupled;
96#endif
4f86d3a8
LB
97};
98
99DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
f08dbf8a 100DECLARE_PER_CPU(struct cpuidle_device, cpuidle_dev);
4f86d3a8
LB
101
102/**
103 * cpuidle_get_last_residency - retrieves the last state's residency time
104 * @dev: the target CPU
4f86d3a8
LB
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 {
db70b044 117 const char *name;
4f86d3a8 118 struct module *owner;
42f67f2a 119 int refcnt;
46bcfad7 120
a06df062
DL
121 /* used by the cpuidle framework to setup the broadcast timer */
122 unsigned int bctimer:1;
8aef33a7 123 /* states array must be ordered in decreasing power consumption */
46bcfad7
DD
124 struct cpuidle_state states[CPUIDLE_STATE_MAX];
125 int state_count;
126 int safe_state_index;
82467a5a
DL
127
128 /* the driver handles the cpus in cpumask */
6587fca2 129 struct cpumask *cpumask;
4f86d3a8
LB
130};
131
132#ifdef CONFIG_CPU_IDLE
d91ee586 133extern void disable_cpuidle(void);
ef2b22ac
RW
134extern bool cpuidle_not_available(struct cpuidle_driver *drv,
135 struct cpuidle_device *dev);
907e30f1 136
907e30f1 137extern int cpuidle_select(struct cpuidle_driver *drv,
45f1ff59
RW
138 struct cpuidle_device *dev,
139 bool *stop_tick);
907e30f1
DL
140extern int cpuidle_enter(struct cpuidle_driver *drv,
141 struct cpuidle_device *dev, int index);
142extern void cpuidle_reflect(struct cpuidle_device *dev, int index);
143
4f86d3a8 144extern int cpuidle_register_driver(struct cpuidle_driver *drv);
6e797a07
RW
145extern struct cpuidle_driver *cpuidle_get_driver(void);
146extern struct cpuidle_driver *cpuidle_driver_ref(void);
147extern void cpuidle_driver_unref(void);
4f86d3a8
LB
148extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
149extern int cpuidle_register_device(struct cpuidle_device *dev);
150extern void cpuidle_unregister_device(struct cpuidle_device *dev);
4c637b21
DL
151extern int cpuidle_register(struct cpuidle_driver *drv,
152 const struct cpumask *const coupled_cpus);
153extern void cpuidle_unregister(struct cpuidle_driver *drv);
4f86d3a8
LB
154extern void cpuidle_pause_and_lock(void);
155extern void cpuidle_resume_and_unlock(void);
8651f97b
PM
156extern void cpuidle_pause(void);
157extern void cpuidle_resume(void);
4f86d3a8
LB
158extern int cpuidle_enable_device(struct cpuidle_device *dev);
159extern void cpuidle_disable_device(struct cpuidle_device *dev);
1a022e3f
BO
160extern int cpuidle_play_dead(void);
161
bf4d1b5d 162extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
9bd616e3
CM
163static inline struct cpuidle_device *cpuidle_get_device(void)
164{return __this_cpu_read(cpuidle_devices); }
4f86d3a8 165#else
d91ee586 166static inline void disable_cpuidle(void) { }
ef2b22ac
RW
167static inline bool cpuidle_not_available(struct cpuidle_driver *drv,
168 struct cpuidle_device *dev)
169{return true; }
907e30f1 170static inline int cpuidle_select(struct cpuidle_driver *drv,
45f1ff59 171 struct cpuidle_device *dev, bool *stop_tick)
907e30f1
DL
172{return -ENODEV; }
173static inline int cpuidle_enter(struct cpuidle_driver *drv,
174 struct cpuidle_device *dev, int index)
175{return -ENODEV; }
176static inline void cpuidle_reflect(struct cpuidle_device *dev, int index) { }
4f86d3a8 177static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
6b2c676b 178{return -ENODEV; }
752138df 179static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
6e797a07
RW
180static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; }
181static inline void cpuidle_driver_unref(void) {}
4f86d3a8
LB
182static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
183static inline int cpuidle_register_device(struct cpuidle_device *dev)
6b2c676b 184{return -ENODEV; }
4f86d3a8 185static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
4c637b21
DL
186static inline int cpuidle_register(struct cpuidle_driver *drv,
187 const struct cpumask *const coupled_cpus)
188{return -ENODEV; }
189static inline void cpuidle_unregister(struct cpuidle_driver *drv) { }
4f86d3a8
LB
190static inline void cpuidle_pause_and_lock(void) { }
191static inline void cpuidle_resume_and_unlock(void) { }
8651f97b
PM
192static inline void cpuidle_pause(void) { }
193static inline void cpuidle_resume(void) { }
4f86d3a8 194static inline int cpuidle_enable_device(struct cpuidle_device *dev)
6b2c676b 195{return -ENODEV; }
4f86d3a8 196static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
1a022e3f 197static inline int cpuidle_play_dead(void) {return -ENODEV; }
87e9b9f1
RW
198static inline struct cpuidle_driver *cpuidle_get_cpu_driver(
199 struct cpuidle_device *dev) {return NULL; }
9bd616e3 200static inline struct cpuidle_device *cpuidle_get_device(void) {return NULL; }
87e9b9f1
RW
201#endif
202
bb8313b6 203#ifdef CONFIG_CPU_IDLE
87e9b9f1
RW
204extern int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
205 struct cpuidle_device *dev);
28ba086e 206extern int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
87e9b9f1 207 struct cpuidle_device *dev);
bb8313b6 208extern void cpuidle_use_deepest_state(bool enable);
87e9b9f1 209#else
ef2b22ac
RW
210static inline int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
211 struct cpuidle_device *dev)
212{return -ENODEV; }
28ba086e 213static inline int cpuidle_enter_s2idle(struct cpuidle_driver *drv,
ef2b22ac
RW
214 struct cpuidle_device *dev)
215{return -ENODEV; }
bb8313b6
JP
216static inline void cpuidle_use_deepest_state(bool enable)
217{
218}
4f86d3a8
LB
219#endif
220
faad3849
RW
221/* kernel/sched/idle.c */
222extern void sched_idle_set_state(struct cpuidle_state *idle_state);
827a5aef 223extern void default_idle_call(void);
faad3849 224
20ff51a3
CC
225#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
226void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
c7a9b09b
AB
227#else
228static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
229{
230}
20ff51a3
CC
231#endif
232
d7212cfb 233#if defined(CONFIG_CPU_IDLE) && defined(CONFIG_ARCH_HAS_CPU_RELAX)
1b39e3f8 234void cpuidle_poll_state_init(struct cpuidle_driver *drv);
34c2f65b 235#else
1b39e3f8 236static inline void cpuidle_poll_state_init(struct cpuidle_driver *drv) {}
34c2f65b
RW
237#endif
238
4f86d3a8
LB
239/******************************
240 * CPUIDLE GOVERNOR INTERFACE *
241 ******************************/
242
243struct cpuidle_governor {
244 char name[CPUIDLE_NAME_LEN];
245 struct list_head governor_list;
246 unsigned int rating;
247
46bcfad7
DD
248 int (*enable) (struct cpuidle_driver *drv,
249 struct cpuidle_device *dev);
250 void (*disable) (struct cpuidle_driver *drv,
251 struct cpuidle_device *dev);
4f86d3a8 252
46bcfad7 253 int (*select) (struct cpuidle_driver *drv,
45f1ff59
RW
254 struct cpuidle_device *dev,
255 bool *stop_tick);
e978aa7d 256 void (*reflect) (struct cpuidle_device *dev, int index);
4f86d3a8
LB
257};
258
259#ifdef CONFIG_CPU_IDLE
4f86d3a8 260extern int cpuidle_register_governor(struct cpuidle_governor *gov);
4f86d3a8 261#else
4f86d3a8
LB
262static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
263{return 0;}
4f86d3a8
LB
264#endif
265
db50a74d
PP
266#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, is_retention) \
267({ \
268 int __ret = 0; \
269 \
270 if (!idx) { \
271 cpu_do_idle(); \
272 return idx; \
273 } \
274 \
275 if (!is_retention) \
276 __ret = cpu_pm_enter(); \
277 if (!__ret) { \
278 __ret = low_level_idle_enter(idx); \
279 if (!is_retention) \
280 cpu_pm_exit(); \
281 } \
282 \
283 __ret ? -1 : idx; \
220276e0
SH
284})
285
db50a74d
PP
286#define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx) \
287 __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 0)
288
289#define CPU_PM_CPU_IDLE_ENTER_RETENTION(low_level_idle_enter, idx) \
290 __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 1)
291
4f86d3a8 292#endif /* _LINUX_CPUIDLE_H */