GNU Linux-libre 4.4.289-gnu1
[releases.git] / drivers / cpuidle / driver.c
1 /*
2  * driver.c - driver support
3  *
4  * (C) 2006-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 #include <linux/mutex.h>
12 #include <linux/module.h>
13 #include <linux/sched.h>
14 #include <linux/cpuidle.h>
15 #include <linux/cpumask.h>
16 #include <linux/tick.h>
17
18 #include "cpuidle.h"
19
20 DEFINE_SPINLOCK(cpuidle_driver_lock);
21
22 #ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
23
24 static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
25
26 /**
27  * __cpuidle_get_cpu_driver - return the cpuidle driver tied to a CPU.
28  * @cpu: the CPU handled by the driver
29  *
30  * Returns a pointer to struct cpuidle_driver or NULL if no driver has been
31  * registered for @cpu.
32  */
33 static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
34 {
35         return per_cpu(cpuidle_drivers, cpu);
36 }
37
38 /**
39  * __cpuidle_unset_driver - unset per CPU driver variables.
40  * @drv: a valid pointer to a struct cpuidle_driver
41  *
42  * For each CPU in the driver's CPU mask, unset the registered driver per CPU
43  * variable. If @drv is different from the registered driver, the corresponding
44  * variable is not cleared.
45  */
46 static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
47 {
48         int cpu;
49
50         for_each_cpu(cpu, drv->cpumask) {
51
52                 if (drv != __cpuidle_get_cpu_driver(cpu))
53                         continue;
54
55                 per_cpu(cpuidle_drivers, cpu) = NULL;
56         }
57 }
58
59 /**
60  * __cpuidle_set_driver - set per CPU driver variables for the given driver.
61  * @drv: a valid pointer to a struct cpuidle_driver
62  *
63  * Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver
64  * different from drv already.
65  */
66 static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
67 {
68         int cpu;
69
70         for_each_cpu(cpu, drv->cpumask) {
71                 struct cpuidle_driver *old_drv;
72
73                 old_drv = __cpuidle_get_cpu_driver(cpu);
74                 if (old_drv && old_drv != drv)
75                         return -EBUSY;
76         }
77
78         for_each_cpu(cpu, drv->cpumask)
79                 per_cpu(cpuidle_drivers, cpu) = drv;
80
81         return 0;
82 }
83
84 #else
85
86 static struct cpuidle_driver *cpuidle_curr_driver;
87
88 /**
89  * __cpuidle_get_cpu_driver - return the global cpuidle driver pointer.
90  * @cpu: ignored without the multiple driver support
91  *
92  * Return a pointer to a struct cpuidle_driver object or NULL if no driver was
93  * previously registered.
94  */
95 static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
96 {
97         return cpuidle_curr_driver;
98 }
99
100 /**
101  * __cpuidle_set_driver - assign the global cpuidle driver variable.
102  * @drv: pointer to a struct cpuidle_driver object
103  *
104  * Returns 0 on success, -EBUSY if the driver is already registered.
105  */
106 static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
107 {
108         if (cpuidle_curr_driver)
109                 return -EBUSY;
110
111         cpuidle_curr_driver = drv;
112
113         return 0;
114 }
115
116 /**
117  * __cpuidle_unset_driver - unset the global cpuidle driver variable.
118  * @drv: a pointer to a struct cpuidle_driver
119  *
120  * Reset the global cpuidle variable to NULL.  If @drv does not match the
121  * registered driver, do nothing.
122  */
123 static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
124 {
125         if (drv == cpuidle_curr_driver)
126                 cpuidle_curr_driver = NULL;
127 }
128
129 #endif
130
131 /**
132  * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer on a cpu
133  * @arg: a void pointer used to match the SMP cross call API
134  *
135  * If @arg is NULL broadcast is disabled otherwise enabled
136  *
137  * This function is executed per CPU by an SMP cross call.  It's not
138  * supposed to be called directly.
139  */
140 static void cpuidle_setup_broadcast_timer(void *arg)
141 {
142         if (arg)
143                 tick_broadcast_enable();
144         else
145                 tick_broadcast_disable();
146 }
147
148 /**
149  * __cpuidle_driver_init - initialize the driver's internal data
150  * @drv: a valid pointer to a struct cpuidle_driver
151  */
152 static void __cpuidle_driver_init(struct cpuidle_driver *drv)
153 {
154         int i;
155
156         drv->refcnt = 0;
157
158         /*
159          * Use all possible CPUs as the default, because if the kernel boots
160          * with some CPUs offline and then we online one of them, the CPU
161          * notifier has to know which driver to assign.
162          */
163         if (!drv->cpumask)
164                 drv->cpumask = (struct cpumask *)cpu_possible_mask;
165
166         /*
167          * Look for the timer stop flag in the different states, so that we know
168          * if the broadcast timer has to be set up.  The loop is in the reverse
169          * order, because usually one of the deeper states have this flag set.
170          */
171         for (i = drv->state_count - 1; i >= 0 ; i--) {
172                 if (drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP) {
173                         drv->bctimer = 1;
174                         break;
175                 }
176         }
177 }
178
179 #ifdef CONFIG_ARCH_HAS_CPU_RELAX
180 static int poll_idle(struct cpuidle_device *dev,
181                 struct cpuidle_driver *drv, int index)
182 {
183         local_irq_enable();
184         if (!current_set_polling_and_test()) {
185                 while (!need_resched())
186                         cpu_relax();
187         }
188         current_clr_polling();
189
190         return index;
191 }
192
193 static void poll_idle_init(struct cpuidle_driver *drv)
194 {
195         struct cpuidle_state *state = &drv->states[0];
196
197         snprintf(state->name, CPUIDLE_NAME_LEN, "POLL");
198         snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE");
199         state->exit_latency = 0;
200         state->target_residency = 0;
201         state->power_usage = -1;
202         state->enter = poll_idle;
203         state->disabled = false;
204 }
205 #else
206 static void poll_idle_init(struct cpuidle_driver *drv) {}
207 #endif /* !CONFIG_ARCH_HAS_CPU_RELAX */
208
209 /**
210  * __cpuidle_register_driver: register the driver
211  * @drv: a valid pointer to a struct cpuidle_driver
212  *
213  * Do some sanity checks, initialize the driver, assign the driver to the
214  * global cpuidle driver variable(s) and set up the broadcast timer if the
215  * cpuidle driver has some states that shut down the local timer.
216  *
217  * Returns 0 on success, a negative error code otherwise:
218  *  * -EINVAL if the driver pointer is NULL or no idle states are available
219  *  * -ENODEV if the cpuidle framework is disabled
220  *  * -EBUSY if the driver is already assigned to the global variable(s)
221  */
222 static int __cpuidle_register_driver(struct cpuidle_driver *drv)
223 {
224         int ret;
225
226         if (!drv || !drv->state_count)
227                 return -EINVAL;
228
229         ret = cpuidle_coupled_state_verify(drv);
230         if (ret)
231                 return ret;
232
233         if (cpuidle_disabled())
234                 return -ENODEV;
235
236         __cpuidle_driver_init(drv);
237
238         ret = __cpuidle_set_driver(drv);
239         if (ret)
240                 return ret;
241
242         if (drv->bctimer)
243                 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
244                                  (void *)1, 1);
245
246         poll_idle_init(drv);
247
248         return 0;
249 }
250
251 /**
252  * __cpuidle_unregister_driver - unregister the driver
253  * @drv: a valid pointer to a struct cpuidle_driver
254  *
255  * Check if the driver is no longer in use, reset the global cpuidle driver
256  * variable(s) and disable the timer broadcast notification mechanism if it was
257  * in use.
258  *
259  */
260 static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)
261 {
262         if (WARN_ON(drv->refcnt > 0))
263                 return;
264
265         if (drv->bctimer) {
266                 drv->bctimer = 0;
267                 on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
268                                  NULL, 1);
269         }
270
271         __cpuidle_unset_driver(drv);
272 }
273
274 /**
275  * cpuidle_register_driver - registers a driver
276  * @drv: a pointer to a valid struct cpuidle_driver
277  *
278  * Register the driver under a lock to prevent concurrent attempts to
279  * [un]register the driver from occuring at the same time.
280  *
281  * Returns 0 on success, a negative error code (returned by
282  * __cpuidle_register_driver()) otherwise.
283  */
284 int cpuidle_register_driver(struct cpuidle_driver *drv)
285 {
286         int ret;
287
288         spin_lock(&cpuidle_driver_lock);
289         ret = __cpuidle_register_driver(drv);
290         spin_unlock(&cpuidle_driver_lock);
291
292         return ret;
293 }
294 EXPORT_SYMBOL_GPL(cpuidle_register_driver);
295
296 /**
297  * cpuidle_unregister_driver - unregisters a driver
298  * @drv: a pointer to a valid struct cpuidle_driver
299  *
300  * Unregisters the cpuidle driver under a lock to prevent concurrent attempts
301  * to [un]register the driver from occuring at the same time.  @drv has to
302  * match the currently registered driver.
303  */
304 void cpuidle_unregister_driver(struct cpuidle_driver *drv)
305 {
306         spin_lock(&cpuidle_driver_lock);
307         __cpuidle_unregister_driver(drv);
308         spin_unlock(&cpuidle_driver_lock);
309 }
310 EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
311
312 /**
313  * cpuidle_get_driver - return the driver tied to the current CPU.
314  *
315  * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered.
316  */
317 struct cpuidle_driver *cpuidle_get_driver(void)
318 {
319         struct cpuidle_driver *drv;
320         int cpu;
321
322         cpu = get_cpu();
323         drv = __cpuidle_get_cpu_driver(cpu);
324         put_cpu();
325
326         return drv;
327 }
328 EXPORT_SYMBOL_GPL(cpuidle_get_driver);
329
330 /**
331  * cpuidle_get_cpu_driver - return the driver registered for a CPU.
332  * @dev: a valid pointer to a struct cpuidle_device
333  *
334  * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered
335  * for the CPU associated with @dev.
336  */
337 struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
338 {
339         if (!dev)
340                 return NULL;
341
342         return __cpuidle_get_cpu_driver(dev->cpu);
343 }
344 EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver);
345
346 /**
347  * cpuidle_driver_ref - get a reference to the driver.
348  *
349  * Increment the reference counter of the cpuidle driver associated with
350  * the current CPU.
351  *
352  * Returns a pointer to the driver, or NULL if the current CPU has no driver.
353  */
354 struct cpuidle_driver *cpuidle_driver_ref(void)
355 {
356         struct cpuidle_driver *drv;
357
358         spin_lock(&cpuidle_driver_lock);
359
360         drv = cpuidle_get_driver();
361         if (drv)
362                 drv->refcnt++;
363
364         spin_unlock(&cpuidle_driver_lock);
365         return drv;
366 }
367
368 /**
369  * cpuidle_driver_unref - puts down the refcount for the driver
370  *
371  * Decrement the reference counter of the cpuidle driver associated with
372  * the current CPU.
373  */
374 void cpuidle_driver_unref(void)
375 {
376         struct cpuidle_driver *drv;
377
378         spin_lock(&cpuidle_driver_lock);
379
380         drv = cpuidle_get_driver();
381         if (drv && !WARN_ON(drv->refcnt <= 0))
382                 drv->refcnt--;
383
384         spin_unlock(&cpuidle_driver_lock);
385 }