blob: 0dc9933069c510c0a47ae50501e883a344762a92 [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 kumar8bf1ac72012-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 Kumarb3940582013-02-01 05:42:58 +00001555 if (!policy->governor->initialized && (event == CPUFREQ_GOV_START))
1556 policy->governor->initialized = 1;
1557
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301558 /* we keep one module reference alive for
1559 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 if ((event != CPUFREQ_GOV_START) || ret)
1561 module_put(policy->governor->owner);
1562 if ((event == CPUFREQ_GOV_STOP) && !ret)
1563 module_put(policy->governor->owner);
1564
1565 return ret;
1566}
1567
1568
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569int cpufreq_register_governor(struct cpufreq_governor *governor)
1570{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001571 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572
1573 if (!governor)
1574 return -EINVAL;
1575
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001576 if (cpufreq_disabled())
1577 return -ENODEV;
1578
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001579 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001580
Viresh Kumarb3940582013-02-01 05:42:58 +00001581 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001582 err = -EBUSY;
1583 if (__find_governor(governor->name) == NULL) {
1584 err = 0;
1585 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
Dave Jones32ee8c32006-02-28 00:43:23 -05001588 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001589 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590}
1591EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1592
1593
1594void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1595{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001596#ifdef CONFIG_HOTPLUG_CPU
1597 int cpu;
1598#endif
1599
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 if (!governor)
1601 return;
1602
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001603 if (cpufreq_disabled())
1604 return;
1605
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001606#ifdef CONFIG_HOTPLUG_CPU
1607 for_each_present_cpu(cpu) {
1608 if (cpu_online(cpu))
1609 continue;
1610 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1611 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1612 }
1613#endif
1614
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001615 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001617 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618 return;
1619}
1620EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1621
1622
1623
1624/*********************************************************************
1625 * POLICY INTERFACE *
1626 *********************************************************************/
1627
1628/**
1629 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001630 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1631 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 *
1633 * Reads the current cpufreq policy.
1634 */
1635int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1636{
1637 struct cpufreq_policy *cpu_policy;
1638 if (!policy)
1639 return -EINVAL;
1640
1641 cpu_policy = cpufreq_cpu_get(cpu);
1642 if (!cpu_policy)
1643 return -EINVAL;
1644
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646
1647 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 return 0;
1649}
1650EXPORT_SYMBOL(cpufreq_get_policy);
1651
1652
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001653/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301654 * data : current policy.
1655 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001656 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301657static int __cpufreq_set_policy(struct cpufreq_policy *data,
1658 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659{
1660 int ret = 0;
1661
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001662 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 policy->min, policy->max);
1664
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301665 memcpy(&policy->cpuinfo, &data->cpuinfo,
1666 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
Yi Yang53391fa2008-01-30 13:33:34 +01001668 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001669 ret = -EINVAL;
1670 goto error_out;
1671 }
1672
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 /* verify the cpu speed can be set within this limit */
1674 ret = cpufreq_driver->verify(policy);
1675 if (ret)
1676 goto error_out;
1677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001679 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1680 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
1682 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001683 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1684 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
1686 /* verify the cpu speed can be set within this limit,
1687 which might be different to the first one */
1688 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001689 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
1692 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001693 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1694 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
Dave Jones7d5e3502006-02-02 17:03:42 -05001696 data->min = policy->min;
1697 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001699 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301700 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702 if (cpufreq_driver->setpolicy) {
1703 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001704 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 ret = cpufreq_driver->setpolicy(policy);
1706 } else {
1707 if (policy->governor != data->governor) {
1708 /* save old, working values */
1709 struct cpufreq_governor *old_gov = data->governor;
1710
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001711 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
1713 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001714 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1716
1717 /* start new governor */
1718 data->governor = policy->governor;
1719 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1720 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001721 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301722 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 if (old_gov) {
1724 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301725 __cpufreq_governor(data,
1726 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 }
1728 ret = -EINVAL;
1729 goto error_out;
1730 }
1731 /* might be a policy change, too, so fall through */
1732 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001733 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1735 }
1736
Dave Jones7d5e3502006-02-02 17:03:42 -05001737error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 return ret;
1739}
1740
1741/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1743 * @cpu: CPU which shall be re-evaluated
1744 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001745 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 * at different times.
1747 */
1748int cpufreq_update_policy(unsigned int cpu)
1749{
1750 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1751 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001752 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
Julia Lawallf1829e42008-07-25 22:44:53 +02001754 if (!data) {
1755 ret = -ENODEV;
1756 goto no_policy;
1757 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
Julia Lawallf1829e42008-07-25 22:44:53 +02001759 if (unlikely(lock_policy_rwsem_write(cpu))) {
1760 ret = -EINVAL;
1761 goto fail;
1762 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001764 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001765 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 policy.min = data->user_policy.min;
1767 policy.max = data->user_policy.max;
1768 policy.policy = data->user_policy.policy;
1769 policy.governor = data->user_policy.governor;
1770
Thomas Renninger0961dd02006-01-26 18:46:33 +01001771 /* BIOS might change freq behind our back
1772 -> ask driver for current freq and notify governors about a change */
1773 if (cpufreq_driver->get) {
1774 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001775 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001776 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001777 data->cur = policy.cur;
1778 } else {
1779 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301780 cpufreq_out_of_sync(cpu, data->cur,
1781 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001782 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001783 }
1784
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 ret = __cpufreq_set_policy(data, &policy);
1786
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001787 unlock_policy_rwsem_write(cpu);
1788
Julia Lawallf1829e42008-07-25 22:44:53 +02001789fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001791no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 return ret;
1793}
1794EXPORT_SYMBOL(cpufreq_update_policy);
1795
Satyam Sharmadd184a02007-10-02 13:28:14 -07001796static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001797 unsigned long action, void *hcpu)
1798{
1799 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001800 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001801
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001802 dev = get_cpu_device(cpu);
1803 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001804 switch (action) {
1805 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001806 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001807 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001808 break;
1809 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001810 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001811 if (unlikely(lock_policy_rwsem_write(cpu)))
1812 BUG();
1813
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001814 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001815 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001816 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001817 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001818 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001819 break;
1820 }
1821 }
1822 return NOTIFY_OK;
1823}
1824
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001825static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001826 .notifier_call = cpufreq_cpu_callback,
1827};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
1829/*********************************************************************
1830 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1831 *********************************************************************/
1832
1833/**
1834 * cpufreq_register_driver - register a CPU Frequency driver
1835 * @driver_data: A struct cpufreq_driver containing the values#
1836 * submitted by the CPU Frequency driver.
1837 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001838 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001840 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 *
1842 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001843int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844{
1845 unsigned long flags;
1846 int ret;
1847
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001848 if (cpufreq_disabled())
1849 return -ENODEV;
1850
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 if (!driver_data || !driver_data->verify || !driver_data->init ||
1852 ((!driver_data->setpolicy) && (!driver_data->target)))
1853 return -EINVAL;
1854
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001855 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856
1857 if (driver_data->setpolicy)
1858 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1859
1860 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1861 if (cpufreq_driver) {
1862 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1863 return -EBUSY;
1864 }
1865 cpufreq_driver = driver_data;
1866 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1867
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001868 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001869 if (ret)
1870 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001872 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 int i;
1874 ret = -ENODEV;
1875
1876 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001877 for (i = 0; i < nr_cpu_ids; i++)
1878 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001880 break;
1881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
1883 /* if all ->init() calls failed, unregister */
1884 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001885 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301886 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001887 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 }
1889 }
1890
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001891 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001892 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001894 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001895err_if_unreg:
1896 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001897err_null_driver:
1898 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1899 cpufreq_driver = NULL;
1900 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001901 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902}
1903EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1904
1905
1906/**
1907 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1908 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001909 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 * the right to do so, i.e. if you have succeeded in initialising before!
1911 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1912 * currently not initialised.
1913 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001914int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915{
1916 unsigned long flags;
1917
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001918 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001921 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001923 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001924 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925
1926 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1927 cpufreq_driver = NULL;
1928 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1929
1930 return 0;
1931}
1932EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001933
1934static int __init cpufreq_core_init(void)
1935{
1936 int cpu;
1937
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001938 if (cpufreq_disabled())
1939 return -ENODEV;
1940
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001941 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001942 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001943 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1944 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001945
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001946 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001947 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001948 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001949
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001950 return 0;
1951}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001952core_initcall(cpufreq_core_init);