blob: 3564947ea7ac48d44e0035680390f6f093dfc9cc [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 */
Nathan Zimmer58000432013-04-04 14:53:25 +000042static struct cpufreq_driver __rcu *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
Nathan Zimmer0d1857a2013-02-22 16:24:34 +000048static DEFINE_RWLOCK(cpufreq_driver_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
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:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080062 * - Governor routines that can be called in cpufreq hotplug path should not
63 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040064 * - Lock should not be held across
65 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080066 */
Tejun Heof1625062009-10-29 22:34:13 +090067static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080068static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
69
70#define lock_policy_rwsem(mode, cpu) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053071static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072{ \
Tejun Heof1625062009-10-29 22:34:13 +090073 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080074 BUG_ON(policy_cpu == -1); \
75 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076 \
77 return 0; \
78}
79
80lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080081lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080082
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053083#define unlock_policy_rwsem(mode, cpu) \
84static void unlock_policy_rwsem_##mode(int cpu) \
85{ \
86 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
87 BUG_ON(policy_cpu == -1); \
88 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080089}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053091unlock_policy_rwsem(read, cpu);
92unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Linus Torvalds1da177e2005-04-16 15:20:36 -070094/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -050095static int __cpufreq_governor(struct cpufreq_policy *policy,
96 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +000098static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500101 * Two notifier lists: the "policy" list is involved in the
102 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 * "transition" list for kernel code that needs to handle
104 * changes to devices when the CPU clock speed changes.
105 * The mutex locks both lists.
106 */
Alan Sterne041c682006-03-27 01:16:30 -0800107static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700108static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200110static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700111static int __init init_cpufreq_transition_notifier_list(void)
112{
113 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200114 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700115 return 0;
116}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800117pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400119static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200120static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400121{
122 return off;
123}
124void disable_cpufreq(void)
125{
126 off = 1;
127}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500129static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000131bool have_governor_per_policy(void)
132{
Nathan Zimmer58000432013-04-04 14:53:25 +0000133 bool have_governor_per_policy;
134 rcu_read_lock();
135 have_governor_per_policy =
136 rcu_dereference(cpufreq_driver)->have_governor_per_policy;
137 rcu_read_unlock();
138 return have_governor_per_policy;
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000139}
140
Stephen Boyda9144432012-07-20 18:14:38 +0000141static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142{
143 struct cpufreq_policy *data;
Nathan Zimmer58000432013-04-04 14:53:25 +0000144 struct cpufreq_driver *driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 unsigned long flags;
146
Mike Travis7a6aedf2008-03-25 15:06:53 -0700147 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 goto err_out;
149
150 /* get the cpufreq driver */
Nathan Zimmer58000432013-04-04 14:53:25 +0000151 rcu_read_lock();
152 driver = rcu_dereference(cpufreq_driver);
153
154 if (!driver)
155 goto err_out_unlock;
156
157 if (!try_module_get(driver->owner))
158 goto err_out_unlock;
159
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000160 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700163 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
165 if (!data)
166 goto err_out_put_module;
167
Stephen Boyda9144432012-07-20 18:14:38 +0000168 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 goto err_out_put_module;
170
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000171 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +0000172 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 return data;
174
Dave Jones7d5e3502006-02-02 17:03:42 -0500175err_out_put_module:
Nathan Zimmer58000432013-04-04 14:53:25 +0000176 module_put(driver->owner);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000177 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +0000178err_out_unlock:
179 rcu_read_unlock();
Dave Jones7d5e3502006-02-02 17:03:42 -0500180err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 return NULL;
182}
Stephen Boyda9144432012-07-20 18:14:38 +0000183
184struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
185{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000186 if (cpufreq_disabled())
187 return NULL;
188
Stephen Boyda9144432012-07-20 18:14:38 +0000189 return __cpufreq_cpu_get(cpu, false);
190}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
192
Stephen Boyda9144432012-07-20 18:14:38 +0000193static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
194{
195 return __cpufreq_cpu_get(cpu, true);
196}
197
198static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
199{
200 if (!sysfs)
201 kobject_put(&data->kobj);
Nathan Zimmer58000432013-04-04 14:53:25 +0000202 rcu_read_lock();
203 module_put(rcu_dereference(cpufreq_driver)->owner);
204 rcu_read_unlock();
Stephen Boyda9144432012-07-20 18:14:38 +0000205}
Dave Jones7d5e3502006-02-02 17:03:42 -0500206
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207void cpufreq_cpu_put(struct cpufreq_policy *data)
208{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000209 if (cpufreq_disabled())
210 return;
211
Stephen Boyda9144432012-07-20 18:14:38 +0000212 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213}
214EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
215
Stephen Boyda9144432012-07-20 18:14:38 +0000216static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
217{
218 __cpufreq_cpu_put(data, true);
219}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
223 *********************************************************************/
224
225/**
226 * adjust_jiffies - adjust the system "loops_per_jiffy"
227 *
228 * This function alters the system "loops_per_jiffy" for the clock
229 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500230 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 * per-CPU loops_per_jiffy value wherever possible.
232 */
233#ifndef CONFIG_SMP
234static unsigned long l_p_j_ref;
235static unsigned int l_p_j_ref_freq;
236
Arjan van de Ven858119e2006-01-14 13:20:43 -0800237static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238{
239 if (ci->flags & CPUFREQ_CONST_LOOPS)
240 return;
241
242 if (!l_p_j_ref_freq) {
243 l_p_j_ref = loops_per_jiffy;
244 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200245 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530246 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530248 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700249 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530250 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
251 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200252 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530253 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 }
255}
256#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530257static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
258{
259 return;
260}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261#endif
262
263
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530264void __cpufreq_notify_transition(struct cpufreq_policy *policy,
265 struct cpufreq_freqs *freqs, unsigned int state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266{
267 BUG_ON(irqs_disabled());
268
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000269 if (cpufreq_disabled())
270 return;
271
Nathan Zimmer58000432013-04-04 14:53:25 +0000272 rcu_read_lock();
273 freqs->flags = rcu_dereference(cpufreq_driver)->flags;
274 rcu_read_unlock();
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200275 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800276 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800279
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500281 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800282 * which is not equal to what the cpufreq core thinks is
283 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 */
Nathan Zimmer58000432013-04-04 14:53:25 +0000285 if (!(freqs->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800286 if ((policy) && (policy->cpu == freqs->cpu) &&
287 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200288 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800289 " %u, cpufreq assumed %u kHz.\n",
290 freqs->old, policy->cur);
291 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 }
293 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700294 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800295 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
297 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800298
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 case CPUFREQ_POSTCHANGE:
300 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200301 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200302 (unsigned long)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}
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530311/**
312 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
313 * on frequency transition.
314 *
315 * This function calls the transition notifiers and the "adjust_jiffies"
316 * function. It is called twice on all CPU frequency changes that have
317 * external effects.
318 */
319void cpufreq_notify_transition(struct cpufreq_policy *policy,
320 struct cpufreq_freqs *freqs, unsigned int state)
321{
322 for_each_cpu(freqs->cpu, policy->cpus)
323 __cpufreq_notify_transition(policy, freqs, state);
324}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
326
327
328
329/*********************************************************************
330 * SYSFS INTERFACE *
331 *********************************************************************/
332
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700333static struct cpufreq_governor *__find_governor(const char *str_governor)
334{
335 struct cpufreq_governor *t;
336
337 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500338 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700339 return t;
340
341 return NULL;
342}
343
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344/**
345 * cpufreq_parse_governor - parse a governor string
346 */
Dave Jones905d77c2008-03-05 14:28:32 -0500347static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 struct cpufreq_governor **governor)
349{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700350 int err = -EINVAL;
Nathan Zimmer58000432013-04-04 14:53:25 +0000351 struct cpufreq_driver *driver;
352 bool has_setpolicy;
353 bool has_target;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700354
Nathan Zimmer58000432013-04-04 14:53:25 +0000355 rcu_read_lock();
356 driver = rcu_dereference(cpufreq_driver);
357 if (!driver) {
358 rcu_read_unlock();
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700359 goto out;
Nathan Zimmer58000432013-04-04 14:53:25 +0000360 }
361 has_setpolicy = driver->setpolicy ? true : false;
362 has_target = driver->target ? true : false;
363 rcu_read_unlock();
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700364
Nathan Zimmer58000432013-04-04 14:53:25 +0000365 if (has_setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
367 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700368 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530369 } else if (!strnicmp(str_governor, "powersave",
370 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700372 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 }
Nathan Zimmer58000432013-04-04 14:53:25 +0000374 } else if (has_target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700376
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800377 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700378
379 t = __find_governor(str_governor);
380
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700381 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700382 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700383
Kees Cook1a8e1462011-05-04 08:38:56 -0700384 mutex_unlock(&cpufreq_governor_mutex);
385 ret = request_module("cpufreq_%s", str_governor);
386 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700387
Kees Cook1a8e1462011-05-04 08:38:56 -0700388 if (ret == 0)
389 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700390 }
391
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700392 if (t != NULL) {
393 *governor = t;
394 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700396
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800397 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 }
Dave Jones29464f22009-01-18 01:37:11 -0500399out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700400 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
403
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530405 * cpufreq_per_cpu_attr_read() / show_##file_name() -
406 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 *
408 * Write out information from cpufreq_driver->policy[cpu]; object must be
409 * "unsigned int".
410 */
411
Dave Jones32ee8c32006-02-28 00:43:23 -0500412#define show_one(file_name, object) \
413static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500414(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500415{ \
Dave Jones29464f22009-01-18 01:37:11 -0500416 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417}
418
419show_one(cpuinfo_min_freq, cpuinfo.min_freq);
420show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100421show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422show_one(scaling_min_freq, min);
423show_one(scaling_max_freq, max);
424show_one(scaling_cur_freq, cur);
425
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530426static int __cpufreq_set_policy(struct cpufreq_policy *data,
427 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200428
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429/**
430 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
431 */
432#define store_one(file_name, object) \
433static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500434(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000436 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 struct cpufreq_policy new_policy; \
438 \
439 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
440 if (ret) \
441 return -EINVAL; \
442 \
Dave Jones29464f22009-01-18 01:37:11 -0500443 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 if (ret != 1) \
445 return -EINVAL; \
446 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200447 ret = __cpufreq_set_policy(policy, &new_policy); \
448 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 \
450 return ret ? ret : count; \
451}
452
Dave Jones29464f22009-01-18 01:37:11 -0500453store_one(scaling_min_freq, min);
454store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455
456/**
457 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
458 */
Dave Jones905d77c2008-03-05 14:28:32 -0500459static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
460 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800462 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 if (!cur_freq)
464 return sprintf(buf, "<unknown>");
465 return sprintf(buf, "%u\n", cur_freq);
466}
467
468
469/**
470 * show_scaling_governor - show the current policy for the specified CPU
471 */
Dave Jones905d77c2008-03-05 14:28:32 -0500472static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473{
Dave Jones29464f22009-01-18 01:37:11 -0500474 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 return sprintf(buf, "powersave\n");
476 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
477 return sprintf(buf, "performance\n");
478 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200479 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500480 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 return -EINVAL;
482}
483
484
485/**
486 * store_scaling_governor - store policy for the specified CPU
487 */
Dave Jones905d77c2008-03-05 14:28:32 -0500488static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
489 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000491 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 char str_governor[16];
493 struct cpufreq_policy new_policy;
494
495 ret = cpufreq_get_policy(&new_policy, policy->cpu);
496 if (ret)
497 return ret;
498
Dave Jones29464f22009-01-18 01:37:11 -0500499 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 if (ret != 1)
501 return -EINVAL;
502
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530503 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
504 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 return -EINVAL;
506
Thomas Renninger7970e082006-04-13 15:14:04 +0200507 /* Do not use cpufreq_set_policy here or the user_policy.max
508 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200509 ret = __cpufreq_set_policy(policy, &new_policy);
510
511 policy->user_policy.policy = policy->policy;
512 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200513
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530514 if (ret)
515 return ret;
516 else
517 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518}
519
520/**
521 * show_scaling_driver - show the cpufreq driver currently loaded
522 */
Dave Jones905d77c2008-03-05 14:28:32 -0500523static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524{
Nathan Zimmer58000432013-04-04 14:53:25 +0000525 ssize_t size;
526 rcu_read_lock();
527 size = scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
528 rcu_dereference(cpufreq_driver)->name);
529 rcu_read_unlock();
530 return size;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531}
532
533/**
534 * show_scaling_available_governors - show the available CPUfreq governors
535 */
Dave Jones905d77c2008-03-05 14:28:32 -0500536static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
537 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538{
539 ssize_t i = 0;
540 struct cpufreq_governor *t;
541
Nathan Zimmer58000432013-04-04 14:53:25 +0000542 rcu_read_lock();
543 if (!rcu_dereference(cpufreq_driver)->target) {
544 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 i += sprintf(buf, "performance powersave");
546 goto out;
547 }
Nathan Zimmer58000432013-04-04 14:53:25 +0000548 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500551 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
552 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200554 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500556out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 i += sprintf(&buf[i], "\n");
558 return i;
559}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700560
Rusty Russell835481d2009-01-04 05:18:06 -0800561static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562{
563 ssize_t i = 0;
564 unsigned int cpu;
565
Rusty Russell835481d2009-01-04 05:18:06 -0800566 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 if (i)
568 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
569 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
570 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500571 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 }
573 i += sprintf(&buf[i], "\n");
574 return i;
575}
576
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700577/**
578 * show_related_cpus - show the CPUs affected by each transition even if
579 * hw coordination is in use
580 */
581static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
582{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700583 return show_cpus(policy->related_cpus, buf);
584}
585
586/**
587 * show_affected_cpus - show the CPUs affected by each transition
588 */
589static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
590{
591 return show_cpus(policy->cpus, buf);
592}
593
Venki Pallipadi9e769882007-10-26 10:18:21 -0700594static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500595 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700596{
597 unsigned int freq = 0;
598 unsigned int ret;
599
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700600 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700601 return -EINVAL;
602
603 ret = sscanf(buf, "%u", &freq);
604 if (ret != 1)
605 return -EINVAL;
606
607 policy->governor->store_setspeed(policy, freq);
608
609 return count;
610}
611
612static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
613{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700614 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700615 return sprintf(buf, "<unsupported>\n");
616
617 return policy->governor->show_setspeed(policy, buf);
618}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
Thomas Renningere2f74f32009-11-19 12:31:01 +0100620/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200621 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100622 */
623static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
624{
625 unsigned int limit;
Nathan Zimmer58000432013-04-04 14:53:25 +0000626 int (*bios_limit)(int cpu, unsigned int *limit);
Thomas Renningere2f74f32009-11-19 12:31:01 +0100627 int ret;
Nathan Zimmer58000432013-04-04 14:53:25 +0000628
629 rcu_read_lock();
630 bios_limit = rcu_dereference(cpufreq_driver)->bios_limit;
631 rcu_read_unlock();
632
633 if (bios_limit) {
634 ret = bios_limit(policy->cpu, &limit);
Thomas Renningere2f74f32009-11-19 12:31:01 +0100635 if (!ret)
636 return sprintf(buf, "%u\n", limit);
637 }
638 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
639}
640
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200641cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
642cpufreq_freq_attr_ro(cpuinfo_min_freq);
643cpufreq_freq_attr_ro(cpuinfo_max_freq);
644cpufreq_freq_attr_ro(cpuinfo_transition_latency);
645cpufreq_freq_attr_ro(scaling_available_governors);
646cpufreq_freq_attr_ro(scaling_driver);
647cpufreq_freq_attr_ro(scaling_cur_freq);
648cpufreq_freq_attr_ro(bios_limit);
649cpufreq_freq_attr_ro(related_cpus);
650cpufreq_freq_attr_ro(affected_cpus);
651cpufreq_freq_attr_rw(scaling_min_freq);
652cpufreq_freq_attr_rw(scaling_max_freq);
653cpufreq_freq_attr_rw(scaling_governor);
654cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655
Dave Jones905d77c2008-03-05 14:28:32 -0500656static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 &cpuinfo_min_freq.attr,
658 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100659 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 &scaling_min_freq.attr,
661 &scaling_max_freq.attr,
662 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700663 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 &scaling_governor.attr,
665 &scaling_driver.attr,
666 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700667 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 NULL
669};
670
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200671struct kobject *cpufreq_global_kobject;
672EXPORT_SYMBOL(cpufreq_global_kobject);
673
Dave Jones29464f22009-01-18 01:37:11 -0500674#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
675#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676
Dave Jones29464f22009-01-18 01:37:11 -0500677static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678{
Dave Jones905d77c2008-03-05 14:28:32 -0500679 struct cpufreq_policy *policy = to_policy(kobj);
680 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500681 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000682 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500684 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800685
686 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500687 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800688
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530689 if (fattr->show)
690 ret = fattr->show(policy, buf);
691 else
692 ret = -EIO;
693
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800694 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500695fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000696 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500697no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 return ret;
699}
700
Dave Jones905d77c2008-03-05 14:28:32 -0500701static ssize_t store(struct kobject *kobj, struct attribute *attr,
702 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703{
Dave Jones905d77c2008-03-05 14:28:32 -0500704 struct cpufreq_policy *policy = to_policy(kobj);
705 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500706 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000707 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500709 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800710
711 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500712 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800713
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530714 if (fattr->store)
715 ret = fattr->store(policy, buf, count);
716 else
717 ret = -EIO;
718
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800719 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500720fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000721 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500722no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 return ret;
724}
725
Dave Jones905d77c2008-03-05 14:28:32 -0500726static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727{
Dave Jones905d77c2008-03-05 14:28:32 -0500728 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200729 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 complete(&policy->kobj_unregister);
731}
732
Emese Revfy52cf25d2010-01-19 02:58:23 +0100733static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 .show = show,
735 .store = store,
736};
737
738static struct kobj_type ktype_cpufreq = {
739 .sysfs_ops = &sysfs_ops,
740 .default_attrs = default_attrs,
741 .release = cpufreq_sysfs_release,
742};
743
Dave Jones19d6f7e2009-07-08 17:35:39 -0400744/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700745static int cpufreq_add_dev_symlink(unsigned int cpu,
746 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400747{
748 unsigned int j;
749 int ret = 0;
750
751 for_each_cpu(j, policy->cpus) {
752 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800753 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400754
755 if (j == cpu)
756 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400757
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200758 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400759 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800760 cpu_dev = get_cpu_device(j);
761 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400762 "cpufreq");
763 if (ret) {
764 cpufreq_cpu_put(managed_policy);
765 return ret;
766 }
767 }
768 return ret;
769}
770
Alex Chiangcf3289d02009-11-17 20:27:08 -0700771static int cpufreq_add_dev_interface(unsigned int cpu,
772 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800773 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400774{
Dave Jonesecf7e462009-07-08 18:48:47 -0400775 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400776 struct freq_attr **drv_attr;
Nathan Zimmer58000432013-04-04 14:53:25 +0000777 struct cpufreq_driver *driver;
Dave Jones909a6942009-07-08 18:05:42 -0400778 unsigned long flags;
779 int ret = 0;
780 unsigned int j;
781
782 /* prepare interface data */
783 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800784 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400785 if (ret)
786 return ret;
787
788 /* set up files for this cpu device */
Nathan Zimmer58000432013-04-04 14:53:25 +0000789 rcu_read_lock();
790 driver = rcu_dereference(cpufreq_driver);
791 drv_attr = driver->attr;
Dave Jones909a6942009-07-08 18:05:42 -0400792 while ((drv_attr) && (*drv_attr)) {
793 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
794 if (ret)
Nathan Zimmer58000432013-04-04 14:53:25 +0000795 goto err_out_unlock;
Dave Jones909a6942009-07-08 18:05:42 -0400796 drv_attr++;
797 }
Nathan Zimmer58000432013-04-04 14:53:25 +0000798 if (driver->get) {
Dave Jones909a6942009-07-08 18:05:42 -0400799 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
800 if (ret)
Nathan Zimmer58000432013-04-04 14:53:25 +0000801 goto err_out_unlock;
Dave Jones909a6942009-07-08 18:05:42 -0400802 }
Nathan Zimmer58000432013-04-04 14:53:25 +0000803 if (driver->target) {
Dave Jones909a6942009-07-08 18:05:42 -0400804 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
805 if (ret)
Nathan Zimmer58000432013-04-04 14:53:25 +0000806 goto err_out_unlock;
Dave Jones909a6942009-07-08 18:05:42 -0400807 }
Nathan Zimmer58000432013-04-04 14:53:25 +0000808 if (driver->bios_limit) {
Thomas Renningere2f74f32009-11-19 12:31:01 +0100809 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
810 if (ret)
Nathan Zimmer58000432013-04-04 14:53:25 +0000811 goto err_out_unlock;
Thomas Renningere2f74f32009-11-19 12:31:01 +0100812 }
Nathan Zimmer58000432013-04-04 14:53:25 +0000813 rcu_read_unlock();
Dave Jones909a6942009-07-08 18:05:42 -0400814
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000815 write_lock_irqsave(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400816 for_each_cpu(j, policy->cpus) {
Dave Jones909a6942009-07-08 18:05:42 -0400817 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900818 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400819 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000820 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400821
822 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400823 if (ret)
824 goto err_out_kobj_put;
825
826 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
827 /* assure that the starting sequence is run in __cpufreq_set_policy */
828 policy->governor = NULL;
829
830 /* set default policy */
831 ret = __cpufreq_set_policy(policy, &new_policy);
832 policy->user_policy.policy = policy->policy;
833 policy->user_policy.governor = policy->governor;
834
835 if (ret) {
Nathan Zimmer58000432013-04-04 14:53:25 +0000836 int (*exit)(struct cpufreq_policy *policy);
837
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200838 pr_debug("setting policy failed\n");
Nathan Zimmer58000432013-04-04 14:53:25 +0000839 rcu_read_lock();
840 exit = rcu_dereference(cpufreq_driver)->exit;
841 rcu_read_unlock();
842 if (exit)
843 exit(policy);
844
Dave Jonesecf7e462009-07-08 18:48:47 -0400845 }
Dave Jones909a6942009-07-08 18:05:42 -0400846 return ret;
847
Nathan Zimmer58000432013-04-04 14:53:25 +0000848err_out_unlock:
849 rcu_read_unlock();
Dave Jones909a6942009-07-08 18:05:42 -0400850err_out_kobj_put:
851 kobject_put(&policy->kobj);
852 wait_for_completion(&policy->kobj_unregister);
853 return ret;
854}
855
Viresh Kumarfcf80582013-01-29 14:39:08 +0000856#ifdef CONFIG_HOTPLUG_CPU
857static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
858 struct device *dev)
859{
860 struct cpufreq_policy *policy;
861 int ret = 0;
862 unsigned long flags;
863
864 policy = cpufreq_cpu_get(sibling);
865 WARN_ON(!policy);
866
Viresh Kumarfcf80582013-01-29 14:39:08 +0000867 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
868
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530869 lock_policy_rwsem_write(sibling);
870
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000871 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530872
Viresh Kumarfcf80582013-01-29 14:39:08 +0000873 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530874 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000875 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000876 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000877
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530878 unlock_policy_rwsem_write(sibling);
879
Viresh Kumarfcf80582013-01-29 14:39:08 +0000880 __cpufreq_governor(policy, CPUFREQ_GOV_START);
881 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
882
Viresh Kumarfcf80582013-01-29 14:39:08 +0000883 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
884 if (ret) {
885 cpufreq_cpu_put(policy);
886 return ret;
887 }
888
889 return 0;
890}
891#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892
893/**
894 * cpufreq_add_dev - add a CPU device
895 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500896 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400897 *
898 * The Oracle says: try running cpufreq registration/unregistration concurrently
899 * with with cpu hotplugging and all hell will break loose. Tried to clean this
900 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800902static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000904 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530905 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 struct cpufreq_policy *policy;
Nathan Zimmer58000432013-04-04 14:53:25 +0000907 struct cpufreq_driver *driver;
908 int (*init)(struct cpufreq_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500910#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000911 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500912 int sibling;
913#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914
Ashok Rajc32b6b82005-10-30 14:59:54 -0800915 if (cpu_is_offline(cpu))
916 return 0;
917
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200918 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919
920#ifdef CONFIG_SMP
921 /* check whether a different CPU already registered this
922 * CPU because it is in the same boat. */
923 policy = cpufreq_cpu_get(cpu);
924 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500925 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 return 0;
927 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000928
929#ifdef CONFIG_HOTPLUG_CPU
930 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000931 read_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000932 for_each_online_cpu(sibling) {
933 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530934 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000935 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000936 return cpufreq_add_policy_cpu(cpu, sibling, dev);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530937 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000938 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000939 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000940#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941#endif
942
Nathan Zimmer58000432013-04-04 14:53:25 +0000943 rcu_read_lock();
944 driver = rcu_dereference(cpufreq_driver);
945 if (!try_module_get(driver->owner)) {
946 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 ret = -EINVAL;
948 goto module_out;
949 }
Nathan Zimmer58000432013-04-04 14:53:25 +0000950 init = driver->init;
951 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
Dave Jonese98df502005-10-20 15:17:43 -0700953 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400954 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400956
957 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400958 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400959
960 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400961 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
963 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +0530964 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -0800965 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800967 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900968 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800969
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000971 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
973 /* call driver. From then on the cpufreq must be able
974 * to accept all calls to ->verify and ->setpolicy for this CPU
975 */
Nathan Zimmer58000432013-04-04 14:53:25 +0000976 ret = init(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200978 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530979 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000981
Viresh Kumarfcf80582013-01-29 14:39:08 +0000982 /* related cpus should atleast have policy->cpus */
983 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
984
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000985 /*
986 * affected cpus must always be the one, which are online. We aren't
987 * managing offline cpus here.
988 */
989 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
990
Mike Chan187d9f42008-12-04 12:19:17 -0800991 policy->user_policy.min = policy->min;
992 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Thomas Renningera1531ac2008-07-29 22:32:58 -0700994 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
995 CPUFREQ_START, policy);
996
Viresh Kumarfcf80582013-01-29 14:39:08 +0000997#ifdef CONFIG_HOTPLUG_CPU
998 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
999 if (gov) {
1000 policy->governor = gov;
1001 pr_debug("Restoring governor %s for cpu %d\n",
1002 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001003 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001004#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001006 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -04001007 if (ret)
1008 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -05001009
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001010 kobject_uevent(&policy->kobj, KOBJ_ADD);
Nathan Zimmer58000432013-04-04 14:53:25 +00001011 rcu_read_lock();
1012 module_put(rcu_dereference(cpufreq_driver)->owner);
1013 rcu_read_unlock();
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001014 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001015
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 return 0;
1017
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001019 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001020 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001021 per_cpu(cpufreq_cpu_data, j) = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001022 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001024 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 wait_for_completion(&policy->kobj_unregister);
1026
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301027err_set_policy_cpu:
1028 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001029 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001030err_free_cpumask:
1031 free_cpumask_var(policy->cpus);
1032err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034nomem_out:
Nathan Zimmer58000432013-04-04 14:53:25 +00001035 rcu_read_lock();
1036 module_put(rcu_dereference(cpufreq_driver)->owner);
1037 rcu_read_unlock();
Ashok Rajc32b6b82005-10-30 14:59:54 -08001038module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 return ret;
1040}
1041
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001042static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1043{
1044 int j;
1045
1046 policy->last_cpu = policy->cpu;
1047 policy->cpu = cpu;
1048
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001049 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001050 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001051
1052#ifdef CONFIG_CPU_FREQ_TABLE
1053 cpufreq_frequency_table_update_policy_cpu(policy);
1054#endif
1055 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1056 CPUFREQ_UPDATE_POLICY_CPU, policy);
1057}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001060 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 *
1062 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001063 * Caller should already have policy_rwsem in write mode for this CPU.
1064 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001066static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001068 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 unsigned long flags;
1070 struct cpufreq_policy *data;
Nathan Zimmer58000432013-04-04 14:53:25 +00001071 struct cpufreq_driver *driver;
Amerigo Wang499bca92010-03-04 03:23:46 -05001072 struct kobject *kobj;
1073 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001074 struct device *cpu_dev;
Nathan Zimmer58000432013-04-04 14:53:25 +00001075 bool has_target;
1076 int (*exit)(struct cpufreq_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001078 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001080 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 data = per_cpu(cpufreq_cpu_data, cpu);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001083 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001085 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001088 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091
Nathan Zimmer58000432013-04-04 14:53:25 +00001092 rcu_read_lock();
1093 driver = rcu_dereference(cpufreq_driver);
1094 has_target = driver->target ? true : false;
1095 exit = driver->exit;
1096 if (has_target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001098
Jacob Shin27ecddc2011-04-27 13:32:11 -05001099#ifdef CONFIG_HOTPLUG_CPU
Nathan Zimmer58000432013-04-04 14:53:25 +00001100 if (!driver->setpolicy)
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001101 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
1102 data->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001103#endif
Nathan Zimmer58000432013-04-04 14:53:25 +00001104 rcu_read_unlock();
Jacob Shin27ecddc2011-04-27 13:32:11 -05001105
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301106 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001107 cpus = cpumask_weight(data->cpus);
Viresh Kumare4969eb2013-04-11 08:04:53 +00001108
1109 if (cpus > 1)
1110 cpumask_clear_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301111 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001113 if (cpu != data->cpu) {
1114 sysfs_remove_link(&dev->kobj, "cpufreq");
1115 } else if (cpus > 1) {
Venki Pallipadiec282972007-03-26 12:03:19 -07001116 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001117 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1118 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1119 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1120 if (ret) {
1121 pr_err("%s: Failed to move kobj: %d", __func__, ret);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301122
1123 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001124 cpumask_set_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301125
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001126 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301127 per_cpu(cpufreq_cpu_data, cpu) = data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001128 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301129
1130 unlock_policy_rwsem_write(cpu);
1131
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001132 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1133 "cpufreq");
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001134 return -EINVAL;
1135 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001136
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301137 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001138 update_policy_cpu(data, cpu_dev->id);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301139 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001140 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1141 __func__, cpu_dev->id, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001142 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001143
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001144 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1145 cpufreq_cpu_put(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001146
1147 /* If cpu is last user of policy, free policy */
1148 if (cpus == 1) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001149 __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
1150
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301151 lock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001152 kobj = &data->kobj;
1153 cmp = &data->kobj_unregister;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301154 unlock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001155 kobject_put(kobj);
1156
1157 /* we need to make sure that the underlying kobj is actually
1158 * not referenced anymore by anybody before we proceed with
1159 * unloading.
1160 */
1161 pr_debug("waiting for dropping of refcount\n");
1162 wait_for_completion(cmp);
1163 pr_debug("wait complete\n");
1164
Nathan Zimmer58000432013-04-04 14:53:25 +00001165 if (exit)
1166 exit(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001167
1168 free_cpumask_var(data->related_cpus);
1169 free_cpumask_var(data->cpus);
1170 kfree(data);
Nathan Zimmer58000432013-04-04 14:53:25 +00001171 } else if (has_target) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001172 __cpufreq_governor(data, CPUFREQ_GOV_START);
1173 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1174 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301176 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 return 0;
1178}
1179
1180
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001181static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001182{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001183 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001184 int retval;
1185
1186 if (cpu_is_offline(cpu))
1187 return 0;
1188
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001189 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001190 return retval;
1191}
1192
1193
David Howells65f27f32006-11-22 14:55:48 +00001194static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195{
David Howells65f27f32006-11-22 14:55:48 +00001196 struct cpufreq_policy *policy =
1197 container_of(work, struct cpufreq_policy, update);
1198 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001199 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 cpufreq_update_policy(cpu);
1201}
1202
1203/**
1204 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1205 * @cpu: cpu number
1206 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1207 * @new_freq: CPU frequency the CPU actually runs at
1208 *
Dave Jones29464f22009-01-18 01:37:11 -05001209 * We adjust to current frequency first, and need to clean up later.
1210 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301212static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1213 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214{
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301215 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 struct cpufreq_freqs freqs;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301217 unsigned long flags;
1218
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001220 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1222
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 freqs.old = old_freq;
1224 freqs.new = new_freq;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301225
1226 read_lock_irqsave(&cpufreq_driver_lock, flags);
1227 policy = per_cpu(cpufreq_cpu_data, cpu);
1228 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1229
1230 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
1231 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232}
1233
1234
Dave Jones32ee8c32006-02-28 00:43:23 -05001235/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301236 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001237 * @cpu: CPU number
1238 *
1239 * This is the last known freq, without actually getting it from the driver.
1240 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1241 */
1242unsigned int cpufreq_quick_get(unsigned int cpu)
1243{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001244 struct cpufreq_policy *policy;
Nathan Zimmer58000432013-04-04 14:53:25 +00001245 struct cpufreq_driver *driver;
1246 unsigned int (*get)(unsigned int cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301247 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001248
Nathan Zimmer58000432013-04-04 14:53:25 +00001249 rcu_read_lock();
1250 driver = rcu_dereference(cpufreq_driver);
1251 if (driver && driver->setpolicy && driver->get) {
1252 get = driver->get;
1253 rcu_read_unlock();
1254 return get(cpu);
1255 }
1256 rcu_read_unlock();
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001257
1258 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001259 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301260 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001261 cpufreq_cpu_put(policy);
1262 }
1263
Dave Jones4d34a672008-02-07 16:33:49 -05001264 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001265}
1266EXPORT_SYMBOL(cpufreq_quick_get);
1267
Jesse Barnes3d737102011-06-28 10:59:12 -07001268/**
1269 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1270 * @cpu: CPU number
1271 *
1272 * Just return the max possible frequency for a given CPU.
1273 */
1274unsigned int cpufreq_quick_get_max(unsigned int cpu)
1275{
1276 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1277 unsigned int ret_freq = 0;
1278
1279 if (policy) {
1280 ret_freq = policy->max;
1281 cpufreq_cpu_put(policy);
1282 }
1283
1284 return ret_freq;
1285}
1286EXPORT_SYMBOL(cpufreq_quick_get_max);
1287
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001288
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001289static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001291 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Nathan Zimmer58000432013-04-04 14:53:25 +00001292 struct cpufreq_driver *driver;
1293 unsigned int (*get)(unsigned int cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301294 unsigned int ret_freq = 0;
Nathan Zimmer58000432013-04-04 14:53:25 +00001295 u8 flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296
Nathan Zimmer58000432013-04-04 14:53:25 +00001297
1298 rcu_read_lock();
1299 driver = rcu_dereference(cpufreq_driver);
1300 if (!driver->get) {
1301 rcu_read_unlock();
Dave Jones4d34a672008-02-07 16:33:49 -05001302 return ret_freq;
Nathan Zimmer58000432013-04-04 14:53:25 +00001303 }
1304 flags = driver->flags;
1305 get = driver->get;
1306 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
Nathan Zimmer58000432013-04-04 14:53:25 +00001308 ret_freq = get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301310 if (ret_freq && policy->cur &&
Nathan Zimmer58000432013-04-04 14:53:25 +00001311 !(flags & CPUFREQ_CONST_LOOPS)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301312 /* verify no discrepancy between actual and
1313 saved value exists */
1314 if (unlikely(ret_freq != policy->cur)) {
1315 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 schedule_work(&policy->update);
1317 }
1318 }
1319
Dave Jones4d34a672008-02-07 16:33:49 -05001320 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001321}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001323/**
1324 * cpufreq_get - get the current CPU frequency (in kHz)
1325 * @cpu: CPU number
1326 *
1327 * Get the CPU current (static) CPU frequency
1328 */
1329unsigned int cpufreq_get(unsigned int cpu)
1330{
1331 unsigned int ret_freq = 0;
1332 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1333
1334 if (!policy)
1335 goto out;
1336
1337 if (unlikely(lock_policy_rwsem_read(cpu)))
1338 goto out_policy;
1339
1340 ret_freq = __cpufreq_get(cpu);
1341
1342 unlock_policy_rwsem_read(cpu);
1343
1344out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001346out:
Dave Jones4d34a672008-02-07 16:33:49 -05001347 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348}
1349EXPORT_SYMBOL(cpufreq_get);
1350
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001351static struct subsys_interface cpufreq_interface = {
1352 .name = "cpufreq",
1353 .subsys = &cpu_subsys,
1354 .add_dev = cpufreq_add_dev,
1355 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001356};
1357
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358
1359/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001360 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1361 *
1362 * This function is only executed for the boot processor. The other CPUs
1363 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001364 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001365static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001366{
Nathan Zimmer58000432013-04-04 14:53:25 +00001367 int (*suspend)(struct cpufreq_policy *policy);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301368 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001369
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001370 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001371 struct cpufreq_policy *cpu_policy;
1372
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001373 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001374
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001375 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001376 cpu_policy = cpufreq_cpu_get(cpu);
1377 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001378 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001379
Nathan Zimmer58000432013-04-04 14:53:25 +00001380 rcu_read_lock();
1381 suspend = rcu_dereference(cpufreq_driver)->suspend;
1382 rcu_read_unlock();
1383 if (suspend) {
1384 ret = suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001385 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001386 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1387 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001388 }
1389
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001390 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001391 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001392}
1393
1394/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001395 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 *
1397 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001398 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1399 * restored. It will verify that the current freq is in sync with
1400 * what we believe it to be. This is a bit later than when it
1401 * should be, but nonethteless it's better than calling
1402 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001403 *
1404 * This function is only executed for the boot CPU. The other CPUs have not
1405 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001407static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301409 int ret = 0;
Nathan Zimmer58000432013-04-04 14:53:25 +00001410 int (*resume)(struct cpufreq_policy *policy);
Dave Jones4bc5d342009-08-04 14:03:25 -04001411
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001412 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 struct cpufreq_policy *cpu_policy;
1414
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001415 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001417 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 cpu_policy = cpufreq_cpu_get(cpu);
1419 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001420 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Nathan Zimmer58000432013-04-04 14:53:25 +00001422 rcu_read_lock();
1423 resume = rcu_dereference(cpufreq_driver)->resume;
1424 rcu_read_unlock();
1425
1426 if (resume) {
1427 ret = resume(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 if (ret) {
1429 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1430 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001431 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 }
1433 }
1434
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001436
Dave Jonesc9060492008-02-07 16:32:18 -05001437fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439}
1440
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001441static struct syscore_ops cpufreq_syscore_ops = {
1442 .suspend = cpufreq_bp_suspend,
1443 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444};
1445
Borislav Petkov9d950462013-01-20 10:24:28 +00001446/**
1447 * cpufreq_get_current_driver - return current driver's name
1448 *
1449 * Return the name string of the currently loaded cpufreq driver
1450 * or NULL, if none.
1451 */
1452const char *cpufreq_get_current_driver(void)
1453{
Nathan Zimmer58000432013-04-04 14:53:25 +00001454 struct cpufreq_driver *driver;
1455 const char *name = NULL;
1456 rcu_read_lock();
1457 driver = rcu_dereference(cpufreq_driver);
1458 if (driver)
1459 name = driver->name;
1460 rcu_read_unlock();
1461 return name;
Borislav Petkov9d950462013-01-20 10:24:28 +00001462}
1463EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464
1465/*********************************************************************
1466 * NOTIFIER LISTS INTERFACE *
1467 *********************************************************************/
1468
1469/**
1470 * cpufreq_register_notifier - register a driver with cpufreq
1471 * @nb: notifier function to register
1472 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1473 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001474 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 * are notified about clock rate changes (once before and once after
1476 * the transition), or a list of drivers that are notified about
1477 * changes in cpufreq policy.
1478 *
1479 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001480 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 */
1482int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1483{
1484 int ret;
1485
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001486 if (cpufreq_disabled())
1487 return -EINVAL;
1488
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001489 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 switch (list) {
1492 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001493 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001494 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 break;
1496 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001497 ret = blocking_notifier_chain_register(
1498 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 break;
1500 default:
1501 ret = -EINVAL;
1502 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503
1504 return ret;
1505}
1506EXPORT_SYMBOL(cpufreq_register_notifier);
1507
1508
1509/**
1510 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1511 * @nb: notifier block to be unregistered
1512 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1513 *
1514 * Remove a driver from the CPU frequency notifier list.
1515 *
1516 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001517 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 */
1519int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1520{
1521 int ret;
1522
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001523 if (cpufreq_disabled())
1524 return -EINVAL;
1525
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 switch (list) {
1527 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001528 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001529 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 break;
1531 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001532 ret = blocking_notifier_chain_unregister(
1533 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 break;
1535 default:
1536 ret = -EINVAL;
1537 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538
1539 return ret;
1540}
1541EXPORT_SYMBOL(cpufreq_unregister_notifier);
1542
1543
1544/*********************************************************************
1545 * GOVERNORS *
1546 *********************************************************************/
1547
1548
1549int __cpufreq_driver_target(struct cpufreq_policy *policy,
1550 unsigned int target_freq,
1551 unsigned int relation)
1552{
1553 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001554 unsigned int old_target_freq = target_freq;
Nathan Zimmer58000432013-04-04 14:53:25 +00001555 int (*target)(struct cpufreq_policy *policy,
1556 unsigned int target_freq,
1557 unsigned int relation);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001558
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001559 if (cpufreq_disabled())
1560 return -ENODEV;
1561
Viresh Kumar72499242012-10-31 01:28:21 +01001562 /* Make sure that target_freq is within supported range */
1563 if (target_freq > policy->max)
1564 target_freq = policy->max;
1565 if (target_freq < policy->min)
1566 target_freq = policy->min;
1567
1568 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1569 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001570
1571 if (target_freq == policy->cur)
1572 return 0;
1573
Nathan Zimmer58000432013-04-04 14:53:25 +00001574 rcu_read_lock();
1575 target = rcu_dereference(cpufreq_driver)->target;
1576 rcu_read_unlock();
1577 if (target)
1578 retval = target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001579
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 return retval;
1581}
1582EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1583
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584int cpufreq_driver_target(struct cpufreq_policy *policy,
1585 unsigned int target_freq,
1586 unsigned int relation)
1587{
Julia Lawallf1829e42008-07-25 22:44:53 +02001588 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
1590 policy = cpufreq_cpu_get(policy->cpu);
1591 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001592 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001594 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001595 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596
1597 ret = __cpufreq_driver_target(policy, target_freq, relation);
1598
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001599 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
Julia Lawallf1829e42008-07-25 22:44:53 +02001601fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001603no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 return ret;
1605}
1606EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1607
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001608int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001609{
1610 int ret = 0;
Nathan Zimmer58000432013-04-04 14:53:25 +00001611 unsigned int (*getavg)(struct cpufreq_policy *policy,
1612 unsigned int cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001613
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001614 if (cpufreq_disabled())
1615 return ret;
1616
Nathan Zimmer58000432013-04-04 14:53:25 +00001617 rcu_read_lock();
1618 getavg = rcu_dereference(cpufreq_driver)->getavg;
1619 rcu_read_unlock();
1620
1621 if (!getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001622 return 0;
1623
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001624 policy = cpufreq_cpu_get(policy->cpu);
1625 if (!policy)
1626 return -EINVAL;
1627
Nathan Zimmer58000432013-04-04 14:53:25 +00001628 ret = getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001629
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001630 cpufreq_cpu_put(policy);
1631 return ret;
1632}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001633EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001634
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001635/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001636 * when "event" is CPUFREQ_GOV_LIMITS
1637 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301639static int __cpufreq_governor(struct cpufreq_policy *policy,
1640 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641{
Dave Jonescc993ca2005-07-28 09:43:56 -07001642 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001643
1644 /* Only must be defined when default governor is known to have latency
1645 restrictions, like e.g. conservative or ondemand.
1646 That this is the case is already ensured in Kconfig
1647 */
1648#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1649 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1650#else
1651 struct cpufreq_governor *gov = NULL;
1652#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001653
1654 if (policy->governor->max_transition_latency &&
1655 policy->cpuinfo.transition_latency >
1656 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001657 if (!gov)
1658 return -EINVAL;
1659 else {
1660 printk(KERN_WARNING "%s governor failed, too long"
1661 " transition latency of HW, fallback"
1662 " to %s governor\n",
1663 policy->governor->name,
1664 gov->name);
1665 policy->governor = gov;
1666 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001667 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
1669 if (!try_module_get(policy->governor->owner))
1670 return -EINVAL;
1671
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001672 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301673 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 ret = policy->governor->governor(policy, event);
1675
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001676 if (!ret) {
1677 if (event == CPUFREQ_GOV_POLICY_INIT)
1678 policy->governor->initialized++;
1679 else if (event == CPUFREQ_GOV_POLICY_EXIT)
1680 policy->governor->initialized--;
1681 }
Viresh Kumarb3940582013-02-01 05:42:58 +00001682
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301683 /* we keep one module reference alive for
1684 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 if ((event != CPUFREQ_GOV_START) || ret)
1686 module_put(policy->governor->owner);
1687 if ((event == CPUFREQ_GOV_STOP) && !ret)
1688 module_put(policy->governor->owner);
1689
1690 return ret;
1691}
1692
1693
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694int cpufreq_register_governor(struct cpufreq_governor *governor)
1695{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001696 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
1698 if (!governor)
1699 return -EINVAL;
1700
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001701 if (cpufreq_disabled())
1702 return -ENODEV;
1703
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001704 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001705
Viresh Kumarb3940582013-02-01 05:42:58 +00001706 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001707 err = -EBUSY;
1708 if (__find_governor(governor->name) == NULL) {
1709 err = 0;
1710 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
Dave Jones32ee8c32006-02-28 00:43:23 -05001713 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001714 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715}
1716EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1717
1718
1719void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1720{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001721#ifdef CONFIG_HOTPLUG_CPU
1722 int cpu;
1723#endif
1724
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 if (!governor)
1726 return;
1727
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001728 if (cpufreq_disabled())
1729 return;
1730
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001731#ifdef CONFIG_HOTPLUG_CPU
1732 for_each_present_cpu(cpu) {
1733 if (cpu_online(cpu))
1734 continue;
1735 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1736 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1737 }
1738#endif
1739
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001740 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001742 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 return;
1744}
1745EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1746
1747
1748
1749/*********************************************************************
1750 * POLICY INTERFACE *
1751 *********************************************************************/
1752
1753/**
1754 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001755 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1756 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 *
1758 * Reads the current cpufreq policy.
1759 */
1760int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1761{
1762 struct cpufreq_policy *cpu_policy;
1763 if (!policy)
1764 return -EINVAL;
1765
1766 cpu_policy = cpufreq_cpu_get(cpu);
1767 if (!cpu_policy)
1768 return -EINVAL;
1769
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771
1772 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 return 0;
1774}
1775EXPORT_SYMBOL(cpufreq_get_policy);
1776
1777
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001778/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301779 * data : current policy.
1780 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001781 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301782static int __cpufreq_set_policy(struct cpufreq_policy *data,
1783 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001785 int ret = 0, failed = 1;
Nathan Zimmer58000432013-04-04 14:53:25 +00001786 struct cpufreq_driver *driver;
1787 int (*verify)(struct cpufreq_policy *policy);
1788 int (*setpolicy)(struct cpufreq_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001790 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 policy->min, policy->max);
1792
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301793 memcpy(&policy->cpuinfo, &data->cpuinfo,
1794 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
Yi Yang53391fa2008-01-30 13:33:34 +01001796 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001797 ret = -EINVAL;
1798 goto error_out;
1799 }
1800
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 /* verify the cpu speed can be set within this limit */
Nathan Zimmer58000432013-04-04 14:53:25 +00001802 rcu_read_lock();
1803 driver = rcu_dereference(cpufreq_driver);
1804 verify = driver->verify;
1805 setpolicy = driver->setpolicy;
1806 rcu_read_unlock();
1807
1808 ret = verify(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 if (ret)
1810 goto error_out;
1811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001813 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1814 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815
1816 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001817 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1818 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820 /* verify the cpu speed can be set within this limit,
1821 which might be different to the first one */
Nathan Zimmer58000432013-04-04 14:53:25 +00001822 ret = verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001823 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
1826 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001827 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1828 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
Dave Jones7d5e3502006-02-02 17:03:42 -05001830 data->min = policy->min;
1831 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001833 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301834 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
Nathan Zimmer58000432013-04-04 14:53:25 +00001836 if (setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001838 pr_debug("setting range\n");
Nathan Zimmer58000432013-04-04 14:53:25 +00001839 ret = setpolicy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 } else {
1841 if (policy->governor != data->governor) {
1842 /* save old, working values */
1843 struct cpufreq_governor *old_gov = data->governor;
1844
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001845 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
1847 /* end old governor */
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001848 if (data->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001850 __cpufreq_governor(data,
1851 CPUFREQ_GOV_POLICY_EXIT);
1852 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
1854 /* start new governor */
1855 data->governor = policy->governor;
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001856 if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
1857 if (!__cpufreq_governor(data, CPUFREQ_GOV_START))
1858 failed = 0;
1859 else
1860 __cpufreq_governor(data,
1861 CPUFREQ_GOV_POLICY_EXIT);
1862 }
1863
1864 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001866 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301867 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 if (old_gov) {
1869 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301870 __cpufreq_governor(data,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001871 CPUFREQ_GOV_POLICY_INIT);
1872 __cpufreq_governor(data,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301873 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 }
1875 ret = -EINVAL;
1876 goto error_out;
1877 }
1878 /* might be a policy change, too, so fall through */
1879 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001880 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1882 }
1883
Dave Jones7d5e3502006-02-02 17:03:42 -05001884error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 return ret;
1886}
1887
1888/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1890 * @cpu: CPU which shall be re-evaluated
1891 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001892 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893 * at different times.
1894 */
1895int cpufreq_update_policy(unsigned int cpu)
1896{
1897 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1898 struct cpufreq_policy policy;
Nathan Zimmer58000432013-04-04 14:53:25 +00001899 struct cpufreq_driver *driver;
1900 unsigned int (*get)(unsigned int cpu);
1901 int (*target)(struct cpufreq_policy *policy,
1902 unsigned int target_freq,
1903 unsigned int relation);
Julia Lawallf1829e42008-07-25 22:44:53 +02001904 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905
Julia Lawallf1829e42008-07-25 22:44:53 +02001906 if (!data) {
1907 ret = -ENODEV;
1908 goto no_policy;
1909 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910
Julia Lawallf1829e42008-07-25 22:44:53 +02001911 if (unlikely(lock_policy_rwsem_write(cpu))) {
1912 ret = -EINVAL;
1913 goto fail;
1914 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001916 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001917 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 policy.min = data->user_policy.min;
1919 policy.max = data->user_policy.max;
1920 policy.policy = data->user_policy.policy;
1921 policy.governor = data->user_policy.governor;
1922
Thomas Renninger0961dd02006-01-26 18:46:33 +01001923 /* BIOS might change freq behind our back
1924 -> ask driver for current freq and notify governors about a change */
Nathan Zimmer58000432013-04-04 14:53:25 +00001925 rcu_read_lock();
1926 driver = rcu_access_pointer(cpufreq_driver);
1927 get = driver->get;
1928 target = driver->target;
1929 rcu_read_unlock();
1930 if (get) {
1931 policy.cur = get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001932 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001933 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001934 data->cur = policy.cur;
1935 } else {
Nathan Zimmer58000432013-04-04 14:53:25 +00001936 if (data->cur != policy.cur && target)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301937 cpufreq_out_of_sync(cpu, data->cur,
1938 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001939 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001940 }
1941
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 ret = __cpufreq_set_policy(data, &policy);
1943
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001944 unlock_policy_rwsem_write(cpu);
1945
Julia Lawallf1829e42008-07-25 22:44:53 +02001946fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001948no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 return ret;
1950}
1951EXPORT_SYMBOL(cpufreq_update_policy);
1952
Satyam Sharmadd184a02007-10-02 13:28:14 -07001953static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001954 unsigned long action, void *hcpu)
1955{
1956 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001957 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001958
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001959 dev = get_cpu_device(cpu);
1960 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001961 switch (action) {
1962 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001963 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001964 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001965 break;
1966 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001967 case CPU_DOWN_PREPARE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001968 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001969 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001970 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001971 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001972 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001973 break;
1974 }
1975 }
1976 return NOTIFY_OK;
1977}
1978
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001979static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001980 .notifier_call = cpufreq_cpu_callback,
1981};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982
1983/*********************************************************************
1984 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1985 *********************************************************************/
1986
1987/**
1988 * cpufreq_register_driver - register a CPU Frequency driver
1989 * @driver_data: A struct cpufreq_driver containing the values#
1990 * submitted by the CPU Frequency driver.
1991 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001992 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001994 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995 *
1996 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001997int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998{
1999 unsigned long flags;
2000 int ret;
2001
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002002 if (cpufreq_disabled())
2003 return -ENODEV;
2004
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 if (!driver_data || !driver_data->verify || !driver_data->init ||
2006 ((!driver_data->setpolicy) && (!driver_data->target)))
2007 return -EINVAL;
2008
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002009 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011 if (driver_data->setpolicy)
2012 driver_data->flags |= CPUFREQ_CONST_LOOPS;
2013
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002014 write_lock_irqsave(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002015 if (rcu_access_pointer(cpufreq_driver)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002016 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 return -EBUSY;
2018 }
Nathan Zimmer58000432013-04-04 14:53:25 +00002019 rcu_assign_pointer(cpufreq_driver, driver_data);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002020 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002021 synchronize_rcu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002023 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002024 if (ret)
2025 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026
Nathan Zimmer58000432013-04-04 14:53:25 +00002027 if (!(driver_data->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 int i;
2029 ret = -ENODEV;
2030
2031 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07002032 for (i = 0; i < nr_cpu_ids; i++)
2033 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07002035 break;
2036 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037
2038 /* if all ->init() calls failed, unregister */
2039 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002040 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05302041 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002042 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 }
2044 }
2045
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002046 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002047 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002049 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002050err_if_unreg:
2051 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002052err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002053 write_lock_irqsave(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002054 rcu_assign_pointer(cpufreq_driver, NULL);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002055 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002056 synchronize_rcu();
Dave Jones4d34a672008-02-07 16:33:49 -05002057 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058}
2059EXPORT_SYMBOL_GPL(cpufreq_register_driver);
2060
2061
2062/**
2063 * cpufreq_unregister_driver - unregister the current CPUFreq driver
2064 *
Dave Jones32ee8c32006-02-28 00:43:23 -05002065 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066 * the right to do so, i.e. if you have succeeded in initialising before!
2067 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
2068 * currently not initialised.
2069 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002070int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071{
2072 unsigned long flags;
Nathan Zimmer58000432013-04-04 14:53:25 +00002073 struct cpufreq_driver *old_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074
Nathan Zimmer58000432013-04-04 14:53:25 +00002075 rcu_read_lock();
2076 old_driver = rcu_access_pointer(cpufreq_driver);
2077 if (!old_driver || (driver != old_driver)) {
2078 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 return -EINVAL;
Nathan Zimmer58000432013-04-04 14:53:25 +00002080 }
2081 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002083 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002085 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07002086 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002088 write_lock_irqsave(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002089 rcu_assign_pointer(cpufreq_driver, NULL);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002090 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002091 synchronize_rcu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092
2093 return 0;
2094}
2095EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002096
2097static int __init cpufreq_core_init(void)
2098{
2099 int cpu;
2100
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002101 if (cpufreq_disabled())
2102 return -ENODEV;
2103
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002104 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09002105 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002106 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
2107 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002108
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002109 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002110 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002111 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002112
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002113 return 0;
2114}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002115core_initcall(cpufreq_core_init);