blob: 1cea7a1eac13677f1d2b85cd8792270264d0d646 [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 Kumarb8eed8a2013-01-14 13:23:03 +00001062 if (unlikely((cpu == data->cpu) && (cpus > 1))) {
Jacob Shin27ecddc2011-04-27 13:32:11 -05001063 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001064 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1065 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1066 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1067 if (ret) {
1068 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1069 cpumask_set_cpu(cpu, data->cpus);
1070 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1071 "cpufreq");
1072 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1073 unlock_policy_rwsem_write(cpu);
1074 return -EINVAL;
1075 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001076
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001077 update_policy_cpu(data, cpu_dev->id);
1078 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1079 __func__, cpu_dev->id, cpu);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001080 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001081
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001082 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1083
1084 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1085 cpufreq_cpu_put(data);
1086 unlock_policy_rwsem_write(cpu);
1087 sysfs_remove_link(&dev->kobj, "cpufreq");
1088
1089 /* If cpu is last user of policy, free policy */
1090 if (cpus == 1) {
1091 lock_policy_rwsem_write(cpu);
1092 kobj = &data->kobj;
1093 cmp = &data->kobj_unregister;
1094 unlock_policy_rwsem_write(cpu);
1095 kobject_put(kobj);
1096
1097 /* we need to make sure that the underlying kobj is actually
1098 * not referenced anymore by anybody before we proceed with
1099 * unloading.
1100 */
1101 pr_debug("waiting for dropping of refcount\n");
1102 wait_for_completion(cmp);
1103 pr_debug("wait complete\n");
1104
1105 lock_policy_rwsem_write(cpu);
1106 if (cpufreq_driver->exit)
1107 cpufreq_driver->exit(data);
1108 unlock_policy_rwsem_write(cpu);
1109
1110 free_cpumask_var(data->related_cpus);
1111 free_cpumask_var(data->cpus);
1112 kfree(data);
1113 } else if (cpufreq_driver->target) {
1114 __cpufreq_governor(data, CPUFREQ_GOV_START);
1115 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1116 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 return 0;
1119}
1120
1121
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001122static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001123{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001124 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001125 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001126
1127 if (cpu_is_offline(cpu))
1128 return 0;
1129
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001130 if (unlikely(lock_policy_rwsem_write(cpu)))
1131 BUG();
1132
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001133 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001134 return retval;
1135}
1136
1137
David Howells65f27f32006-11-22 14:55:48 +00001138static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139{
David Howells65f27f32006-11-22 14:55:48 +00001140 struct cpufreq_policy *policy =
1141 container_of(work, struct cpufreq_policy, update);
1142 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001143 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 cpufreq_update_policy(cpu);
1145}
1146
1147/**
1148 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1149 * @cpu: cpu number
1150 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1151 * @new_freq: CPU frequency the CPU actually runs at
1152 *
Dave Jones29464f22009-01-18 01:37:11 -05001153 * We adjust to current frequency first, and need to clean up later.
1154 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301156static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1157 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158{
1159 struct cpufreq_freqs freqs;
1160
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001161 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1163
1164 freqs.cpu = cpu;
1165 freqs.old = old_freq;
1166 freqs.new = new_freq;
1167 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1168 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1169}
1170
1171
Dave Jones32ee8c32006-02-28 00:43:23 -05001172/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301173 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001174 * @cpu: CPU number
1175 *
1176 * This is the last known freq, without actually getting it from the driver.
1177 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1178 */
1179unsigned int cpufreq_quick_get(unsigned int cpu)
1180{
1181 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301182 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001183
1184 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301185 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001186 cpufreq_cpu_put(policy);
1187 }
1188
Dave Jones4d34a672008-02-07 16:33:49 -05001189 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001190}
1191EXPORT_SYMBOL(cpufreq_quick_get);
1192
Jesse Barnes3d737102011-06-28 10:59:12 -07001193/**
1194 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1195 * @cpu: CPU number
1196 *
1197 * Just return the max possible frequency for a given CPU.
1198 */
1199unsigned int cpufreq_quick_get_max(unsigned int cpu)
1200{
1201 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1202 unsigned int ret_freq = 0;
1203
1204 if (policy) {
1205 ret_freq = policy->max;
1206 cpufreq_cpu_put(policy);
1207 }
1208
1209 return ret_freq;
1210}
1211EXPORT_SYMBOL(cpufreq_quick_get_max);
1212
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001213
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001214static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001216 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301217 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001220 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301222 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301224 if (ret_freq && policy->cur &&
1225 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1226 /* verify no discrepancy between actual and
1227 saved value exists */
1228 if (unlikely(ret_freq != policy->cur)) {
1229 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 schedule_work(&policy->update);
1231 }
1232 }
1233
Dave Jones4d34a672008-02-07 16:33:49 -05001234 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001235}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001237/**
1238 * cpufreq_get - get the current CPU frequency (in kHz)
1239 * @cpu: CPU number
1240 *
1241 * Get the CPU current (static) CPU frequency
1242 */
1243unsigned int cpufreq_get(unsigned int cpu)
1244{
1245 unsigned int ret_freq = 0;
1246 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1247
1248 if (!policy)
1249 goto out;
1250
1251 if (unlikely(lock_policy_rwsem_read(cpu)))
1252 goto out_policy;
1253
1254 ret_freq = __cpufreq_get(cpu);
1255
1256 unlock_policy_rwsem_read(cpu);
1257
1258out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001260out:
Dave Jones4d34a672008-02-07 16:33:49 -05001261 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262}
1263EXPORT_SYMBOL(cpufreq_get);
1264
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001265static struct subsys_interface cpufreq_interface = {
1266 .name = "cpufreq",
1267 .subsys = &cpu_subsys,
1268 .add_dev = cpufreq_add_dev,
1269 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001270};
1271
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272
1273/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001274 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1275 *
1276 * This function is only executed for the boot processor. The other CPUs
1277 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001278 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001279static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001280{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301281 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001282
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001283 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001284 struct cpufreq_policy *cpu_policy;
1285
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001286 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001287
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001288 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001289 cpu_policy = cpufreq_cpu_get(cpu);
1290 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001291 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001292
1293 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001294 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001295 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001296 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1297 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001298 }
1299
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001300 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001301 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001302}
1303
1304/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001305 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 *
1307 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001308 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1309 * restored. It will verify that the current freq is in sync with
1310 * what we believe it to be. This is a bit later than when it
1311 * should be, but nonethteless it's better than calling
1312 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001313 *
1314 * This function is only executed for the boot CPU. The other CPUs have not
1315 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001317static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301319 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001320
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001321 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 struct cpufreq_policy *cpu_policy;
1323
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001324 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001326 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 cpu_policy = cpufreq_cpu_get(cpu);
1328 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001329 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
1331 if (cpufreq_driver->resume) {
1332 ret = cpufreq_driver->resume(cpu_policy);
1333 if (ret) {
1334 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1335 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001336 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 }
1338 }
1339
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001341
Dave Jonesc9060492008-02-07 16:32:18 -05001342fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344}
1345
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001346static struct syscore_ops cpufreq_syscore_ops = {
1347 .suspend = cpufreq_bp_suspend,
1348 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349};
1350
Borislav Petkov9d950462013-01-20 10:24:28 +00001351/**
1352 * cpufreq_get_current_driver - return current driver's name
1353 *
1354 * Return the name string of the currently loaded cpufreq driver
1355 * or NULL, if none.
1356 */
1357const char *cpufreq_get_current_driver(void)
1358{
1359 if (cpufreq_driver)
1360 return cpufreq_driver->name;
1361
1362 return NULL;
1363}
1364EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
1366/*********************************************************************
1367 * NOTIFIER LISTS INTERFACE *
1368 *********************************************************************/
1369
1370/**
1371 * cpufreq_register_notifier - register a driver with cpufreq
1372 * @nb: notifier function to register
1373 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1374 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001375 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 * are notified about clock rate changes (once before and once after
1377 * the transition), or a list of drivers that are notified about
1378 * changes in cpufreq policy.
1379 *
1380 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001381 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 */
1383int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1384{
1385 int ret;
1386
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001387 if (cpufreq_disabled())
1388 return -EINVAL;
1389
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001390 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1391
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 switch (list) {
1393 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001394 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001395 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 break;
1397 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001398 ret = blocking_notifier_chain_register(
1399 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 break;
1401 default:
1402 ret = -EINVAL;
1403 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405 return ret;
1406}
1407EXPORT_SYMBOL(cpufreq_register_notifier);
1408
1409
1410/**
1411 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1412 * @nb: notifier block to be unregistered
1413 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1414 *
1415 * Remove a driver from the CPU frequency notifier list.
1416 *
1417 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001418 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 */
1420int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1421{
1422 int ret;
1423
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001424 if (cpufreq_disabled())
1425 return -EINVAL;
1426
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 switch (list) {
1428 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001429 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001430 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 break;
1432 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001433 ret = blocking_notifier_chain_unregister(
1434 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 break;
1436 default:
1437 ret = -EINVAL;
1438 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439
1440 return ret;
1441}
1442EXPORT_SYMBOL(cpufreq_unregister_notifier);
1443
1444
1445/*********************************************************************
1446 * GOVERNORS *
1447 *********************************************************************/
1448
1449
1450int __cpufreq_driver_target(struct cpufreq_policy *policy,
1451 unsigned int target_freq,
1452 unsigned int relation)
1453{
1454 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001455 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001456
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001457 if (cpufreq_disabled())
1458 return -ENODEV;
1459
Viresh Kumar72499242012-10-31 01:28:21 +01001460 /* Make sure that target_freq is within supported range */
1461 if (target_freq > policy->max)
1462 target_freq = policy->max;
1463 if (target_freq < policy->min)
1464 target_freq = policy->min;
1465
1466 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1467 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001468
1469 if (target_freq == policy->cur)
1470 return 0;
1471
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1473 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001474
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 return retval;
1476}
1477EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1478
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479int cpufreq_driver_target(struct cpufreq_policy *policy,
1480 unsigned int target_freq,
1481 unsigned int relation)
1482{
Julia Lawallf1829e42008-07-25 22:44:53 +02001483 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484
1485 policy = cpufreq_cpu_get(policy->cpu);
1486 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001487 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001489 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001490 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491
1492 ret = __cpufreq_driver_target(policy, target_freq, relation);
1493
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001494 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
Julia Lawallf1829e42008-07-25 22:44:53 +02001496fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001498no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 return ret;
1500}
1501EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1502
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001503int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001504{
1505 int ret = 0;
1506
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001507 if (cpufreq_disabled())
1508 return ret;
1509
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001510 if (!(cpu_online(cpu) && cpufreq_driver->getavg))
1511 return 0;
1512
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001513 policy = cpufreq_cpu_get(policy->cpu);
1514 if (!policy)
1515 return -EINVAL;
1516
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001517 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001518
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001519 cpufreq_cpu_put(policy);
1520 return ret;
1521}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001522EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001523
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001524/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001525 * when "event" is CPUFREQ_GOV_LIMITS
1526 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301528static int __cpufreq_governor(struct cpufreq_policy *policy,
1529 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530{
Dave Jonescc993ca2005-07-28 09:43:56 -07001531 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001532
1533 /* Only must be defined when default governor is known to have latency
1534 restrictions, like e.g. conservative or ondemand.
1535 That this is the case is already ensured in Kconfig
1536 */
1537#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1538 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1539#else
1540 struct cpufreq_governor *gov = NULL;
1541#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001542
1543 if (policy->governor->max_transition_latency &&
1544 policy->cpuinfo.transition_latency >
1545 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001546 if (!gov)
1547 return -EINVAL;
1548 else {
1549 printk(KERN_WARNING "%s governor failed, too long"
1550 " transition latency of HW, fallback"
1551 " to %s governor\n",
1552 policy->governor->name,
1553 gov->name);
1554 policy->governor = gov;
1555 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001556 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558 if (!try_module_get(policy->governor->owner))
1559 return -EINVAL;
1560
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001561 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301562 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 ret = policy->governor->governor(policy, event);
1564
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301565 /* we keep one module reference alive for
1566 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 if ((event != CPUFREQ_GOV_START) || ret)
1568 module_put(policy->governor->owner);
1569 if ((event == CPUFREQ_GOV_STOP) && !ret)
1570 module_put(policy->governor->owner);
1571
1572 return ret;
1573}
1574
1575
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576int cpufreq_register_governor(struct cpufreq_governor *governor)
1577{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001578 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
1580 if (!governor)
1581 return -EINVAL;
1582
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001583 if (cpufreq_disabled())
1584 return -ENODEV;
1585
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001586 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001587
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001588 err = -EBUSY;
1589 if (__find_governor(governor->name) == NULL) {
1590 err = 0;
1591 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593
Dave Jones32ee8c32006-02-28 00:43:23 -05001594 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001595 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596}
1597EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1598
1599
1600void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1601{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001602#ifdef CONFIG_HOTPLUG_CPU
1603 int cpu;
1604#endif
1605
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606 if (!governor)
1607 return;
1608
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001609 if (cpufreq_disabled())
1610 return;
1611
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001612#ifdef CONFIG_HOTPLUG_CPU
1613 for_each_present_cpu(cpu) {
1614 if (cpu_online(cpu))
1615 continue;
1616 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1617 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1618 }
1619#endif
1620
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001621 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001623 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 return;
1625}
1626EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1627
1628
1629
1630/*********************************************************************
1631 * POLICY INTERFACE *
1632 *********************************************************************/
1633
1634/**
1635 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001636 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1637 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 *
1639 * Reads the current cpufreq policy.
1640 */
1641int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1642{
1643 struct cpufreq_policy *cpu_policy;
1644 if (!policy)
1645 return -EINVAL;
1646
1647 cpu_policy = cpufreq_cpu_get(cpu);
1648 if (!cpu_policy)
1649 return -EINVAL;
1650
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652
1653 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 return 0;
1655}
1656EXPORT_SYMBOL(cpufreq_get_policy);
1657
1658
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001659/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301660 * data : current policy.
1661 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001662 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301663static int __cpufreq_set_policy(struct cpufreq_policy *data,
1664 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665{
1666 int ret = 0;
1667
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001668 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 policy->min, policy->max);
1670
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301671 memcpy(&policy->cpuinfo, &data->cpuinfo,
1672 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673
Yi Yang53391fa2008-01-30 13:33:34 +01001674 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001675 ret = -EINVAL;
1676 goto error_out;
1677 }
1678
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 /* verify the cpu speed can be set within this limit */
1680 ret = cpufreq_driver->verify(policy);
1681 if (ret)
1682 goto error_out;
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001685 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1686 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
1688 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001689 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1690 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
1692 /* verify the cpu speed can be set within this limit,
1693 which might be different to the first one */
1694 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001695 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
1698 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001699 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1700 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
Dave Jones7d5e3502006-02-02 17:03:42 -05001702 data->min = policy->min;
1703 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001705 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301706 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707
1708 if (cpufreq_driver->setpolicy) {
1709 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001710 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 ret = cpufreq_driver->setpolicy(policy);
1712 } else {
1713 if (policy->governor != data->governor) {
1714 /* save old, working values */
1715 struct cpufreq_governor *old_gov = data->governor;
1716
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001717 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718
1719 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001720 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1722
1723 /* start new governor */
1724 data->governor = policy->governor;
1725 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1726 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001727 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301728 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 if (old_gov) {
1730 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301731 __cpufreq_governor(data,
1732 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 }
1734 ret = -EINVAL;
1735 goto error_out;
1736 }
1737 /* might be a policy change, too, so fall through */
1738 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001739 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1741 }
1742
Dave Jones7d5e3502006-02-02 17:03:42 -05001743error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 return ret;
1745}
1746
1747/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1749 * @cpu: CPU which shall be re-evaluated
1750 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001751 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 * at different times.
1753 */
1754int cpufreq_update_policy(unsigned int cpu)
1755{
1756 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1757 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001758 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
Julia Lawallf1829e42008-07-25 22:44:53 +02001760 if (!data) {
1761 ret = -ENODEV;
1762 goto no_policy;
1763 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
Julia Lawallf1829e42008-07-25 22:44:53 +02001765 if (unlikely(lock_policy_rwsem_write(cpu))) {
1766 ret = -EINVAL;
1767 goto fail;
1768 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001770 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001771 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 policy.min = data->user_policy.min;
1773 policy.max = data->user_policy.max;
1774 policy.policy = data->user_policy.policy;
1775 policy.governor = data->user_policy.governor;
1776
Thomas Renninger0961dd02006-01-26 18:46:33 +01001777 /* BIOS might change freq behind our back
1778 -> ask driver for current freq and notify governors about a change */
1779 if (cpufreq_driver->get) {
1780 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001781 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001782 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001783 data->cur = policy.cur;
1784 } else {
1785 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301786 cpufreq_out_of_sync(cpu, data->cur,
1787 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001788 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001789 }
1790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 ret = __cpufreq_set_policy(data, &policy);
1792
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001793 unlock_policy_rwsem_write(cpu);
1794
Julia Lawallf1829e42008-07-25 22:44:53 +02001795fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001797no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 return ret;
1799}
1800EXPORT_SYMBOL(cpufreq_update_policy);
1801
Satyam Sharmadd184a02007-10-02 13:28:14 -07001802static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001803 unsigned long action, void *hcpu)
1804{
1805 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001806 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001807
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001808 dev = get_cpu_device(cpu);
1809 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001810 switch (action) {
1811 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001812 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001813 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001814 break;
1815 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001816 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001817 if (unlikely(lock_policy_rwsem_write(cpu)))
1818 BUG();
1819
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001820 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001821 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001822 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001823 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001824 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001825 break;
1826 }
1827 }
1828 return NOTIFY_OK;
1829}
1830
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001831static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001832 .notifier_call = cpufreq_cpu_callback,
1833};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835/*********************************************************************
1836 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1837 *********************************************************************/
1838
1839/**
1840 * cpufreq_register_driver - register a CPU Frequency driver
1841 * @driver_data: A struct cpufreq_driver containing the values#
1842 * submitted by the CPU Frequency driver.
1843 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001844 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001846 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 *
1848 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001849int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850{
1851 unsigned long flags;
1852 int ret;
1853
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001854 if (cpufreq_disabled())
1855 return -ENODEV;
1856
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 if (!driver_data || !driver_data->verify || !driver_data->init ||
1858 ((!driver_data->setpolicy) && (!driver_data->target)))
1859 return -EINVAL;
1860
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001861 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 if (driver_data->setpolicy)
1864 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1865
1866 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1867 if (cpufreq_driver) {
1868 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1869 return -EBUSY;
1870 }
1871 cpufreq_driver = driver_data;
1872 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1873
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001874 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001875 if (ret)
1876 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001878 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 int i;
1880 ret = -ENODEV;
1881
1882 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001883 for (i = 0; i < nr_cpu_ids; i++)
1884 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001886 break;
1887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
1889 /* if all ->init() calls failed, unregister */
1890 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001891 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301892 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001893 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 }
1895 }
1896
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001897 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001898 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001900 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001901err_if_unreg:
1902 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001903err_null_driver:
1904 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1905 cpufreq_driver = NULL;
1906 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001907 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908}
1909EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1910
1911
1912/**
1913 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1914 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001915 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 * the right to do so, i.e. if you have succeeded in initialising before!
1917 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1918 * currently not initialised.
1919 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001920int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921{
1922 unsigned long flags;
1923
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001924 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001927 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001929 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001930 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931
1932 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1933 cpufreq_driver = NULL;
1934 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1935
1936 return 0;
1937}
1938EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001939
1940static int __init cpufreq_core_init(void)
1941{
1942 int cpu;
1943
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001944 if (cpufreq_disabled())
1945 return -ENODEV;
1946
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001947 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001948 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001949 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1950 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001951
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001952 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001953 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001954 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001955
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001956 return 0;
1957}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001958core_initcall(cpufreq_core_init);