blob: 41d72c3aa2b26c5a86cf82b9d460571a6fbdc893 [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)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080079 \
80 return 0; \
81}
82
83lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080084
85lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080086
Amerigo Wang226528c2010-03-04 03:23:36 -050087static void unlock_policy_rwsem_read(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080088{
Tejun Heof1625062009-10-29 22:34:13 +090089 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090 BUG_ON(policy_cpu == -1);
91 up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
92}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Amerigo Wang226528c2010-03-04 03:23:36 -050094static void unlock_policy_rwsem_write(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080095{
Tejun Heof1625062009-10-29 22:34:13 +090096 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097 BUG_ON(policy_cpu == -1);
98 up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
99}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800100
101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500103static int __cpufreq_governor(struct cpufreq_policy *policy,
104 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800105static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000106static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
108/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500109 * Two notifier lists: the "policy" list is involved in the
110 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 * "transition" list for kernel code that needs to handle
112 * changes to devices when the CPU clock speed changes.
113 * The mutex locks both lists.
114 */
Alan Sterne041c682006-03-27 01:16:30 -0800115static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700116static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200118static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700119static int __init init_cpufreq_transition_notifier_list(void)
120{
121 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200122 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700123 return 0;
124}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800125pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400127static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200128static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400129{
130 return off;
131}
132void disable_cpufreq(void)
133{
134 off = 1;
135}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500137static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Stephen Boyda9144432012-07-20 18:14:38 +0000139static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140{
141 struct cpufreq_policy *data;
142 unsigned long flags;
143
Mike Travis7a6aedf2008-03-25 15:06:53 -0700144 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 goto err_out;
146
147 /* get the cpufreq driver */
148 spin_lock_irqsave(&cpufreq_driver_lock, flags);
149
150 if (!cpufreq_driver)
151 goto err_out_unlock;
152
153 if (!try_module_get(cpufreq_driver->owner))
154 goto err_out_unlock;
155
156
157 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700158 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159
160 if (!data)
161 goto err_out_put_module;
162
Stephen Boyda9144432012-07-20 18:14:38 +0000163 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 goto err_out_put_module;
165
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 return data;
168
Dave Jones7d5e3502006-02-02 17:03:42 -0500169err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500171err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500173err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 return NULL;
175}
Stephen Boyda9144432012-07-20 18:14:38 +0000176
177struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
178{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000179 if (cpufreq_disabled())
180 return NULL;
181
Stephen Boyda9144432012-07-20 18:14:38 +0000182 return __cpufreq_cpu_get(cpu, false);
183}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
185
Stephen Boyda9144432012-07-20 18:14:38 +0000186static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
187{
188 return __cpufreq_cpu_get(cpu, true);
189}
190
191static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
192{
193 if (!sysfs)
194 kobject_put(&data->kobj);
195 module_put(cpufreq_driver->owner);
196}
Dave Jones7d5e3502006-02-02 17:03:42 -0500197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198void cpufreq_cpu_put(struct cpufreq_policy *data)
199{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000200 if (cpufreq_disabled())
201 return;
202
Stephen Boyda9144432012-07-20 18:14:38 +0000203 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204}
205EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
206
Stephen Boyda9144432012-07-20 18:14:38 +0000207static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
208{
209 __cpufreq_cpu_put(data, true);
210}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
212/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
214 *********************************************************************/
215
216/**
217 * adjust_jiffies - adjust the system "loops_per_jiffy"
218 *
219 * This function alters the system "loops_per_jiffy" for the clock
220 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500221 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 * per-CPU loops_per_jiffy value wherever possible.
223 */
224#ifndef CONFIG_SMP
225static unsigned long l_p_j_ref;
226static unsigned int l_p_j_ref_freq;
227
Arjan van de Ven858119e2006-01-14 13:20:43 -0800228static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229{
230 if (ci->flags & CPUFREQ_CONST_LOOPS)
231 return;
232
233 if (!l_p_j_ref_freq) {
234 l_p_j_ref = loops_per_jiffy;
235 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200236 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530237 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530239 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700240 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530241 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
242 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200243 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530244 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 }
246}
247#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530248static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
249{
250 return;
251}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252#endif
253
254
255/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800256 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
257 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800259 * This function calls the transition notifiers and the "adjust_jiffies"
260 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500261 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 */
263void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
264{
Dave Jonese4472cb2006-01-31 15:53:55 -0800265 struct cpufreq_policy *policy;
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 BUG_ON(irqs_disabled());
268
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000269 if (cpufreq_disabled())
270 return;
271
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200273 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800274 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275
Mike Travis7a6aedf2008-03-25 15:06:53 -0700276 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500280 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800281 * which is not equal to what the cpufreq core thinks is
282 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 */
284 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800285 if ((policy) && (policy->cpu == freqs->cpu) &&
286 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200287 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800288 " %u, cpufreq assumed %u kHz.\n",
289 freqs->old, policy->cur);
290 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 }
292 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700293 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800294 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
296 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800297
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 case CPUFREQ_POSTCHANGE:
299 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200300 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200301 (unsigned long)freqs->cpu);
302 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100303 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700304 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800305 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800306 if (likely(policy) && likely(policy->cpu == freqs->cpu))
307 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 break;
309 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310}
311EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
312
313
314
315/*********************************************************************
316 * SYSFS INTERFACE *
317 *********************************************************************/
318
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700319static struct cpufreq_governor *__find_governor(const char *str_governor)
320{
321 struct cpufreq_governor *t;
322
323 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500324 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700325 return t;
326
327 return NULL;
328}
329
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330/**
331 * cpufreq_parse_governor - parse a governor string
332 */
Dave Jones905d77c2008-03-05 14:28:32 -0500333static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 struct cpufreq_governor **governor)
335{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700336 int err = -EINVAL;
337
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700339 goto out;
340
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 if (cpufreq_driver->setpolicy) {
342 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
343 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700344 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530345 } else if (!strnicmp(str_governor, "powersave",
346 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700348 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700350 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700352
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800353 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700354
355 t = __find_governor(str_governor);
356
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700357 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700358 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700359
Kees Cook1a8e1462011-05-04 08:38:56 -0700360 mutex_unlock(&cpufreq_governor_mutex);
361 ret = request_module("cpufreq_%s", str_governor);
362 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700363
Kees Cook1a8e1462011-05-04 08:38:56 -0700364 if (ret == 0)
365 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700366 }
367
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700368 if (t != NULL) {
369 *governor = t;
370 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700372
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800373 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 }
Dave Jones29464f22009-01-18 01:37:11 -0500375out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700376 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
379
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530381 * cpufreq_per_cpu_attr_read() / show_##file_name() -
382 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 *
384 * Write out information from cpufreq_driver->policy[cpu]; object must be
385 * "unsigned int".
386 */
387
Dave Jones32ee8c32006-02-28 00:43:23 -0500388#define show_one(file_name, object) \
389static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500390(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500391{ \
Dave Jones29464f22009-01-18 01:37:11 -0500392 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393}
394
395show_one(cpuinfo_min_freq, cpuinfo.min_freq);
396show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100397show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398show_one(scaling_min_freq, min);
399show_one(scaling_max_freq, max);
400show_one(scaling_cur_freq, cur);
401
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530402static int __cpufreq_set_policy(struct cpufreq_policy *data,
403 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405/**
406 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
407 */
408#define store_one(file_name, object) \
409static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500410(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000412 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 struct cpufreq_policy new_policy; \
414 \
415 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
416 if (ret) \
417 return -EINVAL; \
418 \
Dave Jones29464f22009-01-18 01:37:11 -0500419 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 if (ret != 1) \
421 return -EINVAL; \
422 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200423 ret = __cpufreq_set_policy(policy, &new_policy); \
424 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 \
426 return ret ? ret : count; \
427}
428
Dave Jones29464f22009-01-18 01:37:11 -0500429store_one(scaling_min_freq, min);
430store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431
432/**
433 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
434 */
Dave Jones905d77c2008-03-05 14:28:32 -0500435static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
436 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800438 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 if (!cur_freq)
440 return sprintf(buf, "<unknown>");
441 return sprintf(buf, "%u\n", cur_freq);
442}
443
444
445/**
446 * show_scaling_governor - show the current policy for the specified CPU
447 */
Dave Jones905d77c2008-03-05 14:28:32 -0500448static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449{
Dave Jones29464f22009-01-18 01:37:11 -0500450 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 return sprintf(buf, "powersave\n");
452 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
453 return sprintf(buf, "performance\n");
454 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200455 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500456 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 return -EINVAL;
458}
459
460
461/**
462 * store_scaling_governor - store policy for the specified CPU
463 */
Dave Jones905d77c2008-03-05 14:28:32 -0500464static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
465 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000467 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 char str_governor[16];
469 struct cpufreq_policy new_policy;
470
471 ret = cpufreq_get_policy(&new_policy, policy->cpu);
472 if (ret)
473 return ret;
474
Dave Jones29464f22009-01-18 01:37:11 -0500475 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 if (ret != 1)
477 return -EINVAL;
478
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530479 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
480 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 return -EINVAL;
482
Thomas Renninger7970e082006-04-13 15:14:04 +0200483 /* Do not use cpufreq_set_policy here or the user_policy.max
484 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200485 ret = __cpufreq_set_policy(policy, &new_policy);
486
487 policy->user_policy.policy = policy->policy;
488 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200489
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530490 if (ret)
491 return ret;
492 else
493 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494}
495
496/**
497 * show_scaling_driver - show the cpufreq driver currently loaded
498 */
Dave Jones905d77c2008-03-05 14:28:32 -0500499static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500{
viresh kumar4b972f02012-10-23 01:23:43 +0200501 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502}
503
504/**
505 * show_scaling_available_governors - show the available CPUfreq governors
506 */
Dave Jones905d77c2008-03-05 14:28:32 -0500507static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
508 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509{
510 ssize_t i = 0;
511 struct cpufreq_governor *t;
512
513 if (!cpufreq_driver->target) {
514 i += sprintf(buf, "performance powersave");
515 goto out;
516 }
517
518 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500519 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
520 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200522 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500524out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 i += sprintf(&buf[i], "\n");
526 return i;
527}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700528
Rusty Russell835481d2009-01-04 05:18:06 -0800529static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530{
531 ssize_t i = 0;
532 unsigned int cpu;
533
Rusty Russell835481d2009-01-04 05:18:06 -0800534 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 if (i)
536 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
537 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
538 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500539 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 }
541 i += sprintf(&buf[i], "\n");
542 return i;
543}
544
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700545/**
546 * show_related_cpus - show the CPUs affected by each transition even if
547 * hw coordination is in use
548 */
549static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
550{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700551 return show_cpus(policy->related_cpus, buf);
552}
553
554/**
555 * show_affected_cpus - show the CPUs affected by each transition
556 */
557static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
558{
559 return show_cpus(policy->cpus, buf);
560}
561
Venki Pallipadi9e769882007-10-26 10:18:21 -0700562static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500563 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700564{
565 unsigned int freq = 0;
566 unsigned int ret;
567
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700568 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700569 return -EINVAL;
570
571 ret = sscanf(buf, "%u", &freq);
572 if (ret != 1)
573 return -EINVAL;
574
575 policy->governor->store_setspeed(policy, freq);
576
577 return count;
578}
579
580static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
581{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700582 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700583 return sprintf(buf, "<unsupported>\n");
584
585 return policy->governor->show_setspeed(policy, buf);
586}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587
Thomas Renningere2f74f32009-11-19 12:31:01 +0100588/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200589 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100590 */
591static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
592{
593 unsigned int limit;
594 int ret;
595 if (cpufreq_driver->bios_limit) {
596 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
597 if (!ret)
598 return sprintf(buf, "%u\n", limit);
599 }
600 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
601}
602
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200603cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
604cpufreq_freq_attr_ro(cpuinfo_min_freq);
605cpufreq_freq_attr_ro(cpuinfo_max_freq);
606cpufreq_freq_attr_ro(cpuinfo_transition_latency);
607cpufreq_freq_attr_ro(scaling_available_governors);
608cpufreq_freq_attr_ro(scaling_driver);
609cpufreq_freq_attr_ro(scaling_cur_freq);
610cpufreq_freq_attr_ro(bios_limit);
611cpufreq_freq_attr_ro(related_cpus);
612cpufreq_freq_attr_ro(affected_cpus);
613cpufreq_freq_attr_rw(scaling_min_freq);
614cpufreq_freq_attr_rw(scaling_max_freq);
615cpufreq_freq_attr_rw(scaling_governor);
616cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
Dave Jones905d77c2008-03-05 14:28:32 -0500618static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 &cpuinfo_min_freq.attr,
620 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100621 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 &scaling_min_freq.attr,
623 &scaling_max_freq.attr,
624 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700625 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 &scaling_governor.attr,
627 &scaling_driver.attr,
628 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700629 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 NULL
631};
632
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200633struct kobject *cpufreq_global_kobject;
634EXPORT_SYMBOL(cpufreq_global_kobject);
635
Dave Jones29464f22009-01-18 01:37:11 -0500636#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
637#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638
Dave Jones29464f22009-01-18 01:37:11 -0500639static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640{
Dave Jones905d77c2008-03-05 14:28:32 -0500641 struct cpufreq_policy *policy = to_policy(kobj);
642 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500643 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000644 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500646 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800647
648 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500649 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800650
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530651 if (fattr->show)
652 ret = fattr->show(policy, buf);
653 else
654 ret = -EIO;
655
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800656 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500657fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000658 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500659no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 return ret;
661}
662
Dave Jones905d77c2008-03-05 14:28:32 -0500663static ssize_t store(struct kobject *kobj, struct attribute *attr,
664 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665{
Dave Jones905d77c2008-03-05 14:28:32 -0500666 struct cpufreq_policy *policy = to_policy(kobj);
667 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500668 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000669 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500671 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800672
673 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500674 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800675
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530676 if (fattr->store)
677 ret = fattr->store(policy, buf, count);
678 else
679 ret = -EIO;
680
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800681 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500682fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000683 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500684no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 return ret;
686}
687
Dave Jones905d77c2008-03-05 14:28:32 -0500688static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689{
Dave Jones905d77c2008-03-05 14:28:32 -0500690 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200691 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 complete(&policy->kobj_unregister);
693}
694
Emese Revfy52cf25d2010-01-19 02:58:23 +0100695static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 .show = show,
697 .store = store,
698};
699
700static struct kobj_type ktype_cpufreq = {
701 .sysfs_ops = &sysfs_ops,
702 .default_attrs = default_attrs,
703 .release = cpufreq_sysfs_release,
704};
705
Dave Jones19d6f7e2009-07-08 17:35:39 -0400706/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700707static int cpufreq_add_dev_symlink(unsigned int cpu,
708 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400709{
710 unsigned int j;
711 int ret = 0;
712
713 for_each_cpu(j, policy->cpus) {
714 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800715 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400716
717 if (j == cpu)
718 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400719
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200720 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400721 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800722 cpu_dev = get_cpu_device(j);
723 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400724 "cpufreq");
725 if (ret) {
726 cpufreq_cpu_put(managed_policy);
727 return ret;
728 }
729 }
730 return ret;
731}
732
Alex Chiangcf3289d02009-11-17 20:27:08 -0700733static int cpufreq_add_dev_interface(unsigned int cpu,
734 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800735 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400736{
Dave Jonesecf7e462009-07-08 18:48:47 -0400737 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400738 struct freq_attr **drv_attr;
739 unsigned long flags;
740 int ret = 0;
741 unsigned int j;
742
743 /* prepare interface data */
744 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800745 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400746 if (ret)
747 return ret;
748
749 /* set up files for this cpu device */
750 drv_attr = cpufreq_driver->attr;
751 while ((drv_attr) && (*drv_attr)) {
752 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
753 if (ret)
754 goto err_out_kobj_put;
755 drv_attr++;
756 }
757 if (cpufreq_driver->get) {
758 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
759 if (ret)
760 goto err_out_kobj_put;
761 }
762 if (cpufreq_driver->target) {
763 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
764 if (ret)
765 goto err_out_kobj_put;
766 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100767 if (cpufreq_driver->bios_limit) {
768 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
769 if (ret)
770 goto err_out_kobj_put;
771 }
Dave Jones909a6942009-07-08 18:05:42 -0400772
773 spin_lock_irqsave(&cpufreq_driver_lock, flags);
774 for_each_cpu(j, policy->cpus) {
Dave Jones909a6942009-07-08 18:05:42 -0400775 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900776 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400777 }
778 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
779
780 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400781 if (ret)
782 goto err_out_kobj_put;
783
784 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
785 /* assure that the starting sequence is run in __cpufreq_set_policy */
786 policy->governor = NULL;
787
788 /* set default policy */
789 ret = __cpufreq_set_policy(policy, &new_policy);
790 policy->user_policy.policy = policy->policy;
791 policy->user_policy.governor = policy->governor;
792
793 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200794 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400795 if (cpufreq_driver->exit)
796 cpufreq_driver->exit(policy);
797 }
Dave Jones909a6942009-07-08 18:05:42 -0400798 return ret;
799
800err_out_kobj_put:
801 kobject_put(&policy->kobj);
802 wait_for_completion(&policy->kobj_unregister);
803 return ret;
804}
805
Viresh Kumarfcf80582013-01-29 14:39:08 +0000806#ifdef CONFIG_HOTPLUG_CPU
807static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
808 struct device *dev)
809{
810 struct cpufreq_policy *policy;
811 int ret = 0;
812 unsigned long flags;
813
814 policy = cpufreq_cpu_get(sibling);
815 WARN_ON(!policy);
816
817 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
818
819 lock_policy_rwsem_write(cpu);
820
821 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
822
823 spin_lock_irqsave(&cpufreq_driver_lock, flags);
824 cpumask_set_cpu(cpu, policy->cpus);
825 per_cpu(cpufreq_cpu_data, cpu) = policy;
826 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
827
828 __cpufreq_governor(policy, CPUFREQ_GOV_START);
829 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
830
831 unlock_policy_rwsem_write(cpu);
832
833 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
834 if (ret) {
835 cpufreq_cpu_put(policy);
836 return ret;
837 }
838
839 return 0;
840}
841#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
843/**
844 * cpufreq_add_dev - add a CPU device
845 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500846 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400847 *
848 * The Oracle says: try running cpufreq registration/unregistration concurrently
849 * with with cpu hotplugging and all hell will break loose. Tried to clean this
850 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800852static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000854 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530855 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500858#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000859 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500860 int sibling;
861#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862
Ashok Rajc32b6b82005-10-30 14:59:54 -0800863 if (cpu_is_offline(cpu))
864 return 0;
865
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200866 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867
868#ifdef CONFIG_SMP
869 /* check whether a different CPU already registered this
870 * CPU because it is in the same boat. */
871 policy = cpufreq_cpu_get(cpu);
872 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500873 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 return 0;
875 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000876
877#ifdef CONFIG_HOTPLUG_CPU
878 /* Check if this cpu was hot-unplugged earlier and has siblings */
879 for_each_online_cpu(sibling) {
880 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
881 if (cp && cpumask_test_cpu(cpu, cp->related_cpus))
882 return cpufreq_add_policy_cpu(cpu, sibling, dev);
883 }
884#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885#endif
886
887 if (!try_module_get(cpufreq_driver->owner)) {
888 ret = -EINVAL;
889 goto module_out;
890 }
891
Dave Jonese98df502005-10-20 15:17:43 -0700892 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400893 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400895
896 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400897 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400898
899 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400900 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901
902 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +0530903 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -0800904 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800906 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900907 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400908 ret = (lock_policy_rwsem_write(cpu) < 0);
909 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800910
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000912 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913
914 /* call driver. From then on the cpufreq must be able
915 * to accept all calls to ->verify and ->setpolicy for this CPU
916 */
917 ret = cpufreq_driver->init(policy);
918 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200919 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400920 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000922
Viresh Kumarfcf80582013-01-29 14:39:08 +0000923 /* related cpus should atleast have policy->cpus */
924 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
925
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000926 /*
927 * affected cpus must always be the one, which are online. We aren't
928 * managing offline cpus here.
929 */
930 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
931
Mike Chan187d9f42008-12-04 12:19:17 -0800932 policy->user_policy.min = policy->min;
933 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
Thomas Renningera1531ac2008-07-29 22:32:58 -0700935 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
936 CPUFREQ_START, policy);
937
Viresh Kumarfcf80582013-01-29 14:39:08 +0000938#ifdef CONFIG_HOTPLUG_CPU
939 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
940 if (gov) {
941 policy->governor = gov;
942 pr_debug("Restoring governor %s for cpu %d\n",
943 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200944 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000945#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800947 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400948 if (ret)
949 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500950
Lothar Waßmanndca02612008-05-29 17:54:52 +0200951 unlock_policy_rwsem_write(cpu);
952
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400953 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200955 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500956
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957 return 0;
958
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959err_out_unregister:
960 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -0800961 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -0700962 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
964
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -0800965 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 wait_for_completion(&policy->kobj_unregister);
967
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400968err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -0500969 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +0800970 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400971err_free_cpumask:
972 free_cpumask_var(policy->cpus);
973err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975nomem_out:
976 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -0800977module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 return ret;
979}
980
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000981static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
982{
983 int j;
984
985 policy->last_cpu = policy->cpu;
986 policy->cpu = cpu;
987
Viresh Kumar3361b7b2013-02-04 11:38:51 +0000988 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000989 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000990
991#ifdef CONFIG_CPU_FREQ_TABLE
992 cpufreq_frequency_table_update_policy_cpu(policy);
993#endif
994 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
995 CPUFREQ_UPDATE_POLICY_CPU, policy);
996}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
998/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800999 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 *
1001 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001002 * Caller should already have policy_rwsem in write mode for this CPU.
1003 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001005static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001007 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 unsigned long flags;
1009 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001010 struct kobject *kobj;
1011 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001012 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001014 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001017 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001020 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001022 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 return -EINVAL;
1024 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001026 if (cpufreq_driver->target)
Viresh Kumarf6a74092013-01-12 05:14:39 +00001027 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Thomas Renninger084f3492007-07-09 11:35:28 -07001028
1029#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001030 strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
1031 CPUFREQ_NAME_LEN);
Thomas Renninger084f3492007-07-09 11:35:28 -07001032#endif
1033
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001034 per_cpu(cpufreq_cpu_data, cpu) = NULL;
1035 cpus = cpumask_weight(data->cpus);
1036 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001038 if (cpu != data->cpu) {
1039 sysfs_remove_link(&dev->kobj, "cpufreq");
1040 } else if (cpus > 1) {
Jacob Shin27ecddc2011-04-27 13:32:11 -05001041 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001042 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1043 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1044 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1045 if (ret) {
1046 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1047 cpumask_set_cpu(cpu, data->cpus);
1048 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1049 "cpufreq");
1050 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1051 unlock_policy_rwsem_write(cpu);
1052 return -EINVAL;
1053 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001054
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001055 update_policy_cpu(data, cpu_dev->id);
1056 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1057 __func__, cpu_dev->id, cpu);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001058 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001059
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001060 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1061
1062 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1063 cpufreq_cpu_put(data);
1064 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001065
1066 /* If cpu is last user of policy, free policy */
1067 if (cpus == 1) {
1068 lock_policy_rwsem_write(cpu);
1069 kobj = &data->kobj;
1070 cmp = &data->kobj_unregister;
1071 unlock_policy_rwsem_write(cpu);
1072 kobject_put(kobj);
1073
1074 /* we need to make sure that the underlying kobj is actually
1075 * not referenced anymore by anybody before we proceed with
1076 * unloading.
1077 */
1078 pr_debug("waiting for dropping of refcount\n");
1079 wait_for_completion(cmp);
1080 pr_debug("wait complete\n");
1081
1082 lock_policy_rwsem_write(cpu);
1083 if (cpufreq_driver->exit)
1084 cpufreq_driver->exit(data);
1085 unlock_policy_rwsem_write(cpu);
1086
1087 free_cpumask_var(data->related_cpus);
1088 free_cpumask_var(data->cpus);
1089 kfree(data);
1090 } else if (cpufreq_driver->target) {
1091 __cpufreq_governor(data, CPUFREQ_GOV_START);
1092 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1093 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 return 0;
1096}
1097
1098
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001099static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001100{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001101 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001102 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001103
1104 if (cpu_is_offline(cpu))
1105 return 0;
1106
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001107 if (unlikely(lock_policy_rwsem_write(cpu)))
1108 BUG();
1109
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001110 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001111 return retval;
1112}
1113
1114
David Howells65f27f32006-11-22 14:55:48 +00001115static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116{
David Howells65f27f32006-11-22 14:55:48 +00001117 struct cpufreq_policy *policy =
1118 container_of(work, struct cpufreq_policy, update);
1119 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001120 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 cpufreq_update_policy(cpu);
1122}
1123
1124/**
1125 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1126 * @cpu: cpu number
1127 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1128 * @new_freq: CPU frequency the CPU actually runs at
1129 *
Dave Jones29464f22009-01-18 01:37:11 -05001130 * We adjust to current frequency first, and need to clean up later.
1131 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301133static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1134 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135{
1136 struct cpufreq_freqs freqs;
1137
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001138 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1140
1141 freqs.cpu = cpu;
1142 freqs.old = old_freq;
1143 freqs.new = new_freq;
1144 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1145 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1146}
1147
1148
Dave Jones32ee8c32006-02-28 00:43:23 -05001149/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301150 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001151 * @cpu: CPU number
1152 *
1153 * This is the last known freq, without actually getting it from the driver.
1154 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1155 */
1156unsigned int cpufreq_quick_get(unsigned int cpu)
1157{
1158 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301159 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001160
1161 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301162 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001163 cpufreq_cpu_put(policy);
1164 }
1165
Dave Jones4d34a672008-02-07 16:33:49 -05001166 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001167}
1168EXPORT_SYMBOL(cpufreq_quick_get);
1169
Jesse Barnes3d737102011-06-28 10:59:12 -07001170/**
1171 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1172 * @cpu: CPU number
1173 *
1174 * Just return the max possible frequency for a given CPU.
1175 */
1176unsigned int cpufreq_quick_get_max(unsigned int cpu)
1177{
1178 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1179 unsigned int ret_freq = 0;
1180
1181 if (policy) {
1182 ret_freq = policy->max;
1183 cpufreq_cpu_put(policy);
1184 }
1185
1186 return ret_freq;
1187}
1188EXPORT_SYMBOL(cpufreq_quick_get_max);
1189
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001190
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001191static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001193 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301194 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001197 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301199 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301201 if (ret_freq && policy->cur &&
1202 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1203 /* verify no discrepancy between actual and
1204 saved value exists */
1205 if (unlikely(ret_freq != policy->cur)) {
1206 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 schedule_work(&policy->update);
1208 }
1209 }
1210
Dave Jones4d34a672008-02-07 16:33:49 -05001211 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001212}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001214/**
1215 * cpufreq_get - get the current CPU frequency (in kHz)
1216 * @cpu: CPU number
1217 *
1218 * Get the CPU current (static) CPU frequency
1219 */
1220unsigned int cpufreq_get(unsigned int cpu)
1221{
1222 unsigned int ret_freq = 0;
1223 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1224
1225 if (!policy)
1226 goto out;
1227
1228 if (unlikely(lock_policy_rwsem_read(cpu)))
1229 goto out_policy;
1230
1231 ret_freq = __cpufreq_get(cpu);
1232
1233 unlock_policy_rwsem_read(cpu);
1234
1235out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001237out:
Dave Jones4d34a672008-02-07 16:33:49 -05001238 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239}
1240EXPORT_SYMBOL(cpufreq_get);
1241
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001242static struct subsys_interface cpufreq_interface = {
1243 .name = "cpufreq",
1244 .subsys = &cpu_subsys,
1245 .add_dev = cpufreq_add_dev,
1246 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001247};
1248
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
1250/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001251 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1252 *
1253 * This function is only executed for the boot processor. The other CPUs
1254 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001255 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001256static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001257{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301258 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001259
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001260 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001261 struct cpufreq_policy *cpu_policy;
1262
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001263 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001264
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001265 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001266 cpu_policy = cpufreq_cpu_get(cpu);
1267 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001268 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001269
1270 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001271 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001272 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001273 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1274 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001275 }
1276
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001277 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001278 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001279}
1280
1281/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001282 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 *
1284 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001285 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1286 * restored. It will verify that the current freq is in sync with
1287 * what we believe it to be. This is a bit later than when it
1288 * should be, but nonethteless it's better than calling
1289 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001290 *
1291 * This function is only executed for the boot CPU. The other CPUs have not
1292 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001294static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301296 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001297
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001298 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 struct cpufreq_policy *cpu_policy;
1300
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001301 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001303 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 cpu_policy = cpufreq_cpu_get(cpu);
1305 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001306 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
1308 if (cpufreq_driver->resume) {
1309 ret = cpufreq_driver->resume(cpu_policy);
1310 if (ret) {
1311 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1312 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001313 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 }
1315 }
1316
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001318
Dave Jonesc9060492008-02-07 16:32:18 -05001319fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321}
1322
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001323static struct syscore_ops cpufreq_syscore_ops = {
1324 .suspend = cpufreq_bp_suspend,
1325 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326};
1327
Borislav Petkov9d950462013-01-20 10:24:28 +00001328/**
1329 * cpufreq_get_current_driver - return current driver's name
1330 *
1331 * Return the name string of the currently loaded cpufreq driver
1332 * or NULL, if none.
1333 */
1334const char *cpufreq_get_current_driver(void)
1335{
1336 if (cpufreq_driver)
1337 return cpufreq_driver->name;
1338
1339 return NULL;
1340}
1341EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
1343/*********************************************************************
1344 * NOTIFIER LISTS INTERFACE *
1345 *********************************************************************/
1346
1347/**
1348 * cpufreq_register_notifier - register a driver with cpufreq
1349 * @nb: notifier function to register
1350 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1351 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001352 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 * are notified about clock rate changes (once before and once after
1354 * the transition), or a list of drivers that are notified about
1355 * changes in cpufreq policy.
1356 *
1357 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001358 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 */
1360int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1361{
1362 int ret;
1363
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001364 if (cpufreq_disabled())
1365 return -EINVAL;
1366
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001367 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1368
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 switch (list) {
1370 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001371 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001372 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373 break;
1374 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001375 ret = blocking_notifier_chain_register(
1376 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 break;
1378 default:
1379 ret = -EINVAL;
1380 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
1382 return ret;
1383}
1384EXPORT_SYMBOL(cpufreq_register_notifier);
1385
1386
1387/**
1388 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1389 * @nb: notifier block to be unregistered
1390 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1391 *
1392 * Remove a driver from the CPU frequency notifier list.
1393 *
1394 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001395 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 */
1397int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1398{
1399 int ret;
1400
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001401 if (cpufreq_disabled())
1402 return -EINVAL;
1403
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 switch (list) {
1405 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001406 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001407 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 break;
1409 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001410 ret = blocking_notifier_chain_unregister(
1411 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 break;
1413 default:
1414 ret = -EINVAL;
1415 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 return ret;
1418}
1419EXPORT_SYMBOL(cpufreq_unregister_notifier);
1420
1421
1422/*********************************************************************
1423 * GOVERNORS *
1424 *********************************************************************/
1425
1426
1427int __cpufreq_driver_target(struct cpufreq_policy *policy,
1428 unsigned int target_freq,
1429 unsigned int relation)
1430{
1431 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001432 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001433
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001434 if (cpufreq_disabled())
1435 return -ENODEV;
1436
Viresh Kumar72499242012-10-31 01:28:21 +01001437 /* Make sure that target_freq is within supported range */
1438 if (target_freq > policy->max)
1439 target_freq = policy->max;
1440 if (target_freq < policy->min)
1441 target_freq = policy->min;
1442
1443 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1444 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001445
1446 if (target_freq == policy->cur)
1447 return 0;
1448
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001449 if (cpufreq_driver->target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001451
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 return retval;
1453}
1454EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1455
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456int cpufreq_driver_target(struct cpufreq_policy *policy,
1457 unsigned int target_freq,
1458 unsigned int relation)
1459{
Julia Lawallf1829e42008-07-25 22:44:53 +02001460 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461
1462 policy = cpufreq_cpu_get(policy->cpu);
1463 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001464 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001466 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001467 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
1469 ret = __cpufreq_driver_target(policy, target_freq, relation);
1470
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001471 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
Julia Lawallf1829e42008-07-25 22:44:53 +02001473fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001475no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 return ret;
1477}
1478EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1479
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001480int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001481{
1482 int ret = 0;
1483
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001484 if (cpufreq_disabled())
1485 return ret;
1486
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001487 if (!cpufreq_driver->getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001488 return 0;
1489
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001490 policy = cpufreq_cpu_get(policy->cpu);
1491 if (!policy)
1492 return -EINVAL;
1493
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001494 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001495
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001496 cpufreq_cpu_put(policy);
1497 return ret;
1498}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001499EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001500
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001501/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001502 * when "event" is CPUFREQ_GOV_LIMITS
1503 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301505static int __cpufreq_governor(struct cpufreq_policy *policy,
1506 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507{
Dave Jonescc993ca2005-07-28 09:43:56 -07001508 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001509
1510 /* Only must be defined when default governor is known to have latency
1511 restrictions, like e.g. conservative or ondemand.
1512 That this is the case is already ensured in Kconfig
1513 */
1514#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1515 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1516#else
1517 struct cpufreq_governor *gov = NULL;
1518#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001519
1520 if (policy->governor->max_transition_latency &&
1521 policy->cpuinfo.transition_latency >
1522 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001523 if (!gov)
1524 return -EINVAL;
1525 else {
1526 printk(KERN_WARNING "%s governor failed, too long"
1527 " transition latency of HW, fallback"
1528 " to %s governor\n",
1529 policy->governor->name,
1530 gov->name);
1531 policy->governor = gov;
1532 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001533 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
1535 if (!try_module_get(policy->governor->owner))
1536 return -EINVAL;
1537
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001538 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301539 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 ret = policy->governor->governor(policy, event);
1541
Viresh Kumar8e536952013-02-07 12:51:27 +05301542 if (event == CPUFREQ_GOV_START)
1543 policy->governor->initialized++;
1544 else if (event == CPUFREQ_GOV_STOP)
1545 policy->governor->initialized--;
Viresh Kumarb3940582013-02-01 05:42:58 +00001546
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301547 /* we keep one module reference alive for
1548 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 if ((event != CPUFREQ_GOV_START) || ret)
1550 module_put(policy->governor->owner);
1551 if ((event == CPUFREQ_GOV_STOP) && !ret)
1552 module_put(policy->governor->owner);
1553
1554 return ret;
1555}
1556
1557
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558int cpufreq_register_governor(struct cpufreq_governor *governor)
1559{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001560 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561
1562 if (!governor)
1563 return -EINVAL;
1564
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001565 if (cpufreq_disabled())
1566 return -ENODEV;
1567
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001568 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001569
Viresh Kumarb3940582013-02-01 05:42:58 +00001570 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001571 err = -EBUSY;
1572 if (__find_governor(governor->name) == NULL) {
1573 err = 0;
1574 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
Dave Jones32ee8c32006-02-28 00:43:23 -05001577 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001578 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579}
1580EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1581
1582
1583void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1584{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001585#ifdef CONFIG_HOTPLUG_CPU
1586 int cpu;
1587#endif
1588
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 if (!governor)
1590 return;
1591
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001592 if (cpufreq_disabled())
1593 return;
1594
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001595#ifdef CONFIG_HOTPLUG_CPU
1596 for_each_present_cpu(cpu) {
1597 if (cpu_online(cpu))
1598 continue;
1599 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1600 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1601 }
1602#endif
1603
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001604 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001606 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 return;
1608}
1609EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1610
1611
1612
1613/*********************************************************************
1614 * POLICY INTERFACE *
1615 *********************************************************************/
1616
1617/**
1618 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001619 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1620 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621 *
1622 * Reads the current cpufreq policy.
1623 */
1624int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1625{
1626 struct cpufreq_policy *cpu_policy;
1627 if (!policy)
1628 return -EINVAL;
1629
1630 cpu_policy = cpufreq_cpu_get(cpu);
1631 if (!cpu_policy)
1632 return -EINVAL;
1633
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635
1636 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 return 0;
1638}
1639EXPORT_SYMBOL(cpufreq_get_policy);
1640
1641
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001642/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301643 * data : current policy.
1644 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001645 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301646static int __cpufreq_set_policy(struct cpufreq_policy *data,
1647 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648{
1649 int ret = 0;
1650
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001651 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 policy->min, policy->max);
1653
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301654 memcpy(&policy->cpuinfo, &data->cpuinfo,
1655 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
Yi Yang53391fa2008-01-30 13:33:34 +01001657 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001658 ret = -EINVAL;
1659 goto error_out;
1660 }
1661
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 /* verify the cpu speed can be set within this limit */
1663 ret = cpufreq_driver->verify(policy);
1664 if (ret)
1665 goto error_out;
1666
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001668 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1669 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670
1671 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001672 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1673 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
1675 /* verify the cpu speed can be set within this limit,
1676 which might be different to the first one */
1677 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001678 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
1681 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001682 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1683 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Dave Jones7d5e3502006-02-02 17:03:42 -05001685 data->min = policy->min;
1686 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001688 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301689 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
1691 if (cpufreq_driver->setpolicy) {
1692 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001693 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 ret = cpufreq_driver->setpolicy(policy);
1695 } else {
1696 if (policy->governor != data->governor) {
1697 /* save old, working values */
1698 struct cpufreq_governor *old_gov = data->governor;
1699
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001700 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001703 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1705
1706 /* start new governor */
1707 data->governor = policy->governor;
1708 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1709 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001710 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301711 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 if (old_gov) {
1713 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301714 __cpufreq_governor(data,
1715 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 }
1717 ret = -EINVAL;
1718 goto error_out;
1719 }
1720 /* might be a policy change, too, so fall through */
1721 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001722 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1724 }
1725
Dave Jones7d5e3502006-02-02 17:03:42 -05001726error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 return ret;
1728}
1729
1730/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1732 * @cpu: CPU which shall be re-evaluated
1733 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001734 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 * at different times.
1736 */
1737int cpufreq_update_policy(unsigned int cpu)
1738{
1739 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1740 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001741 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742
Julia Lawallf1829e42008-07-25 22:44:53 +02001743 if (!data) {
1744 ret = -ENODEV;
1745 goto no_policy;
1746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
Julia Lawallf1829e42008-07-25 22:44:53 +02001748 if (unlikely(lock_policy_rwsem_write(cpu))) {
1749 ret = -EINVAL;
1750 goto fail;
1751 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001753 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001754 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 policy.min = data->user_policy.min;
1756 policy.max = data->user_policy.max;
1757 policy.policy = data->user_policy.policy;
1758 policy.governor = data->user_policy.governor;
1759
Thomas Renninger0961dd02006-01-26 18:46:33 +01001760 /* BIOS might change freq behind our back
1761 -> ask driver for current freq and notify governors about a change */
1762 if (cpufreq_driver->get) {
1763 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001764 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001765 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001766 data->cur = policy.cur;
1767 } else {
1768 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301769 cpufreq_out_of_sync(cpu, data->cur,
1770 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001771 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001772 }
1773
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 ret = __cpufreq_set_policy(data, &policy);
1775
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001776 unlock_policy_rwsem_write(cpu);
1777
Julia Lawallf1829e42008-07-25 22:44:53 +02001778fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001780no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 return ret;
1782}
1783EXPORT_SYMBOL(cpufreq_update_policy);
1784
Satyam Sharmadd184a02007-10-02 13:28:14 -07001785static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001786 unsigned long action, void *hcpu)
1787{
1788 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001789 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001790
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001791 dev = get_cpu_device(cpu);
1792 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001793 switch (action) {
1794 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001795 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001796 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001797 break;
1798 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001799 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001800 if (unlikely(lock_policy_rwsem_write(cpu)))
1801 BUG();
1802
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001803 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001804 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001805 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001806 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001807 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001808 break;
1809 }
1810 }
1811 return NOTIFY_OK;
1812}
1813
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001814static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001815 .notifier_call = cpufreq_cpu_callback,
1816};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
1818/*********************************************************************
1819 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1820 *********************************************************************/
1821
1822/**
1823 * cpufreq_register_driver - register a CPU Frequency driver
1824 * @driver_data: A struct cpufreq_driver containing the values#
1825 * submitted by the CPU Frequency driver.
1826 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001827 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001829 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 *
1831 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001832int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833{
1834 unsigned long flags;
1835 int ret;
1836
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001837 if (cpufreq_disabled())
1838 return -ENODEV;
1839
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 if (!driver_data || !driver_data->verify || !driver_data->init ||
1841 ((!driver_data->setpolicy) && (!driver_data->target)))
1842 return -EINVAL;
1843
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001844 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
1846 if (driver_data->setpolicy)
1847 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1848
1849 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1850 if (cpufreq_driver) {
1851 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1852 return -EBUSY;
1853 }
1854 cpufreq_driver = driver_data;
1855 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1856
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001857 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001858 if (ret)
1859 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001861 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862 int i;
1863 ret = -ENODEV;
1864
1865 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001866 for (i = 0; i < nr_cpu_ids; i++)
1867 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001869 break;
1870 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
1872 /* if all ->init() calls failed, unregister */
1873 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001874 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301875 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001876 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 }
1878 }
1879
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001880 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001881 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001883 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001884err_if_unreg:
1885 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001886err_null_driver:
1887 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1888 cpufreq_driver = NULL;
1889 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001890 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891}
1892EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1893
1894
1895/**
1896 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1897 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001898 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 * the right to do so, i.e. if you have succeeded in initialising before!
1900 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1901 * currently not initialised.
1902 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001903int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904{
1905 unsigned long flags;
1906
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001907 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001910 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001912 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001913 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
1915 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1916 cpufreq_driver = NULL;
1917 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1918
1919 return 0;
1920}
1921EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001922
1923static int __init cpufreq_core_init(void)
1924{
1925 int cpu;
1926
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001927 if (cpufreq_disabled())
1928 return -ENODEV;
1929
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001930 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001931 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001932 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1933 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001934
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001935 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001936 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001937 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001938
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001939 return 0;
1940}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001941core_initcall(cpufreq_core_init);