blob: ff15497e919956282724156bfb707ca1414b4424 [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>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010031#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
Thomas Renninger6f4f2722010-04-20 13:17:36 +020033#include <trace/events/power.h>
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/**
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;
Mike Travis7a6aedf2008-03-25 15:06:53 -070041static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070042#ifdef CONFIG_HOTPLUG_CPU
43/* This one keeps track of the previously set governor of a removed CPU */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070044struct cpufreq_cpu_save_data {
45 char gov[CPUFREQ_NAME_LEN];
46 unsigned int max, min;
47};
48static DEFINE_PER_CPU(struct cpufreq_cpu_save_data, cpufreq_policy_save);
Thomas Renninger084f3492007-07-09 11:35:28 -070049#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070050static DEFINE_SPINLOCK(cpufreq_driver_lock);
51
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080052/*
53 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
54 * all cpufreq/hotplug/workqueue/etc related lock issues.
55 *
56 * The rules for this semaphore:
57 * - Any routine that wants to read from the policy structure will
58 * do a down_read on this semaphore.
59 * - Any routine that will write to the policy structure and/or may take away
60 * the policy altogether (eg. CPU hotplug), will hold this lock in write
61 * mode before doing so.
62 *
63 * Additional rules:
64 * - All holders of the lock should check to make sure that the CPU they
65 * are concerned with are online after they get the lock.
66 * - Governor routines that can be called in cpufreq hotplug path should not
67 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040068 * - Lock should not be held across
69 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080070 */
Tejun Heof1625062009-10-29 22:34:13 +090071static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
73
74#define lock_policy_rwsem(mode, cpu) \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075int lock_policy_rwsem_##mode \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076(int cpu) \
77{ \
Tejun Heof1625062009-10-29 22:34:13 +090078 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080079 BUG_ON(policy_cpu == -1); \
80 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
81 if (unlikely(!cpu_online(cpu))) { \
82 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
83 return -1; \
84 } \
85 \
86 return 0; \
87}
88
89lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
91lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080092
Amerigo Wang226528c2010-03-04 03:23:36 -050093static void unlock_policy_rwsem_read(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080094{
Tejun Heof1625062009-10-29 22:34:13 +090095 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080096 BUG_ON(policy_cpu == -1);
97 up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
98}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080099
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100void unlock_policy_rwsem_write(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800101{
Tejun Heof1625062009-10-29 22:34:13 +0900102 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800103 BUG_ON(policy_cpu == -1);
104 up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
105}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800106
107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500109static int __cpufreq_governor(struct cpufreq_policy *policy,
110 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800111static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000112static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500115 * Two notifier lists: the "policy" list is involved in the
116 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 * "transition" list for kernel code that needs to handle
118 * changes to devices when the CPU clock speed changes.
119 * The mutex locks both lists.
120 */
Alan Sterne041c682006-03-27 01:16:30 -0800121static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700122static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200124static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700125static int __init init_cpufreq_transition_notifier_list(void)
126{
127 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200128 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700129 return 0;
130}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800131pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500134static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Dave Jones7d5e3502006-02-02 17:03:42 -0500136struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137{
138 struct cpufreq_policy *data;
139 unsigned long flags;
140
Mike Travis7a6aedf2008-03-25 15:06:53 -0700141 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 goto err_out;
143
144 /* get the cpufreq driver */
145 spin_lock_irqsave(&cpufreq_driver_lock, flags);
146
147 if (!cpufreq_driver)
148 goto err_out_unlock;
149
150 if (!try_module_get(cpufreq_driver->owner))
151 goto err_out_unlock;
152
153
154 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700155 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
157 if (!data)
158 goto err_out_put_module;
159
160 if (!kobject_get(&data->kobj))
161 goto err_out_put_module;
162
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 return data;
165
Dave Jones7d5e3502006-02-02 17:03:42 -0500166err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500168err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500170err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 return NULL;
172}
173EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
174
Dave Jones7d5e3502006-02-02 17:03:42 -0500175
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176void cpufreq_cpu_put(struct cpufreq_policy *data)
177{
178 kobject_put(&data->kobj);
179 module_put(cpufreq_driver->owner);
180}
181EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
182
183
184/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
186 *********************************************************************/
187
188/**
189 * adjust_jiffies - adjust the system "loops_per_jiffy"
190 *
191 * This function alters the system "loops_per_jiffy" for the clock
192 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500193 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 * per-CPU loops_per_jiffy value wherever possible.
195 */
196#ifndef CONFIG_SMP
197static unsigned long l_p_j_ref;
198static unsigned int l_p_j_ref_freq;
199
Arjan van de Ven858119e2006-01-14 13:20:43 -0800200static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201{
202 if (ci->flags & CPUFREQ_CONST_LOOPS)
203 return;
204
205 if (!l_p_j_ref_freq) {
206 l_p_j_ref = loops_per_jiffy;
207 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200208 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530209 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 }
211 if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
212 (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700213 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530214 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
215 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200216 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530217 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 }
219}
220#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530221static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
222{
223 return;
224}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225#endif
226
227
228/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800229 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
230 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800232 * This function calls the transition notifiers and the "adjust_jiffies"
233 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500234 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 */
236void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
237{
Dave Jonese4472cb2006-01-31 15:53:55 -0800238 struct cpufreq_policy *policy;
239
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 BUG_ON(irqs_disabled());
241
242 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200243 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800244 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Mike Travis7a6aedf2008-03-25 15:06:53 -0700246 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800248
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500250 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800251 * which is not equal to what the cpufreq core thinks is
252 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 */
254 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800255 if ((policy) && (policy->cpu == freqs->cpu) &&
256 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200257 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800258 " %u, cpufreq assumed %u kHz.\n",
259 freqs->old, policy->cur);
260 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 }
262 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700263 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800264 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
266 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800267
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 case CPUFREQ_POSTCHANGE:
269 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200270 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200271 (unsigned long)freqs->cpu);
272 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100273 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700274 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800275 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800276 if (likely(policy) && likely(policy->cpu == freqs->cpu))
277 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 break;
279 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280}
281EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
282
283
284
285/*********************************************************************
286 * SYSFS INTERFACE *
287 *********************************************************************/
288
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700289static struct cpufreq_governor *__find_governor(const char *str_governor)
290{
291 struct cpufreq_governor *t;
292
293 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500294 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700295 return t;
296
297 return NULL;
298}
299
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300/**
301 * cpufreq_parse_governor - parse a governor string
302 */
Dave Jones905d77c2008-03-05 14:28:32 -0500303static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 struct cpufreq_governor **governor)
305{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700306 int err = -EINVAL;
307
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700309 goto out;
310
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 if (cpufreq_driver->setpolicy) {
312 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
313 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700314 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530315 } else if (!strnicmp(str_governor, "powersave",
316 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700318 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700320 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700322
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800323 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700324
325 t = __find_governor(str_governor);
326
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700327 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700328 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700329
Kees Cook1a8e1462011-05-04 08:38:56 -0700330 mutex_unlock(&cpufreq_governor_mutex);
331 ret = request_module("cpufreq_%s", str_governor);
332 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700333
Kees Cook1a8e1462011-05-04 08:38:56 -0700334 if (ret == 0)
335 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700336 }
337
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700338 if (t != NULL) {
339 *governor = t;
340 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700342
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800343 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 }
Dave Jones29464f22009-01-18 01:37:11 -0500345out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700346 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348
349
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530351 * cpufreq_per_cpu_attr_read() / show_##file_name() -
352 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 *
354 * Write out information from cpufreq_driver->policy[cpu]; object must be
355 * "unsigned int".
356 */
357
Dave Jones32ee8c32006-02-28 00:43:23 -0500358#define show_one(file_name, object) \
359static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500360(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500361{ \
Dave Jones29464f22009-01-18 01:37:11 -0500362 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363}
364
365show_one(cpuinfo_min_freq, cpuinfo.min_freq);
366show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100367show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368show_one(scaling_min_freq, min);
369show_one(scaling_max_freq, max);
370show_one(scaling_cur_freq, cur);
371
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530372static int __cpufreq_set_policy(struct cpufreq_policy *data,
373 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375/**
376 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
377 */
378#define store_one(file_name, object) \
379static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500380(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{ \
382 unsigned int ret = -EINVAL; \
383 struct cpufreq_policy new_policy; \
384 \
385 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
386 if (ret) \
387 return -EINVAL; \
388 \
Dave Jones29464f22009-01-18 01:37:11 -0500389 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 if (ret != 1) \
391 return -EINVAL; \
392 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200393 ret = __cpufreq_set_policy(policy, &new_policy); \
394 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 \
396 return ret ? ret : count; \
397}
398
Dave Jones29464f22009-01-18 01:37:11 -0500399store_one(scaling_min_freq, min);
400store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
402/**
403 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
404 */
Dave Jones905d77c2008-03-05 14:28:32 -0500405static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
406 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800408 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 if (!cur_freq)
410 return sprintf(buf, "<unknown>");
411 return sprintf(buf, "%u\n", cur_freq);
412}
413
414
415/**
416 * show_scaling_governor - show the current policy for the specified CPU
417 */
Dave Jones905d77c2008-03-05 14:28:32 -0500418static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419{
Dave Jones29464f22009-01-18 01:37:11 -0500420 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 return sprintf(buf, "powersave\n");
422 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
423 return sprintf(buf, "performance\n");
424 else if (policy->governor)
Dave Jones29464f22009-01-18 01:37:11 -0500425 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
426 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 return -EINVAL;
428}
429
430
431/**
432 * store_scaling_governor - store policy for the specified CPU
433 */
Dave Jones905d77c2008-03-05 14:28:32 -0500434static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
435 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436{
437 unsigned int ret = -EINVAL;
438 char str_governor[16];
439 struct cpufreq_policy new_policy;
440
441 ret = cpufreq_get_policy(&new_policy, policy->cpu);
442 if (ret)
443 return ret;
444
Dave Jones29464f22009-01-18 01:37:11 -0500445 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 if (ret != 1)
447 return -EINVAL;
448
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530449 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
450 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 return -EINVAL;
452
Thomas Renninger7970e082006-04-13 15:14:04 +0200453 /* Do not use cpufreq_set_policy here or the user_policy.max
454 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200455 ret = __cpufreq_set_policy(policy, &new_policy);
456
457 policy->user_policy.policy = policy->policy;
458 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200459
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530460 if (ret)
461 return ret;
462 else
463 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464}
465
466/**
467 * show_scaling_driver - show the cpufreq driver currently loaded
468 */
Dave Jones905d77c2008-03-05 14:28:32 -0500469static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470{
471 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
472}
473
474/**
475 * show_scaling_available_governors - show the available CPUfreq governors
476 */
Dave Jones905d77c2008-03-05 14:28:32 -0500477static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
478 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479{
480 ssize_t i = 0;
481 struct cpufreq_governor *t;
482
483 if (!cpufreq_driver->target) {
484 i += sprintf(buf, "performance powersave");
485 goto out;
486 }
487
488 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500489 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
490 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 goto out;
492 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
493 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500494out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 i += sprintf(&buf[i], "\n");
496 return i;
497}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700498
Rusty Russell835481d2009-01-04 05:18:06 -0800499static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500{
501 ssize_t i = 0;
502 unsigned int cpu;
503
Rusty Russell835481d2009-01-04 05:18:06 -0800504 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 if (i)
506 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
507 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
508 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500509 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 }
511 i += sprintf(&buf[i], "\n");
512 return i;
513}
514
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700515/**
516 * show_related_cpus - show the CPUs affected by each transition even if
517 * hw coordination is in use
518 */
519static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
520{
Rusty Russell835481d2009-01-04 05:18:06 -0800521 if (cpumask_empty(policy->related_cpus))
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700522 return show_cpus(policy->cpus, buf);
523 return show_cpus(policy->related_cpus, buf);
524}
525
526/**
527 * show_affected_cpus - show the CPUs affected by each transition
528 */
529static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
530{
531 return show_cpus(policy->cpus, buf);
532}
533
Venki Pallipadi9e769882007-10-26 10:18:21 -0700534static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500535 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700536{
537 unsigned int freq = 0;
538 unsigned int ret;
539
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700540 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700541 return -EINVAL;
542
543 ret = sscanf(buf, "%u", &freq);
544 if (ret != 1)
545 return -EINVAL;
546
547 policy->governor->store_setspeed(policy, freq);
548
549 return count;
550}
551
552static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
553{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700554 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700555 return sprintf(buf, "<unsupported>\n");
556
557 return policy->governor->show_setspeed(policy, buf);
558}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
Thomas Renningere2f74f32009-11-19 12:31:01 +0100560/**
561 * show_scaling_driver - show the current cpufreq HW/BIOS limitation
562 */
563static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
564{
565 unsigned int limit;
566 int ret;
567 if (cpufreq_driver->bios_limit) {
568 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
569 if (!ret)
570 return sprintf(buf, "%u\n", limit);
571 }
572 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
573}
574
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200575cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
576cpufreq_freq_attr_ro(cpuinfo_min_freq);
577cpufreq_freq_attr_ro(cpuinfo_max_freq);
578cpufreq_freq_attr_ro(cpuinfo_transition_latency);
579cpufreq_freq_attr_ro(scaling_available_governors);
580cpufreq_freq_attr_ro(scaling_driver);
581cpufreq_freq_attr_ro(scaling_cur_freq);
582cpufreq_freq_attr_ro(bios_limit);
583cpufreq_freq_attr_ro(related_cpus);
584cpufreq_freq_attr_ro(affected_cpus);
585cpufreq_freq_attr_rw(scaling_min_freq);
586cpufreq_freq_attr_rw(scaling_max_freq);
587cpufreq_freq_attr_rw(scaling_governor);
588cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589
Dave Jones905d77c2008-03-05 14:28:32 -0500590static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 &cpuinfo_min_freq.attr,
592 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100593 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 &scaling_min_freq.attr,
595 &scaling_max_freq.attr,
596 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700597 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 &scaling_governor.attr,
599 &scaling_driver.attr,
600 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700601 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 NULL
603};
604
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200605struct kobject *cpufreq_global_kobject;
606EXPORT_SYMBOL(cpufreq_global_kobject);
607
Dave Jones29464f22009-01-18 01:37:11 -0500608#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
609#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Dave Jones29464f22009-01-18 01:37:11 -0500611static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612{
Dave Jones905d77c2008-03-05 14:28:32 -0500613 struct cpufreq_policy *policy = to_policy(kobj);
614 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500615 ssize_t ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 policy = cpufreq_cpu_get(policy->cpu);
617 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500618 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800619
620 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500621 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800622
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530623 if (fattr->show)
624 ret = fattr->show(policy, buf);
625 else
626 ret = -EIO;
627
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800628 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500629fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 cpufreq_cpu_put(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500631no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 return ret;
633}
634
Dave Jones905d77c2008-03-05 14:28:32 -0500635static ssize_t store(struct kobject *kobj, struct attribute *attr,
636 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637{
Dave Jones905d77c2008-03-05 14:28:32 -0500638 struct cpufreq_policy *policy = to_policy(kobj);
639 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500640 ssize_t ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 policy = cpufreq_cpu_get(policy->cpu);
642 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500643 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800644
645 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500646 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800647
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530648 if (fattr->store)
649 ret = fattr->store(policy, buf, count);
650 else
651 ret = -EIO;
652
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800653 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500654fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 cpufreq_cpu_put(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500656no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 return ret;
658}
659
Dave Jones905d77c2008-03-05 14:28:32 -0500660static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661{
Dave Jones905d77c2008-03-05 14:28:32 -0500662 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200663 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 complete(&policy->kobj_unregister);
665}
666
Emese Revfy52cf25d2010-01-19 02:58:23 +0100667static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 .show = show,
669 .store = store,
670};
671
672static struct kobj_type ktype_cpufreq = {
673 .sysfs_ops = &sysfs_ops,
674 .default_attrs = default_attrs,
675 .release = cpufreq_sysfs_release,
676};
677
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200678/*
679 * Returns:
680 * Negative: Failure
681 * 0: Success
682 * Positive: When we have a managed CPU and the sysfs got symlinked
683 */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700684static int cpufreq_add_dev_policy(unsigned int cpu,
685 struct cpufreq_policy *policy,
686 struct sys_device *sys_dev)
Dave Jonesecf7e462009-07-08 18:48:47 -0400687{
688 int ret = 0;
689#ifdef CONFIG_SMP
690 unsigned long flags;
691 unsigned int j;
Dave Jonesecf7e462009-07-08 18:48:47 -0400692#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400693 struct cpufreq_governor *gov;
694
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700695 gov = __find_governor(per_cpu(cpufreq_policy_save, cpu).gov);
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400696 if (gov) {
697 policy->governor = gov;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200698 pr_debug("Restoring governor %s for cpu %d\n",
Dave Jonesecf7e462009-07-08 18:48:47 -0400699 policy->governor->name, cpu);
700 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700701 if (per_cpu(cpufreq_policy_save, cpu).min) {
702 policy->min = per_cpu(cpufreq_policy_save, cpu).min;
703 policy->user_policy.min = policy->min;
704 }
705 if (per_cpu(cpufreq_policy_save, cpu).max) {
706 policy->max = per_cpu(cpufreq_policy_save, cpu).max;
707 policy->user_policy.max = policy->max;
708 }
709 pr_debug("Restoring CPU%d min %d and max %d\n",
710 cpu, policy->min, policy->max);
Dave Jonesecf7e462009-07-08 18:48:47 -0400711#endif
712
713 for_each_cpu(j, policy->cpus) {
714 struct cpufreq_policy *managed_policy;
715
716 if (cpu == j)
717 continue;
718
719 /* Check for existing affected CPUs.
720 * They may not be aware of it due to CPU Hotplug.
721 * cpufreq_cpu_put is called when the device is removed
722 * in __cpufreq_remove_dev()
723 */
724 managed_policy = cpufreq_cpu_get(j);
725 if (unlikely(managed_policy)) {
726
727 /* Set proper policy_cpu */
728 unlock_policy_rwsem_write(cpu);
Tejun Heof1625062009-10-29 22:34:13 +0900729 per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
Dave Jonesecf7e462009-07-08 18:48:47 -0400730
731 if (lock_policy_rwsem_write(cpu) < 0) {
732 /* Should not go through policy unlock path */
733 if (cpufreq_driver->exit)
734 cpufreq_driver->exit(policy);
735 cpufreq_cpu_put(managed_policy);
736 return -EBUSY;
737 }
738
739 spin_lock_irqsave(&cpufreq_driver_lock, flags);
740 cpumask_copy(managed_policy->cpus, policy->cpus);
741 per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
742 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
743
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200744 pr_debug("CPU already managed, adding link\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400745 ret = sysfs_create_link(&sys_dev->kobj,
746 &managed_policy->kobj,
747 "cpufreq");
748 if (ret)
749 cpufreq_cpu_put(managed_policy);
750 /*
751 * Success. We only needed to be added to the mask.
752 * Call driver->exit() because only the cpu parent of
753 * the kobj needed to call init().
754 */
755 if (cpufreq_driver->exit)
756 cpufreq_driver->exit(policy);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200757
758 if (!ret)
759 return 1;
760 else
761 return ret;
Dave Jonesecf7e462009-07-08 18:48:47 -0400762 }
763 }
764#endif
765 return ret;
766}
767
768
Dave Jones19d6f7e2009-07-08 17:35:39 -0400769/* symlink affected CPUs */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700770static int cpufreq_add_dev_symlink(unsigned int cpu,
771 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400772{
773 unsigned int j;
774 int ret = 0;
775
776 for_each_cpu(j, policy->cpus) {
777 struct cpufreq_policy *managed_policy;
778 struct sys_device *cpu_sys_dev;
779
780 if (j == cpu)
781 continue;
782 if (!cpu_online(j))
783 continue;
784
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200785 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400786 managed_policy = cpufreq_cpu_get(cpu);
787 cpu_sys_dev = get_cpu_sysdev(j);
788 ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
789 "cpufreq");
790 if (ret) {
791 cpufreq_cpu_put(managed_policy);
792 return ret;
793 }
794 }
795 return ret;
796}
797
Alex Chiangcf3289d2009-11-17 20:27:08 -0700798static int cpufreq_add_dev_interface(unsigned int cpu,
799 struct cpufreq_policy *policy,
800 struct sys_device *sys_dev)
Dave Jones909a6942009-07-08 18:05:42 -0400801{
Dave Jonesecf7e462009-07-08 18:48:47 -0400802 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400803 struct freq_attr **drv_attr;
804 unsigned long flags;
805 int ret = 0;
806 unsigned int j;
807
808 /* prepare interface data */
809 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
810 &sys_dev->kobj, "cpufreq");
811 if (ret)
812 return ret;
813
814 /* set up files for this cpu device */
815 drv_attr = cpufreq_driver->attr;
816 while ((drv_attr) && (*drv_attr)) {
817 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
818 if (ret)
819 goto err_out_kobj_put;
820 drv_attr++;
821 }
822 if (cpufreq_driver->get) {
823 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
824 if (ret)
825 goto err_out_kobj_put;
826 }
827 if (cpufreq_driver->target) {
828 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
829 if (ret)
830 goto err_out_kobj_put;
831 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100832 if (cpufreq_driver->bios_limit) {
833 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
834 if (ret)
835 goto err_out_kobj_put;
836 }
Dave Jones909a6942009-07-08 18:05:42 -0400837
838 spin_lock_irqsave(&cpufreq_driver_lock, flags);
839 for_each_cpu(j, policy->cpus) {
Julia Lawallbec037a2010-08-05 22:23:00 +0200840 if (!cpu_online(j))
841 continue;
Dave Jones909a6942009-07-08 18:05:42 -0400842 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900843 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400844 }
845 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
846
847 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400848 if (ret)
849 goto err_out_kobj_put;
850
851 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
852 /* assure that the starting sequence is run in __cpufreq_set_policy */
853 policy->governor = NULL;
854
855 /* set default policy */
856 ret = __cpufreq_set_policy(policy, &new_policy);
857 policy->user_policy.policy = policy->policy;
858 policy->user_policy.governor = policy->governor;
859
860 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200861 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400862 if (cpufreq_driver->exit)
863 cpufreq_driver->exit(policy);
864 }
Dave Jones909a6942009-07-08 18:05:42 -0400865 return ret;
866
867err_out_kobj_put:
868 kobject_put(&policy->kobj);
869 wait_for_completion(&policy->kobj_unregister);
870 return ret;
871}
872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
874/**
875 * cpufreq_add_dev - add a CPU device
876 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500877 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400878 *
879 * The Oracle says: try running cpufreq registration/unregistration concurrently
880 * with with cpu hotplugging and all hell will break loose. Tried to clean this
881 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 */
Dave Jones905d77c2008-03-05 14:28:32 -0500883static int cpufreq_add_dev(struct sys_device *sys_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884{
885 unsigned int cpu = sys_dev->id;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500886 int ret = 0, found = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 unsigned long flags;
889 unsigned int j;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500890#ifdef CONFIG_HOTPLUG_CPU
891 int sibling;
892#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
Ashok Rajc32b6b82005-10-30 14:59:54 -0800894 if (cpu_is_offline(cpu))
895 return 0;
896
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200897 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
899#ifdef CONFIG_SMP
900 /* check whether a different CPU already registered this
901 * CPU because it is in the same boat. */
902 policy = cpufreq_cpu_get(cpu);
903 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500904 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 return 0;
906 }
907#endif
908
909 if (!try_module_get(cpufreq_driver->owner)) {
910 ret = -EINVAL;
911 goto module_out;
912 }
913
Dave Jones059019a2009-07-08 16:30:03 -0400914 ret = -ENOMEM;
Dave Jonese98df502005-10-20 15:17:43 -0700915 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400916 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400918
919 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400920 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400921
922 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400923 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924
925 policy->cpu = cpu;
Rusty Russell835481d2009-01-04 05:18:06 -0800926 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800928 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900929 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400930 ret = (lock_policy_rwsem_write(cpu) < 0);
931 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800932
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000934 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700936 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500937#ifdef CONFIG_HOTPLUG_CPU
938 for_each_online_cpu(sibling) {
939 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
940 if (cp && cp->governor &&
941 (cpumask_test_cpu(cpu, cp->related_cpus))) {
942 policy->governor = cp->governor;
943 found = 1;
944 break;
945 }
946 }
947#endif
948 if (!found)
949 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 /* call driver. From then on the cpufreq must be able
951 * to accept all calls to ->verify and ->setpolicy for this CPU
952 */
953 ret = cpufreq_driver->init(policy);
954 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200955 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400956 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957 }
Mike Chan187d9f42008-12-04 12:19:17 -0800958 policy->user_policy.min = policy->min;
959 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960
Thomas Renningera1531ac2008-07-29 22:32:58 -0700961 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
962 CPUFREQ_START, policy);
963
Dave Jonesecf7e462009-07-08 18:48:47 -0400964 ret = cpufreq_add_dev_policy(cpu, policy, sys_dev);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200965 if (ret) {
966 if (ret > 0)
967 /* This is a managed cpu, symlink created,
968 exit with 0 */
969 ret = 0;
Dave Jonesecf7e462009-07-08 18:48:47 -0400970 goto err_unlock_policy;
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200971 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
Dave Jones909a6942009-07-08 18:05:42 -0400973 ret = cpufreq_add_dev_interface(cpu, policy, sys_dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400974 if (ret)
975 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500976
Lothar Waßmanndca02612008-05-29 17:54:52 +0200977 unlock_policy_rwsem_write(cpu);
978
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400979 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200981 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500982
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 return 0;
984
985
986err_out_unregister:
987 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -0800988 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -0700989 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
991
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -0800992 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 wait_for_completion(&policy->kobj_unregister);
994
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400995err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -0500996 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +0800997 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400998err_free_cpumask:
999 free_cpumask_var(policy->cpus);
1000err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002nomem_out:
1003 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001004module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 return ret;
1006}
1007
1008
1009/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001010 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 *
1012 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001013 * Caller should already have policy_rwsem in write mode for this CPU.
1014 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 */
Dave Jones905d77c2008-03-05 14:28:32 -05001016static int __cpufreq_remove_dev(struct sys_device *sys_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017{
1018 unsigned int cpu = sys_dev->id;
1019 unsigned long flags;
1020 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001021 struct kobject *kobj;
1022 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023#ifdef CONFIG_SMP
Grant Coadye738cf62005-11-21 21:32:28 -08001024 struct sys_device *cpu_sys_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 unsigned int j;
1026#endif
1027
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001028 pr_debug("unregistering CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029
1030 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001031 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032
1033 if (!data) {
1034 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001035 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 return -EINVAL;
1037 }
Mike Travis7a6aedf2008-03-25 15:06:53 -07001038 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
1040
1041#ifdef CONFIG_SMP
1042 /* if this isn't the CPU which is the parent of the kobj, we
Dave Jones32ee8c32006-02-28 00:43:23 -05001043 * only need to unlink, put and exit
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 */
1045 if (unlikely(cpu != data->cpu)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001046 pr_debug("removing link\n");
Rusty Russell835481d2009-01-04 05:18:06 -08001047 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Amerigo Wang499bca92010-03-04 03:23:46 -05001049 kobj = &sys_dev->kobj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 cpufreq_cpu_put(data);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001051 unlock_policy_rwsem_write(cpu);
Amerigo Wang499bca92010-03-04 03:23:46 -05001052 sysfs_remove_link(kobj, "cpufreq");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 return 0;
1054 }
1055#endif
1056
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057#ifdef CONFIG_SMP
Thomas Renninger084f3492007-07-09 11:35:28 -07001058
1059#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001060 strncpy(per_cpu(cpufreq_policy_save, cpu).gov, data->governor->name,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001061 CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001062 per_cpu(cpufreq_policy_save, cpu).min = data->min;
1063 per_cpu(cpufreq_policy_save, cpu).max = data->max;
1064 pr_debug("Saving CPU%d policy min %d and max %d\n",
1065 cpu, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001066#endif
1067
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 /* if we have other CPUs still registered, we need to unlink them,
1069 * or else wait_for_completion below will lock up. Clean the
Mike Travis7a6aedf2008-03-25 15:06:53 -07001070 * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
1071 * the sysfs links afterwards.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 */
Rusty Russell835481d2009-01-04 05:18:06 -08001073 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1074 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 if (j == cpu)
1076 continue;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001077 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 }
1079 }
1080
1081 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1082
Rusty Russell835481d2009-01-04 05:18:06 -08001083 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1084 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 if (j == cpu)
1086 continue;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001087 pr_debug("removing link for cpu %u\n", j);
Thomas Renninger084f3492007-07-09 11:35:28 -07001088#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001089 strncpy(per_cpu(cpufreq_policy_save, j).gov,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001090 data->governor->name, CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001091 per_cpu(cpufreq_policy_save, j).min = data->min;
1092 per_cpu(cpufreq_policy_save, j).max = data->max;
1093 pr_debug("Saving CPU%d policy min %d and max %d\n",
1094 j, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001095#endif
Ashok Rajd434fca2005-10-30 14:59:52 -08001096 cpu_sys_dev = get_cpu_sysdev(j);
Amerigo Wang499bca92010-03-04 03:23:46 -05001097 kobj = &cpu_sys_dev->kobj;
1098 unlock_policy_rwsem_write(cpu);
1099 sysfs_remove_link(kobj, "cpufreq");
1100 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101 cpufreq_cpu_put(data);
1102 }
1103 }
1104#else
1105 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1106#endif
1107
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 if (cpufreq_driver->target)
1109 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001110
Amerigo Wang499bca92010-03-04 03:23:46 -05001111 kobj = &data->kobj;
1112 cmp = &data->kobj_unregister;
1113 unlock_policy_rwsem_write(cpu);
1114 kobject_put(kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115
1116 /* we need to make sure that the underlying kobj is actually
Dave Jones32ee8c32006-02-28 00:43:23 -05001117 * not referenced anymore by anybody before we proceed with
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 * unloading.
1119 */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001120 pr_debug("waiting for dropping of refcount\n");
Amerigo Wang499bca92010-03-04 03:23:46 -05001121 wait_for_completion(cmp);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001122 pr_debug("wait complete\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123
Amerigo Wang499bca92010-03-04 03:23:46 -05001124 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 if (cpufreq_driver->exit)
1126 cpufreq_driver->exit(data);
venkatesh.pallipadi@intel.com7d26e2d2009-07-02 17:08:30 -07001127 unlock_policy_rwsem_write(cpu);
1128
Jacob Shin27ecddc2011-04-27 13:32:11 -05001129#ifdef CONFIG_HOTPLUG_CPU
1130 /* when the CPU which is the parent of the kobj is hotplugged
1131 * offline, check for siblings, and create cpufreq sysfs interface
1132 * and symlinks
1133 */
1134 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1135 /* first sibling now owns the new sysfs dir */
1136 cpumask_clear_cpu(cpu, data->cpus);
1137 cpufreq_add_dev(get_cpu_sysdev(cpumask_first(data->cpus)));
1138
1139 /* finally remove our own symlink */
1140 lock_policy_rwsem_write(cpu);
1141 __cpufreq_remove_dev(sys_dev);
1142 }
1143#endif
1144
Rusty Russell835481d2009-01-04 05:18:06 -08001145 free_cpumask_var(data->related_cpus);
1146 free_cpumask_var(data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 kfree(data);
1148
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 return 0;
1150}
1151
1152
Dave Jones905d77c2008-03-05 14:28:32 -05001153static int cpufreq_remove_dev(struct sys_device *sys_dev)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001154{
1155 unsigned int cpu = sys_dev->id;
1156 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001157
1158 if (cpu_is_offline(cpu))
1159 return 0;
1160
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001161 if (unlikely(lock_policy_rwsem_write(cpu)))
1162 BUG();
1163
1164 retval = __cpufreq_remove_dev(sys_dev);
1165 return retval;
1166}
1167
1168
David Howells65f27f32006-11-22 14:55:48 +00001169static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170{
David Howells65f27f32006-11-22 14:55:48 +00001171 struct cpufreq_policy *policy =
1172 container_of(work, struct cpufreq_policy, update);
1173 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001174 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 cpufreq_update_policy(cpu);
1176}
1177
1178/**
1179 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1180 * @cpu: cpu number
1181 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1182 * @new_freq: CPU frequency the CPU actually runs at
1183 *
Dave Jones29464f22009-01-18 01:37:11 -05001184 * We adjust to current frequency first, and need to clean up later.
1185 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301187static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1188 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189{
1190 struct cpufreq_freqs freqs;
1191
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001192 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1194
1195 freqs.cpu = cpu;
1196 freqs.old = old_freq;
1197 freqs.new = new_freq;
1198 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1199 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1200}
1201
1202
Dave Jones32ee8c32006-02-28 00:43:23 -05001203/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301204 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001205 * @cpu: CPU number
1206 *
1207 * This is the last known freq, without actually getting it from the driver.
1208 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1209 */
1210unsigned int cpufreq_quick_get(unsigned int cpu)
1211{
1212 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301213 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001214
1215 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301216 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001217 cpufreq_cpu_put(policy);
1218 }
1219
Dave Jones4d34a672008-02-07 16:33:49 -05001220 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001221}
1222EXPORT_SYMBOL(cpufreq_quick_get);
1223
1224
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001225static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001227 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301228 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001231 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301233 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301235 if (ret_freq && policy->cur &&
1236 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1237 /* verify no discrepancy between actual and
1238 saved value exists */
1239 if (unlikely(ret_freq != policy->cur)) {
1240 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 schedule_work(&policy->update);
1242 }
1243 }
1244
Dave Jones4d34a672008-02-07 16:33:49 -05001245 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001246}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001248/**
1249 * cpufreq_get - get the current CPU frequency (in kHz)
1250 * @cpu: CPU number
1251 *
1252 * Get the CPU current (static) CPU frequency
1253 */
1254unsigned int cpufreq_get(unsigned int cpu)
1255{
1256 unsigned int ret_freq = 0;
1257 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1258
1259 if (!policy)
1260 goto out;
1261
1262 if (unlikely(lock_policy_rwsem_read(cpu)))
1263 goto out_policy;
1264
1265 ret_freq = __cpufreq_get(cpu);
1266
1267 unlock_policy_rwsem_read(cpu);
1268
1269out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001271out:
Dave Jones4d34a672008-02-07 16:33:49 -05001272 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273}
1274EXPORT_SYMBOL(cpufreq_get);
1275
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001276static struct sysdev_driver cpufreq_sysdev_driver = {
1277 .add = cpufreq_add_dev,
1278 .remove = cpufreq_remove_dev,
1279};
1280
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281
1282/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001283 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1284 *
1285 * This function is only executed for the boot processor. The other CPUs
1286 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001287 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001288static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001289{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301290 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001291
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001292 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001293 struct cpufreq_policy *cpu_policy;
1294
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001295 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001296
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001297 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001298 cpu_policy = cpufreq_cpu_get(cpu);
1299 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001300 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001301
1302 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001303 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001304 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001305 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1306 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001307 }
1308
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001309 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001310 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001311}
1312
1313/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001314 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 *
1316 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001317 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1318 * restored. It will verify that the current freq is in sync with
1319 * what we believe it to be. This is a bit later than when it
1320 * should be, but nonethteless it's better than calling
1321 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001322 *
1323 * This function is only executed for the boot CPU. The other CPUs have not
1324 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001326static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301328 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001329
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001330 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 struct cpufreq_policy *cpu_policy;
1332
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001333 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001335 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 cpu_policy = cpufreq_cpu_get(cpu);
1337 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001338 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
1340 if (cpufreq_driver->resume) {
1341 ret = cpufreq_driver->resume(cpu_policy);
1342 if (ret) {
1343 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1344 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001345 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 }
1347 }
1348
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001350
Dave Jonesc9060492008-02-07 16:32:18 -05001351fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353}
1354
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001355static struct syscore_ops cpufreq_syscore_ops = {
1356 .suspend = cpufreq_bp_suspend,
1357 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358};
1359
1360
1361/*********************************************************************
1362 * NOTIFIER LISTS INTERFACE *
1363 *********************************************************************/
1364
1365/**
1366 * cpufreq_register_notifier - register a driver with cpufreq
1367 * @nb: notifier function to register
1368 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1369 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001370 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 * are notified about clock rate changes (once before and once after
1372 * the transition), or a list of drivers that are notified about
1373 * changes in cpufreq policy.
1374 *
1375 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001376 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 */
1378int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1379{
1380 int ret;
1381
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001382 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1383
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 switch (list) {
1385 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001386 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001387 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 break;
1389 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001390 ret = blocking_notifier_chain_register(
1391 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 break;
1393 default:
1394 ret = -EINVAL;
1395 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
1397 return ret;
1398}
1399EXPORT_SYMBOL(cpufreq_register_notifier);
1400
1401
1402/**
1403 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1404 * @nb: notifier block to be unregistered
1405 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1406 *
1407 * Remove a driver from the CPU frequency notifier list.
1408 *
1409 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001410 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 */
1412int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1413{
1414 int ret;
1415
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416 switch (list) {
1417 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001418 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001419 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 break;
1421 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001422 ret = blocking_notifier_chain_unregister(
1423 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 break;
1425 default:
1426 ret = -EINVAL;
1427 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 return ret;
1430}
1431EXPORT_SYMBOL(cpufreq_unregister_notifier);
1432
1433
1434/*********************************************************************
1435 * GOVERNORS *
1436 *********************************************************************/
1437
1438
1439int __cpufreq_driver_target(struct cpufreq_policy *policy,
1440 unsigned int target_freq,
1441 unsigned int relation)
1442{
1443 int retval = -EINVAL;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001444
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001445 pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 target_freq, relation);
1447 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1448 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001449
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 return retval;
1451}
1452EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1453
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454int cpufreq_driver_target(struct cpufreq_policy *policy,
1455 unsigned int target_freq,
1456 unsigned int relation)
1457{
Julia Lawallf1829e42008-07-25 22:44:53 +02001458 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459
1460 policy = cpufreq_cpu_get(policy->cpu);
1461 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001462 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001464 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001465 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
1467 ret = __cpufreq_driver_target(policy, target_freq, relation);
1468
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001469 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470
Julia Lawallf1829e42008-07-25 22:44:53 +02001471fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001473no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 return ret;
1475}
1476EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1477
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001478int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001479{
1480 int ret = 0;
1481
1482 policy = cpufreq_cpu_get(policy->cpu);
1483 if (!policy)
1484 return -EINVAL;
1485
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001486 if (cpu_online(cpu) && cpufreq_driver->getavg)
1487 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001488
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001489 cpufreq_cpu_put(policy);
1490 return ret;
1491}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001492EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001493
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001494/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001495 * when "event" is CPUFREQ_GOV_LIMITS
1496 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301498static int __cpufreq_governor(struct cpufreq_policy *policy,
1499 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500{
Dave Jonescc993ca2005-07-28 09:43:56 -07001501 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001502
1503 /* Only must be defined when default governor is known to have latency
1504 restrictions, like e.g. conservative or ondemand.
1505 That this is the case is already ensured in Kconfig
1506 */
1507#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1508 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1509#else
1510 struct cpufreq_governor *gov = NULL;
1511#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001512
1513 if (policy->governor->max_transition_latency &&
1514 policy->cpuinfo.transition_latency >
1515 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001516 if (!gov)
1517 return -EINVAL;
1518 else {
1519 printk(KERN_WARNING "%s governor failed, too long"
1520 " transition latency of HW, fallback"
1521 " to %s governor\n",
1522 policy->governor->name,
1523 gov->name);
1524 policy->governor = gov;
1525 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001526 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
1528 if (!try_module_get(policy->governor->owner))
1529 return -EINVAL;
1530
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001531 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301532 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 ret = policy->governor->governor(policy, event);
1534
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301535 /* we keep one module reference alive for
1536 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 if ((event != CPUFREQ_GOV_START) || ret)
1538 module_put(policy->governor->owner);
1539 if ((event == CPUFREQ_GOV_STOP) && !ret)
1540 module_put(policy->governor->owner);
1541
1542 return ret;
1543}
1544
1545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546int cpufreq_register_governor(struct cpufreq_governor *governor)
1547{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001548 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
1550 if (!governor)
1551 return -EINVAL;
1552
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001553 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001554
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001555 err = -EBUSY;
1556 if (__find_governor(governor->name) == NULL) {
1557 err = 0;
1558 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560
Dave Jones32ee8c32006-02-28 00:43:23 -05001561 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001562 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563}
1564EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1565
1566
1567void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1568{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001569#ifdef CONFIG_HOTPLUG_CPU
1570 int cpu;
1571#endif
1572
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 if (!governor)
1574 return;
1575
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001576#ifdef CONFIG_HOTPLUG_CPU
1577 for_each_present_cpu(cpu) {
1578 if (cpu_online(cpu))
1579 continue;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001580 if (!strcmp(per_cpu(cpufreq_policy_save, cpu).gov,
1581 governor->name))
1582 strcpy(per_cpu(cpufreq_policy_save, cpu).gov, "\0");
1583 per_cpu(cpufreq_policy_save, cpu).min = 0;
1584 per_cpu(cpufreq_policy_save, cpu).max = 0;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001585 }
1586#endif
1587
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001588 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001590 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 return;
1592}
1593EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1594
1595
1596
1597/*********************************************************************
1598 * POLICY INTERFACE *
1599 *********************************************************************/
1600
1601/**
1602 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001603 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1604 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 *
1606 * Reads the current cpufreq policy.
1607 */
1608int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1609{
1610 struct cpufreq_policy *cpu_policy;
1611 if (!policy)
1612 return -EINVAL;
1613
1614 cpu_policy = cpufreq_cpu_get(cpu);
1615 if (!cpu_policy)
1616 return -EINVAL;
1617
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619
1620 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 return 0;
1622}
1623EXPORT_SYMBOL(cpufreq_get_policy);
1624
1625
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001626/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301627 * data : current policy.
1628 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001629 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301630static int __cpufreq_set_policy(struct cpufreq_policy *data,
1631 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632{
1633 int ret = 0;
1634
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001635 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 policy->min, policy->max);
1637
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301638 memcpy(&policy->cpuinfo, &data->cpuinfo,
1639 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640
Yi Yang53391fa2008-01-30 13:33:34 +01001641 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001642 ret = -EINVAL;
1643 goto error_out;
1644 }
1645
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646 /* verify the cpu speed can be set within this limit */
1647 ret = cpufreq_driver->verify(policy);
1648 if (ret)
1649 goto error_out;
1650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001652 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1653 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
1655 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001656 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1657 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
1659 /* verify the cpu speed can be set within this limit,
1660 which might be different to the first one */
1661 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001662 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
1665 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001666 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1667 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
Dave Jones7d5e3502006-02-02 17:03:42 -05001669 data->min = policy->min;
1670 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001672 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301673 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
1675 if (cpufreq_driver->setpolicy) {
1676 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001677 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 ret = cpufreq_driver->setpolicy(policy);
1679 } else {
1680 if (policy->governor != data->governor) {
1681 /* save old, working values */
1682 struct cpufreq_governor *old_gov = data->governor;
1683
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001684 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
1686 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001687 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1689
1690 /* start new governor */
1691 data->governor = policy->governor;
1692 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1693 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001694 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301695 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 if (old_gov) {
1697 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301698 __cpufreq_governor(data,
1699 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 }
1701 ret = -EINVAL;
1702 goto error_out;
1703 }
1704 /* might be a policy change, too, so fall through */
1705 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001706 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1708 }
1709
Dave Jones7d5e3502006-02-02 17:03:42 -05001710error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 return ret;
1712}
1713
1714/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1716 * @cpu: CPU which shall be re-evaluated
1717 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001718 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 * at different times.
1720 */
1721int cpufreq_update_policy(unsigned int cpu)
1722{
1723 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1724 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001725 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
Julia Lawallf1829e42008-07-25 22:44:53 +02001727 if (!data) {
1728 ret = -ENODEV;
1729 goto no_policy;
1730 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
Julia Lawallf1829e42008-07-25 22:44:53 +02001732 if (unlikely(lock_policy_rwsem_write(cpu))) {
1733 ret = -EINVAL;
1734 goto fail;
1735 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001737 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001738 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 policy.min = data->user_policy.min;
1740 policy.max = data->user_policy.max;
1741 policy.policy = data->user_policy.policy;
1742 policy.governor = data->user_policy.governor;
1743
Thomas Renninger0961dd02006-01-26 18:46:33 +01001744 /* BIOS might change freq behind our back
1745 -> ask driver for current freq and notify governors about a change */
1746 if (cpufreq_driver->get) {
1747 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001748 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001749 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001750 data->cur = policy.cur;
1751 } else {
1752 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301753 cpufreq_out_of_sync(cpu, data->cur,
1754 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001755 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001756 }
1757
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 ret = __cpufreq_set_policy(data, &policy);
1759
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001760 unlock_policy_rwsem_write(cpu);
1761
Julia Lawallf1829e42008-07-25 22:44:53 +02001762fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001764no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 return ret;
1766}
1767EXPORT_SYMBOL(cpufreq_update_policy);
1768
Satyam Sharmadd184a02007-10-02 13:28:14 -07001769static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001770 unsigned long action, void *hcpu)
1771{
1772 unsigned int cpu = (unsigned long)hcpu;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001773 struct sys_device *sys_dev;
1774
1775 sys_dev = get_cpu_sysdev(cpu);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001776 if (sys_dev) {
1777 switch (action) {
1778 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001779 case CPU_ONLINE_FROZEN:
Ashok Rajc32b6b82005-10-30 14:59:54 -08001780 cpufreq_add_dev(sys_dev);
1781 break;
1782 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001783 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001784 if (unlikely(lock_policy_rwsem_write(cpu)))
1785 BUG();
1786
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001787 __cpufreq_remove_dev(sys_dev);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001788 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001789 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001790 case CPU_DOWN_FAILED_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001791 cpufreq_add_dev(sys_dev);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001792 break;
1793 }
1794 }
1795 return NOTIFY_OK;
1796}
1797
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001798static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001799 .notifier_call = cpufreq_cpu_callback,
1800};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801
1802/*********************************************************************
1803 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1804 *********************************************************************/
1805
1806/**
1807 * cpufreq_register_driver - register a CPU Frequency driver
1808 * @driver_data: A struct cpufreq_driver containing the values#
1809 * submitted by the CPU Frequency driver.
1810 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001811 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001813 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 *
1815 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001816int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817{
1818 unsigned long flags;
1819 int ret;
1820
1821 if (!driver_data || !driver_data->verify || !driver_data->init ||
1822 ((!driver_data->setpolicy) && (!driver_data->target)))
1823 return -EINVAL;
1824
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001825 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
1827 if (driver_data->setpolicy)
1828 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1829
1830 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1831 if (cpufreq_driver) {
1832 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1833 return -EBUSY;
1834 }
1835 cpufreq_driver = driver_data;
1836 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1837
Mike Travis7a6aedf2008-03-25 15:06:53 -07001838 ret = sysdev_driver_register(&cpu_sysdev_class,
1839 &cpufreq_sysdev_driver);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001840 if (ret)
1841 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001843 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 int i;
1845 ret = -ENODEV;
1846
1847 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001848 for (i = 0; i < nr_cpu_ids; i++)
1849 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001851 break;
1852 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
1854 /* if all ->init() calls failed, unregister */
1855 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001856 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301857 driver_data->name);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001858 goto err_sysdev_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 }
1860 }
1861
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001862 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001863 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001865 return 0;
1866err_sysdev_unreg:
1867 sysdev_driver_unregister(&cpu_sysdev_class,
1868 &cpufreq_sysdev_driver);
1869err_null_driver:
1870 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1871 cpufreq_driver = NULL;
1872 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001873 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874}
1875EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1876
1877
1878/**
1879 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1880 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001881 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 * the right to do so, i.e. if you have succeeded in initialising before!
1883 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1884 * currently not initialised.
1885 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001886int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887{
1888 unsigned long flags;
1889
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001890 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001893 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
1895 sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001896 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897
1898 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1899 cpufreq_driver = NULL;
1900 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1901
1902 return 0;
1903}
1904EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001905
1906static int __init cpufreq_core_init(void)
1907{
1908 int cpu;
1909
1910 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001911 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001912 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1913 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001914
1915 cpufreq_global_kobject = kobject_create_and_add("cpufreq",
1916 &cpu_sysdev_class.kset.kobj);
1917 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001918 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001919
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001920 return 0;
1921}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001922core_initcall(cpufreq_core_init);