blob: cd7644554a628485f2e2fffdd3dd9a5b97d74172 [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;
855 int ret = -ENOMEM, found = 0;
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;
Rusty Russell835481d2009-01-04 05:18:06 -0800903 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800905 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900906 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400907 ret = (lock_policy_rwsem_write(cpu) < 0);
908 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800909
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000911 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700913 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500914#ifdef CONFIG_HOTPLUG_CPU
915 for_each_online_cpu(sibling) {
916 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
917 if (cp && cp->governor &&
918 (cpumask_test_cpu(cpu, cp->related_cpus))) {
919 policy->governor = cp->governor;
920 found = 1;
921 break;
922 }
923 }
924#endif
925 if (!found)
926 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 /* call driver. From then on the cpufreq must be able
928 * to accept all calls to ->verify and ->setpolicy for this CPU
929 */
930 ret = cpufreq_driver->init(policy);
931 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200932 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400933 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000935
Viresh Kumarfcf80582013-01-29 14:39:08 +0000936 /* related cpus should atleast have policy->cpus */
937 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
938
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000939 /*
940 * affected cpus must always be the one, which are online. We aren't
941 * managing offline cpus here.
942 */
943 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
944
Mike Chan187d9f42008-12-04 12:19:17 -0800945 policy->user_policy.min = policy->min;
946 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
Thomas Renningera1531ac2008-07-29 22:32:58 -0700948 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
949 CPUFREQ_START, policy);
950
Viresh Kumarfcf80582013-01-29 14:39:08 +0000951#ifdef CONFIG_HOTPLUG_CPU
952 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
953 if (gov) {
954 policy->governor = gov;
955 pr_debug("Restoring governor %s for cpu %d\n",
956 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200957 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000958#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800960 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400961 if (ret)
962 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500963
Lothar Waßmanndca02612008-05-29 17:54:52 +0200964 unlock_policy_rwsem_write(cpu);
965
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400966 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200968 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500969
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 return 0;
971
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972err_out_unregister:
973 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -0800974 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -0700975 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
977
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -0800978 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 wait_for_completion(&policy->kobj_unregister);
980
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400981err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -0500982 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +0800983 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400984err_free_cpumask:
985 free_cpumask_var(policy->cpus);
986err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988nomem_out:
989 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -0800990module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 return ret;
992}
993
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000994static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
995{
996 int j;
997
998 policy->last_cpu = policy->cpu;
999 policy->cpu = cpu;
1000
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001001 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001002 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001003
1004#ifdef CONFIG_CPU_FREQ_TABLE
1005 cpufreq_frequency_table_update_policy_cpu(policy);
1006#endif
1007 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1008 CPUFREQ_UPDATE_POLICY_CPU, policy);
1009}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010
1011/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001012 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 *
1014 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001015 * Caller should already have policy_rwsem in write mode for this CPU.
1016 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001018static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001020 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 unsigned long flags;
1022 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001023 struct kobject *kobj;
1024 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001025 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001027 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
1029 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001030 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
1032 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001033 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001035 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 return -EINVAL;
1037 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001039 if (cpufreq_driver->target)
Viresh Kumarf6a74092013-01-12 05:14:39 +00001040 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Thomas Renninger084f3492007-07-09 11:35:28 -07001041
1042#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001043 strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
1044 CPUFREQ_NAME_LEN);
Thomas Renninger084f3492007-07-09 11:35:28 -07001045#endif
1046
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001047 per_cpu(cpufreq_cpu_data, cpu) = NULL;
1048 cpus = cpumask_weight(data->cpus);
1049 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001051 if (cpu != data->cpu) {
1052 sysfs_remove_link(&dev->kobj, "cpufreq");
1053 } else if (cpus > 1) {
Jacob Shin27ecddc2011-04-27 13:32:11 -05001054 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001055 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1056 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1057 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1058 if (ret) {
1059 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1060 cpumask_set_cpu(cpu, data->cpus);
1061 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1062 "cpufreq");
1063 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1064 unlock_policy_rwsem_write(cpu);
1065 return -EINVAL;
1066 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001067
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001068 update_policy_cpu(data, cpu_dev->id);
1069 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1070 __func__, cpu_dev->id, cpu);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001071 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001072
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001073 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1074
1075 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1076 cpufreq_cpu_put(data);
1077 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001078
1079 /* If cpu is last user of policy, free policy */
1080 if (cpus == 1) {
1081 lock_policy_rwsem_write(cpu);
1082 kobj = &data->kobj;
1083 cmp = &data->kobj_unregister;
1084 unlock_policy_rwsem_write(cpu);
1085 kobject_put(kobj);
1086
1087 /* we need to make sure that the underlying kobj is actually
1088 * not referenced anymore by anybody before we proceed with
1089 * unloading.
1090 */
1091 pr_debug("waiting for dropping of refcount\n");
1092 wait_for_completion(cmp);
1093 pr_debug("wait complete\n");
1094
1095 lock_policy_rwsem_write(cpu);
1096 if (cpufreq_driver->exit)
1097 cpufreq_driver->exit(data);
1098 unlock_policy_rwsem_write(cpu);
1099
1100 free_cpumask_var(data->related_cpus);
1101 free_cpumask_var(data->cpus);
1102 kfree(data);
1103 } else if (cpufreq_driver->target) {
1104 __cpufreq_governor(data, CPUFREQ_GOV_START);
1105 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1106 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 return 0;
1109}
1110
1111
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001112static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001113{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001114 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001115 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001116
1117 if (cpu_is_offline(cpu))
1118 return 0;
1119
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001120 if (unlikely(lock_policy_rwsem_write(cpu)))
1121 BUG();
1122
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001123 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001124 return retval;
1125}
1126
1127
David Howells65f27f32006-11-22 14:55:48 +00001128static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129{
David Howells65f27f32006-11-22 14:55:48 +00001130 struct cpufreq_policy *policy =
1131 container_of(work, struct cpufreq_policy, update);
1132 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001133 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 cpufreq_update_policy(cpu);
1135}
1136
1137/**
1138 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1139 * @cpu: cpu number
1140 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1141 * @new_freq: CPU frequency the CPU actually runs at
1142 *
Dave Jones29464f22009-01-18 01:37:11 -05001143 * We adjust to current frequency first, and need to clean up later.
1144 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301146static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1147 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148{
1149 struct cpufreq_freqs freqs;
1150
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001151 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1153
1154 freqs.cpu = cpu;
1155 freqs.old = old_freq;
1156 freqs.new = new_freq;
1157 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1158 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1159}
1160
1161
Dave Jones32ee8c32006-02-28 00:43:23 -05001162/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301163 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001164 * @cpu: CPU number
1165 *
1166 * This is the last known freq, without actually getting it from the driver.
1167 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1168 */
1169unsigned int cpufreq_quick_get(unsigned int cpu)
1170{
1171 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301172 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001173
1174 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301175 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001176 cpufreq_cpu_put(policy);
1177 }
1178
Dave Jones4d34a672008-02-07 16:33:49 -05001179 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001180}
1181EXPORT_SYMBOL(cpufreq_quick_get);
1182
Jesse Barnes3d737102011-06-28 10:59:12 -07001183/**
1184 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1185 * @cpu: CPU number
1186 *
1187 * Just return the max possible frequency for a given CPU.
1188 */
1189unsigned int cpufreq_quick_get_max(unsigned int cpu)
1190{
1191 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1192 unsigned int ret_freq = 0;
1193
1194 if (policy) {
1195 ret_freq = policy->max;
1196 cpufreq_cpu_put(policy);
1197 }
1198
1199 return ret_freq;
1200}
1201EXPORT_SYMBOL(cpufreq_quick_get_max);
1202
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001203
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001204static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001206 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301207 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001210 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301212 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301214 if (ret_freq && policy->cur &&
1215 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1216 /* verify no discrepancy between actual and
1217 saved value exists */
1218 if (unlikely(ret_freq != policy->cur)) {
1219 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 schedule_work(&policy->update);
1221 }
1222 }
1223
Dave Jones4d34a672008-02-07 16:33:49 -05001224 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001225}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001227/**
1228 * cpufreq_get - get the current CPU frequency (in kHz)
1229 * @cpu: CPU number
1230 *
1231 * Get the CPU current (static) CPU frequency
1232 */
1233unsigned int cpufreq_get(unsigned int cpu)
1234{
1235 unsigned int ret_freq = 0;
1236 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1237
1238 if (!policy)
1239 goto out;
1240
1241 if (unlikely(lock_policy_rwsem_read(cpu)))
1242 goto out_policy;
1243
1244 ret_freq = __cpufreq_get(cpu);
1245
1246 unlock_policy_rwsem_read(cpu);
1247
1248out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001250out:
Dave Jones4d34a672008-02-07 16:33:49 -05001251 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252}
1253EXPORT_SYMBOL(cpufreq_get);
1254
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001255static struct subsys_interface cpufreq_interface = {
1256 .name = "cpufreq",
1257 .subsys = &cpu_subsys,
1258 .add_dev = cpufreq_add_dev,
1259 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001260};
1261
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262
1263/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001264 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1265 *
1266 * This function is only executed for the boot processor. The other CPUs
1267 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001268 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001269static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001270{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301271 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001272
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001273 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001274 struct cpufreq_policy *cpu_policy;
1275
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001276 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001277
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001278 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001279 cpu_policy = cpufreq_cpu_get(cpu);
1280 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001281 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001282
1283 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001284 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001285 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001286 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1287 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001288 }
1289
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001290 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001291 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001292}
1293
1294/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001295 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 *
1297 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001298 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1299 * restored. It will verify that the current freq is in sync with
1300 * what we believe it to be. This is a bit later than when it
1301 * should be, but nonethteless it's better than calling
1302 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001303 *
1304 * This function is only executed for the boot CPU. The other CPUs have not
1305 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001307static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301309 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001310
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001311 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 struct cpufreq_policy *cpu_policy;
1313
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001314 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001316 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 cpu_policy = cpufreq_cpu_get(cpu);
1318 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001319 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320
1321 if (cpufreq_driver->resume) {
1322 ret = cpufreq_driver->resume(cpu_policy);
1323 if (ret) {
1324 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1325 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001326 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 }
1328 }
1329
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001331
Dave Jonesc9060492008-02-07 16:32:18 -05001332fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334}
1335
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001336static struct syscore_ops cpufreq_syscore_ops = {
1337 .suspend = cpufreq_bp_suspend,
1338 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339};
1340
Borislav Petkov9d950462013-01-20 10:24:28 +00001341/**
1342 * cpufreq_get_current_driver - return current driver's name
1343 *
1344 * Return the name string of the currently loaded cpufreq driver
1345 * or NULL, if none.
1346 */
1347const char *cpufreq_get_current_driver(void)
1348{
1349 if (cpufreq_driver)
1350 return cpufreq_driver->name;
1351
1352 return NULL;
1353}
1354EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355
1356/*********************************************************************
1357 * NOTIFIER LISTS INTERFACE *
1358 *********************************************************************/
1359
1360/**
1361 * cpufreq_register_notifier - register a driver with cpufreq
1362 * @nb: notifier function to register
1363 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1364 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001365 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 * are notified about clock rate changes (once before and once after
1367 * the transition), or a list of drivers that are notified about
1368 * changes in cpufreq policy.
1369 *
1370 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001371 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 */
1373int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1374{
1375 int ret;
1376
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001377 if (cpufreq_disabled())
1378 return -EINVAL;
1379
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001380 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1381
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 switch (list) {
1383 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001384 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001385 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 break;
1387 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001388 ret = blocking_notifier_chain_register(
1389 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 break;
1391 default:
1392 ret = -EINVAL;
1393 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
1395 return ret;
1396}
1397EXPORT_SYMBOL(cpufreq_register_notifier);
1398
1399
1400/**
1401 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1402 * @nb: notifier block to be unregistered
1403 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1404 *
1405 * Remove a driver from the CPU frequency notifier list.
1406 *
1407 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001408 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 */
1410int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1411{
1412 int ret;
1413
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001414 if (cpufreq_disabled())
1415 return -EINVAL;
1416
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 switch (list) {
1418 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001419 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001420 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 break;
1422 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001423 ret = blocking_notifier_chain_unregister(
1424 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 break;
1426 default:
1427 ret = -EINVAL;
1428 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
1430 return ret;
1431}
1432EXPORT_SYMBOL(cpufreq_unregister_notifier);
1433
1434
1435/*********************************************************************
1436 * GOVERNORS *
1437 *********************************************************************/
1438
1439
1440int __cpufreq_driver_target(struct cpufreq_policy *policy,
1441 unsigned int target_freq,
1442 unsigned int relation)
1443{
1444 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001445 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001446
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001447 if (cpufreq_disabled())
1448 return -ENODEV;
1449
Viresh Kumar72499242012-10-31 01:28:21 +01001450 /* Make sure that target_freq is within supported range */
1451 if (target_freq > policy->max)
1452 target_freq = policy->max;
1453 if (target_freq < policy->min)
1454 target_freq = policy->min;
1455
1456 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1457 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001458
1459 if (target_freq == policy->cur)
1460 return 0;
1461
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001462 if (cpufreq_driver->target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001464
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 return retval;
1466}
1467EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1468
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469int cpufreq_driver_target(struct cpufreq_policy *policy,
1470 unsigned int target_freq,
1471 unsigned int relation)
1472{
Julia Lawallf1829e42008-07-25 22:44:53 +02001473 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
1475 policy = cpufreq_cpu_get(policy->cpu);
1476 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001477 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001479 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001480 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
1482 ret = __cpufreq_driver_target(policy, target_freq, relation);
1483
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001484 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485
Julia Lawallf1829e42008-07-25 22:44:53 +02001486fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001488no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 return ret;
1490}
1491EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1492
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001493int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001494{
1495 int ret = 0;
1496
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001497 if (cpufreq_disabled())
1498 return ret;
1499
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001500 if (!cpufreq_driver->getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001501 return 0;
1502
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001503 policy = cpufreq_cpu_get(policy->cpu);
1504 if (!policy)
1505 return -EINVAL;
1506
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001507 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001508
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001509 cpufreq_cpu_put(policy);
1510 return ret;
1511}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001512EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001513
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001514/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001515 * when "event" is CPUFREQ_GOV_LIMITS
1516 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301518static int __cpufreq_governor(struct cpufreq_policy *policy,
1519 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520{
Dave Jonescc993ca2005-07-28 09:43:56 -07001521 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001522
1523 /* Only must be defined when default governor is known to have latency
1524 restrictions, like e.g. conservative or ondemand.
1525 That this is the case is already ensured in Kconfig
1526 */
1527#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1528 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1529#else
1530 struct cpufreq_governor *gov = NULL;
1531#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001532
1533 if (policy->governor->max_transition_latency &&
1534 policy->cpuinfo.transition_latency >
1535 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001536 if (!gov)
1537 return -EINVAL;
1538 else {
1539 printk(KERN_WARNING "%s governor failed, too long"
1540 " transition latency of HW, fallback"
1541 " to %s governor\n",
1542 policy->governor->name,
1543 gov->name);
1544 policy->governor = gov;
1545 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001546 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547
1548 if (!try_module_get(policy->governor->owner))
1549 return -EINVAL;
1550
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001551 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301552 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 ret = policy->governor->governor(policy, event);
1554
Viresh Kumar8e536952013-02-07 12:51:27 +05301555 if (event == CPUFREQ_GOV_START)
1556 policy->governor->initialized++;
1557 else if (event == CPUFREQ_GOV_STOP)
1558 policy->governor->initialized--;
Viresh Kumarb3940582013-02-01 05:42:58 +00001559
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301560 /* we keep one module reference alive for
1561 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 if ((event != CPUFREQ_GOV_START) || ret)
1563 module_put(policy->governor->owner);
1564 if ((event == CPUFREQ_GOV_STOP) && !ret)
1565 module_put(policy->governor->owner);
1566
1567 return ret;
1568}
1569
1570
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571int cpufreq_register_governor(struct cpufreq_governor *governor)
1572{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001573 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574
1575 if (!governor)
1576 return -EINVAL;
1577
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001578 if (cpufreq_disabled())
1579 return -ENODEV;
1580
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001581 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001582
Viresh Kumarb3940582013-02-01 05:42:58 +00001583 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001584 err = -EBUSY;
1585 if (__find_governor(governor->name) == NULL) {
1586 err = 0;
1587 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
Dave Jones32ee8c32006-02-28 00:43:23 -05001590 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001591 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001592}
1593EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1594
1595
1596void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1597{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001598#ifdef CONFIG_HOTPLUG_CPU
1599 int cpu;
1600#endif
1601
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 if (!governor)
1603 return;
1604
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001605 if (cpufreq_disabled())
1606 return;
1607
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001608#ifdef CONFIG_HOTPLUG_CPU
1609 for_each_present_cpu(cpu) {
1610 if (cpu_online(cpu))
1611 continue;
1612 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1613 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1614 }
1615#endif
1616
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001617 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001619 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 return;
1621}
1622EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1623
1624
1625
1626/*********************************************************************
1627 * POLICY INTERFACE *
1628 *********************************************************************/
1629
1630/**
1631 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001632 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1633 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 *
1635 * Reads the current cpufreq policy.
1636 */
1637int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1638{
1639 struct cpufreq_policy *cpu_policy;
1640 if (!policy)
1641 return -EINVAL;
1642
1643 cpu_policy = cpufreq_cpu_get(cpu);
1644 if (!cpu_policy)
1645 return -EINVAL;
1646
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648
1649 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 return 0;
1651}
1652EXPORT_SYMBOL(cpufreq_get_policy);
1653
1654
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001655/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301656 * data : current policy.
1657 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001658 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301659static int __cpufreq_set_policy(struct cpufreq_policy *data,
1660 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661{
1662 int ret = 0;
1663
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001664 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 policy->min, policy->max);
1666
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301667 memcpy(&policy->cpuinfo, &data->cpuinfo,
1668 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669
Yi Yang53391fa2008-01-30 13:33:34 +01001670 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001671 ret = -EINVAL;
1672 goto error_out;
1673 }
1674
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 /* verify the cpu speed can be set within this limit */
1676 ret = cpufreq_driver->verify(policy);
1677 if (ret)
1678 goto error_out;
1679
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001681 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1682 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
1684 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001685 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1686 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
1688 /* verify the cpu speed can be set within this limit,
1689 which might be different to the first one */
1690 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001691 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
1694 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001695 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1696 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
Dave Jones7d5e3502006-02-02 17:03:42 -05001698 data->min = policy->min;
1699 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001701 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301702 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703
1704 if (cpufreq_driver->setpolicy) {
1705 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001706 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 ret = cpufreq_driver->setpolicy(policy);
1708 } else {
1709 if (policy->governor != data->governor) {
1710 /* save old, working values */
1711 struct cpufreq_governor *old_gov = data->governor;
1712
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001713 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
1715 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001716 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1718
1719 /* start new governor */
1720 data->governor = policy->governor;
1721 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1722 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001723 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301724 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 if (old_gov) {
1726 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301727 __cpufreq_governor(data,
1728 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 }
1730 ret = -EINVAL;
1731 goto error_out;
1732 }
1733 /* might be a policy change, too, so fall through */
1734 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001735 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1737 }
1738
Dave Jones7d5e3502006-02-02 17:03:42 -05001739error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 return ret;
1741}
1742
1743/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1745 * @cpu: CPU which shall be re-evaluated
1746 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001747 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 * at different times.
1749 */
1750int cpufreq_update_policy(unsigned int cpu)
1751{
1752 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1753 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001754 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755
Julia Lawallf1829e42008-07-25 22:44:53 +02001756 if (!data) {
1757 ret = -ENODEV;
1758 goto no_policy;
1759 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Julia Lawallf1829e42008-07-25 22:44:53 +02001761 if (unlikely(lock_policy_rwsem_write(cpu))) {
1762 ret = -EINVAL;
1763 goto fail;
1764 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001766 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001767 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 policy.min = data->user_policy.min;
1769 policy.max = data->user_policy.max;
1770 policy.policy = data->user_policy.policy;
1771 policy.governor = data->user_policy.governor;
1772
Thomas Renninger0961dd02006-01-26 18:46:33 +01001773 /* BIOS might change freq behind our back
1774 -> ask driver for current freq and notify governors about a change */
1775 if (cpufreq_driver->get) {
1776 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001777 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001778 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001779 data->cur = policy.cur;
1780 } else {
1781 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301782 cpufreq_out_of_sync(cpu, data->cur,
1783 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001784 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001785 }
1786
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 ret = __cpufreq_set_policy(data, &policy);
1788
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001789 unlock_policy_rwsem_write(cpu);
1790
Julia Lawallf1829e42008-07-25 22:44:53 +02001791fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001793no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 return ret;
1795}
1796EXPORT_SYMBOL(cpufreq_update_policy);
1797
Satyam Sharmadd184a02007-10-02 13:28:14 -07001798static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001799 unsigned long action, void *hcpu)
1800{
1801 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001802 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001803
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001804 dev = get_cpu_device(cpu);
1805 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001806 switch (action) {
1807 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001808 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001809 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001810 break;
1811 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001812 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001813 if (unlikely(lock_policy_rwsem_write(cpu)))
1814 BUG();
1815
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001816 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001817 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001818 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001819 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001820 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001821 break;
1822 }
1823 }
1824 return NOTIFY_OK;
1825}
1826
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001827static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001828 .notifier_call = cpufreq_cpu_callback,
1829};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
1831/*********************************************************************
1832 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1833 *********************************************************************/
1834
1835/**
1836 * cpufreq_register_driver - register a CPU Frequency driver
1837 * @driver_data: A struct cpufreq_driver containing the values#
1838 * submitted by the CPU Frequency driver.
1839 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001840 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001842 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 *
1844 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001845int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846{
1847 unsigned long flags;
1848 int ret;
1849
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001850 if (cpufreq_disabled())
1851 return -ENODEV;
1852
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 if (!driver_data || !driver_data->verify || !driver_data->init ||
1854 ((!driver_data->setpolicy) && (!driver_data->target)))
1855 return -EINVAL;
1856
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001857 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
1859 if (driver_data->setpolicy)
1860 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1861
1862 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1863 if (cpufreq_driver) {
1864 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1865 return -EBUSY;
1866 }
1867 cpufreq_driver = driver_data;
1868 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1869
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001870 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001871 if (ret)
1872 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001874 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 int i;
1876 ret = -ENODEV;
1877
1878 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001879 for (i = 0; i < nr_cpu_ids; i++)
1880 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001882 break;
1883 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884
1885 /* if all ->init() calls failed, unregister */
1886 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001887 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301888 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001889 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 }
1891 }
1892
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001893 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001894 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001896 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001897err_if_unreg:
1898 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001899err_null_driver:
1900 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1901 cpufreq_driver = NULL;
1902 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001903 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904}
1905EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1906
1907
1908/**
1909 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1910 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001911 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 * the right to do so, i.e. if you have succeeded in initialising before!
1913 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1914 * currently not initialised.
1915 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001916int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917{
1918 unsigned long flags;
1919
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001920 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001923 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001925 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001926 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927
1928 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1929 cpufreq_driver = NULL;
1930 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1931
1932 return 0;
1933}
1934EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001935
1936static int __init cpufreq_core_init(void)
1937{
1938 int cpu;
1939
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001940 if (cpufreq_disabled())
1941 return -ENODEV;
1942
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001943 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001944 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001945 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1946 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001947
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001948 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001949 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001950 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001951
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001952 return 0;
1953}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001954core_initcall(cpufreq_core_init);