blob: 9fb2edf366119bff78e252f5d4fd89d62e350cb8 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/cpufreq/cpufreq.c
3 *
4 * Copyright (C) 2001 Russell King
5 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08007 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05008 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -05009 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
10 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080011 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/notifier.h>
22#include <linux/cpufreq.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <linux/spinlock.h>
26#include <linux/device.h>
27#include <linux/slab.h>
28#include <linux/cpu.h>
29#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080030#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Gautham R Shenoye08f5f52006-10-26 16:20:58 +053032#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
33 "cpufreq-core", msg)
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
35/**
Dave Jonescd878472006-08-11 17:59:28 -040036 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 * level driver of CPUFreq support, and its spinlock. This lock
38 * also protects the cpufreq_cpu_data array.
39 */
Dave Jones7d5e3502006-02-02 17:03:42 -050040static struct cpufreq_driver *cpufreq_driver;
41static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
Linus Torvalds1da177e2005-04-16 15:20:36 -070042static DEFINE_SPINLOCK(cpufreq_driver_lock);
43
Linus Torvalds1da177e2005-04-16 15:20:36 -070044/* internal prototypes */
45static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
David Howells65f27f32006-11-22 14:55:48 +000046static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
48/**
Dave Jones32ee8c32006-02-28 00:43:23 -050049 * Two notifier lists: the "policy" list is involved in the
50 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -070051 * "transition" list for kernel code that needs to handle
52 * changes to devices when the CPU clock speed changes.
53 * The mutex locks both lists.
54 */
Alan Sterne041c682006-03-27 01:16:30 -080055static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -070056static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Alan Sternb4dfdbb2006-10-04 02:17:06 -070058static int __init init_cpufreq_transition_notifier_list(void)
59{
60 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
61 return 0;
62}
Linus Torvaldsb3438f82006-11-20 11:47:18 -080063pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
65static LIST_HEAD(cpufreq_governor_list);
Dave Jones7d5e3502006-02-02 17:03:42 -050066static DEFINE_MUTEX (cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
Dave Jones7d5e3502006-02-02 17:03:42 -050068struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069{
70 struct cpufreq_policy *data;
71 unsigned long flags;
72
73 if (cpu >= NR_CPUS)
74 goto err_out;
75
76 /* get the cpufreq driver */
77 spin_lock_irqsave(&cpufreq_driver_lock, flags);
78
79 if (!cpufreq_driver)
80 goto err_out_unlock;
81
82 if (!try_module_get(cpufreq_driver->owner))
83 goto err_out_unlock;
84
85
86 /* get the CPU */
87 data = cpufreq_cpu_data[cpu];
88
89 if (!data)
90 goto err_out_put_module;
91
92 if (!kobject_get(&data->kobj))
93 goto err_out_put_module;
94
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 return data;
97
Dave Jones7d5e3502006-02-02 17:03:42 -050098err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500100err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500102err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 return NULL;
104}
105EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
106
Dave Jones7d5e3502006-02-02 17:03:42 -0500107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108void cpufreq_cpu_put(struct cpufreq_policy *data)
109{
110 kobject_put(&data->kobj);
111 module_put(cpufreq_driver->owner);
112}
113EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
114
115
116/*********************************************************************
117 * UNIFIED DEBUG HELPERS *
118 *********************************************************************/
119#ifdef CONFIG_CPU_FREQ_DEBUG
120
121/* what part(s) of the CPUfreq subsystem are debugged? */
122static unsigned int debug;
123
124/* is the debug output ratelimit'ed using printk_ratelimit? User can
125 * set or modify this value.
126 */
127static unsigned int debug_ratelimit = 1;
128
129/* is the printk_ratelimit'ing enabled? It's enabled after a successful
130 * loading of a cpufreq driver, temporarily disabled when a new policy
131 * is set, and disabled upon cpufreq driver removal
132 */
133static unsigned int disable_ratelimit = 1;
134static DEFINE_SPINLOCK(disable_ratelimit_lock);
135
Arjan van de Ven858119e2006-01-14 13:20:43 -0800136static void cpufreq_debug_enable_ratelimit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137{
138 unsigned long flags;
139
140 spin_lock_irqsave(&disable_ratelimit_lock, flags);
141 if (disable_ratelimit)
142 disable_ratelimit--;
143 spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
144}
145
Arjan van de Ven858119e2006-01-14 13:20:43 -0800146static void cpufreq_debug_disable_ratelimit(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147{
148 unsigned long flags;
149
150 spin_lock_irqsave(&disable_ratelimit_lock, flags);
151 disable_ratelimit++;
152 spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
153}
154
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530155void cpufreq_debug_printk(unsigned int type, const char *prefix,
156 const char *fmt, ...)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157{
158 char s[256];
159 va_list args;
160 unsigned int len;
161 unsigned long flags;
Dave Jones32ee8c32006-02-28 00:43:23 -0500162
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 WARN_ON(!prefix);
164 if (type & debug) {
165 spin_lock_irqsave(&disable_ratelimit_lock, flags);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530166 if (!disable_ratelimit && debug_ratelimit
167 && !printk_ratelimit()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
169 return;
170 }
171 spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
172
173 len = snprintf(s, 256, KERN_DEBUG "%s: ", prefix);
174
175 va_start(args, fmt);
176 len += vsnprintf(&s[len], (256 - len), fmt, args);
177 va_end(args);
178
179 printk(s);
180
181 WARN_ON(len < 5);
182 }
183}
184EXPORT_SYMBOL(cpufreq_debug_printk);
185
186
187module_param(debug, uint, 0644);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530188MODULE_PARM_DESC(debug, "CPUfreq debugging: add 1 to debug core,"
189 " 2 to debug drivers, and 4 to debug governors.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190
191module_param(debug_ratelimit, uint, 0644);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530192MODULE_PARM_DESC(debug_ratelimit, "CPUfreq debugging:"
193 " set to 0 to disable ratelimiting.");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194
195#else /* !CONFIG_CPU_FREQ_DEBUG */
196
197static inline void cpufreq_debug_enable_ratelimit(void) { return; }
198static inline void cpufreq_debug_disable_ratelimit(void) { return; }
199
200#endif /* CONFIG_CPU_FREQ_DEBUG */
201
202
203/*********************************************************************
204 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
205 *********************************************************************/
206
207/**
208 * adjust_jiffies - adjust the system "loops_per_jiffy"
209 *
210 * This function alters the system "loops_per_jiffy" for the clock
211 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500212 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 * per-CPU loops_per_jiffy value wherever possible.
214 */
215#ifndef CONFIG_SMP
216static unsigned long l_p_j_ref;
217static unsigned int l_p_j_ref_freq;
218
Arjan van de Ven858119e2006-01-14 13:20:43 -0800219static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220{
221 if (ci->flags & CPUFREQ_CONST_LOOPS)
222 return;
223
224 if (!l_p_j_ref_freq) {
225 l_p_j_ref = loops_per_jiffy;
226 l_p_j_ref_freq = ci->old;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530227 dprintk("saving %lu as reference value for loops_per_jiffy;"
228 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 }
230 if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
231 (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700232 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530233 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
234 ci->new);
235 dprintk("scaling loops_per_jiffy to %lu"
236 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 }
238}
239#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530240static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
241{
242 return;
243}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244#endif
245
246
247/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800248 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
249 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800251 * This function calls the transition notifiers and the "adjust_jiffies"
252 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500253 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 */
255void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
256{
Dave Jonese4472cb2006-01-31 15:53:55 -0800257 struct cpufreq_policy *policy;
258
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 BUG_ON(irqs_disabled());
260
261 freqs->flags = cpufreq_driver->flags;
Dave Jonese4472cb2006-01-31 15:53:55 -0800262 dprintk("notification %u of frequency transition to %u kHz\n",
263 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264
Dave Jonese4472cb2006-01-31 15:53:55 -0800265 policy = cpufreq_cpu_data[freqs->cpu];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800267
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500269 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800270 * which is not equal to what the cpufreq core thinks is
271 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 */
273 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800274 if ((policy) && (policy->cpu == freqs->cpu) &&
275 (policy->cur) && (policy->cur != freqs->old)) {
Jan Beulichb10eec22006-04-28 13:47:13 +0200276 dprintk("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800277 " %u, cpufreq assumed %u kHz.\n",
278 freqs->old, policy->cur);
279 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 }
281 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700282 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800283 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
285 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800286
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 case CPUFREQ_POSTCHANGE:
288 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700289 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800290 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800291 if (likely(policy) && likely(policy->cpu == freqs->cpu))
292 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 break;
294 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295}
296EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
297
298
299
300/*********************************************************************
301 * SYSFS INTERFACE *
302 *********************************************************************/
303
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700304static struct cpufreq_governor *__find_governor(const char *str_governor)
305{
306 struct cpufreq_governor *t;
307
308 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
309 if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN))
310 return t;
311
312 return NULL;
313}
314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315/**
316 * cpufreq_parse_governor - parse a governor string
317 */
318static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
319 struct cpufreq_governor **governor)
320{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700321 int err = -EINVAL;
322
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700324 goto out;
325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 if (cpufreq_driver->setpolicy) {
327 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
328 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700329 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530330 } else if (!strnicmp(str_governor, "powersave",
331 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700333 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700335 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700337
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800338 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700339
340 t = __find_governor(str_governor);
341
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700342 if (t == NULL) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530343 char *name = kasprintf(GFP_KERNEL, "cpufreq_%s",
344 str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700345
346 if (name) {
347 int ret;
348
349 mutex_unlock(&cpufreq_governor_mutex);
350 ret = request_module(name);
351 mutex_lock(&cpufreq_governor_mutex);
352
353 if (ret == 0)
354 t = __find_governor(str_governor);
355 }
356
357 kfree(name);
358 }
359
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700360 if (t != NULL) {
361 *governor = t;
362 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700364
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800365 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700367 out:
368 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
371
372/* drivers/base/cpu.c */
373extern struct sysdev_class cpu_sysdev_class;
374
375
376/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530377 * cpufreq_per_cpu_attr_read() / show_##file_name() -
378 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 *
380 * Write out information from cpufreq_driver->policy[cpu]; object must be
381 * "unsigned int".
382 */
383
Dave Jones32ee8c32006-02-28 00:43:23 -0500384#define show_one(file_name, object) \
385static ssize_t show_##file_name \
386(struct cpufreq_policy * policy, char *buf) \
387{ \
388 return sprintf (buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389}
390
391show_one(cpuinfo_min_freq, cpuinfo.min_freq);
392show_one(cpuinfo_max_freq, cpuinfo.max_freq);
393show_one(scaling_min_freq, min);
394show_one(scaling_max_freq, max);
395show_one(scaling_cur_freq, cur);
396
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530397static int __cpufreq_set_policy(struct cpufreq_policy *data,
398 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400/**
401 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
402 */
403#define store_one(file_name, object) \
404static ssize_t store_##file_name \
405(struct cpufreq_policy * policy, const char *buf, size_t count) \
406{ \
407 unsigned int ret = -EINVAL; \
408 struct cpufreq_policy new_policy; \
409 \
410 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
411 if (ret) \
412 return -EINVAL; \
413 \
414 ret = sscanf (buf, "%u", &new_policy.object); \
415 if (ret != 1) \
416 return -EINVAL; \
417 \
Arjan van de Ven153d7f32006-07-26 15:40:07 +0200418 lock_cpu_hotplug(); \
Thomas Renninger7970e082006-04-13 15:14:04 +0200419 mutex_lock(&policy->lock); \
420 ret = __cpufreq_set_policy(policy, &new_policy); \
421 policy->user_policy.object = policy->object; \
422 mutex_unlock(&policy->lock); \
Arjan van de Ven153d7f32006-07-26 15:40:07 +0200423 unlock_cpu_hotplug(); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 \
425 return ret ? ret : count; \
426}
427
428store_one(scaling_min_freq,min);
429store_one(scaling_max_freq,max);
430
431/**
432 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
433 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530434static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy,
435 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436{
437 unsigned int cur_freq = cpufreq_get(policy->cpu);
438 if (!cur_freq)
439 return sprintf(buf, "<unknown>");
440 return sprintf(buf, "%u\n", cur_freq);
441}
442
443
444/**
445 * show_scaling_governor - show the current policy for the specified CPU
446 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530447static ssize_t show_scaling_governor (struct cpufreq_policy * policy,
448 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449{
450 if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
451 return sprintf(buf, "powersave\n");
452 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
453 return sprintf(buf, "performance\n");
454 else if (policy->governor)
455 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
456 return -EINVAL;
457}
458
459
460/**
461 * store_scaling_governor - store policy for the specified CPU
462 */
Dave Jones32ee8c32006-02-28 00:43:23 -0500463static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
464 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465{
466 unsigned int ret = -EINVAL;
467 char str_governor[16];
468 struct cpufreq_policy new_policy;
469
470 ret = cpufreq_get_policy(&new_policy, policy->cpu);
471 if (ret)
472 return ret;
473
474 ret = sscanf (buf, "%15s", str_governor);
475 if (ret != 1)
476 return -EINVAL;
477
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530478 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
479 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 return -EINVAL;
481
Dave Jonesa496e252006-07-07 12:31:27 -0400482 lock_cpu_hotplug();
483
Thomas Renninger7970e082006-04-13 15:14:04 +0200484 /* Do not use cpufreq_set_policy here or the user_policy.max
485 will be wrongly overridden */
486 mutex_lock(&policy->lock);
487 ret = __cpufreq_set_policy(policy, &new_policy);
488
489 policy->user_policy.policy = policy->policy;
490 policy->user_policy.governor = policy->governor;
491 mutex_unlock(&policy->lock);
492
Dave Jonesa496e252006-07-07 12:31:27 -0400493 unlock_cpu_hotplug();
494
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530495 if (ret)
496 return ret;
497 else
498 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499}
500
501/**
502 * show_scaling_driver - show the cpufreq driver currently loaded
503 */
504static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf)
505{
506 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
507}
508
509/**
510 * show_scaling_available_governors - show the available CPUfreq governors
511 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530512static ssize_t show_scaling_available_governors (struct cpufreq_policy *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 char *buf)
514{
515 ssize_t i = 0;
516 struct cpufreq_governor *t;
517
518 if (!cpufreq_driver->target) {
519 i += sprintf(buf, "performance powersave");
520 goto out;
521 }
522
523 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
524 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
525 goto out;
526 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
527 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500528out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 i += sprintf(&buf[i], "\n");
530 return i;
531}
532/**
533 * show_affected_cpus - show the CPUs affected by each transition
534 */
535static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf)
536{
537 ssize_t i = 0;
538 unsigned int cpu;
539
540 for_each_cpu_mask(cpu, policy->cpus) {
541 if (i)
542 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
543 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
544 if (i >= (PAGE_SIZE - 5))
545 break;
546 }
547 i += sprintf(&buf[i], "\n");
548 return i;
549}
550
551
552#define define_one_ro(_name) \
553static struct freq_attr _name = \
554__ATTR(_name, 0444, show_##_name, NULL)
555
556#define define_one_ro0400(_name) \
557static struct freq_attr _name = \
558__ATTR(_name, 0400, show_##_name, NULL)
559
560#define define_one_rw(_name) \
561static struct freq_attr _name = \
562__ATTR(_name, 0644, show_##_name, store_##_name)
563
564define_one_ro0400(cpuinfo_cur_freq);
565define_one_ro(cpuinfo_min_freq);
566define_one_ro(cpuinfo_max_freq);
567define_one_ro(scaling_available_governors);
568define_one_ro(scaling_driver);
569define_one_ro(scaling_cur_freq);
570define_one_ro(affected_cpus);
571define_one_rw(scaling_min_freq);
572define_one_rw(scaling_max_freq);
573define_one_rw(scaling_governor);
574
575static struct attribute * default_attrs[] = {
576 &cpuinfo_min_freq.attr,
577 &cpuinfo_max_freq.attr,
578 &scaling_min_freq.attr,
579 &scaling_max_freq.attr,
580 &affected_cpus.attr,
581 &scaling_governor.attr,
582 &scaling_driver.attr,
583 &scaling_available_governors.attr,
584 NULL
585};
586
587#define to_policy(k) container_of(k,struct cpufreq_policy,kobj)
588#define to_attr(a) container_of(a,struct freq_attr,attr)
589
590static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
591{
592 struct cpufreq_policy * policy = to_policy(kobj);
593 struct freq_attr * fattr = to_attr(attr);
594 ssize_t ret;
595 policy = cpufreq_cpu_get(policy->cpu);
596 if (!policy)
597 return -EINVAL;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530598 if (fattr->show)
599 ret = fattr->show(policy, buf);
600 else
601 ret = -EIO;
602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 cpufreq_cpu_put(policy);
604 return ret;
605}
606
Dave Jones32ee8c32006-02-28 00:43:23 -0500607static ssize_t store(struct kobject * kobj, struct attribute * attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 const char * buf, size_t count)
609{
610 struct cpufreq_policy * policy = to_policy(kobj);
611 struct freq_attr * fattr = to_attr(attr);
612 ssize_t ret;
613 policy = cpufreq_cpu_get(policy->cpu);
614 if (!policy)
615 return -EINVAL;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530616 if (fattr->store)
617 ret = fattr->store(policy, buf, count);
618 else
619 ret = -EIO;
620
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 cpufreq_cpu_put(policy);
622 return ret;
623}
624
625static void cpufreq_sysfs_release(struct kobject * kobj)
626{
627 struct cpufreq_policy * policy = to_policy(kobj);
628 dprintk("last reference is dropped\n");
629 complete(&policy->kobj_unregister);
630}
631
632static struct sysfs_ops sysfs_ops = {
633 .show = show,
634 .store = store,
635};
636
637static struct kobj_type ktype_cpufreq = {
638 .sysfs_ops = &sysfs_ops,
639 .default_attrs = default_attrs,
640 .release = cpufreq_sysfs_release,
641};
642
643
644/**
645 * cpufreq_add_dev - add a CPU device
646 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500647 * Adds the cpufreq interface for a CPU device.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 */
649static int cpufreq_add_dev (struct sys_device * sys_dev)
650{
651 unsigned int cpu = sys_dev->id;
652 int ret = 0;
653 struct cpufreq_policy new_policy;
654 struct cpufreq_policy *policy;
655 struct freq_attr **drv_attr;
Dave Jones8ff69732006-03-05 03:37:23 -0500656 struct sys_device *cpu_sys_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 unsigned long flags;
658 unsigned int j;
Dave Jones8ff69732006-03-05 03:37:23 -0500659#ifdef CONFIG_SMP
660 struct cpufreq_policy *managed_policy;
661#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662
Ashok Rajc32b6b82005-10-30 14:59:54 -0800663 if (cpu_is_offline(cpu))
664 return 0;
665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 cpufreq_debug_disable_ratelimit();
667 dprintk("adding CPU %u\n", cpu);
668
669#ifdef CONFIG_SMP
670 /* check whether a different CPU already registered this
671 * CPU because it is in the same boat. */
672 policy = cpufreq_cpu_get(cpu);
673 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500674 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 cpufreq_debug_enable_ratelimit();
676 return 0;
677 }
678#endif
679
680 if (!try_module_get(cpufreq_driver->owner)) {
681 ret = -EINVAL;
682 goto module_out;
683 }
684
Dave Jonese98df502005-10-20 15:17:43 -0700685 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 if (!policy) {
687 ret = -ENOMEM;
688 goto nomem_out;
689 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690
691 policy->cpu = cpu;
692 policy->cpus = cpumask_of_cpu(cpu);
693
Arjan van de Ven83933af2006-01-14 16:01:49 +0100694 mutex_init(&policy->lock);
695 mutex_lock(&policy->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000697 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698
699 /* call driver. From then on the cpufreq must be able
700 * to accept all calls to ->verify and ->setpolicy for this CPU
701 */
702 ret = cpufreq_driver->init(policy);
703 if (ret) {
704 dprintk("initialization failed\n");
Andrew Mortonf3876c12006-01-18 13:40:54 -0800705 mutex_unlock(&policy->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 goto err_out;
707 }
708
Dave Jones8ff69732006-03-05 03:37:23 -0500709#ifdef CONFIG_SMP
710 for_each_cpu_mask(j, policy->cpus) {
711 if (cpu == j)
712 continue;
713
714 /* check for existing affected CPUs. They may not be aware
715 * of it due to CPU Hotplug.
716 */
717 managed_policy = cpufreq_cpu_get(j);
718 if (unlikely(managed_policy)) {
719 spin_lock_irqsave(&cpufreq_driver_lock, flags);
720 managed_policy->cpus = policy->cpus;
721 cpufreq_cpu_data[cpu] = managed_policy;
722 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
723
724 dprintk("CPU already managed, adding link\n");
725 sysfs_create_link(&sys_dev->kobj,
726 &managed_policy->kobj, "cpufreq");
727
728 cpufreq_debug_enable_ratelimit();
729 mutex_unlock(&policy->lock);
730 ret = 0;
731 goto err_out_driver_exit; /* call driver->exit() */
732 }
733 }
734#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
736
737 /* prepare interface data */
738 policy->kobj.parent = &sys_dev->kobj;
739 policy->kobj.ktype = &ktype_cpufreq;
740 strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
741
742 ret = kobject_register(&policy->kobj);
Andrew Mortonf3876c12006-01-18 13:40:54 -0800743 if (ret) {
744 mutex_unlock(&policy->lock);
Venkatesh Pallipadi8085e1f2005-08-25 13:14:06 -0700745 goto err_out_driver_exit;
Andrew Mortonf3876c12006-01-18 13:40:54 -0800746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 /* set up files for this cpu device */
748 drv_attr = cpufreq_driver->attr;
749 while ((drv_attr) && (*drv_attr)) {
750 sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
751 drv_attr++;
752 }
753 if (cpufreq_driver->get)
754 sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
755 if (cpufreq_driver->target)
756 sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
757
758 spin_lock_irqsave(&cpufreq_driver_lock, flags);
759 for_each_cpu_mask(j, policy->cpus)
760 cpufreq_cpu_data[j] = policy;
761 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones8ff69732006-03-05 03:37:23 -0500762
763 /* symlink affected CPUs */
764 for_each_cpu_mask(j, policy->cpus) {
765 if (j == cpu)
766 continue;
767 if (!cpu_online(j))
768 continue;
769
Dave Jones1f8b2c92006-03-29 01:40:04 -0500770 dprintk("CPU %u already managed, adding link\n", j);
Dave Jones8ff69732006-03-05 03:37:23 -0500771 cpufreq_cpu_get(cpu);
772 cpu_sys_dev = get_cpu_sysdev(j);
773 sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
774 "cpufreq");
775 }
776
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 policy->governor = NULL; /* to assure that the starting sequence is
778 * run in cpufreq_set_policy */
Arjan van de Ven83933af2006-01-14 16:01:49 +0100779 mutex_unlock(&policy->lock);
Dave Jones87c32272006-03-29 01:48:37 -0500780
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 /* set default policy */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 ret = cpufreq_set_policy(&new_policy);
783 if (ret) {
784 dprintk("setting policy failed\n");
785 goto err_out_unregister;
786 }
787
788 module_put(cpufreq_driver->owner);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 dprintk("initialization complete\n");
790 cpufreq_debug_enable_ratelimit();
Dave Jones87c32272006-03-29 01:48:37 -0500791
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 return 0;
793
794
795err_out_unregister:
796 spin_lock_irqsave(&cpufreq_driver_lock, flags);
797 for_each_cpu_mask(j, policy->cpus)
798 cpufreq_cpu_data[j] = NULL;
799 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
800
801 kobject_unregister(&policy->kobj);
802 wait_for_completion(&policy->kobj_unregister);
803
Venkatesh Pallipadi8085e1f2005-08-25 13:14:06 -0700804err_out_driver_exit:
805 if (cpufreq_driver->exit)
806 cpufreq_driver->exit(policy);
807
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808err_out:
809 kfree(policy);
810
811nomem_out:
812 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -0800813module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 cpufreq_debug_enable_ratelimit();
815 return ret;
816}
817
818
819/**
820 * cpufreq_remove_dev - remove a CPU device
821 *
822 * Removes the cpufreq interface for a CPU device.
823 */
824static int cpufreq_remove_dev (struct sys_device * sys_dev)
825{
826 unsigned int cpu = sys_dev->id;
827 unsigned long flags;
828 struct cpufreq_policy *data;
829#ifdef CONFIG_SMP
Grant Coadye738cf62005-11-21 21:32:28 -0800830 struct sys_device *cpu_sys_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 unsigned int j;
832#endif
833
834 cpufreq_debug_disable_ratelimit();
835 dprintk("unregistering CPU %u\n", cpu);
836
837 spin_lock_irqsave(&cpufreq_driver_lock, flags);
838 data = cpufreq_cpu_data[cpu];
839
840 if (!data) {
841 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 cpufreq_debug_enable_ratelimit();
843 return -EINVAL;
844 }
845 cpufreq_cpu_data[cpu] = NULL;
846
847
848#ifdef CONFIG_SMP
849 /* if this isn't the CPU which is the parent of the kobj, we
Dave Jones32ee8c32006-02-28 00:43:23 -0500850 * only need to unlink, put and exit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 */
852 if (unlikely(cpu != data->cpu)) {
853 dprintk("removing link\n");
Dave Jones8ff69732006-03-05 03:37:23 -0500854 cpu_clear(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
856 sysfs_remove_link(&sys_dev->kobj, "cpufreq");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 cpufreq_cpu_put(data);
858 cpufreq_debug_enable_ratelimit();
859 return 0;
860 }
861#endif
862
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863
864 if (!kobject_get(&data->kobj)) {
865 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
866 cpufreq_debug_enable_ratelimit();
Dave Jones32ee8c32006-02-28 00:43:23 -0500867 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868 }
869
870#ifdef CONFIG_SMP
871 /* if we have other CPUs still registered, we need to unlink them,
872 * or else wait_for_completion below will lock up. Clean the
873 * cpufreq_cpu_data[] while holding the lock, and remove the sysfs
874 * links afterwards.
875 */
876 if (unlikely(cpus_weight(data->cpus) > 1)) {
877 for_each_cpu_mask(j, data->cpus) {
878 if (j == cpu)
879 continue;
880 cpufreq_cpu_data[j] = NULL;
881 }
882 }
883
884 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
885
886 if (unlikely(cpus_weight(data->cpus) > 1)) {
887 for_each_cpu_mask(j, data->cpus) {
888 if (j == cpu)
889 continue;
890 dprintk("removing link for cpu %u\n", j);
Ashok Rajd434fca2005-10-30 14:59:52 -0800891 cpu_sys_dev = get_cpu_sysdev(j);
892 sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 cpufreq_cpu_put(data);
894 }
895 }
896#else
897 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
898#endif
899
Arjan van de Ven83933af2006-01-14 16:01:49 +0100900 mutex_lock(&data->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 if (cpufreq_driver->target)
902 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Arjan van de Ven83933af2006-01-14 16:01:49 +0100903 mutex_unlock(&data->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
905 kobject_unregister(&data->kobj);
906
907 kobject_put(&data->kobj);
908
909 /* we need to make sure that the underlying kobj is actually
Dave Jones32ee8c32006-02-28 00:43:23 -0500910 * not referenced anymore by anybody before we proceed with
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 * unloading.
912 */
913 dprintk("waiting for dropping of refcount\n");
914 wait_for_completion(&data->kobj_unregister);
915 dprintk("wait complete\n");
916
917 if (cpufreq_driver->exit)
918 cpufreq_driver->exit(data);
919
920 kfree(data);
921
922 cpufreq_debug_enable_ratelimit();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 return 0;
924}
925
926
David Howells65f27f32006-11-22 14:55:48 +0000927static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928{
David Howells65f27f32006-11-22 14:55:48 +0000929 struct cpufreq_policy *policy =
930 container_of(work, struct cpufreq_policy, update);
931 unsigned int cpu = policy->cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 dprintk("handle_update for cpu %u called\n", cpu);
933 cpufreq_update_policy(cpu);
934}
935
936/**
937 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
938 * @cpu: cpu number
939 * @old_freq: CPU frequency the kernel thinks the CPU runs at
940 * @new_freq: CPU frequency the CPU actually runs at
941 *
942 * We adjust to current frequency first, and need to clean up later. So either call
943 * to cpufreq_update_policy() or schedule handle_update()).
944 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530945static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
946 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947{
948 struct cpufreq_freqs freqs;
949
Jan Beulichb10eec22006-04-28 13:47:13 +0200950 dprintk("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
952
953 freqs.cpu = cpu;
954 freqs.old = old_freq;
955 freqs.new = new_freq;
956 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
957 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
958}
959
960
Dave Jones32ee8c32006-02-28 00:43:23 -0500961/**
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -0800962 * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
963 * @cpu: CPU number
964 *
965 * This is the last known freq, without actually getting it from the driver.
966 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
967 */
968unsigned int cpufreq_quick_get(unsigned int cpu)
969{
970 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530971 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -0800972
973 if (policy) {
Arjan van de Ven83933af2006-01-14 16:01:49 +0100974 mutex_lock(&policy->lock);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530975 ret_freq = policy->cur;
Arjan van de Ven83933af2006-01-14 16:01:49 +0100976 mutex_unlock(&policy->lock);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -0800977 cpufreq_cpu_put(policy);
978 }
979
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530980 return (ret_freq);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -0800981}
982EXPORT_SYMBOL(cpufreq_quick_get);
983
984
Dave Jones32ee8c32006-02-28 00:43:23 -0500985/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 * cpufreq_get - get the current CPU frequency (in kHz)
987 * @cpu: CPU number
988 *
989 * Get the CPU current (static) CPU frequency
990 */
991unsigned int cpufreq_get(unsigned int cpu)
992{
993 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530994 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995
996 if (!policy)
997 return 0;
998
999 if (!cpufreq_driver->get)
1000 goto out;
1001
Arjan van de Ven83933af2006-01-14 16:01:49 +01001002 mutex_lock(&policy->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301004 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301006 if (ret_freq && policy->cur &&
1007 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1008 /* verify no discrepancy between actual and
1009 saved value exists */
1010 if (unlikely(ret_freq != policy->cur)) {
1011 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 schedule_work(&policy->update);
1013 }
1014 }
1015
Arjan van de Ven83933af2006-01-14 16:01:49 +01001016 mutex_unlock(&policy->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
Dave Jones7d5e3502006-02-02 17:03:42 -05001018out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 cpufreq_cpu_put(policy);
1020
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301021 return (ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022}
1023EXPORT_SYMBOL(cpufreq_get);
1024
1025
1026/**
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001027 * cpufreq_suspend - let the low level driver prepare for suspend
1028 */
1029
Bernard Blackhame00d9962005-07-07 17:56:42 -07001030static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001031{
1032 int cpu = sysdev->id;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301033 int ret = 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001034 unsigned int cur_freq = 0;
1035 struct cpufreq_policy *cpu_policy;
1036
Dave Jones0e37b152006-09-26 23:02:34 -04001037 dprintk("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001038
1039 if (!cpu_online(cpu))
1040 return 0;
1041
1042 /* we may be lax here as interrupts are off. Nonetheless
1043 * we need to grab the correct cpu policy, as to check
1044 * whether we really run on this CPU.
1045 */
1046
1047 cpu_policy = cpufreq_cpu_get(cpu);
1048 if (!cpu_policy)
1049 return -EINVAL;
1050
1051 /* only handle each CPU group once */
1052 if (unlikely(cpu_policy->cpu != cpu)) {
1053 cpufreq_cpu_put(cpu_policy);
1054 return 0;
1055 }
1056
1057 if (cpufreq_driver->suspend) {
Bernard Blackhame00d9962005-07-07 17:56:42 -07001058 ret = cpufreq_driver->suspend(cpu_policy, pmsg);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001059 if (ret) {
1060 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1061 "step on CPU %u\n", cpu_policy->cpu);
1062 cpufreq_cpu_put(cpu_policy);
1063 return ret;
1064 }
1065 }
1066
1067
1068 if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)
1069 goto out;
1070
1071 if (cpufreq_driver->get)
1072 cur_freq = cpufreq_driver->get(cpu_policy->cpu);
1073
1074 if (!cur_freq || !cpu_policy->cur) {
1075 printk(KERN_ERR "cpufreq: suspend failed to assert current "
1076 "frequency is what timing core thinks it is.\n");
1077 goto out;
1078 }
1079
1080 if (unlikely(cur_freq != cpu_policy->cur)) {
1081 struct cpufreq_freqs freqs;
1082
1083 if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
Jan Beulichb10eec22006-04-28 13:47:13 +02001084 dprintk("Warning: CPU frequency is %u, "
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001085 "cpufreq assumed %u kHz.\n",
1086 cur_freq, cpu_policy->cur);
1087
1088 freqs.cpu = cpu;
1089 freqs.old = cpu_policy->cur;
1090 freqs.new = cur_freq;
1091
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001092 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001093 CPUFREQ_SUSPENDCHANGE, &freqs);
1094 adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
1095
1096 cpu_policy->cur = cur_freq;
1097 }
1098
Dave Jones7d5e3502006-02-02 17:03:42 -05001099out:
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001100 cpufreq_cpu_put(cpu_policy);
1101 return 0;
1102}
1103
1104/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 * cpufreq_resume - restore proper CPU frequency handling after resume
1106 *
1107 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
1108 * 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001109 * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are
1110 * restored.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 */
1112static int cpufreq_resume(struct sys_device * sysdev)
1113{
1114 int cpu = sysdev->id;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301115 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 struct cpufreq_policy *cpu_policy;
1117
1118 dprintk("resuming cpu %u\n", cpu);
1119
1120 if (!cpu_online(cpu))
1121 return 0;
1122
1123 /* we may be lax here as interrupts are off. Nonetheless
1124 * we need to grab the correct cpu policy, as to check
1125 * whether we really run on this CPU.
1126 */
1127
1128 cpu_policy = cpufreq_cpu_get(cpu);
1129 if (!cpu_policy)
1130 return -EINVAL;
1131
1132 /* only handle each CPU group once */
1133 if (unlikely(cpu_policy->cpu != cpu)) {
1134 cpufreq_cpu_put(cpu_policy);
1135 return 0;
1136 }
1137
1138 if (cpufreq_driver->resume) {
1139 ret = cpufreq_driver->resume(cpu_policy);
1140 if (ret) {
1141 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1142 "step on CPU %u\n", cpu_policy->cpu);
1143 cpufreq_cpu_put(cpu_policy);
1144 return ret;
1145 }
1146 }
1147
1148 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1149 unsigned int cur_freq = 0;
1150
1151 if (cpufreq_driver->get)
1152 cur_freq = cpufreq_driver->get(cpu_policy->cpu);
1153
1154 if (!cur_freq || !cpu_policy->cur) {
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001155 printk(KERN_ERR "cpufreq: resume failed to assert "
1156 "current frequency is what timing core "
1157 "thinks it is.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 goto out;
1159 }
1160
1161 if (unlikely(cur_freq != cpu_policy->cur)) {
1162 struct cpufreq_freqs freqs;
1163
Benjamin Herrenschmidtac09f692005-05-02 16:25:10 +10001164 if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
Jan Beulichb10eec22006-04-28 13:47:13 +02001165 dprintk("Warning: CPU frequency"
Benjamin Herrenschmidtac09f692005-05-02 16:25:10 +10001166 "is %u, cpufreq assumed %u kHz.\n",
1167 cur_freq, cpu_policy->cur);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 freqs.cpu = cpu;
1170 freqs.old = cpu_policy->cur;
1171 freqs.new = cur_freq;
1172
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001173 srcu_notifier_call_chain(
Alan Sterne041c682006-03-27 01:16:30 -08001174 &cpufreq_transition_notifier_list,
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001175 CPUFREQ_RESUMECHANGE, &freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
1177
1178 cpu_policy->cur = cur_freq;
1179 }
1180 }
1181
1182out:
1183 schedule_work(&cpu_policy->update);
1184 cpufreq_cpu_put(cpu_policy);
1185 return ret;
1186}
1187
1188static struct sysdev_driver cpufreq_sysdev_driver = {
1189 .add = cpufreq_add_dev,
1190 .remove = cpufreq_remove_dev,
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001191 .suspend = cpufreq_suspend,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 .resume = cpufreq_resume,
1193};
1194
1195
1196/*********************************************************************
1197 * NOTIFIER LISTS INTERFACE *
1198 *********************************************************************/
1199
1200/**
1201 * cpufreq_register_notifier - register a driver with cpufreq
1202 * @nb: notifier function to register
1203 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1204 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001205 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 * are notified about clock rate changes (once before and once after
1207 * the transition), or a list of drivers that are notified about
1208 * changes in cpufreq policy.
1209 *
1210 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001211 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 */
1213int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1214{
1215 int ret;
1216
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 switch (list) {
1218 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001219 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001220 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 break;
1222 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001223 ret = blocking_notifier_chain_register(
1224 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 break;
1226 default:
1227 ret = -EINVAL;
1228 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229
1230 return ret;
1231}
1232EXPORT_SYMBOL(cpufreq_register_notifier);
1233
1234
1235/**
1236 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1237 * @nb: notifier block to be unregistered
1238 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1239 *
1240 * Remove a driver from the CPU frequency notifier list.
1241 *
1242 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001243 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 */
1245int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1246{
1247 int ret;
1248
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 switch (list) {
1250 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001251 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001252 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 break;
1254 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001255 ret = blocking_notifier_chain_unregister(
1256 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257 break;
1258 default:
1259 ret = -EINVAL;
1260 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261
1262 return ret;
1263}
1264EXPORT_SYMBOL(cpufreq_unregister_notifier);
1265
1266
1267/*********************************************************************
1268 * GOVERNORS *
1269 *********************************************************************/
1270
1271
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001272/* Must be called with lock_cpu_hotplug held */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273int __cpufreq_driver_target(struct cpufreq_policy *policy,
1274 unsigned int target_freq,
1275 unsigned int relation)
1276{
1277 int retval = -EINVAL;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001278
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
1280 target_freq, relation);
1281 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1282 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001283
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 return retval;
1285}
1286EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1287
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288int cpufreq_driver_target(struct cpufreq_policy *policy,
1289 unsigned int target_freq,
1290 unsigned int relation)
1291{
Dave Jonescc993ca2005-07-28 09:43:56 -07001292 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293
1294 policy = cpufreq_cpu_get(policy->cpu);
1295 if (!policy)
1296 return -EINVAL;
1297
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001298 lock_cpu_hotplug();
Arjan van de Ven83933af2006-01-14 16:01:49 +01001299 mutex_lock(&policy->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300
1301 ret = __cpufreq_driver_target(policy, target_freq, relation);
1302
Arjan van de Ven83933af2006-01-14 16:01:49 +01001303 mutex_unlock(&policy->lock);
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001304 unlock_cpu_hotplug();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
1306 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 return ret;
1308}
1309EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1310
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001311int cpufreq_driver_getavg(struct cpufreq_policy *policy)
1312{
1313 int ret = 0;
1314
1315 policy = cpufreq_cpu_get(policy->cpu);
1316 if (!policy)
1317 return -EINVAL;
1318
1319 mutex_lock(&policy->lock);
1320
1321 if (cpu_online(policy->cpu) && cpufreq_driver->getavg)
1322 ret = cpufreq_driver->getavg(policy->cpu);
1323
1324 mutex_unlock(&policy->lock);
1325
1326 cpufreq_cpu_put(policy);
1327 return ret;
1328}
1329EXPORT_SYMBOL_GPL(cpufreq_driver_getavg);
1330
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001331/*
1332 * Locking: Must be called with the lock_cpu_hotplug() lock held
1333 * when "event" is CPUFREQ_GOV_LIMITS
1334 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301336static int __cpufreq_governor(struct cpufreq_policy *policy,
1337 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338{
Dave Jonescc993ca2005-07-28 09:43:56 -07001339 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340
1341 if (!try_module_get(policy->governor->owner))
1342 return -EINVAL;
1343
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301344 dprintk("__cpufreq_governor for CPU %u, event %u\n",
1345 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 ret = policy->governor->governor(policy, event);
1347
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301348 /* we keep one module reference alive for
1349 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 if ((event != CPUFREQ_GOV_START) || ret)
1351 module_put(policy->governor->owner);
1352 if ((event == CPUFREQ_GOV_STOP) && !ret)
1353 module_put(policy->governor->owner);
1354
1355 return ret;
1356}
1357
1358
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359int cpufreq_register_governor(struct cpufreq_governor *governor)
1360{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001361 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
1363 if (!governor)
1364 return -EINVAL;
1365
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001366 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001367
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001368 err = -EBUSY;
1369 if (__find_governor(governor->name) == NULL) {
1370 err = 0;
1371 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
Dave Jones32ee8c32006-02-28 00:43:23 -05001374 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001375 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376}
1377EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1378
1379
1380void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1381{
1382 if (!governor)
1383 return;
1384
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001385 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001387 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 return;
1389}
1390EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1391
1392
1393
1394/*********************************************************************
1395 * POLICY INTERFACE *
1396 *********************************************************************/
1397
1398/**
1399 * cpufreq_get_policy - get the current cpufreq_policy
1400 * @policy: struct cpufreq_policy into which the current cpufreq_policy is written
1401 *
1402 * Reads the current cpufreq policy.
1403 */
1404int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1405{
1406 struct cpufreq_policy *cpu_policy;
1407 if (!policy)
1408 return -EINVAL;
1409
1410 cpu_policy = cpufreq_cpu_get(cpu);
1411 if (!cpu_policy)
1412 return -EINVAL;
1413
Arjan van de Ven83933af2006-01-14 16:01:49 +01001414 mutex_lock(&cpu_policy->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Arjan van de Ven83933af2006-01-14 16:01:49 +01001416 mutex_unlock(&cpu_policy->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
1418 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 return 0;
1420}
1421EXPORT_SYMBOL(cpufreq_get_policy);
1422
1423
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001424/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301425 * data : current policy.
1426 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001427 * Locking: Must be called with the lock_cpu_hotplug() lock held
1428 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301429static int __cpufreq_set_policy(struct cpufreq_policy *data,
1430 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431{
1432 int ret = 0;
1433
1434 cpufreq_debug_disable_ratelimit();
1435 dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
1436 policy->min, policy->max);
1437
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301438 memcpy(&policy->cpuinfo, &data->cpuinfo,
1439 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001441 if (policy->min > data->min && policy->min > policy->max) {
1442 ret = -EINVAL;
1443 goto error_out;
1444 }
1445
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 /* verify the cpu speed can be set within this limit */
1447 ret = cpufreq_driver->verify(policy);
1448 if (ret)
1449 goto error_out;
1450
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001452 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1453 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
1455 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001456 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1457 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458
1459 /* verify the cpu speed can be set within this limit,
1460 which might be different to the first one */
1461 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001462 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464
1465 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001466 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1467 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
Dave Jones7d5e3502006-02-02 17:03:42 -05001469 data->min = policy->min;
1470 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301472 dprintk("new min and max freqs are %u - %u kHz\n",
1473 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
1475 if (cpufreq_driver->setpolicy) {
1476 data->policy = policy->policy;
1477 dprintk("setting range\n");
1478 ret = cpufreq_driver->setpolicy(policy);
1479 } else {
1480 if (policy->governor != data->governor) {
1481 /* save old, working values */
1482 struct cpufreq_governor *old_gov = data->governor;
1483
1484 dprintk("governor switch\n");
1485
1486 /* end old governor */
1487 if (data->governor)
1488 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1489
1490 /* start new governor */
1491 data->governor = policy->governor;
1492 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1493 /* new governor failed, so re-start old one */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301494 dprintk("starting governor %s failed\n",
1495 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 if (old_gov) {
1497 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301498 __cpufreq_governor(data,
1499 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 }
1501 ret = -EINVAL;
1502 goto error_out;
1503 }
1504 /* might be a policy change, too, so fall through */
1505 }
1506 dprintk("governor: change or update limits\n");
1507 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1508 }
1509
Dave Jones7d5e3502006-02-02 17:03:42 -05001510error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 cpufreq_debug_enable_ratelimit();
1512 return ret;
1513}
1514
1515/**
1516 * cpufreq_set_policy - set a new CPUFreq policy
1517 * @policy: policy to be set.
1518 *
1519 * Sets a new CPU frequency and voltage scaling policy.
1520 */
1521int cpufreq_set_policy(struct cpufreq_policy *policy)
1522{
1523 int ret = 0;
1524 struct cpufreq_policy *data;
1525
1526 if (!policy)
1527 return -EINVAL;
1528
1529 data = cpufreq_cpu_get(policy->cpu);
1530 if (!data)
1531 return -EINVAL;
1532
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001533 lock_cpu_hotplug();
1534
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 /* lock this CPU */
Arjan van de Ven83933af2006-01-14 16:01:49 +01001536 mutex_lock(&data->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
1538 ret = __cpufreq_set_policy(data, policy);
1539 data->user_policy.min = data->min;
1540 data->user_policy.max = data->max;
1541 data->user_policy.policy = data->policy;
1542 data->user_policy.governor = data->governor;
1543
Arjan van de Ven83933af2006-01-14 16:01:49 +01001544 mutex_unlock(&data->lock);
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001545
1546 unlock_cpu_hotplug();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 cpufreq_cpu_put(data);
1548
1549 return ret;
1550}
1551EXPORT_SYMBOL(cpufreq_set_policy);
1552
1553
1554/**
1555 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1556 * @cpu: CPU which shall be re-evaluated
1557 *
1558 * Usefull for policy notifiers which have different necessities
1559 * at different times.
1560 */
1561int cpufreq_update_policy(unsigned int cpu)
1562{
1563 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1564 struct cpufreq_policy policy;
1565 int ret = 0;
1566
1567 if (!data)
1568 return -ENODEV;
1569
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001570 lock_cpu_hotplug();
Arjan van de Ven83933af2006-01-14 16:01:49 +01001571 mutex_lock(&data->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572
1573 dprintk("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001574 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 policy.min = data->user_policy.min;
1576 policy.max = data->user_policy.max;
1577 policy.policy = data->user_policy.policy;
1578 policy.governor = data->user_policy.governor;
1579
Thomas Renninger0961dd02006-01-26 18:46:33 +01001580 /* BIOS might change freq behind our back
1581 -> ask driver for current freq and notify governors about a change */
1582 if (cpufreq_driver->get) {
1583 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001584 if (!data->cur) {
1585 dprintk("Driver did not initialize current freq");
1586 data->cur = policy.cur;
1587 } else {
1588 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301589 cpufreq_out_of_sync(cpu, data->cur,
1590 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001591 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001592 }
1593
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 ret = __cpufreq_set_policy(data, &policy);
1595
Arjan van de Ven83933af2006-01-14 16:01:49 +01001596 mutex_unlock(&data->lock);
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001597 unlock_cpu_hotplug();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 cpufreq_cpu_put(data);
1599 return ret;
1600}
1601EXPORT_SYMBOL(cpufreq_update_policy);
1602
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001603static int cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001604 unsigned long action, void *hcpu)
1605{
1606 unsigned int cpu = (unsigned long)hcpu;
1607 struct cpufreq_policy *policy;
1608 struct sys_device *sys_dev;
1609
1610 sys_dev = get_cpu_sysdev(cpu);
1611
1612 if (sys_dev) {
1613 switch (action) {
1614 case CPU_ONLINE:
1615 cpufreq_add_dev(sys_dev);
1616 break;
1617 case CPU_DOWN_PREPARE:
1618 /*
1619 * We attempt to put this cpu in lowest frequency
1620 * possible before going down. This will permit
1621 * hardware-managed P-State to switch other related
1622 * threads to min or higher speeds if possible.
1623 */
1624 policy = cpufreq_cpu_data[cpu];
1625 if (policy) {
1626 cpufreq_driver_target(policy, policy->min,
1627 CPUFREQ_RELATION_H);
1628 }
1629 break;
1630 case CPU_DEAD:
1631 cpufreq_remove_dev(sys_dev);
1632 break;
1633 }
1634 }
1635 return NOTIFY_OK;
1636}
1637
Chandra Seetharaman74b85f32006-06-27 02:54:09 -07001638static struct notifier_block __cpuinitdata cpufreq_cpu_notifier =
Ashok Rajc32b6b82005-10-30 14:59:54 -08001639{
1640 .notifier_call = cpufreq_cpu_callback,
1641};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642
1643/*********************************************************************
1644 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1645 *********************************************************************/
1646
1647/**
1648 * cpufreq_register_driver - register a CPU Frequency driver
1649 * @driver_data: A struct cpufreq_driver containing the values#
1650 * submitted by the CPU Frequency driver.
1651 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001652 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001654 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 *
1656 */
1657int cpufreq_register_driver(struct cpufreq_driver *driver_data)
1658{
1659 unsigned long flags;
1660 int ret;
1661
1662 if (!driver_data || !driver_data->verify || !driver_data->init ||
1663 ((!driver_data->setpolicy) && (!driver_data->target)))
1664 return -EINVAL;
1665
1666 dprintk("trying to register driver %s\n", driver_data->name);
1667
1668 if (driver_data->setpolicy)
1669 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1670
1671 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1672 if (cpufreq_driver) {
1673 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1674 return -EBUSY;
1675 }
1676 cpufreq_driver = driver_data;
1677 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1678
1679 ret = sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
1680
1681 if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) {
1682 int i;
1683 ret = -ENODEV;
1684
1685 /* check for at least one working CPU */
1686 for (i=0; i<NR_CPUS; i++)
1687 if (cpufreq_cpu_data[i])
1688 ret = 0;
1689
1690 /* if all ->init() calls failed, unregister */
1691 if (ret) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301692 dprintk("no CPU initialized for driver %s\n",
1693 driver_data->name);
1694 sysdev_driver_unregister(&cpu_sysdev_class,
1695 &cpufreq_sysdev_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
1697 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1698 cpufreq_driver = NULL;
1699 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1700 }
1701 }
1702
1703 if (!ret) {
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001704 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 dprintk("driver %s up and running\n", driver_data->name);
1706 cpufreq_debug_enable_ratelimit();
1707 }
1708
1709 return (ret);
1710}
1711EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1712
1713
1714/**
1715 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1716 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001717 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 * the right to do so, i.e. if you have succeeded in initialising before!
1719 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1720 * currently not initialised.
1721 */
1722int cpufreq_unregister_driver(struct cpufreq_driver *driver)
1723{
1724 unsigned long flags;
1725
1726 cpufreq_debug_disable_ratelimit();
1727
1728 if (!cpufreq_driver || (driver != cpufreq_driver)) {
1729 cpufreq_debug_enable_ratelimit();
1730 return -EINVAL;
1731 }
1732
1733 dprintk("unregistering driver %s\n", driver->name);
1734
1735 sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001736 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
1738 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1739 cpufreq_driver = NULL;
1740 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1741
1742 return 0;
1743}
1744EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);