blob: fd97a620518d9c37f84c0af06088b76cd9e93837 [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 kumar8bf1ac72012-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);
1108 cpumask_clear_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301109 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001111 if (cpu != data->cpu) {
1112 sysfs_remove_link(&dev->kobj, "cpufreq");
1113 } else if (cpus > 1) {
Venki Pallipadiec282972007-03-26 12:03:19 -07001114 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001115 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1116 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1117 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1118 if (ret) {
1119 pr_err("%s: Failed to move kobj: %d", __func__, ret);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301120
1121 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001122 cpumask_set_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301123
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001124 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301125 per_cpu(cpufreq_cpu_data, cpu) = data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001126 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301127
1128 unlock_policy_rwsem_write(cpu);
1129
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001130 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1131 "cpufreq");
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001132 return -EINVAL;
1133 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001134
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301135 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001136 update_policy_cpu(data, cpu_dev->id);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301137 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001138 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1139 __func__, cpu_dev->id, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001140 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001141
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001142 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1143 cpufreq_cpu_put(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001144
1145 /* If cpu is last user of policy, free policy */
1146 if (cpus == 1) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001147 __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
1148
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301149 lock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001150 kobj = &data->kobj;
1151 cmp = &data->kobj_unregister;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301152 unlock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001153 kobject_put(kobj);
1154
1155 /* we need to make sure that the underlying kobj is actually
1156 * not referenced anymore by anybody before we proceed with
1157 * unloading.
1158 */
1159 pr_debug("waiting for dropping of refcount\n");
1160 wait_for_completion(cmp);
1161 pr_debug("wait complete\n");
1162
Nathan Zimmer58000432013-04-04 14:53:25 +00001163 if (exit)
1164 exit(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001165
1166 free_cpumask_var(data->related_cpus);
1167 free_cpumask_var(data->cpus);
1168 kfree(data);
Nathan Zimmer58000432013-04-04 14:53:25 +00001169 } else if (has_target) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001170 __cpufreq_governor(data, CPUFREQ_GOV_START);
1171 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1172 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301174 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 return 0;
1176}
1177
1178
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001179static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001180{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001181 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001182 int retval;
1183
1184 if (cpu_is_offline(cpu))
1185 return 0;
1186
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001187 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001188 return retval;
1189}
1190
1191
David Howells65f27f32006-11-22 14:55:48 +00001192static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193{
David Howells65f27f32006-11-22 14:55:48 +00001194 struct cpufreq_policy *policy =
1195 container_of(work, struct cpufreq_policy, update);
1196 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001197 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198 cpufreq_update_policy(cpu);
1199}
1200
1201/**
1202 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1203 * @cpu: cpu number
1204 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1205 * @new_freq: CPU frequency the CPU actually runs at
1206 *
Dave Jones29464f22009-01-18 01:37:11 -05001207 * We adjust to current frequency first, and need to clean up later.
1208 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301210static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1211 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212{
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301213 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 struct cpufreq_freqs freqs;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301215 unsigned long flags;
1216
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001218 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1220
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 freqs.old = old_freq;
1222 freqs.new = new_freq;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301223
1224 read_lock_irqsave(&cpufreq_driver_lock, flags);
1225 policy = per_cpu(cpufreq_cpu_data, cpu);
1226 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1227
1228 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
1229 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230}
1231
1232
Dave Jones32ee8c32006-02-28 00:43:23 -05001233/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301234 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001235 * @cpu: CPU number
1236 *
1237 * This is the last known freq, without actually getting it from the driver.
1238 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1239 */
1240unsigned int cpufreq_quick_get(unsigned int cpu)
1241{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001242 struct cpufreq_policy *policy;
Nathan Zimmer58000432013-04-04 14:53:25 +00001243 struct cpufreq_driver *driver;
1244 unsigned int (*get)(unsigned int cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301245 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001246
Nathan Zimmer58000432013-04-04 14:53:25 +00001247 rcu_read_lock();
1248 driver = rcu_dereference(cpufreq_driver);
1249 if (driver && driver->setpolicy && driver->get) {
1250 get = driver->get;
1251 rcu_read_unlock();
1252 return get(cpu);
1253 }
1254 rcu_read_unlock();
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001255
1256 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001257 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301258 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001259 cpufreq_cpu_put(policy);
1260 }
1261
Dave Jones4d34a672008-02-07 16:33:49 -05001262 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001263}
1264EXPORT_SYMBOL(cpufreq_quick_get);
1265
Jesse Barnes3d737102011-06-28 10:59:12 -07001266/**
1267 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1268 * @cpu: CPU number
1269 *
1270 * Just return the max possible frequency for a given CPU.
1271 */
1272unsigned int cpufreq_quick_get_max(unsigned int cpu)
1273{
1274 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1275 unsigned int ret_freq = 0;
1276
1277 if (policy) {
1278 ret_freq = policy->max;
1279 cpufreq_cpu_put(policy);
1280 }
1281
1282 return ret_freq;
1283}
1284EXPORT_SYMBOL(cpufreq_quick_get_max);
1285
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001286
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001287static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001289 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Nathan Zimmer58000432013-04-04 14:53:25 +00001290 struct cpufreq_driver *driver;
1291 unsigned int (*get)(unsigned int cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301292 unsigned int ret_freq = 0;
Nathan Zimmer58000432013-04-04 14:53:25 +00001293 u8 flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294
Nathan Zimmer58000432013-04-04 14:53:25 +00001295
1296 rcu_read_lock();
1297 driver = rcu_dereference(cpufreq_driver);
1298 if (!driver->get) {
1299 rcu_read_unlock();
Dave Jones4d34a672008-02-07 16:33:49 -05001300 return ret_freq;
Nathan Zimmer58000432013-04-04 14:53:25 +00001301 }
1302 flags = driver->flags;
1303 get = driver->get;
1304 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
Nathan Zimmer58000432013-04-04 14:53:25 +00001306 ret_freq = get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301308 if (ret_freq && policy->cur &&
Nathan Zimmer58000432013-04-04 14:53:25 +00001309 !(flags & CPUFREQ_CONST_LOOPS)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301310 /* verify no discrepancy between actual and
1311 saved value exists */
1312 if (unlikely(ret_freq != policy->cur)) {
1313 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 schedule_work(&policy->update);
1315 }
1316 }
1317
Dave Jones4d34a672008-02-07 16:33:49 -05001318 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001319}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001321/**
1322 * cpufreq_get - get the current CPU frequency (in kHz)
1323 * @cpu: CPU number
1324 *
1325 * Get the CPU current (static) CPU frequency
1326 */
1327unsigned int cpufreq_get(unsigned int cpu)
1328{
1329 unsigned int ret_freq = 0;
1330 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1331
1332 if (!policy)
1333 goto out;
1334
1335 if (unlikely(lock_policy_rwsem_read(cpu)))
1336 goto out_policy;
1337
1338 ret_freq = __cpufreq_get(cpu);
1339
1340 unlock_policy_rwsem_read(cpu);
1341
1342out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001344out:
Dave Jones4d34a672008-02-07 16:33:49 -05001345 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346}
1347EXPORT_SYMBOL(cpufreq_get);
1348
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001349static struct subsys_interface cpufreq_interface = {
1350 .name = "cpufreq",
1351 .subsys = &cpu_subsys,
1352 .add_dev = cpufreq_add_dev,
1353 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001354};
1355
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356
1357/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001358 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1359 *
1360 * This function is only executed for the boot processor. The other CPUs
1361 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001362 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001363static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001364{
Nathan Zimmer58000432013-04-04 14:53:25 +00001365 int (*suspend)(struct cpufreq_policy *policy);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301366 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001367
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001368 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001369 struct cpufreq_policy *cpu_policy;
1370
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001371 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001372
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001373 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001374 cpu_policy = cpufreq_cpu_get(cpu);
1375 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001376 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001377
Nathan Zimmer58000432013-04-04 14:53:25 +00001378 rcu_read_lock();
1379 suspend = rcu_dereference(cpufreq_driver)->suspend;
1380 rcu_read_unlock();
1381 if (suspend) {
1382 ret = suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001383 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001384 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1385 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001386 }
1387
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001388 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001389 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001390}
1391
1392/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001393 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 *
1395 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001396 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1397 * restored. It will verify that the current freq is in sync with
1398 * what we believe it to be. This is a bit later than when it
1399 * should be, but nonethteless it's better than calling
1400 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001401 *
1402 * This function is only executed for the boot CPU. The other CPUs have not
1403 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001405static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301407 int ret = 0;
Nathan Zimmer58000432013-04-04 14:53:25 +00001408 int (*resume)(struct cpufreq_policy *policy);
Dave Jones4bc5d342009-08-04 14:03:25 -04001409
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001410 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 struct cpufreq_policy *cpu_policy;
1412
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001413 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001415 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416 cpu_policy = cpufreq_cpu_get(cpu);
1417 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001418 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
Nathan Zimmer58000432013-04-04 14:53:25 +00001420 rcu_read_lock();
1421 resume = rcu_dereference(cpufreq_driver)->resume;
1422 rcu_read_unlock();
1423
1424 if (resume) {
1425 ret = resume(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 if (ret) {
1427 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1428 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001429 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 }
1431 }
1432
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001434
Dave Jonesc9060492008-02-07 16:32:18 -05001435fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437}
1438
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001439static struct syscore_ops cpufreq_syscore_ops = {
1440 .suspend = cpufreq_bp_suspend,
1441 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442};
1443
Borislav Petkov9d950462013-01-20 10:24:28 +00001444/**
1445 * cpufreq_get_current_driver - return current driver's name
1446 *
1447 * Return the name string of the currently loaded cpufreq driver
1448 * or NULL, if none.
1449 */
1450const char *cpufreq_get_current_driver(void)
1451{
Nathan Zimmer58000432013-04-04 14:53:25 +00001452 struct cpufreq_driver *driver;
1453 const char *name = NULL;
1454 rcu_read_lock();
1455 driver = rcu_dereference(cpufreq_driver);
1456 if (driver)
1457 name = driver->name;
1458 rcu_read_unlock();
1459 return name;
Borislav Petkov9d950462013-01-20 10:24:28 +00001460}
1461EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462
1463/*********************************************************************
1464 * NOTIFIER LISTS INTERFACE *
1465 *********************************************************************/
1466
1467/**
1468 * cpufreq_register_notifier - register a driver with cpufreq
1469 * @nb: notifier function to register
1470 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1471 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001472 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 * are notified about clock rate changes (once before and once after
1474 * the transition), or a list of drivers that are notified about
1475 * changes in cpufreq policy.
1476 *
1477 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001478 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 */
1480int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1481{
1482 int ret;
1483
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001484 if (cpufreq_disabled())
1485 return -EINVAL;
1486
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001487 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1488
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 switch (list) {
1490 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001491 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001492 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 break;
1494 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001495 ret = blocking_notifier_chain_register(
1496 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 break;
1498 default:
1499 ret = -EINVAL;
1500 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501
1502 return ret;
1503}
1504EXPORT_SYMBOL(cpufreq_register_notifier);
1505
1506
1507/**
1508 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1509 * @nb: notifier block to be unregistered
1510 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1511 *
1512 * Remove a driver from the CPU frequency notifier list.
1513 *
1514 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001515 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 */
1517int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1518{
1519 int ret;
1520
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001521 if (cpufreq_disabled())
1522 return -EINVAL;
1523
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 switch (list) {
1525 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001526 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001527 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 break;
1529 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001530 ret = blocking_notifier_chain_unregister(
1531 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 break;
1533 default:
1534 ret = -EINVAL;
1535 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
1537 return ret;
1538}
1539EXPORT_SYMBOL(cpufreq_unregister_notifier);
1540
1541
1542/*********************************************************************
1543 * GOVERNORS *
1544 *********************************************************************/
1545
1546
1547int __cpufreq_driver_target(struct cpufreq_policy *policy,
1548 unsigned int target_freq,
1549 unsigned int relation)
1550{
1551 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001552 unsigned int old_target_freq = target_freq;
Nathan Zimmer58000432013-04-04 14:53:25 +00001553 int (*target)(struct cpufreq_policy *policy,
1554 unsigned int target_freq,
1555 unsigned int relation);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001556
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001557 if (cpufreq_disabled())
1558 return -ENODEV;
1559
Viresh Kumar72499242012-10-31 01:28:21 +01001560 /* Make sure that target_freq is within supported range */
1561 if (target_freq > policy->max)
1562 target_freq = policy->max;
1563 if (target_freq < policy->min)
1564 target_freq = policy->min;
1565
1566 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1567 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001568
1569 if (target_freq == policy->cur)
1570 return 0;
1571
Nathan Zimmer58000432013-04-04 14:53:25 +00001572 rcu_read_lock();
1573 target = rcu_dereference(cpufreq_driver)->target;
1574 rcu_read_unlock();
1575 if (target)
1576 retval = target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 return retval;
1579}
1580EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1581
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582int cpufreq_driver_target(struct cpufreq_policy *policy,
1583 unsigned int target_freq,
1584 unsigned int relation)
1585{
Julia Lawallf1829e42008-07-25 22:44:53 +02001586 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
1588 policy = cpufreq_cpu_get(policy->cpu);
1589 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001590 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001592 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001593 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
1595 ret = __cpufreq_driver_target(policy, target_freq, relation);
1596
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001597 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
Julia Lawallf1829e42008-07-25 22:44:53 +02001599fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001601no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602 return ret;
1603}
1604EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1605
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001606int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001607{
1608 int ret = 0;
Nathan Zimmer58000432013-04-04 14:53:25 +00001609 unsigned int (*getavg)(struct cpufreq_policy *policy,
1610 unsigned int cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001611
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001612 if (cpufreq_disabled())
1613 return ret;
1614
Nathan Zimmer58000432013-04-04 14:53:25 +00001615 rcu_read_lock();
1616 getavg = rcu_dereference(cpufreq_driver)->getavg;
1617 rcu_read_unlock();
1618
1619 if (!getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001620 return 0;
1621
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001622 policy = cpufreq_cpu_get(policy->cpu);
1623 if (!policy)
1624 return -EINVAL;
1625
Nathan Zimmer58000432013-04-04 14:53:25 +00001626 ret = getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001627
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001628 cpufreq_cpu_put(policy);
1629 return ret;
1630}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001631EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001632
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001633/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001634 * when "event" is CPUFREQ_GOV_LIMITS
1635 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301637static int __cpufreq_governor(struct cpufreq_policy *policy,
1638 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639{
Dave Jonescc993ca2005-07-28 09:43:56 -07001640 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001641
1642 /* Only must be defined when default governor is known to have latency
1643 restrictions, like e.g. conservative or ondemand.
1644 That this is the case is already ensured in Kconfig
1645 */
1646#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1647 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1648#else
1649 struct cpufreq_governor *gov = NULL;
1650#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001651
1652 if (policy->governor->max_transition_latency &&
1653 policy->cpuinfo.transition_latency >
1654 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001655 if (!gov)
1656 return -EINVAL;
1657 else {
1658 printk(KERN_WARNING "%s governor failed, too long"
1659 " transition latency of HW, fallback"
1660 " to %s governor\n",
1661 policy->governor->name,
1662 gov->name);
1663 policy->governor = gov;
1664 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001665 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
1667 if (!try_module_get(policy->governor->owner))
1668 return -EINVAL;
1669
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001670 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301671 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 ret = policy->governor->governor(policy, event);
1673
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001674 if (!ret) {
1675 if (event == CPUFREQ_GOV_POLICY_INIT)
1676 policy->governor->initialized++;
1677 else if (event == CPUFREQ_GOV_POLICY_EXIT)
1678 policy->governor->initialized--;
1679 }
Viresh Kumarb3940582013-02-01 05:42:58 +00001680
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301681 /* we keep one module reference alive for
1682 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 if ((event != CPUFREQ_GOV_START) || ret)
1684 module_put(policy->governor->owner);
1685 if ((event == CPUFREQ_GOV_STOP) && !ret)
1686 module_put(policy->governor->owner);
1687
1688 return ret;
1689}
1690
1691
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692int cpufreq_register_governor(struct cpufreq_governor *governor)
1693{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001694 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
1696 if (!governor)
1697 return -EINVAL;
1698
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001699 if (cpufreq_disabled())
1700 return -ENODEV;
1701
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001702 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001703
Viresh Kumarb3940582013-02-01 05:42:58 +00001704 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001705 err = -EBUSY;
1706 if (__find_governor(governor->name) == NULL) {
1707 err = 0;
1708 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710
Dave Jones32ee8c32006-02-28 00:43:23 -05001711 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001712 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713}
1714EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1715
1716
1717void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1718{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001719#ifdef CONFIG_HOTPLUG_CPU
1720 int cpu;
1721#endif
1722
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 if (!governor)
1724 return;
1725
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001726 if (cpufreq_disabled())
1727 return;
1728
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001729#ifdef CONFIG_HOTPLUG_CPU
1730 for_each_present_cpu(cpu) {
1731 if (cpu_online(cpu))
1732 continue;
1733 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1734 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1735 }
1736#endif
1737
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001738 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001740 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 return;
1742}
1743EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1744
1745
1746
1747/*********************************************************************
1748 * POLICY INTERFACE *
1749 *********************************************************************/
1750
1751/**
1752 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001753 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1754 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 *
1756 * Reads the current cpufreq policy.
1757 */
1758int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1759{
1760 struct cpufreq_policy *cpu_policy;
1761 if (!policy)
1762 return -EINVAL;
1763
1764 cpu_policy = cpufreq_cpu_get(cpu);
1765 if (!cpu_policy)
1766 return -EINVAL;
1767
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
1770 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 return 0;
1772}
1773EXPORT_SYMBOL(cpufreq_get_policy);
1774
1775
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001776/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301777 * data : current policy.
1778 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001779 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301780static int __cpufreq_set_policy(struct cpufreq_policy *data,
1781 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001783 int ret = 0, failed = 1;
Nathan Zimmer58000432013-04-04 14:53:25 +00001784 struct cpufreq_driver *driver;
1785 int (*verify)(struct cpufreq_policy *policy);
1786 int (*setpolicy)(struct cpufreq_policy *policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001788 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 policy->min, policy->max);
1790
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301791 memcpy(&policy->cpuinfo, &data->cpuinfo,
1792 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793
Yi Yang53391fa2008-01-30 13:33:34 +01001794 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001795 ret = -EINVAL;
1796 goto error_out;
1797 }
1798
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 /* verify the cpu speed can be set within this limit */
Nathan Zimmer58000432013-04-04 14:53:25 +00001800 rcu_read_lock();
1801 driver = rcu_dereference(cpufreq_driver);
1802 verify = driver->verify;
1803 setpolicy = driver->setpolicy;
1804 rcu_read_unlock();
1805
1806 ret = verify(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 if (ret)
1808 goto error_out;
1809
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001811 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1812 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813
1814 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001815 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1816 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
1818 /* verify the cpu speed can be set within this limit,
1819 which might be different to the first one */
Nathan Zimmer58000432013-04-04 14:53:25 +00001820 ret = verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001821 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
1824 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001825 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1826 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827
Dave Jones7d5e3502006-02-02 17:03:42 -05001828 data->min = policy->min;
1829 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001831 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301832 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833
Nathan Zimmer58000432013-04-04 14:53:25 +00001834 if (setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001836 pr_debug("setting range\n");
Nathan Zimmer58000432013-04-04 14:53:25 +00001837 ret = setpolicy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 } else {
1839 if (policy->governor != data->governor) {
1840 /* save old, working values */
1841 struct cpufreq_governor *old_gov = data->governor;
1842
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001843 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844
1845 /* end old governor */
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001846 if (data->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001848 __cpufreq_governor(data,
1849 CPUFREQ_GOV_POLICY_EXIT);
1850 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
1852 /* start new governor */
1853 data->governor = policy->governor;
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001854 if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
1855 if (!__cpufreq_governor(data, CPUFREQ_GOV_START))
1856 failed = 0;
1857 else
1858 __cpufreq_governor(data,
1859 CPUFREQ_GOV_POLICY_EXIT);
1860 }
1861
1862 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001864 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301865 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 if (old_gov) {
1867 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301868 __cpufreq_governor(data,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001869 CPUFREQ_GOV_POLICY_INIT);
1870 __cpufreq_governor(data,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301871 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 }
1873 ret = -EINVAL;
1874 goto error_out;
1875 }
1876 /* might be a policy change, too, so fall through */
1877 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001878 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1880 }
1881
Dave Jones7d5e3502006-02-02 17:03:42 -05001882error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 return ret;
1884}
1885
1886/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1888 * @cpu: CPU which shall be re-evaluated
1889 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001890 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 * at different times.
1892 */
1893int cpufreq_update_policy(unsigned int cpu)
1894{
1895 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1896 struct cpufreq_policy policy;
Nathan Zimmer58000432013-04-04 14:53:25 +00001897 struct cpufreq_driver *driver;
1898 unsigned int (*get)(unsigned int cpu);
1899 int (*target)(struct cpufreq_policy *policy,
1900 unsigned int target_freq,
1901 unsigned int relation);
Julia Lawallf1829e42008-07-25 22:44:53 +02001902 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903
Julia Lawallf1829e42008-07-25 22:44:53 +02001904 if (!data) {
1905 ret = -ENODEV;
1906 goto no_policy;
1907 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908
Julia Lawallf1829e42008-07-25 22:44:53 +02001909 if (unlikely(lock_policy_rwsem_write(cpu))) {
1910 ret = -EINVAL;
1911 goto fail;
1912 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001914 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001915 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 policy.min = data->user_policy.min;
1917 policy.max = data->user_policy.max;
1918 policy.policy = data->user_policy.policy;
1919 policy.governor = data->user_policy.governor;
1920
Thomas Renninger0961dd02006-01-26 18:46:33 +01001921 /* BIOS might change freq behind our back
1922 -> ask driver for current freq and notify governors about a change */
Nathan Zimmer58000432013-04-04 14:53:25 +00001923 rcu_read_lock();
1924 driver = rcu_access_pointer(cpufreq_driver);
1925 get = driver->get;
1926 target = driver->target;
1927 rcu_read_unlock();
1928 if (get) {
1929 policy.cur = get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001930 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001931 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001932 data->cur = policy.cur;
1933 } else {
Nathan Zimmer58000432013-04-04 14:53:25 +00001934 if (data->cur != policy.cur && target)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301935 cpufreq_out_of_sync(cpu, data->cur,
1936 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001937 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001938 }
1939
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 ret = __cpufreq_set_policy(data, &policy);
1941
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001942 unlock_policy_rwsem_write(cpu);
1943
Julia Lawallf1829e42008-07-25 22:44:53 +02001944fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001946no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 return ret;
1948}
1949EXPORT_SYMBOL(cpufreq_update_policy);
1950
Satyam Sharmadd184a02007-10-02 13:28:14 -07001951static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001952 unsigned long action, void *hcpu)
1953{
1954 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001955 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001956
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001957 dev = get_cpu_device(cpu);
1958 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001959 switch (action) {
1960 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001961 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001962 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001963 break;
1964 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001965 case CPU_DOWN_PREPARE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001966 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001967 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001968 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001969 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001970 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001971 break;
1972 }
1973 }
1974 return NOTIFY_OK;
1975}
1976
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001977static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001978 .notifier_call = cpufreq_cpu_callback,
1979};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980
1981/*********************************************************************
1982 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1983 *********************************************************************/
1984
1985/**
1986 * cpufreq_register_driver - register a CPU Frequency driver
1987 * @driver_data: A struct cpufreq_driver containing the values#
1988 * submitted by the CPU Frequency driver.
1989 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001990 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001992 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993 *
1994 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001995int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996{
1997 unsigned long flags;
1998 int ret;
1999
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002000 if (cpufreq_disabled())
2001 return -ENODEV;
2002
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003 if (!driver_data || !driver_data->verify || !driver_data->init ||
2004 ((!driver_data->setpolicy) && (!driver_data->target)))
2005 return -EINVAL;
2006
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002007 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008
2009 if (driver_data->setpolicy)
2010 driver_data->flags |= CPUFREQ_CONST_LOOPS;
2011
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002012 write_lock_irqsave(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002013 if (rcu_access_pointer(cpufreq_driver)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002014 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 return -EBUSY;
2016 }
Nathan Zimmer58000432013-04-04 14:53:25 +00002017 rcu_assign_pointer(cpufreq_driver, driver_data);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002018 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002019 synchronize_rcu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002021 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002022 if (ret)
2023 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024
Nathan Zimmer58000432013-04-04 14:53:25 +00002025 if (!(driver_data->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 int i;
2027 ret = -ENODEV;
2028
2029 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07002030 for (i = 0; i < nr_cpu_ids; i++)
2031 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07002033 break;
2034 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035
2036 /* if all ->init() calls failed, unregister */
2037 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002038 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05302039 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002040 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 }
2042 }
2043
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002044 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002045 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002047 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002048err_if_unreg:
2049 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002050err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002051 write_lock_irqsave(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002052 rcu_assign_pointer(cpufreq_driver, NULL);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002053 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002054 synchronize_rcu();
Dave Jones4d34a672008-02-07 16:33:49 -05002055 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056}
2057EXPORT_SYMBOL_GPL(cpufreq_register_driver);
2058
2059
2060/**
2061 * cpufreq_unregister_driver - unregister the current CPUFreq driver
2062 *
Dave Jones32ee8c32006-02-28 00:43:23 -05002063 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064 * the right to do so, i.e. if you have succeeded in initialising before!
2065 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
2066 * currently not initialised.
2067 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002068int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069{
2070 unsigned long flags;
Nathan Zimmer58000432013-04-04 14:53:25 +00002071 struct cpufreq_driver *old_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072
Nathan Zimmer58000432013-04-04 14:53:25 +00002073 rcu_read_lock();
2074 old_driver = rcu_access_pointer(cpufreq_driver);
2075 if (!old_driver || (driver != old_driver)) {
2076 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077 return -EINVAL;
Nathan Zimmer58000432013-04-04 14:53:25 +00002078 }
2079 rcu_read_unlock();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002081 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002083 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07002084 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002086 write_lock_irqsave(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002087 rcu_assign_pointer(cpufreq_driver, NULL);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002088 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Nathan Zimmer58000432013-04-04 14:53:25 +00002089 synchronize_rcu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090
2091 return 0;
2092}
2093EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002094
2095static int __init cpufreq_core_init(void)
2096{
2097 int cpu;
2098
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002099 if (cpufreq_disabled())
2100 return -ENODEV;
2101
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002102 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09002103 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002104 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
2105 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002106
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002107 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002108 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002109 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002110
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002111 return 0;
2112}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002113core_initcall(cpufreq_core_init);