1
2
3
4
5
6
7
8
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 10
21#define CPUIDLE_NAME_LEN 16
22#define CPUIDLE_DESC_LEN 32
23
24struct module;
25
26struct cpuidle_device;
27struct cpuidle_driver;
28
29
30
31
32
33
34struct cpuidle_state_usage {
35 unsigned long long disable;
36 unsigned long long usage;
37 unsigned long long time;
38};
39
40struct cpuidle_state {
41 char name[CPUIDLE_NAME_LEN];
42 char desc[CPUIDLE_DESC_LEN];
43
44 unsigned int flags;
45 unsigned int exit_latency;
46 int power_usage;
47 unsigned int target_residency;
48 bool disabled;
49
50 int (*enter) (struct cpuidle_device *dev,
51 struct cpuidle_driver *drv,
52 int index);
53
54 int (*enter_dead) (struct cpuidle_device *dev, int index);
55};
56
57
58#define CPUIDLE_FLAG_TIME_INVALID (0x01)
59#define CPUIDLE_FLAG_COUPLED (0x02)
60#define CPUIDLE_FLAG_TIMER_STOP (0x04)
61
62#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
63
64struct cpuidle_device {
65 unsigned int registered:1;
66 unsigned int enabled:1;
67 unsigned int cpu;
68
69 int last_residency;
70 int state_count;
71 struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX];
72 struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
73 struct cpuidle_driver_kobj *kobj_driver;
74 struct list_head device_list;
75 struct kobject kobj;
76 struct completion kobj_unregister;
77
78#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
79 int safe_state_index;
80 cpumask_t coupled_cpus;
81 struct cpuidle_coupled *coupled;
82#endif
83};
84
85DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
86
87
88
89
90
91
92
93static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
94{
95 return dev->last_residency;
96}
97
98
99
100
101
102
103struct cpuidle_driver {
104 const char *name;
105 struct module *owner;
106 int refcnt;
107
108
109 unsigned int bctimer:1;
110
111 struct cpuidle_state states[CPUIDLE_STATE_MAX];
112 int state_count;
113 int safe_state_index;
114
115
116 struct cpumask *cpumask;
117};
118
119#ifdef CONFIG_CPU_IDLE
120extern void disable_cpuidle(void);
121extern int cpuidle_idle_call(void);
122extern int cpuidle_register_driver(struct cpuidle_driver *drv);
123extern struct cpuidle_driver *cpuidle_get_driver(void);
124extern struct cpuidle_driver *cpuidle_driver_ref(void);
125extern void cpuidle_driver_unref(void);
126extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
127extern int cpuidle_register_device(struct cpuidle_device *dev);
128extern void cpuidle_unregister_device(struct cpuidle_device *dev);
129extern int cpuidle_register(struct cpuidle_driver *drv,
130 const struct cpumask *const coupled_cpus);
131extern void cpuidle_unregister(struct cpuidle_driver *drv);
132extern void cpuidle_pause_and_lock(void);
133extern void cpuidle_resume_and_unlock(void);
134extern void cpuidle_pause(void);
135extern void cpuidle_resume(void);
136extern int cpuidle_enable_device(struct cpuidle_device *dev);
137extern void cpuidle_disable_device(struct cpuidle_device *dev);
138extern int cpuidle_play_dead(void);
139
140extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
141#else
142static inline void disable_cpuidle(void) { }
143static inline int cpuidle_idle_call(void) { return -ENODEV; }
144static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
145{return -ENODEV; }
146static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
147static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; }
148static inline void cpuidle_driver_unref(void) {}
149static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
150static inline int cpuidle_register_device(struct cpuidle_device *dev)
151{return -ENODEV; }
152static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
153static inline int cpuidle_register(struct cpuidle_driver *drv,
154 const struct cpumask *const coupled_cpus)
155{return -ENODEV; }
156static inline void cpuidle_unregister(struct cpuidle_driver *drv) { }
157static inline void cpuidle_pause_and_lock(void) { }
158static inline void cpuidle_resume_and_unlock(void) { }
159static inline void cpuidle_pause(void) { }
160static inline void cpuidle_resume(void) { }
161static inline int cpuidle_enable_device(struct cpuidle_device *dev)
162{return -ENODEV; }
163static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
164static inline int cpuidle_play_dead(void) {return -ENODEV; }
165#endif
166
167#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
168void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a);
169#else
170static inline void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
171{
172}
173#endif
174
175
176
177
178
179struct cpuidle_governor {
180 char name[CPUIDLE_NAME_LEN];
181 struct list_head governor_list;
182 unsigned int rating;
183
184 int (*enable) (struct cpuidle_driver *drv,
185 struct cpuidle_device *dev);
186 void (*disable) (struct cpuidle_driver *drv,
187 struct cpuidle_device *dev);
188
189 int (*select) (struct cpuidle_driver *drv,
190 struct cpuidle_device *dev);
191 void (*reflect) (struct cpuidle_device *dev, int index);
192
193 struct module *owner;
194};
195
196#ifdef CONFIG_CPU_IDLE
197
198extern int cpuidle_register_governor(struct cpuidle_governor *gov);
199extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
200
201#else
202
203static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
204{return 0;}
205static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { }
206
207#endif
208
209#ifdef CONFIG_ARCH_HAS_CPU_RELAX
210#define CPUIDLE_DRIVER_STATE_START 1
211#else
212#define CPUIDLE_DRIVER_STATE_START 0
213#endif
214
215#endif
216