blob: b63b3cbfe2c4e78fd94c65af3482f689c23115fe [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
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/notifier.h>
24#include <linux/cpufreq.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/spinlock.h>
28#include <linux/device.h>
29#include <linux/slab.h>
30#include <linux/cpu.h>
31#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080032#include <linux/mutex.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010033#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Thomas Renninger6f4f2722010-04-20 13:17:36 +020035#include <trace/events/power.h>
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037/**
Dave Jonescd878472006-08-11 17:59:28 -040038 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 * level driver of CPUFreq support, and its spinlock. This lock
40 * also protects the cpufreq_cpu_data array.
41 */
Dave Jones7d5e3502006-02-02 17:03:42 -050042static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070043static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070044#ifdef CONFIG_HOTPLUG_CPU
45/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040046static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070047#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070048static DEFINE_SPINLOCK(cpufreq_driver_lock);
49
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080050/*
51 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
52 * all cpufreq/hotplug/workqueue/etc related lock issues.
53 *
54 * The rules for this semaphore:
55 * - Any routine that wants to read from the policy structure will
56 * do a down_read on this semaphore.
57 * - Any routine that will write to the policy structure and/or may take away
58 * the policy altogether (eg. CPU hotplug), will hold this lock in write
59 * mode before doing so.
60 *
61 * Additional rules:
62 * - All holders of the lock should check to make sure that the CPU they
63 * are concerned with are online after they get the lock.
64 * - Governor routines that can be called in cpufreq hotplug path should not
65 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040066 * - Lock should not be held across
67 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080068 */
Tejun Heof1625062009-10-29 22:34:13 +090069static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080070static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
71
72#define lock_policy_rwsem(mode, cpu) \
Amerigo Wang226528c2010-03-04 03:23:36 -050073static int lock_policy_rwsem_##mode \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080074(int cpu) \
75{ \
Tejun Heof1625062009-10-29 22:34:13 +090076 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080077 BUG_ON(policy_cpu == -1); \
78 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
79 if (unlikely(!cpu_online(cpu))) { \
80 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
81 return -1; \
82 } \
83 \
84 return 0; \
85}
86
87lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080088
89lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
Amerigo Wang226528c2010-03-04 03:23:36 -050091static void unlock_policy_rwsem_read(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080092{
Tejun Heof1625062009-10-29 22:34:13 +090093 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080094 BUG_ON(policy_cpu == -1);
95 up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
96}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097
Amerigo Wang226528c2010-03-04 03:23:36 -050098static void unlock_policy_rwsem_write(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080099{
Tejun Heof1625062009-10-29 22:34:13 +0900100 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800101 BUG_ON(policy_cpu == -1);
102 up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
103}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800104
105
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500107static int __cpufreq_governor(struct cpufreq_policy *policy,
108 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800109static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000110static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111
112/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500113 * Two notifier lists: the "policy" list is involved in the
114 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 * "transition" list for kernel code that needs to handle
116 * changes to devices when the CPU clock speed changes.
117 * The mutex locks both lists.
118 */
Alan Sterne041c682006-03-27 01:16:30 -0800119static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700120static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200122static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700123static int __init init_cpufreq_transition_notifier_list(void)
124{
125 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200126 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700127 return 0;
128}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800129pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400131static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200132static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400133{
134 return off;
135}
136void disable_cpufreq(void)
137{
138 off = 1;
139}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500141static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
Stephen Boyda9144432012-07-20 18:14:38 +0000143static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144{
145 struct cpufreq_policy *data;
146 unsigned long flags;
147
Mike Travis7a6aedf2008-03-25 15:06:53 -0700148 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 goto err_out;
150
151 /* get the cpufreq driver */
152 spin_lock_irqsave(&cpufreq_driver_lock, flags);
153
154 if (!cpufreq_driver)
155 goto err_out_unlock;
156
157 if (!try_module_get(cpufreq_driver->owner))
158 goto err_out_unlock;
159
160
161 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700162 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163
164 if (!data)
165 goto err_out_put_module;
166
Stephen Boyda9144432012-07-20 18:14:38 +0000167 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 goto err_out_put_module;
169
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 return data;
172
Dave Jones7d5e3502006-02-02 17:03:42 -0500173err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500175err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500177err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 return NULL;
179}
Stephen Boyda9144432012-07-20 18:14:38 +0000180
181struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
182{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000183 if (cpufreq_disabled())
184 return NULL;
185
Stephen Boyda9144432012-07-20 18:14:38 +0000186 return __cpufreq_cpu_get(cpu, false);
187}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
189
Stephen Boyda9144432012-07-20 18:14:38 +0000190static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
191{
192 return __cpufreq_cpu_get(cpu, true);
193}
194
195static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
196{
197 if (!sysfs)
198 kobject_put(&data->kobj);
199 module_put(cpufreq_driver->owner);
200}
Dave Jones7d5e3502006-02-02 17:03:42 -0500201
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202void cpufreq_cpu_put(struct cpufreq_policy *data)
203{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000204 if (cpufreq_disabled())
205 return;
206
Stephen Boyda9144432012-07-20 18:14:38 +0000207 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208}
209EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
210
Stephen Boyda9144432012-07-20 18:14:38 +0000211static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
212{
213 __cpufreq_cpu_put(data, true);
214}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
218 *********************************************************************/
219
220/**
221 * adjust_jiffies - adjust the system "loops_per_jiffy"
222 *
223 * This function alters the system "loops_per_jiffy" for the clock
224 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500225 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 * per-CPU loops_per_jiffy value wherever possible.
227 */
228#ifndef CONFIG_SMP
229static unsigned long l_p_j_ref;
230static unsigned int l_p_j_ref_freq;
231
Arjan van de Ven858119e2006-01-14 13:20:43 -0800232static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233{
234 if (ci->flags & CPUFREQ_CONST_LOOPS)
235 return;
236
237 if (!l_p_j_ref_freq) {
238 l_p_j_ref = loops_per_jiffy;
239 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200240 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530241 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530243 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700244 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530245 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
246 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200247 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530248 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 }
250}
251#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530252static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
253{
254 return;
255}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256#endif
257
258
259/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800260 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
261 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800263 * This function calls the transition notifiers and the "adjust_jiffies"
264 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500265 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 */
267void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
268{
Dave Jonese4472cb2006-01-31 15:53:55 -0800269 struct cpufreq_policy *policy;
270
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 BUG_ON(irqs_disabled());
272
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000273 if (cpufreq_disabled())
274 return;
275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200277 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800278 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
Mike Travis7a6aedf2008-03-25 15:06:53 -0700280 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500284 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800285 * which is not equal to what the cpufreq core thinks is
286 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 */
288 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800289 if ((policy) && (policy->cpu == freqs->cpu) &&
290 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200291 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800292 " %u, cpufreq assumed %u kHz.\n",
293 freqs->old, policy->cur);
294 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 }
296 }
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_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
300 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800301
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 case CPUFREQ_POSTCHANGE:
303 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200304 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200305 (unsigned long)freqs->cpu);
306 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100307 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700308 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800309 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800310 if (likely(policy) && likely(policy->cpu == freqs->cpu))
311 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 break;
313 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314}
315EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
316
317
318
319/*********************************************************************
320 * SYSFS INTERFACE *
321 *********************************************************************/
322
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700323static struct cpufreq_governor *__find_governor(const char *str_governor)
324{
325 struct cpufreq_governor *t;
326
327 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500328 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700329 return t;
330
331 return NULL;
332}
333
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334/**
335 * cpufreq_parse_governor - parse a governor string
336 */
Dave Jones905d77c2008-03-05 14:28:32 -0500337static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 struct cpufreq_governor **governor)
339{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700340 int err = -EINVAL;
341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700343 goto out;
344
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 if (cpufreq_driver->setpolicy) {
346 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
347 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700348 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530349 } else if (!strnicmp(str_governor, "powersave",
350 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700352 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700354 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700356
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800357 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700358
359 t = __find_governor(str_governor);
360
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700361 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700362 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700363
Kees Cook1a8e1462011-05-04 08:38:56 -0700364 mutex_unlock(&cpufreq_governor_mutex);
365 ret = request_module("cpufreq_%s", str_governor);
366 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700367
Kees Cook1a8e1462011-05-04 08:38:56 -0700368 if (ret == 0)
369 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700370 }
371
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700372 if (t != NULL) {
373 *governor = t;
374 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700376
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800377 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 }
Dave Jones29464f22009-01-18 01:37:11 -0500379out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700380 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530385 * cpufreq_per_cpu_attr_read() / show_##file_name() -
386 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 *
388 * Write out information from cpufreq_driver->policy[cpu]; object must be
389 * "unsigned int".
390 */
391
Dave Jones32ee8c32006-02-28 00:43:23 -0500392#define show_one(file_name, object) \
393static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500394(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500395{ \
Dave Jones29464f22009-01-18 01:37:11 -0500396 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397}
398
399show_one(cpuinfo_min_freq, cpuinfo.min_freq);
400show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100401show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402show_one(scaling_min_freq, min);
403show_one(scaling_max_freq, max);
404show_one(scaling_cur_freq, cur);
405
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530406static int __cpufreq_set_policy(struct cpufreq_policy *data,
407 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409/**
410 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
411 */
412#define store_one(file_name, object) \
413static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500414(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000416 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417 struct cpufreq_policy new_policy; \
418 \
419 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
420 if (ret) \
421 return -EINVAL; \
422 \
Dave Jones29464f22009-01-18 01:37:11 -0500423 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 if (ret != 1) \
425 return -EINVAL; \
426 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200427 ret = __cpufreq_set_policy(policy, &new_policy); \
428 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 \
430 return ret ? ret : count; \
431}
432
Dave Jones29464f22009-01-18 01:37:11 -0500433store_one(scaling_min_freq, min);
434store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435
436/**
437 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
438 */
Dave Jones905d77c2008-03-05 14:28:32 -0500439static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
440 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800442 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 if (!cur_freq)
444 return sprintf(buf, "<unknown>");
445 return sprintf(buf, "%u\n", cur_freq);
446}
447
448
449/**
450 * show_scaling_governor - show the current policy for the specified CPU
451 */
Dave Jones905d77c2008-03-05 14:28:32 -0500452static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453{
Dave Jones29464f22009-01-18 01:37:11 -0500454 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 return sprintf(buf, "powersave\n");
456 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
457 return sprintf(buf, "performance\n");
458 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200459 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500460 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 return -EINVAL;
462}
463
464
465/**
466 * store_scaling_governor - store policy for the specified CPU
467 */
Dave Jones905d77c2008-03-05 14:28:32 -0500468static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
469 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000471 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 char str_governor[16];
473 struct cpufreq_policy new_policy;
474
475 ret = cpufreq_get_policy(&new_policy, policy->cpu);
476 if (ret)
477 return ret;
478
Dave Jones29464f22009-01-18 01:37:11 -0500479 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 if (ret != 1)
481 return -EINVAL;
482
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530483 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
484 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 return -EINVAL;
486
Thomas Renninger7970e082006-04-13 15:14:04 +0200487 /* Do not use cpufreq_set_policy here or the user_policy.max
488 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200489 ret = __cpufreq_set_policy(policy, &new_policy);
490
491 policy->user_policy.policy = policy->policy;
492 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200493
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530494 if (ret)
495 return ret;
496 else
497 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498}
499
500/**
501 * show_scaling_driver - show the cpufreq driver currently loaded
502 */
Dave Jones905d77c2008-03-05 14:28:32 -0500503static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504{
viresh kumar4b972f02012-10-23 01:23:43 +0200505 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506}
507
508/**
509 * show_scaling_available_governors - show the available CPUfreq governors
510 */
Dave Jones905d77c2008-03-05 14:28:32 -0500511static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
512 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513{
514 ssize_t i = 0;
515 struct cpufreq_governor *t;
516
517 if (!cpufreq_driver->target) {
518 i += sprintf(buf, "performance powersave");
519 goto out;
520 }
521
522 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500523 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
524 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200526 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500528out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 i += sprintf(&buf[i], "\n");
530 return i;
531}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700532
Rusty Russell835481d2009-01-04 05:18:06 -0800533static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534{
535 ssize_t i = 0;
536 unsigned int cpu;
537
Rusty Russell835481d2009-01-04 05:18:06 -0800538 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 if (i)
540 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
541 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
542 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500543 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 }
545 i += sprintf(&buf[i], "\n");
546 return i;
547}
548
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700549/**
550 * show_related_cpus - show the CPUs affected by each transition even if
551 * hw coordination is in use
552 */
553static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
554{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700555 return show_cpus(policy->related_cpus, buf);
556}
557
558/**
559 * show_affected_cpus - show the CPUs affected by each transition
560 */
561static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
562{
563 return show_cpus(policy->cpus, buf);
564}
565
Venki Pallipadi9e769882007-10-26 10:18:21 -0700566static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500567 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700568{
569 unsigned int freq = 0;
570 unsigned int ret;
571
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700572 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700573 return -EINVAL;
574
575 ret = sscanf(buf, "%u", &freq);
576 if (ret != 1)
577 return -EINVAL;
578
579 policy->governor->store_setspeed(policy, freq);
580
581 return count;
582}
583
584static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
585{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700586 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700587 return sprintf(buf, "<unsupported>\n");
588
589 return policy->governor->show_setspeed(policy, buf);
590}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
Thomas Renningere2f74f32009-11-19 12:31:01 +0100592/**
viresh kumar8bf1ac72012-10-23 01:23:33 +0200593 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100594 */
595static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
596{
597 unsigned int limit;
598 int ret;
599 if (cpufreq_driver->bios_limit) {
600 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
601 if (!ret)
602 return sprintf(buf, "%u\n", limit);
603 }
604 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
605}
606
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200607cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
608cpufreq_freq_attr_ro(cpuinfo_min_freq);
609cpufreq_freq_attr_ro(cpuinfo_max_freq);
610cpufreq_freq_attr_ro(cpuinfo_transition_latency);
611cpufreq_freq_attr_ro(scaling_available_governors);
612cpufreq_freq_attr_ro(scaling_driver);
613cpufreq_freq_attr_ro(scaling_cur_freq);
614cpufreq_freq_attr_ro(bios_limit);
615cpufreq_freq_attr_ro(related_cpus);
616cpufreq_freq_attr_ro(affected_cpus);
617cpufreq_freq_attr_rw(scaling_min_freq);
618cpufreq_freq_attr_rw(scaling_max_freq);
619cpufreq_freq_attr_rw(scaling_governor);
620cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
Dave Jones905d77c2008-03-05 14:28:32 -0500622static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 &cpuinfo_min_freq.attr,
624 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100625 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 &scaling_min_freq.attr,
627 &scaling_max_freq.attr,
628 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700629 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 &scaling_governor.attr,
631 &scaling_driver.attr,
632 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700633 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 NULL
635};
636
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200637struct kobject *cpufreq_global_kobject;
638EXPORT_SYMBOL(cpufreq_global_kobject);
639
Dave Jones29464f22009-01-18 01:37:11 -0500640#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
641#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642
Dave Jones29464f22009-01-18 01:37:11 -0500643static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644{
Dave Jones905d77c2008-03-05 14:28:32 -0500645 struct cpufreq_policy *policy = to_policy(kobj);
646 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500647 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000648 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500650 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800651
652 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500653 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800654
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530655 if (fattr->show)
656 ret = fattr->show(policy, buf);
657 else
658 ret = -EIO;
659
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800660 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500661fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000662 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500663no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 return ret;
665}
666
Dave Jones905d77c2008-03-05 14:28:32 -0500667static ssize_t store(struct kobject *kobj, struct attribute *attr,
668 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669{
Dave Jones905d77c2008-03-05 14:28:32 -0500670 struct cpufreq_policy *policy = to_policy(kobj);
671 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500672 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000673 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500675 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800676
677 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500678 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800679
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530680 if (fattr->store)
681 ret = fattr->store(policy, buf, count);
682 else
683 ret = -EIO;
684
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800685 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500686fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000687 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500688no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 return ret;
690}
691
Dave Jones905d77c2008-03-05 14:28:32 -0500692static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693{
Dave Jones905d77c2008-03-05 14:28:32 -0500694 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200695 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 complete(&policy->kobj_unregister);
697}
698
Emese Revfy52cf25d2010-01-19 02:58:23 +0100699static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 .show = show,
701 .store = store,
702};
703
704static struct kobj_type ktype_cpufreq = {
705 .sysfs_ops = &sysfs_ops,
706 .default_attrs = default_attrs,
707 .release = cpufreq_sysfs_release,
708};
709
Dave Jones19d6f7e2009-07-08 17:35:39 -0400710/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700711static int cpufreq_add_dev_symlink(unsigned int cpu,
712 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400713{
714 unsigned int j;
715 int ret = 0;
716
717 for_each_cpu(j, policy->cpus) {
718 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800719 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400720
721 if (j == cpu)
722 continue;
723 if (!cpu_online(j))
724 continue;
725
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200726 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400727 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800728 cpu_dev = get_cpu_device(j);
729 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400730 "cpufreq");
731 if (ret) {
732 cpufreq_cpu_put(managed_policy);
733 return ret;
734 }
735 }
736 return ret;
737}
738
Alex Chiangcf3289d02009-11-17 20:27:08 -0700739static int cpufreq_add_dev_interface(unsigned int cpu,
740 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800741 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400742{
Dave Jonesecf7e462009-07-08 18:48:47 -0400743 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400744 struct freq_attr **drv_attr;
745 unsigned long flags;
746 int ret = 0;
747 unsigned int j;
748
749 /* prepare interface data */
750 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800751 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400752 if (ret)
753 return ret;
754
755 /* set up files for this cpu device */
756 drv_attr = cpufreq_driver->attr;
757 while ((drv_attr) && (*drv_attr)) {
758 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
759 if (ret)
760 goto err_out_kobj_put;
761 drv_attr++;
762 }
763 if (cpufreq_driver->get) {
764 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
765 if (ret)
766 goto err_out_kobj_put;
767 }
768 if (cpufreq_driver->target) {
769 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
770 if (ret)
771 goto err_out_kobj_put;
772 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100773 if (cpufreq_driver->bios_limit) {
774 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
775 if (ret)
776 goto err_out_kobj_put;
777 }
Dave Jones909a6942009-07-08 18:05:42 -0400778
779 spin_lock_irqsave(&cpufreq_driver_lock, flags);
780 for_each_cpu(j, policy->cpus) {
Julia Lawallbec037a2010-08-05 22:23:00 +0200781 if (!cpu_online(j))
782 continue;
Dave Jones909a6942009-07-08 18:05:42 -0400783 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900784 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400785 }
786 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
787
788 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400789 if (ret)
790 goto err_out_kobj_put;
791
792 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
793 /* assure that the starting sequence is run in __cpufreq_set_policy */
794 policy->governor = NULL;
795
796 /* set default policy */
797 ret = __cpufreq_set_policy(policy, &new_policy);
798 policy->user_policy.policy = policy->policy;
799 policy->user_policy.governor = policy->governor;
800
801 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200802 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400803 if (cpufreq_driver->exit)
804 cpufreq_driver->exit(policy);
805 }
Dave Jones909a6942009-07-08 18:05:42 -0400806 return ret;
807
808err_out_kobj_put:
809 kobject_put(&policy->kobj);
810 wait_for_completion(&policy->kobj_unregister);
811 return ret;
812}
813
Viresh Kumarfcf80582013-01-29 14:39:08 +0000814#ifdef CONFIG_HOTPLUG_CPU
815static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
816 struct device *dev)
817{
818 struct cpufreq_policy *policy;
819 int ret = 0;
820 unsigned long flags;
821
822 policy = cpufreq_cpu_get(sibling);
823 WARN_ON(!policy);
824
825 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
826
827 lock_policy_rwsem_write(cpu);
828
829 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
830
831 spin_lock_irqsave(&cpufreq_driver_lock, flags);
832 cpumask_set_cpu(cpu, policy->cpus);
833 per_cpu(cpufreq_cpu_data, cpu) = policy;
834 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
835
836 __cpufreq_governor(policy, CPUFREQ_GOV_START);
837 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
838
839 unlock_policy_rwsem_write(cpu);
840
841 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
842 if (ret) {
843 cpufreq_cpu_put(policy);
844 return ret;
845 }
846
847 return 0;
848}
849#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
851/**
852 * cpufreq_add_dev - add a CPU device
853 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500854 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400855 *
856 * The Oracle says: try running cpufreq registration/unregistration concurrently
857 * with with cpu hotplugging and all hell will break loose. Tried to clean this
858 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800860static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000862 unsigned int j, cpu = dev->id;
863 int ret = -ENOMEM, found = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500866#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000867 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500868 int sibling;
869#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
Ashok Rajc32b6b82005-10-30 14:59:54 -0800871 if (cpu_is_offline(cpu))
872 return 0;
873
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200874 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
876#ifdef CONFIG_SMP
877 /* check whether a different CPU already registered this
878 * CPU because it is in the same boat. */
879 policy = cpufreq_cpu_get(cpu);
880 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500881 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 return 0;
883 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000884
885#ifdef CONFIG_HOTPLUG_CPU
886 /* Check if this cpu was hot-unplugged earlier and has siblings */
887 for_each_online_cpu(sibling) {
888 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
889 if (cp && cpumask_test_cpu(cpu, cp->related_cpus))
890 return cpufreq_add_policy_cpu(cpu, sibling, dev);
891 }
892#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893#endif
894
895 if (!try_module_get(cpufreq_driver->owner)) {
896 ret = -EINVAL;
897 goto module_out;
898 }
899
Dave Jonese98df502005-10-20 15:17:43 -0700900 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400901 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400903
904 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400905 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400906
907 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400908 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909
910 policy->cpu = cpu;
Rusty Russell835481d2009-01-04 05:18:06 -0800911 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800913 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900914 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400915 ret = (lock_policy_rwsem_write(cpu) < 0);
916 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800917
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000919 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700921 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500922#ifdef CONFIG_HOTPLUG_CPU
923 for_each_online_cpu(sibling) {
924 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
925 if (cp && cp->governor &&
926 (cpumask_test_cpu(cpu, cp->related_cpus))) {
927 policy->governor = cp->governor;
928 found = 1;
929 break;
930 }
931 }
932#endif
933 if (!found)
934 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 /* call driver. From then on the cpufreq must be able
936 * to accept all calls to ->verify and ->setpolicy for this CPU
937 */
938 ret = cpufreq_driver->init(policy);
939 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200940 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400941 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000943
Viresh Kumarfcf80582013-01-29 14:39:08 +0000944 /* related cpus should atleast have policy->cpus */
945 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
946
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000947 /*
948 * affected cpus must always be the one, which are online. We aren't
949 * managing offline cpus here.
950 */
951 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
952
Mike Chan187d9f42008-12-04 12:19:17 -0800953 policy->user_policy.min = policy->min;
954 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
Thomas Renningera1531ac2008-07-29 22:32:58 -0700956 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
957 CPUFREQ_START, policy);
958
Viresh Kumarfcf80582013-01-29 14:39:08 +0000959#ifdef CONFIG_HOTPLUG_CPU
960 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
961 if (gov) {
962 policy->governor = gov;
963 pr_debug("Restoring governor %s for cpu %d\n",
964 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200965 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000966#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800968 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400969 if (ret)
970 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500971
Lothar Waßmanndca02612008-05-29 17:54:52 +0200972 unlock_policy_rwsem_write(cpu);
973
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400974 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200976 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500977
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 return 0;
979
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980err_out_unregister:
981 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -0800982 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -0700983 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
985
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -0800986 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 wait_for_completion(&policy->kobj_unregister);
988
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400989err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -0500990 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +0800991 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400992err_free_cpumask:
993 free_cpumask_var(policy->cpus);
994err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996nomem_out:
997 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -0800998module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 return ret;
1000}
1001
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001002static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1003{
1004 int j;
1005
1006 policy->last_cpu = policy->cpu;
1007 policy->cpu = cpu;
1008
1009 for_each_cpu(j, policy->cpus) {
1010 if (!cpu_online(j))
1011 continue;
1012 per_cpu(cpufreq_policy_cpu, j) = cpu;
1013 }
1014
1015#ifdef CONFIG_CPU_FREQ_TABLE
1016 cpufreq_frequency_table_update_policy_cpu(policy);
1017#endif
1018 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1019 CPUFREQ_UPDATE_POLICY_CPU, policy);
1020}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021
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{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001031 unsigned int cpu = dev->id, ret, cpus;
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;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001036 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001038 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
1040 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001041 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
1043 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001044 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001046 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 return -EINVAL;
1048 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001050 if (cpufreq_driver->target)
Viresh Kumarf6a74092013-01-12 05:14:39 +00001051 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Thomas Renninger084f3492007-07-09 11:35:28 -07001052
1053#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001054 strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
1055 CPUFREQ_NAME_LEN);
Thomas Renninger084f3492007-07-09 11:35:28 -07001056#endif
1057
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001058 per_cpu(cpufreq_cpu_data, cpu) = NULL;
1059 cpus = cpumask_weight(data->cpus);
1060 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001062 if (cpu != data->cpu) {
1063 sysfs_remove_link(&dev->kobj, "cpufreq");
1064 } else if (cpus > 1) {
Jacob Shin27ecddc2011-04-27 13:32:11 -05001065 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001066 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1067 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1068 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1069 if (ret) {
1070 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1071 cpumask_set_cpu(cpu, data->cpus);
1072 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1073 "cpufreq");
1074 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1075 unlock_policy_rwsem_write(cpu);
1076 return -EINVAL;
1077 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001078
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001079 update_policy_cpu(data, cpu_dev->id);
1080 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1081 __func__, cpu_dev->id, cpu);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001082 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001083
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001084 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1085
1086 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1087 cpufreq_cpu_put(data);
1088 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001089
1090 /* If cpu is last user of policy, free policy */
1091 if (cpus == 1) {
1092 lock_policy_rwsem_write(cpu);
1093 kobj = &data->kobj;
1094 cmp = &data->kobj_unregister;
1095 unlock_policy_rwsem_write(cpu);
1096 kobject_put(kobj);
1097
1098 /* we need to make sure that the underlying kobj is actually
1099 * not referenced anymore by anybody before we proceed with
1100 * unloading.
1101 */
1102 pr_debug("waiting for dropping of refcount\n");
1103 wait_for_completion(cmp);
1104 pr_debug("wait complete\n");
1105
1106 lock_policy_rwsem_write(cpu);
1107 if (cpufreq_driver->exit)
1108 cpufreq_driver->exit(data);
1109 unlock_policy_rwsem_write(cpu);
1110
1111 free_cpumask_var(data->related_cpus);
1112 free_cpumask_var(data->cpus);
1113 kfree(data);
1114 } else if (cpufreq_driver->target) {
1115 __cpufreq_governor(data, CPUFREQ_GOV_START);
1116 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1117 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 return 0;
1120}
1121
1122
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001123static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001124{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001125 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001126 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001127
1128 if (cpu_is_offline(cpu))
1129 return 0;
1130
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001131 if (unlikely(lock_policy_rwsem_write(cpu)))
1132 BUG();
1133
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001134 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001135 return retval;
1136}
1137
1138
David Howells65f27f32006-11-22 14:55:48 +00001139static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140{
David Howells65f27f32006-11-22 14:55:48 +00001141 struct cpufreq_policy *policy =
1142 container_of(work, struct cpufreq_policy, update);
1143 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001144 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 cpufreq_update_policy(cpu);
1146}
1147
1148/**
1149 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1150 * @cpu: cpu number
1151 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1152 * @new_freq: CPU frequency the CPU actually runs at
1153 *
Dave Jones29464f22009-01-18 01:37:11 -05001154 * We adjust to current frequency first, and need to clean up later.
1155 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301157static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1158 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159{
1160 struct cpufreq_freqs freqs;
1161
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001162 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1164
1165 freqs.cpu = cpu;
1166 freqs.old = old_freq;
1167 freqs.new = new_freq;
1168 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1169 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1170}
1171
1172
Dave Jones32ee8c32006-02-28 00:43:23 -05001173/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301174 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001175 * @cpu: CPU number
1176 *
1177 * This is the last known freq, without actually getting it from the driver.
1178 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1179 */
1180unsigned int cpufreq_quick_get(unsigned int cpu)
1181{
1182 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301183 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001184
1185 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301186 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001187 cpufreq_cpu_put(policy);
1188 }
1189
Dave Jones4d34a672008-02-07 16:33:49 -05001190 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001191}
1192EXPORT_SYMBOL(cpufreq_quick_get);
1193
Jesse Barnes3d737102011-06-28 10:59:12 -07001194/**
1195 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1196 * @cpu: CPU number
1197 *
1198 * Just return the max possible frequency for a given CPU.
1199 */
1200unsigned int cpufreq_quick_get_max(unsigned int cpu)
1201{
1202 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1203 unsigned int ret_freq = 0;
1204
1205 if (policy) {
1206 ret_freq = policy->max;
1207 cpufreq_cpu_put(policy);
1208 }
1209
1210 return ret_freq;
1211}
1212EXPORT_SYMBOL(cpufreq_quick_get_max);
1213
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001214
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001215static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001217 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301218 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001221 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301223 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301225 if (ret_freq && policy->cur &&
1226 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1227 /* verify no discrepancy between actual and
1228 saved value exists */
1229 if (unlikely(ret_freq != policy->cur)) {
1230 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 schedule_work(&policy->update);
1232 }
1233 }
1234
Dave Jones4d34a672008-02-07 16:33:49 -05001235 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001236}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001238/**
1239 * cpufreq_get - get the current CPU frequency (in kHz)
1240 * @cpu: CPU number
1241 *
1242 * Get the CPU current (static) CPU frequency
1243 */
1244unsigned int cpufreq_get(unsigned int cpu)
1245{
1246 unsigned int ret_freq = 0;
1247 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1248
1249 if (!policy)
1250 goto out;
1251
1252 if (unlikely(lock_policy_rwsem_read(cpu)))
1253 goto out_policy;
1254
1255 ret_freq = __cpufreq_get(cpu);
1256
1257 unlock_policy_rwsem_read(cpu);
1258
1259out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001261out:
Dave Jones4d34a672008-02-07 16:33:49 -05001262 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263}
1264EXPORT_SYMBOL(cpufreq_get);
1265
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001266static struct subsys_interface cpufreq_interface = {
1267 .name = "cpufreq",
1268 .subsys = &cpu_subsys,
1269 .add_dev = cpufreq_add_dev,
1270 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001271};
1272
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273
1274/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001275 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1276 *
1277 * This function is only executed for the boot processor. The other CPUs
1278 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001279 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001280static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001281{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301282 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001283
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001284 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001285 struct cpufreq_policy *cpu_policy;
1286
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001287 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001288
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001289 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001290 cpu_policy = cpufreq_cpu_get(cpu);
1291 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001292 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001293
1294 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001295 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001296 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001297 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1298 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001299 }
1300
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001301 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001302 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001303}
1304
1305/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001306 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 *
1308 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001309 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1310 * restored. It will verify that the current freq is in sync with
1311 * what we believe it to be. This is a bit later than when it
1312 * should be, but nonethteless it's better than calling
1313 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001314 *
1315 * This function is only executed for the boot CPU. The other CPUs have not
1316 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001318static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301320 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001321
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001322 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 struct cpufreq_policy *cpu_policy;
1324
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001325 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001327 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 cpu_policy = cpufreq_cpu_get(cpu);
1329 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001330 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331
1332 if (cpufreq_driver->resume) {
1333 ret = cpufreq_driver->resume(cpu_policy);
1334 if (ret) {
1335 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1336 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001337 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 }
1339 }
1340
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001342
Dave Jonesc9060492008-02-07 16:32:18 -05001343fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345}
1346
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001347static struct syscore_ops cpufreq_syscore_ops = {
1348 .suspend = cpufreq_bp_suspend,
1349 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350};
1351
Borislav Petkov9d950462013-01-20 10:24:28 +00001352/**
1353 * cpufreq_get_current_driver - return current driver's name
1354 *
1355 * Return the name string of the currently loaded cpufreq driver
1356 * or NULL, if none.
1357 */
1358const char *cpufreq_get_current_driver(void)
1359{
1360 if (cpufreq_driver)
1361 return cpufreq_driver->name;
1362
1363 return NULL;
1364}
1365EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
1367/*********************************************************************
1368 * NOTIFIER LISTS INTERFACE *
1369 *********************************************************************/
1370
1371/**
1372 * cpufreq_register_notifier - register a driver with cpufreq
1373 * @nb: notifier function to register
1374 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1375 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001376 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 * are notified about clock rate changes (once before and once after
1378 * the transition), or a list of drivers that are notified about
1379 * changes in cpufreq policy.
1380 *
1381 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001382 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 */
1384int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1385{
1386 int ret;
1387
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001388 if (cpufreq_disabled())
1389 return -EINVAL;
1390
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001391 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1392
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 switch (list) {
1394 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001395 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001396 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 break;
1398 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001399 ret = blocking_notifier_chain_register(
1400 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 break;
1402 default:
1403 ret = -EINVAL;
1404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
1406 return ret;
1407}
1408EXPORT_SYMBOL(cpufreq_register_notifier);
1409
1410
1411/**
1412 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1413 * @nb: notifier block to be unregistered
1414 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1415 *
1416 * Remove a driver from the CPU frequency notifier list.
1417 *
1418 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001419 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 */
1421int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1422{
1423 int ret;
1424
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001425 if (cpufreq_disabled())
1426 return -EINVAL;
1427
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 switch (list) {
1429 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001430 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001431 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 break;
1433 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001434 ret = blocking_notifier_chain_unregister(
1435 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 break;
1437 default:
1438 ret = -EINVAL;
1439 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
1441 return ret;
1442}
1443EXPORT_SYMBOL(cpufreq_unregister_notifier);
1444
1445
1446/*********************************************************************
1447 * GOVERNORS *
1448 *********************************************************************/
1449
1450
1451int __cpufreq_driver_target(struct cpufreq_policy *policy,
1452 unsigned int target_freq,
1453 unsigned int relation)
1454{
1455 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001456 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001457
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001458 if (cpufreq_disabled())
1459 return -ENODEV;
1460
Viresh Kumar72499242012-10-31 01:28:21 +01001461 /* Make sure that target_freq is within supported range */
1462 if (target_freq > policy->max)
1463 target_freq = policy->max;
1464 if (target_freq < policy->min)
1465 target_freq = policy->min;
1466
1467 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1468 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001469
1470 if (target_freq == policy->cur)
1471 return 0;
1472
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1474 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001475
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 return retval;
1477}
1478EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1479
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480int cpufreq_driver_target(struct cpufreq_policy *policy,
1481 unsigned int target_freq,
1482 unsigned int relation)
1483{
Julia Lawallf1829e42008-07-25 22:44:53 +02001484 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485
1486 policy = cpufreq_cpu_get(policy->cpu);
1487 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001488 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001490 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001491 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
1493 ret = __cpufreq_driver_target(policy, target_freq, relation);
1494
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001495 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496
Julia Lawallf1829e42008-07-25 22:44:53 +02001497fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001499no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 return ret;
1501}
1502EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1503
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001504int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001505{
1506 int ret = 0;
1507
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001508 if (cpufreq_disabled())
1509 return ret;
1510
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001511 if (!(cpu_online(cpu) && cpufreq_driver->getavg))
1512 return 0;
1513
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001514 policy = cpufreq_cpu_get(policy->cpu);
1515 if (!policy)
1516 return -EINVAL;
1517
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001518 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001519
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001520 cpufreq_cpu_put(policy);
1521 return ret;
1522}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001523EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001524
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001525/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001526 * when "event" is CPUFREQ_GOV_LIMITS
1527 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301529static int __cpufreq_governor(struct cpufreq_policy *policy,
1530 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531{
Dave Jonescc993ca2005-07-28 09:43:56 -07001532 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001533
1534 /* Only must be defined when default governor is known to have latency
1535 restrictions, like e.g. conservative or ondemand.
1536 That this is the case is already ensured in Kconfig
1537 */
1538#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1539 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1540#else
1541 struct cpufreq_governor *gov = NULL;
1542#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001543
1544 if (policy->governor->max_transition_latency &&
1545 policy->cpuinfo.transition_latency >
1546 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001547 if (!gov)
1548 return -EINVAL;
1549 else {
1550 printk(KERN_WARNING "%s governor failed, too long"
1551 " transition latency of HW, fallback"
1552 " to %s governor\n",
1553 policy->governor->name,
1554 gov->name);
1555 policy->governor = gov;
1556 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001557 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558
1559 if (!try_module_get(policy->governor->owner))
1560 return -EINVAL;
1561
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001562 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301563 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 ret = policy->governor->governor(policy, event);
1565
Viresh Kumarb3940582013-02-01 05:42:58 +00001566 if (!policy->governor->initialized && (event == CPUFREQ_GOV_START))
1567 policy->governor->initialized = 1;
1568
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301569 /* we keep one module reference alive for
1570 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 if ((event != CPUFREQ_GOV_START) || ret)
1572 module_put(policy->governor->owner);
1573 if ((event == CPUFREQ_GOV_STOP) && !ret)
1574 module_put(policy->governor->owner);
1575
1576 return ret;
1577}
1578
1579
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580int cpufreq_register_governor(struct cpufreq_governor *governor)
1581{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001582 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
1584 if (!governor)
1585 return -EINVAL;
1586
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001587 if (cpufreq_disabled())
1588 return -ENODEV;
1589
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001590 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001591
Viresh Kumarb3940582013-02-01 05:42:58 +00001592 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001593 err = -EBUSY;
1594 if (__find_governor(governor->name) == NULL) {
1595 err = 0;
1596 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
Dave Jones32ee8c32006-02-28 00:43:23 -05001599 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001600 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601}
1602EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1603
1604
1605void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1606{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001607#ifdef CONFIG_HOTPLUG_CPU
1608 int cpu;
1609#endif
1610
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 if (!governor)
1612 return;
1613
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001614 if (cpufreq_disabled())
1615 return;
1616
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001617#ifdef CONFIG_HOTPLUG_CPU
1618 for_each_present_cpu(cpu) {
1619 if (cpu_online(cpu))
1620 continue;
1621 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1622 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1623 }
1624#endif
1625
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001626 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001628 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 return;
1630}
1631EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1632
1633
1634
1635/*********************************************************************
1636 * POLICY INTERFACE *
1637 *********************************************************************/
1638
1639/**
1640 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001641 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1642 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 *
1644 * Reads the current cpufreq policy.
1645 */
1646int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1647{
1648 struct cpufreq_policy *cpu_policy;
1649 if (!policy)
1650 return -EINVAL;
1651
1652 cpu_policy = cpufreq_cpu_get(cpu);
1653 if (!cpu_policy)
1654 return -EINVAL;
1655
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657
1658 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 return 0;
1660}
1661EXPORT_SYMBOL(cpufreq_get_policy);
1662
1663
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001664/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301665 * data : current policy.
1666 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001667 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301668static int __cpufreq_set_policy(struct cpufreq_policy *data,
1669 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670{
1671 int ret = 0;
1672
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001673 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 policy->min, policy->max);
1675
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301676 memcpy(&policy->cpuinfo, &data->cpuinfo,
1677 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678
Yi Yang53391fa2008-01-30 13:33:34 +01001679 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001680 ret = -EINVAL;
1681 goto error_out;
1682 }
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 /* verify the cpu speed can be set within this limit */
1685 ret = cpufreq_driver->verify(policy);
1686 if (ret)
1687 goto error_out;
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001690 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1691 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
1693 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001694 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1695 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
1697 /* verify the cpu speed can be set within this limit,
1698 which might be different to the first one */
1699 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001700 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702
1703 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001704 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1705 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706
Dave Jones7d5e3502006-02-02 17:03:42 -05001707 data->min = policy->min;
1708 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001710 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301711 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
1713 if (cpufreq_driver->setpolicy) {
1714 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001715 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 ret = cpufreq_driver->setpolicy(policy);
1717 } else {
1718 if (policy->governor != data->governor) {
1719 /* save old, working values */
1720 struct cpufreq_governor *old_gov = data->governor;
1721
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001722 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
1724 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001725 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1727
1728 /* start new governor */
1729 data->governor = policy->governor;
1730 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1731 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001732 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301733 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 if (old_gov) {
1735 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301736 __cpufreq_governor(data,
1737 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 }
1739 ret = -EINVAL;
1740 goto error_out;
1741 }
1742 /* might be a policy change, too, so fall through */
1743 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001744 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1746 }
1747
Dave Jones7d5e3502006-02-02 17:03:42 -05001748error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 return ret;
1750}
1751
1752/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1754 * @cpu: CPU which shall be re-evaluated
1755 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001756 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 * at different times.
1758 */
1759int cpufreq_update_policy(unsigned int cpu)
1760{
1761 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1762 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001763 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
Julia Lawallf1829e42008-07-25 22:44:53 +02001765 if (!data) {
1766 ret = -ENODEV;
1767 goto no_policy;
1768 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Julia Lawallf1829e42008-07-25 22:44:53 +02001770 if (unlikely(lock_policy_rwsem_write(cpu))) {
1771 ret = -EINVAL;
1772 goto fail;
1773 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001775 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001776 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 policy.min = data->user_policy.min;
1778 policy.max = data->user_policy.max;
1779 policy.policy = data->user_policy.policy;
1780 policy.governor = data->user_policy.governor;
1781
Thomas Renninger0961dd02006-01-26 18:46:33 +01001782 /* BIOS might change freq behind our back
1783 -> ask driver for current freq and notify governors about a change */
1784 if (cpufreq_driver->get) {
1785 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001786 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001787 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001788 data->cur = policy.cur;
1789 } else {
1790 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301791 cpufreq_out_of_sync(cpu, data->cur,
1792 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001793 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001794 }
1795
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 ret = __cpufreq_set_policy(data, &policy);
1797
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001798 unlock_policy_rwsem_write(cpu);
1799
Julia Lawallf1829e42008-07-25 22:44:53 +02001800fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001802no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 return ret;
1804}
1805EXPORT_SYMBOL(cpufreq_update_policy);
1806
Satyam Sharmadd184a02007-10-02 13:28:14 -07001807static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001808 unsigned long action, void *hcpu)
1809{
1810 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001811 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001812
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001813 dev = get_cpu_device(cpu);
1814 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001815 switch (action) {
1816 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001817 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001818 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001819 break;
1820 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001821 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001822 if (unlikely(lock_policy_rwsem_write(cpu)))
1823 BUG();
1824
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001825 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001826 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001827 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001828 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001829 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001830 break;
1831 }
1832 }
1833 return NOTIFY_OK;
1834}
1835
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001836static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001837 .notifier_call = cpufreq_cpu_callback,
1838};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
1840/*********************************************************************
1841 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1842 *********************************************************************/
1843
1844/**
1845 * cpufreq_register_driver - register a CPU Frequency driver
1846 * @driver_data: A struct cpufreq_driver containing the values#
1847 * submitted by the CPU Frequency driver.
1848 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001849 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001851 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 *
1853 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001854int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855{
1856 unsigned long flags;
1857 int ret;
1858
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001859 if (cpufreq_disabled())
1860 return -ENODEV;
1861
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 if (!driver_data || !driver_data->verify || !driver_data->init ||
1863 ((!driver_data->setpolicy) && (!driver_data->target)))
1864 return -EINVAL;
1865
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001866 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
1868 if (driver_data->setpolicy)
1869 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1870
1871 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1872 if (cpufreq_driver) {
1873 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1874 return -EBUSY;
1875 }
1876 cpufreq_driver = driver_data;
1877 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1878
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001879 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001880 if (ret)
1881 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001883 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 int i;
1885 ret = -ENODEV;
1886
1887 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001888 for (i = 0; i < nr_cpu_ids; i++)
1889 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001891 break;
1892 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
1894 /* if all ->init() calls failed, unregister */
1895 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001896 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301897 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001898 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 }
1900 }
1901
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001902 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001903 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001905 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001906err_if_unreg:
1907 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001908err_null_driver:
1909 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1910 cpufreq_driver = NULL;
1911 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001912 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913}
1914EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1915
1916
1917/**
1918 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1919 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001920 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 * the right to do so, i.e. if you have succeeded in initialising before!
1922 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1923 * currently not initialised.
1924 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001925int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926{
1927 unsigned long flags;
1928
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001929 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001932 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001934 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001935 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936
1937 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1938 cpufreq_driver = NULL;
1939 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1940
1941 return 0;
1942}
1943EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001944
1945static int __init cpufreq_core_init(void)
1946{
1947 int cpu;
1948
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001949 if (cpufreq_disabled())
1950 return -ENODEV;
1951
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001952 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001953 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001954 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1955 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001956
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001957 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001958 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001959 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001960
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001961 return 0;
1962}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001963core_initcall(cpufreq_core_init);