blob: fb8a5279c5d829898d37336c8b4e023ee55f36a5 [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 */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040044static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070045#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070046static DEFINE_SPINLOCK(cpufreq_driver_lock);
47
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080048/*
49 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
50 * all cpufreq/hotplug/workqueue/etc related lock issues.
51 *
52 * The rules for this semaphore:
53 * - Any routine that wants to read from the policy structure will
54 * do a down_read on this semaphore.
55 * - Any routine that will write to the policy structure and/or may take away
56 * the policy altogether (eg. CPU hotplug), will hold this lock in write
57 * mode before doing so.
58 *
59 * Additional rules:
60 * - All holders of the lock should check to make sure that the CPU they
61 * are concerned with are online after they get the lock.
62 * - Governor routines that can be called in cpufreq hotplug path should not
63 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040064 * - Lock should not be held across
65 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080066 */
Tejun Heof1625062009-10-29 22:34:13 +090067static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080068static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
69
70#define lock_policy_rwsem(mode, cpu) \
Amerigo Wang226528c2010-03-04 03:23:36 -050071static int lock_policy_rwsem_##mode \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072(int cpu) \
73{ \
Tejun Heof1625062009-10-29 22:34:13 +090074 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080075 BUG_ON(policy_cpu == -1); \
76 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
77 if (unlikely(!cpu_online(cpu))) { \
78 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
79 return -1; \
80 } \
81 \
82 return 0; \
83}
84
85lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080086
87lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080088
Amerigo Wang226528c2010-03-04 03:23:36 -050089static void unlock_policy_rwsem_read(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090{
Tejun Heof1625062009-10-29 22:34:13 +090091 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080092 BUG_ON(policy_cpu == -1);
93 up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
94}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080095
Amerigo Wang226528c2010-03-04 03:23:36 -050096static void unlock_policy_rwsem_write(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097{
Tejun Heof1625062009-10-29 22:34:13 +090098 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080099 BUG_ON(policy_cpu == -1);
100 up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
101}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800102
103
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500105static int __cpufreq_governor(struct cpufreq_policy *policy,
106 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800107static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000108static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500111 * Two notifier lists: the "policy" list is involved in the
112 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 * "transition" list for kernel code that needs to handle
114 * changes to devices when the CPU clock speed changes.
115 * The mutex locks both lists.
116 */
Alan Sterne041c682006-03-27 01:16:30 -0800117static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700118static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200120static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700121static int __init init_cpufreq_transition_notifier_list(void)
122{
123 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200124 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700125 return 0;
126}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800127pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400129static int off __read_mostly;
130int cpufreq_disabled(void)
131{
132 return off;
133}
134void disable_cpufreq(void)
135{
136 off = 1;
137}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500139static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
Stephen Boyda9144432012-07-20 18:14:38 +0000141static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142{
143 struct cpufreq_policy *data;
144 unsigned long flags;
145
Mike Travis7a6aedf2008-03-25 15:06:53 -0700146 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147 goto err_out;
148
149 /* get the cpufreq driver */
150 spin_lock_irqsave(&cpufreq_driver_lock, flags);
151
152 if (!cpufreq_driver)
153 goto err_out_unlock;
154
155 if (!try_module_get(cpufreq_driver->owner))
156 goto err_out_unlock;
157
158
159 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700160 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
162 if (!data)
163 goto err_out_put_module;
164
Stephen Boyda9144432012-07-20 18:14:38 +0000165 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 goto err_out_put_module;
167
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 return data;
170
Dave Jones7d5e3502006-02-02 17:03:42 -0500171err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500173err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500175err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 return NULL;
177}
Stephen Boyda9144432012-07-20 18:14:38 +0000178
179struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
180{
181 return __cpufreq_cpu_get(cpu, false);
182}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
184
Stephen Boyda9144432012-07-20 18:14:38 +0000185static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
186{
187 return __cpufreq_cpu_get(cpu, true);
188}
189
190static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
191{
192 if (!sysfs)
193 kobject_put(&data->kobj);
194 module_put(cpufreq_driver->owner);
195}
Dave Jones7d5e3502006-02-02 17:03:42 -0500196
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197void cpufreq_cpu_put(struct cpufreq_policy *data)
198{
Stephen Boyda9144432012-07-20 18:14:38 +0000199 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200}
201EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
202
Stephen Boyda9144432012-07-20 18:14:38 +0000203static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
204{
205 __cpufreq_cpu_put(data, true);
206}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207
208/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
210 *********************************************************************/
211
212/**
213 * adjust_jiffies - adjust the system "loops_per_jiffy"
214 *
215 * This function alters the system "loops_per_jiffy" for the clock
216 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500217 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 * per-CPU loops_per_jiffy value wherever possible.
219 */
220#ifndef CONFIG_SMP
221static unsigned long l_p_j_ref;
222static unsigned int l_p_j_ref_freq;
223
Arjan van de Ven858119e2006-01-14 13:20:43 -0800224static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225{
226 if (ci->flags & CPUFREQ_CONST_LOOPS)
227 return;
228
229 if (!l_p_j_ref_freq) {
230 l_p_j_ref = loops_per_jiffy;
231 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200232 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530233 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530235 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700236 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530237 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
238 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200239 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530240 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 }
242}
243#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530244static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
245{
246 return;
247}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248#endif
249
250
251/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800252 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
253 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800255 * This function calls the transition notifiers and the "adjust_jiffies"
256 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500257 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 */
259void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
260{
Dave Jonese4472cb2006-01-31 15:53:55 -0800261 struct cpufreq_policy *policy;
262
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 BUG_ON(irqs_disabled());
264
265 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200266 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800267 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
Mike Travis7a6aedf2008-03-25 15:06:53 -0700269 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800271
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500273 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800274 * which is not equal to what the cpufreq core thinks is
275 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 */
277 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800278 if ((policy) && (policy->cpu == freqs->cpu) &&
279 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200280 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800281 " %u, cpufreq assumed %u kHz.\n",
282 freqs->old, policy->cur);
283 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 }
285 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700286 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800287 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
289 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800290
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 case CPUFREQ_POSTCHANGE:
292 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200293 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200294 (unsigned long)freqs->cpu);
295 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100296 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700297 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800298 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800299 if (likely(policy) && likely(policy->cpu == freqs->cpu))
300 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 break;
302 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303}
304EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
305
306
307
308/*********************************************************************
309 * SYSFS INTERFACE *
310 *********************************************************************/
311
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700312static struct cpufreq_governor *__find_governor(const char *str_governor)
313{
314 struct cpufreq_governor *t;
315
316 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500317 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700318 return t;
319
320 return NULL;
321}
322
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323/**
324 * cpufreq_parse_governor - parse a governor string
325 */
Dave Jones905d77c2008-03-05 14:28:32 -0500326static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 struct cpufreq_governor **governor)
328{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700329 int err = -EINVAL;
330
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700332 goto out;
333
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 if (cpufreq_driver->setpolicy) {
335 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
336 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700337 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530338 } else if (!strnicmp(str_governor, "powersave",
339 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700341 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700343 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700345
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800346 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700347
348 t = __find_governor(str_governor);
349
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700350 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700351 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700352
Kees Cook1a8e1462011-05-04 08:38:56 -0700353 mutex_unlock(&cpufreq_governor_mutex);
354 ret = request_module("cpufreq_%s", str_governor);
355 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700356
Kees Cook1a8e1462011-05-04 08:38:56 -0700357 if (ret == 0)
358 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700359 }
360
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700361 if (t != NULL) {
362 *governor = t;
363 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700365
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800366 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 }
Dave Jones29464f22009-01-18 01:37:11 -0500368out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700369 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530374 * cpufreq_per_cpu_attr_read() / show_##file_name() -
375 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 *
377 * Write out information from cpufreq_driver->policy[cpu]; object must be
378 * "unsigned int".
379 */
380
Dave Jones32ee8c32006-02-28 00:43:23 -0500381#define show_one(file_name, object) \
382static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500383(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500384{ \
Dave Jones29464f22009-01-18 01:37:11 -0500385 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386}
387
388show_one(cpuinfo_min_freq, cpuinfo.min_freq);
389show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100390show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391show_one(scaling_min_freq, min);
392show_one(scaling_max_freq, max);
393show_one(scaling_cur_freq, cur);
394
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530395static int __cpufreq_set_policy(struct cpufreq_policy *data,
396 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200397
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398/**
399 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
400 */
401#define store_one(file_name, object) \
402static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500403(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404{ \
405 unsigned int ret = -EINVAL; \
406 struct cpufreq_policy new_policy; \
407 \
408 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
409 if (ret) \
410 return -EINVAL; \
411 \
Dave Jones29464f22009-01-18 01:37:11 -0500412 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 if (ret != 1) \
414 return -EINVAL; \
415 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200416 ret = __cpufreq_set_policy(policy, &new_policy); \
417 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 \
419 return ret ? ret : count; \
420}
421
Dave Jones29464f22009-01-18 01:37:11 -0500422store_one(scaling_min_freq, min);
423store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
425/**
426 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
427 */
Dave Jones905d77c2008-03-05 14:28:32 -0500428static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
429 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800431 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 if (!cur_freq)
433 return sprintf(buf, "<unknown>");
434 return sprintf(buf, "%u\n", cur_freq);
435}
436
437
438/**
439 * show_scaling_governor - show the current policy for the specified CPU
440 */
Dave Jones905d77c2008-03-05 14:28:32 -0500441static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442{
Dave Jones29464f22009-01-18 01:37:11 -0500443 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 return sprintf(buf, "powersave\n");
445 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
446 return sprintf(buf, "performance\n");
447 else if (policy->governor)
Dave Jones29464f22009-01-18 01:37:11 -0500448 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
449 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 return -EINVAL;
451}
452
453
454/**
455 * store_scaling_governor - store policy for the specified CPU
456 */
Dave Jones905d77c2008-03-05 14:28:32 -0500457static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
458 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459{
460 unsigned int ret = -EINVAL;
461 char str_governor[16];
462 struct cpufreq_policy new_policy;
463
464 ret = cpufreq_get_policy(&new_policy, policy->cpu);
465 if (ret)
466 return ret;
467
Dave Jones29464f22009-01-18 01:37:11 -0500468 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 if (ret != 1)
470 return -EINVAL;
471
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530472 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
473 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 return -EINVAL;
475
Thomas Renninger7970e082006-04-13 15:14:04 +0200476 /* Do not use cpufreq_set_policy here or the user_policy.max
477 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200478 ret = __cpufreq_set_policy(policy, &new_policy);
479
480 policy->user_policy.policy = policy->policy;
481 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200482
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530483 if (ret)
484 return ret;
485 else
486 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487}
488
489/**
490 * show_scaling_driver - show the cpufreq driver currently loaded
491 */
Dave Jones905d77c2008-03-05 14:28:32 -0500492static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493{
494 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
495}
496
497/**
498 * show_scaling_available_governors - show the available CPUfreq governors
499 */
Dave Jones905d77c2008-03-05 14:28:32 -0500500static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
501 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502{
503 ssize_t i = 0;
504 struct cpufreq_governor *t;
505
506 if (!cpufreq_driver->target) {
507 i += sprintf(buf, "performance powersave");
508 goto out;
509 }
510
511 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500512 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
513 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 goto out;
515 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
516 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500517out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 i += sprintf(&buf[i], "\n");
519 return i;
520}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700521
Rusty Russell835481d2009-01-04 05:18:06 -0800522static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523{
524 ssize_t i = 0;
525 unsigned int cpu;
526
Rusty Russell835481d2009-01-04 05:18:06 -0800527 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 if (i)
529 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
530 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
531 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500532 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 }
534 i += sprintf(&buf[i], "\n");
535 return i;
536}
537
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700538/**
539 * show_related_cpus - show the CPUs affected by each transition even if
540 * hw coordination is in use
541 */
542static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
543{
Rusty Russell835481d2009-01-04 05:18:06 -0800544 if (cpumask_empty(policy->related_cpus))
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700545 return show_cpus(policy->cpus, buf);
546 return show_cpus(policy->related_cpus, buf);
547}
548
549/**
550 * show_affected_cpus - show the CPUs affected by each transition
551 */
552static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
553{
554 return show_cpus(policy->cpus, buf);
555}
556
Venki Pallipadi9e769882007-10-26 10:18:21 -0700557static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500558 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700559{
560 unsigned int freq = 0;
561 unsigned int ret;
562
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700563 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700564 return -EINVAL;
565
566 ret = sscanf(buf, "%u", &freq);
567 if (ret != 1)
568 return -EINVAL;
569
570 policy->governor->store_setspeed(policy, freq);
571
572 return count;
573}
574
575static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
576{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700577 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700578 return sprintf(buf, "<unsupported>\n");
579
580 return policy->governor->show_setspeed(policy, buf);
581}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
Thomas Renningere2f74f32009-11-19 12:31:01 +0100583/**
584 * show_scaling_driver - show the current cpufreq HW/BIOS limitation
585 */
586static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
587{
588 unsigned int limit;
589 int ret;
590 if (cpufreq_driver->bios_limit) {
591 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
592 if (!ret)
593 return sprintf(buf, "%u\n", limit);
594 }
595 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
596}
597
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200598cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
599cpufreq_freq_attr_ro(cpuinfo_min_freq);
600cpufreq_freq_attr_ro(cpuinfo_max_freq);
601cpufreq_freq_attr_ro(cpuinfo_transition_latency);
602cpufreq_freq_attr_ro(scaling_available_governors);
603cpufreq_freq_attr_ro(scaling_driver);
604cpufreq_freq_attr_ro(scaling_cur_freq);
605cpufreq_freq_attr_ro(bios_limit);
606cpufreq_freq_attr_ro(related_cpus);
607cpufreq_freq_attr_ro(affected_cpus);
608cpufreq_freq_attr_rw(scaling_min_freq);
609cpufreq_freq_attr_rw(scaling_max_freq);
610cpufreq_freq_attr_rw(scaling_governor);
611cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Dave Jones905d77c2008-03-05 14:28:32 -0500613static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 &cpuinfo_min_freq.attr,
615 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100616 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 &scaling_min_freq.attr,
618 &scaling_max_freq.attr,
619 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700620 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 &scaling_governor.attr,
622 &scaling_driver.attr,
623 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700624 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 NULL
626};
627
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200628struct kobject *cpufreq_global_kobject;
629EXPORT_SYMBOL(cpufreq_global_kobject);
630
Dave Jones29464f22009-01-18 01:37:11 -0500631#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
632#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
Dave Jones29464f22009-01-18 01:37:11 -0500634static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635{
Dave Jones905d77c2008-03-05 14:28:32 -0500636 struct cpufreq_policy *policy = to_policy(kobj);
637 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500638 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000639 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500641 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800642
643 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500644 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800645
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530646 if (fattr->show)
647 ret = fattr->show(policy, buf);
648 else
649 ret = -EIO;
650
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800651 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500652fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000653 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500654no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 return ret;
656}
657
Dave Jones905d77c2008-03-05 14:28:32 -0500658static ssize_t store(struct kobject *kobj, struct attribute *attr,
659 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
Dave Jones905d77c2008-03-05 14:28:32 -0500661 struct cpufreq_policy *policy = to_policy(kobj);
662 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500663 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000664 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500666 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800667
668 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500669 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800670
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530671 if (fattr->store)
672 ret = fattr->store(policy, buf, count);
673 else
674 ret = -EIO;
675
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800676 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500677fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000678 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500679no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 return ret;
681}
682
Dave Jones905d77c2008-03-05 14:28:32 -0500683static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684{
Dave Jones905d77c2008-03-05 14:28:32 -0500685 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200686 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 complete(&policy->kobj_unregister);
688}
689
Emese Revfy52cf25d2010-01-19 02:58:23 +0100690static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 .show = show,
692 .store = store,
693};
694
695static struct kobj_type ktype_cpufreq = {
696 .sysfs_ops = &sysfs_ops,
697 .default_attrs = default_attrs,
698 .release = cpufreq_sysfs_release,
699};
700
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200701/*
702 * Returns:
703 * Negative: Failure
704 * 0: Success
705 * Positive: When we have a managed CPU and the sysfs got symlinked
706 */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700707static int cpufreq_add_dev_policy(unsigned int cpu,
708 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800709 struct device *dev)
Dave Jonesecf7e462009-07-08 18:48:47 -0400710{
711 int ret = 0;
712#ifdef CONFIG_SMP
713 unsigned long flags;
714 unsigned int j;
Dave Jonesecf7e462009-07-08 18:48:47 -0400715#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400716 struct cpufreq_governor *gov;
717
718 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
719 if (gov) {
720 policy->governor = gov;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200721 pr_debug("Restoring governor %s for cpu %d\n",
Dave Jonesecf7e462009-07-08 18:48:47 -0400722 policy->governor->name, cpu);
723 }
724#endif
725
726 for_each_cpu(j, policy->cpus) {
727 struct cpufreq_policy *managed_policy;
728
729 if (cpu == j)
730 continue;
731
732 /* Check for existing affected CPUs.
733 * They may not be aware of it due to CPU Hotplug.
734 * cpufreq_cpu_put is called when the device is removed
735 * in __cpufreq_remove_dev()
736 */
737 managed_policy = cpufreq_cpu_get(j);
738 if (unlikely(managed_policy)) {
739
740 /* Set proper policy_cpu */
741 unlock_policy_rwsem_write(cpu);
Tejun Heof1625062009-10-29 22:34:13 +0900742 per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
Dave Jonesecf7e462009-07-08 18:48:47 -0400743
744 if (lock_policy_rwsem_write(cpu) < 0) {
745 /* Should not go through policy unlock path */
746 if (cpufreq_driver->exit)
747 cpufreq_driver->exit(policy);
748 cpufreq_cpu_put(managed_policy);
749 return -EBUSY;
750 }
751
752 spin_lock_irqsave(&cpufreq_driver_lock, flags);
753 cpumask_copy(managed_policy->cpus, policy->cpus);
754 per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
755 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
756
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200757 pr_debug("CPU already managed, adding link\n");
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800758 ret = sysfs_create_link(&dev->kobj,
Dave Jonesecf7e462009-07-08 18:48:47 -0400759 &managed_policy->kobj,
760 "cpufreq");
761 if (ret)
762 cpufreq_cpu_put(managed_policy);
763 /*
764 * Success. We only needed to be added to the mask.
765 * Call driver->exit() because only the cpu parent of
766 * the kobj needed to call init().
767 */
768 if (cpufreq_driver->exit)
769 cpufreq_driver->exit(policy);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200770
771 if (!ret)
772 return 1;
773 else
774 return ret;
Dave Jonesecf7e462009-07-08 18:48:47 -0400775 }
776 }
777#endif
778 return ret;
779}
780
781
Dave Jones19d6f7e2009-07-08 17:35:39 -0400782/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700783static int cpufreq_add_dev_symlink(unsigned int cpu,
784 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400785{
786 unsigned int j;
787 int ret = 0;
788
789 for_each_cpu(j, policy->cpus) {
790 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800791 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400792
793 if (j == cpu)
794 continue;
795 if (!cpu_online(j))
796 continue;
797
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200798 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400799 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800800 cpu_dev = get_cpu_device(j);
801 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400802 "cpufreq");
803 if (ret) {
804 cpufreq_cpu_put(managed_policy);
805 return ret;
806 }
807 }
808 return ret;
809}
810
Alex Chiangcf3289d02009-11-17 20:27:08 -0700811static int cpufreq_add_dev_interface(unsigned int cpu,
812 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800813 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400814{
Dave Jonesecf7e462009-07-08 18:48:47 -0400815 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400816 struct freq_attr **drv_attr;
817 unsigned long flags;
818 int ret = 0;
819 unsigned int j;
820
821 /* prepare interface data */
822 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800823 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400824 if (ret)
825 return ret;
826
827 /* set up files for this cpu device */
828 drv_attr = cpufreq_driver->attr;
829 while ((drv_attr) && (*drv_attr)) {
830 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
831 if (ret)
832 goto err_out_kobj_put;
833 drv_attr++;
834 }
835 if (cpufreq_driver->get) {
836 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
837 if (ret)
838 goto err_out_kobj_put;
839 }
840 if (cpufreq_driver->target) {
841 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
842 if (ret)
843 goto err_out_kobj_put;
844 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100845 if (cpufreq_driver->bios_limit) {
846 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
847 if (ret)
848 goto err_out_kobj_put;
849 }
Dave Jones909a6942009-07-08 18:05:42 -0400850
851 spin_lock_irqsave(&cpufreq_driver_lock, flags);
852 for_each_cpu(j, policy->cpus) {
Julia Lawallbec037a2010-08-05 22:23:00 +0200853 if (!cpu_online(j))
854 continue;
Dave Jones909a6942009-07-08 18:05:42 -0400855 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900856 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400857 }
858 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
859
860 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400861 if (ret)
862 goto err_out_kobj_put;
863
864 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
865 /* assure that the starting sequence is run in __cpufreq_set_policy */
866 policy->governor = NULL;
867
868 /* set default policy */
869 ret = __cpufreq_set_policy(policy, &new_policy);
870 policy->user_policy.policy = policy->policy;
871 policy->user_policy.governor = policy->governor;
872
873 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200874 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400875 if (cpufreq_driver->exit)
876 cpufreq_driver->exit(policy);
877 }
Dave Jones909a6942009-07-08 18:05:42 -0400878 return ret;
879
880err_out_kobj_put:
881 kobject_put(&policy->kobj);
882 wait_for_completion(&policy->kobj_unregister);
883 return ret;
884}
885
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
887/**
888 * cpufreq_add_dev - add a CPU device
889 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500890 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400891 *
892 * The Oracle says: try running cpufreq registration/unregistration concurrently
893 * with with cpu hotplugging and all hell will break loose. Tried to clean this
894 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800896static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897{
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800898 unsigned int cpu = dev->id;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500899 int ret = 0, found = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 unsigned long flags;
902 unsigned int j;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500903#ifdef CONFIG_HOTPLUG_CPU
904 int sibling;
905#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906
Ashok Rajc32b6b82005-10-30 14:59:54 -0800907 if (cpu_is_offline(cpu))
908 return 0;
909
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200910 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911
912#ifdef CONFIG_SMP
913 /* check whether a different CPU already registered this
914 * CPU because it is in the same boat. */
915 policy = cpufreq_cpu_get(cpu);
916 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500917 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 return 0;
919 }
920#endif
921
922 if (!try_module_get(cpufreq_driver->owner)) {
923 ret = -EINVAL;
924 goto module_out;
925 }
926
Dave Jones059019a2009-07-08 16:30:03 -0400927 ret = -ENOMEM;
Dave Jonese98df502005-10-20 15:17:43 -0700928 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400929 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400931
932 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400933 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400934
935 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400936 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
938 policy->cpu = cpu;
Rusty Russell835481d2009-01-04 05:18:06 -0800939 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800941 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900942 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400943 ret = (lock_policy_rwsem_write(cpu) < 0);
944 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800945
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000947 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700949 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500950#ifdef CONFIG_HOTPLUG_CPU
951 for_each_online_cpu(sibling) {
952 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
953 if (cp && cp->governor &&
954 (cpumask_test_cpu(cpu, cp->related_cpus))) {
955 policy->governor = cp->governor;
956 found = 1;
957 break;
958 }
959 }
960#endif
961 if (!found)
962 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 /* call driver. From then on the cpufreq must be able
964 * to accept all calls to ->verify and ->setpolicy for this CPU
965 */
966 ret = cpufreq_driver->init(policy);
967 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200968 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400969 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 }
Mike Chan187d9f42008-12-04 12:19:17 -0800971 policy->user_policy.min = policy->min;
972 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973
Thomas Renningera1531ac2008-07-29 22:32:58 -0700974 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
975 CPUFREQ_START, policy);
976
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800977 ret = cpufreq_add_dev_policy(cpu, policy, dev);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200978 if (ret) {
979 if (ret > 0)
980 /* This is a managed cpu, symlink created,
981 exit with 0 */
982 ret = 0;
Dave Jonesecf7e462009-07-08 18:48:47 -0400983 goto err_unlock_policy;
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200984 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800986 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400987 if (ret)
988 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500989
Lothar Waßmanndca02612008-05-29 17:54:52 +0200990 unlock_policy_rwsem_write(cpu);
991
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400992 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200994 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500995
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996 return 0;
997
998
999err_out_unregister:
1000 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001001 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001002 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1004
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001005 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 wait_for_completion(&policy->kobj_unregister);
1007
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001008err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -05001009 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001010 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001011err_free_cpumask:
1012 free_cpumask_var(policy->cpus);
1013err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015nomem_out:
1016 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001017module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 return ret;
1019}
1020
1021
1022/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001023 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 *
1025 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001026 * Caller should already have policy_rwsem in write mode for this CPU.
1027 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001029static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001031 unsigned int cpu = dev->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 unsigned long flags;
1033 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001034 struct kobject *kobj;
1035 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036#ifdef CONFIG_SMP
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001037 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 unsigned int j;
1039#endif
1040
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001041 pr_debug("unregistering CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
1043 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001044 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046 if (!data) {
1047 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001048 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 return -EINVAL;
1050 }
Mike Travis7a6aedf2008-03-25 15:06:53 -07001051 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052
1053
1054#ifdef CONFIG_SMP
1055 /* if this isn't the CPU which is the parent of the kobj, we
Dave Jones32ee8c32006-02-28 00:43:23 -05001056 * only need to unlink, put and exit
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 */
1058 if (unlikely(cpu != data->cpu)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001059 pr_debug("removing link\n");
Rusty Russell835481d2009-01-04 05:18:06 -08001060 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001062 kobj = &dev->kobj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 cpufreq_cpu_put(data);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001064 unlock_policy_rwsem_write(cpu);
Amerigo Wang499bca92010-03-04 03:23:46 -05001065 sysfs_remove_link(kobj, "cpufreq");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 return 0;
1067 }
1068#endif
1069
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070#ifdef CONFIG_SMP
Thomas Renninger084f3492007-07-09 11:35:28 -07001071
1072#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001073 strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
1074 CPUFREQ_NAME_LEN);
Thomas Renninger084f3492007-07-09 11:35:28 -07001075#endif
1076
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 /* if we have other CPUs still registered, we need to unlink them,
1078 * or else wait_for_completion below will lock up. Clean the
Mike Travis7a6aedf2008-03-25 15:06:53 -07001079 * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
1080 * the sysfs links afterwards.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 */
Rusty Russell835481d2009-01-04 05:18:06 -08001082 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1083 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 if (j == cpu)
1085 continue;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001086 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 }
1088 }
1089
1090 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1091
Rusty Russell835481d2009-01-04 05:18:06 -08001092 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1093 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 if (j == cpu)
1095 continue;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001096 pr_debug("removing link for cpu %u\n", j);
Thomas Renninger084f3492007-07-09 11:35:28 -07001097#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001098 strncpy(per_cpu(cpufreq_cpu_governor, j),
1099 data->governor->name, CPUFREQ_NAME_LEN);
Thomas Renninger084f3492007-07-09 11:35:28 -07001100#endif
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001101 cpu_dev = get_cpu_device(j);
1102 kobj = &cpu_dev->kobj;
Amerigo Wang499bca92010-03-04 03:23:46 -05001103 unlock_policy_rwsem_write(cpu);
1104 sysfs_remove_link(kobj, "cpufreq");
1105 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 cpufreq_cpu_put(data);
1107 }
1108 }
1109#else
1110 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1111#endif
1112
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 if (cpufreq_driver->target)
1114 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001115
Amerigo Wang499bca92010-03-04 03:23:46 -05001116 kobj = &data->kobj;
1117 cmp = &data->kobj_unregister;
1118 unlock_policy_rwsem_write(cpu);
1119 kobject_put(kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120
1121 /* we need to make sure that the underlying kobj is actually
Dave Jones32ee8c32006-02-28 00:43:23 -05001122 * not referenced anymore by anybody before we proceed with
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 * unloading.
1124 */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001125 pr_debug("waiting for dropping of refcount\n");
Amerigo Wang499bca92010-03-04 03:23:46 -05001126 wait_for_completion(cmp);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001127 pr_debug("wait complete\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
Amerigo Wang499bca92010-03-04 03:23:46 -05001129 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 if (cpufreq_driver->exit)
1131 cpufreq_driver->exit(data);
venkatesh.pallipadi@intel.com7d26e2d2009-07-02 17:08:30 -07001132 unlock_policy_rwsem_write(cpu);
1133
Jacob Shin27ecddc2011-04-27 13:32:11 -05001134#ifdef CONFIG_HOTPLUG_CPU
1135 /* when the CPU which is the parent of the kobj is hotplugged
1136 * offline, check for siblings, and create cpufreq sysfs interface
1137 * and symlinks
1138 */
1139 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1140 /* first sibling now owns the new sysfs dir */
1141 cpumask_clear_cpu(cpu, data->cpus);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001142 cpufreq_add_dev(get_cpu_device(cpumask_first(data->cpus)), NULL);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001143
1144 /* finally remove our own symlink */
1145 lock_policy_rwsem_write(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001146 __cpufreq_remove_dev(dev, sif);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001147 }
1148#endif
1149
Rusty Russell835481d2009-01-04 05:18:06 -08001150 free_cpumask_var(data->related_cpus);
1151 free_cpumask_var(data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 kfree(data);
1153
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 return 0;
1155}
1156
1157
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001158static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001159{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001160 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001161 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001162
1163 if (cpu_is_offline(cpu))
1164 return 0;
1165
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001166 if (unlikely(lock_policy_rwsem_write(cpu)))
1167 BUG();
1168
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001169 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001170 return retval;
1171}
1172
1173
David Howells65f27f32006-11-22 14:55:48 +00001174static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175{
David Howells65f27f32006-11-22 14:55:48 +00001176 struct cpufreq_policy *policy =
1177 container_of(work, struct cpufreq_policy, update);
1178 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001179 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 cpufreq_update_policy(cpu);
1181}
1182
1183/**
1184 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1185 * @cpu: cpu number
1186 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1187 * @new_freq: CPU frequency the CPU actually runs at
1188 *
Dave Jones29464f22009-01-18 01:37:11 -05001189 * We adjust to current frequency first, and need to clean up later.
1190 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301192static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1193 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194{
1195 struct cpufreq_freqs freqs;
1196
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001197 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1199
1200 freqs.cpu = cpu;
1201 freqs.old = old_freq;
1202 freqs.new = new_freq;
1203 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1204 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1205}
1206
1207
Dave Jones32ee8c32006-02-28 00:43:23 -05001208/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301209 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001210 * @cpu: CPU number
1211 *
1212 * This is the last known freq, without actually getting it from the driver.
1213 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1214 */
1215unsigned int cpufreq_quick_get(unsigned int cpu)
1216{
1217 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301218 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001219
1220 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301221 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001222 cpufreq_cpu_put(policy);
1223 }
1224
Dave Jones4d34a672008-02-07 16:33:49 -05001225 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001226}
1227EXPORT_SYMBOL(cpufreq_quick_get);
1228
Jesse Barnes3d737102011-06-28 10:59:12 -07001229/**
1230 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1231 * @cpu: CPU number
1232 *
1233 * Just return the max possible frequency for a given CPU.
1234 */
1235unsigned int cpufreq_quick_get_max(unsigned int cpu)
1236{
1237 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1238 unsigned int ret_freq = 0;
1239
1240 if (policy) {
1241 ret_freq = policy->max;
1242 cpufreq_cpu_put(policy);
1243 }
1244
1245 return ret_freq;
1246}
1247EXPORT_SYMBOL(cpufreq_quick_get_max);
1248
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001249
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001250static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001252 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301253 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001256 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301258 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301260 if (ret_freq && policy->cur &&
1261 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1262 /* verify no discrepancy between actual and
1263 saved value exists */
1264 if (unlikely(ret_freq != policy->cur)) {
1265 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 schedule_work(&policy->update);
1267 }
1268 }
1269
Dave Jones4d34a672008-02-07 16:33:49 -05001270 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001271}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001273/**
1274 * cpufreq_get - get the current CPU frequency (in kHz)
1275 * @cpu: CPU number
1276 *
1277 * Get the CPU current (static) CPU frequency
1278 */
1279unsigned int cpufreq_get(unsigned int cpu)
1280{
1281 unsigned int ret_freq = 0;
1282 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1283
1284 if (!policy)
1285 goto out;
1286
1287 if (unlikely(lock_policy_rwsem_read(cpu)))
1288 goto out_policy;
1289
1290 ret_freq = __cpufreq_get(cpu);
1291
1292 unlock_policy_rwsem_read(cpu);
1293
1294out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001296out:
Dave Jones4d34a672008-02-07 16:33:49 -05001297 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298}
1299EXPORT_SYMBOL(cpufreq_get);
1300
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001301static struct subsys_interface cpufreq_interface = {
1302 .name = "cpufreq",
1303 .subsys = &cpu_subsys,
1304 .add_dev = cpufreq_add_dev,
1305 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001306};
1307
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308
1309/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001310 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1311 *
1312 * This function is only executed for the boot processor. The other CPUs
1313 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001314 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001315static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001316{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301317 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001318
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001319 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001320 struct cpufreq_policy *cpu_policy;
1321
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001322 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001323
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001324 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001325 cpu_policy = cpufreq_cpu_get(cpu);
1326 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001327 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001328
1329 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001330 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001331 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001332 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1333 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001334 }
1335
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001336 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001337 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001338}
1339
1340/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001341 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 *
1343 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001344 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1345 * restored. It will verify that the current freq is in sync with
1346 * what we believe it to be. This is a bit later than when it
1347 * should be, but nonethteless it's better than calling
1348 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001349 *
1350 * This function is only executed for the boot CPU. The other CPUs have not
1351 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001353static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301355 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001356
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001357 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 struct cpufreq_policy *cpu_policy;
1359
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001360 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001362 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 cpu_policy = cpufreq_cpu_get(cpu);
1364 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001365 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
1367 if (cpufreq_driver->resume) {
1368 ret = cpufreq_driver->resume(cpu_policy);
1369 if (ret) {
1370 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1371 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001372 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 }
1374 }
1375
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001377
Dave Jonesc9060492008-02-07 16:32:18 -05001378fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380}
1381
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001382static struct syscore_ops cpufreq_syscore_ops = {
1383 .suspend = cpufreq_bp_suspend,
1384 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385};
1386
1387
1388/*********************************************************************
1389 * NOTIFIER LISTS INTERFACE *
1390 *********************************************************************/
1391
1392/**
1393 * cpufreq_register_notifier - register a driver with cpufreq
1394 * @nb: notifier function to register
1395 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1396 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001397 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 * are notified about clock rate changes (once before and once after
1399 * the transition), or a list of drivers that are notified about
1400 * changes in cpufreq policy.
1401 *
1402 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001403 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 */
1405int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1406{
1407 int ret;
1408
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001409 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1410
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 switch (list) {
1412 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001413 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001414 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 break;
1416 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001417 ret = blocking_notifier_chain_register(
1418 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 break;
1420 default:
1421 ret = -EINVAL;
1422 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423
1424 return ret;
1425}
1426EXPORT_SYMBOL(cpufreq_register_notifier);
1427
1428
1429/**
1430 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1431 * @nb: notifier block to be unregistered
1432 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1433 *
1434 * Remove a driver from the CPU frequency notifier list.
1435 *
1436 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001437 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 */
1439int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1440{
1441 int ret;
1442
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 switch (list) {
1444 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001445 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001446 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 break;
1448 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001449 ret = blocking_notifier_chain_unregister(
1450 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 break;
1452 default:
1453 ret = -EINVAL;
1454 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
1456 return ret;
1457}
1458EXPORT_SYMBOL(cpufreq_unregister_notifier);
1459
1460
1461/*********************************************************************
1462 * GOVERNORS *
1463 *********************************************************************/
1464
1465
1466int __cpufreq_driver_target(struct cpufreq_policy *policy,
1467 unsigned int target_freq,
1468 unsigned int relation)
1469{
1470 int retval = -EINVAL;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001471
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001472 if (cpufreq_disabled())
1473 return -ENODEV;
1474
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001475 pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 target_freq, relation);
1477 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1478 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001479
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 return retval;
1481}
1482EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1483
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484int cpufreq_driver_target(struct cpufreq_policy *policy,
1485 unsigned int target_freq,
1486 unsigned int relation)
1487{
Julia Lawallf1829e42008-07-25 22:44:53 +02001488 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489
1490 policy = cpufreq_cpu_get(policy->cpu);
1491 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001492 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001494 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001495 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496
1497 ret = __cpufreq_driver_target(policy, target_freq, relation);
1498
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001499 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500
Julia Lawallf1829e42008-07-25 22:44:53 +02001501fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001503no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 return ret;
1505}
1506EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1507
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001508int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001509{
1510 int ret = 0;
1511
1512 policy = cpufreq_cpu_get(policy->cpu);
1513 if (!policy)
1514 return -EINVAL;
1515
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001516 if (cpu_online(cpu) && cpufreq_driver->getavg)
1517 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001518
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001519 cpufreq_cpu_put(policy);
1520 return ret;
1521}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001522EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001523
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001524/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001525 * when "event" is CPUFREQ_GOV_LIMITS
1526 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301528static int __cpufreq_governor(struct cpufreq_policy *policy,
1529 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530{
Dave Jonescc993ca2005-07-28 09:43:56 -07001531 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001532
1533 /* Only must be defined when default governor is known to have latency
1534 restrictions, like e.g. conservative or ondemand.
1535 That this is the case is already ensured in Kconfig
1536 */
1537#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1538 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1539#else
1540 struct cpufreq_governor *gov = NULL;
1541#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001542
1543 if (policy->governor->max_transition_latency &&
1544 policy->cpuinfo.transition_latency >
1545 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001546 if (!gov)
1547 return -EINVAL;
1548 else {
1549 printk(KERN_WARNING "%s governor failed, too long"
1550 " transition latency of HW, fallback"
1551 " to %s governor\n",
1552 policy->governor->name,
1553 gov->name);
1554 policy->governor = gov;
1555 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001556 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558 if (!try_module_get(policy->governor->owner))
1559 return -EINVAL;
1560
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001561 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301562 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 ret = policy->governor->governor(policy, event);
1564
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301565 /* we keep one module reference alive for
1566 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 if ((event != CPUFREQ_GOV_START) || ret)
1568 module_put(policy->governor->owner);
1569 if ((event == CPUFREQ_GOV_STOP) && !ret)
1570 module_put(policy->governor->owner);
1571
1572 return ret;
1573}
1574
1575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576int cpufreq_register_governor(struct cpufreq_governor *governor)
1577{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001578 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
1580 if (!governor)
1581 return -EINVAL;
1582
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001583 if (cpufreq_disabled())
1584 return -ENODEV;
1585
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001586 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001587
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001588 err = -EBUSY;
1589 if (__find_governor(governor->name) == NULL) {
1590 err = 0;
1591 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593
Dave Jones32ee8c32006-02-28 00:43:23 -05001594 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001595 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596}
1597EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1598
1599
1600void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1601{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001602#ifdef CONFIG_HOTPLUG_CPU
1603 int cpu;
1604#endif
1605
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 if (!governor)
1607 return;
1608
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001609 if (cpufreq_disabled())
1610 return;
1611
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001612#ifdef CONFIG_HOTPLUG_CPU
1613 for_each_present_cpu(cpu) {
1614 if (cpu_online(cpu))
1615 continue;
1616 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1617 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1618 }
1619#endif
1620
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001621 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001623 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 return;
1625}
1626EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1627
1628
1629
1630/*********************************************************************
1631 * POLICY INTERFACE *
1632 *********************************************************************/
1633
1634/**
1635 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001636 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1637 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 *
1639 * Reads the current cpufreq policy.
1640 */
1641int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1642{
1643 struct cpufreq_policy *cpu_policy;
1644 if (!policy)
1645 return -EINVAL;
1646
1647 cpu_policy = cpufreq_cpu_get(cpu);
1648 if (!cpu_policy)
1649 return -EINVAL;
1650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
1653 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 return 0;
1655}
1656EXPORT_SYMBOL(cpufreq_get_policy);
1657
1658
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001659/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301660 * data : current policy.
1661 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001662 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301663static int __cpufreq_set_policy(struct cpufreq_policy *data,
1664 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665{
1666 int ret = 0;
1667
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001668 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 policy->min, policy->max);
1670
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301671 memcpy(&policy->cpuinfo, &data->cpuinfo,
1672 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
Yi Yang53391fa2008-01-30 13:33:34 +01001674 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001675 ret = -EINVAL;
1676 goto error_out;
1677 }
1678
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 /* verify the cpu speed can be set within this limit */
1680 ret = cpufreq_driver->verify(policy);
1681 if (ret)
1682 goto error_out;
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001685 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1686 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
1688 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001689 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1690 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
1692 /* verify the cpu speed can be set within this limit,
1693 which might be different to the first one */
1694 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001695 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
1698 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001699 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1700 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
Dave Jones7d5e3502006-02-02 17:03:42 -05001702 data->min = policy->min;
1703 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001705 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301706 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707
1708 if (cpufreq_driver->setpolicy) {
1709 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001710 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 ret = cpufreq_driver->setpolicy(policy);
1712 } else {
1713 if (policy->governor != data->governor) {
1714 /* save old, working values */
1715 struct cpufreq_governor *old_gov = data->governor;
1716
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001717 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718
1719 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001720 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1722
1723 /* start new governor */
1724 data->governor = policy->governor;
1725 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1726 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001727 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301728 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 if (old_gov) {
1730 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301731 __cpufreq_governor(data,
1732 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 }
1734 ret = -EINVAL;
1735 goto error_out;
1736 }
1737 /* might be a policy change, too, so fall through */
1738 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001739 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1741 }
1742
Dave Jones7d5e3502006-02-02 17:03:42 -05001743error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 return ret;
1745}
1746
1747/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1749 * @cpu: CPU which shall be re-evaluated
1750 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001751 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 * at different times.
1753 */
1754int cpufreq_update_policy(unsigned int cpu)
1755{
1756 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1757 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001758 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
Julia Lawallf1829e42008-07-25 22:44:53 +02001760 if (!data) {
1761 ret = -ENODEV;
1762 goto no_policy;
1763 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
Julia Lawallf1829e42008-07-25 22:44:53 +02001765 if (unlikely(lock_policy_rwsem_write(cpu))) {
1766 ret = -EINVAL;
1767 goto fail;
1768 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001770 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001771 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 policy.min = data->user_policy.min;
1773 policy.max = data->user_policy.max;
1774 policy.policy = data->user_policy.policy;
1775 policy.governor = data->user_policy.governor;
1776
Thomas Renninger0961dd02006-01-26 18:46:33 +01001777 /* BIOS might change freq behind our back
1778 -> ask driver for current freq and notify governors about a change */
1779 if (cpufreq_driver->get) {
1780 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001781 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001782 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001783 data->cur = policy.cur;
1784 } else {
1785 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301786 cpufreq_out_of_sync(cpu, data->cur,
1787 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001788 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001789 }
1790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 ret = __cpufreq_set_policy(data, &policy);
1792
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001793 unlock_policy_rwsem_write(cpu);
1794
Julia Lawallf1829e42008-07-25 22:44:53 +02001795fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001797no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 return ret;
1799}
1800EXPORT_SYMBOL(cpufreq_update_policy);
1801
Satyam Sharmadd184a02007-10-02 13:28:14 -07001802static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001803 unsigned long action, void *hcpu)
1804{
1805 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001806 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001807
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001808 dev = get_cpu_device(cpu);
1809 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001810 switch (action) {
1811 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001812 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001813 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001814 break;
1815 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001816 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001817 if (unlikely(lock_policy_rwsem_write(cpu)))
1818 BUG();
1819
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001820 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001821 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001822 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001823 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001824 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001825 break;
1826 }
1827 }
1828 return NOTIFY_OK;
1829}
1830
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001831static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001832 .notifier_call = cpufreq_cpu_callback,
1833};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835/*********************************************************************
1836 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1837 *********************************************************************/
1838
1839/**
1840 * cpufreq_register_driver - register a CPU Frequency driver
1841 * @driver_data: A struct cpufreq_driver containing the values#
1842 * submitted by the CPU Frequency driver.
1843 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001844 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001846 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 *
1848 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001849int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850{
1851 unsigned long flags;
1852 int ret;
1853
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001854 if (cpufreq_disabled())
1855 return -ENODEV;
1856
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 if (!driver_data || !driver_data->verify || !driver_data->init ||
1858 ((!driver_data->setpolicy) && (!driver_data->target)))
1859 return -EINVAL;
1860
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001861 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 if (driver_data->setpolicy)
1864 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1865
1866 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1867 if (cpufreq_driver) {
1868 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1869 return -EBUSY;
1870 }
1871 cpufreq_driver = driver_data;
1872 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1873
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001874 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001875 if (ret)
1876 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001878 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 int i;
1880 ret = -ENODEV;
1881
1882 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001883 for (i = 0; i < nr_cpu_ids; i++)
1884 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001886 break;
1887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
1889 /* if all ->init() calls failed, unregister */
1890 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001891 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301892 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001893 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 }
1895 }
1896
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001897 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001898 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001900 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001901err_if_unreg:
1902 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001903err_null_driver:
1904 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1905 cpufreq_driver = NULL;
1906 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001907 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908}
1909EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1910
1911
1912/**
1913 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1914 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001915 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 * the right to do so, i.e. if you have succeeded in initialising before!
1917 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1918 * currently not initialised.
1919 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001920int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921{
1922 unsigned long flags;
1923
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001924 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001927 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001929 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001930 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931
1932 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1933 cpufreq_driver = NULL;
1934 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1935
1936 return 0;
1937}
1938EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001939
1940static int __init cpufreq_core_init(void)
1941{
1942 int cpu;
1943
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001944 if (cpufreq_disabled())
1945 return -ENODEV;
1946
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001947 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001948 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001949 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1950 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001951
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001952 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001953 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001954 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001955
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001956 return 0;
1957}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001958core_initcall(cpufreq_core_init);