blob: c5996fe7250e2e38660c96821f68e661b9ac95a8 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/cpufreq/cpufreq.c
3 *
4 * Copyright (C) 2001 Russell King
5 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08007 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05008 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -05009 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
10 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080011 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/notifier.h>
24#include <linux/cpufreq.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/spinlock.h>
28#include <linux/device.h>
29#include <linux/slab.h>
30#include <linux/cpu.h>
31#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080032#include <linux/mutex.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010033#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Thomas Renninger6f4f2722010-04-20 13:17:36 +020035#include <trace/events/power.h>
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037/**
Dave Jonescd878472006-08-11 17:59:28 -040038 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 * level driver of CPUFreq support, and its spinlock. This lock
40 * also protects the cpufreq_cpu_data array.
41 */
Dave Jones7d5e3502006-02-02 17:03:42 -050042static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070043static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070044#ifdef CONFIG_HOTPLUG_CPU
45/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040046static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070047#endif
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
Stephen Boyda9144432012-07-20 18:14:38 +0000131static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132{
133 struct cpufreq_policy *data;
134 unsigned long flags;
135
Mike Travis7a6aedf2008-03-25 15:06:53 -0700136 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 goto err_out;
138
139 /* get the cpufreq driver */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000140 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 if (!cpufreq_driver)
143 goto err_out_unlock;
144
145 if (!try_module_get(cpufreq_driver->owner))
146 goto err_out_unlock;
147
148
149 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700150 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
152 if (!data)
153 goto err_out_put_module;
154
Stephen Boyda9144432012-07-20 18:14:38 +0000155 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 goto err_out_put_module;
157
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000158 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 return data;
160
Dave Jones7d5e3502006-02-02 17:03:42 -0500161err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500163err_out_unlock:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000164 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500165err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 return NULL;
167}
Stephen Boyda9144432012-07-20 18:14:38 +0000168
169struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
170{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000171 if (cpufreq_disabled())
172 return NULL;
173
Stephen Boyda9144432012-07-20 18:14:38 +0000174 return __cpufreq_cpu_get(cpu, false);
175}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
177
Stephen Boyda9144432012-07-20 18:14:38 +0000178static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
179{
180 return __cpufreq_cpu_get(cpu, true);
181}
182
183static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
184{
185 if (!sysfs)
186 kobject_put(&data->kobj);
187 module_put(cpufreq_driver->owner);
188}
Dave Jones7d5e3502006-02-02 17:03:42 -0500189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190void cpufreq_cpu_put(struct cpufreq_policy *data)
191{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000192 if (cpufreq_disabled())
193 return;
194
Stephen Boyda9144432012-07-20 18:14:38 +0000195 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196}
197EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
198
Stephen Boyda9144432012-07-20 18:14:38 +0000199static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
200{
201 __cpufreq_cpu_put(data, true);
202}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
206 *********************************************************************/
207
208/**
209 * adjust_jiffies - adjust the system "loops_per_jiffy"
210 *
211 * This function alters the system "loops_per_jiffy" for the clock
212 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500213 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 * per-CPU loops_per_jiffy value wherever possible.
215 */
216#ifndef CONFIG_SMP
217static unsigned long l_p_j_ref;
218static unsigned int l_p_j_ref_freq;
219
Arjan van de Ven858119e2006-01-14 13:20:43 -0800220static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221{
222 if (ci->flags & CPUFREQ_CONST_LOOPS)
223 return;
224
225 if (!l_p_j_ref_freq) {
226 l_p_j_ref = loops_per_jiffy;
227 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200228 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530229 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530231 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700232 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530233 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
234 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200235 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530236 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 }
238}
239#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530240static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
241{
242 return;
243}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244#endif
245
246
247/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800248 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
249 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800251 * This function calls the transition notifiers and the "adjust_jiffies"
252 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500253 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 */
255void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
256{
Dave Jonese4472cb2006-01-31 15:53:55 -0800257 struct cpufreq_policy *policy;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530258 unsigned long flags;
Dave Jonese4472cb2006-01-31 15:53:55 -0800259
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 BUG_ON(irqs_disabled());
261
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000262 if (cpufreq_disabled())
263 return;
264
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200266 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800267 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000269 read_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -0700270 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000271 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800274
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500276 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800277 * which is not equal to what the cpufreq core thinks is
278 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 */
280 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800281 if ((policy) && (policy->cpu == freqs->cpu) &&
282 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200283 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800284 " %u, cpufreq assumed %u kHz.\n",
285 freqs->old, policy->cur);
286 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 }
288 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700289 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800290 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
292 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 case CPUFREQ_POSTCHANGE:
295 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200296 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200297 (unsigned long)freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100298 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700299 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800300 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800301 if (likely(policy) && likely(policy->cpu == freqs->cpu))
302 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 break;
304 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305}
306EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
307
308
309
310/*********************************************************************
311 * SYSFS INTERFACE *
312 *********************************************************************/
313
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700314static struct cpufreq_governor *__find_governor(const char *str_governor)
315{
316 struct cpufreq_governor *t;
317
318 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500319 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700320 return t;
321
322 return NULL;
323}
324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325/**
326 * cpufreq_parse_governor - parse a governor string
327 */
Dave Jones905d77c2008-03-05 14:28:32 -0500328static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 struct cpufreq_governor **governor)
330{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700331 int err = -EINVAL;
332
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700334 goto out;
335
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 if (cpufreq_driver->setpolicy) {
337 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
338 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700339 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530340 } else if (!strnicmp(str_governor, "powersave",
341 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700343 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700345 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700347
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800348 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700349
350 t = __find_governor(str_governor);
351
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700352 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700353 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700354
Kees Cook1a8e1462011-05-04 08:38:56 -0700355 mutex_unlock(&cpufreq_governor_mutex);
356 ret = request_module("cpufreq_%s", str_governor);
357 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700358
Kees Cook1a8e1462011-05-04 08:38:56 -0700359 if (ret == 0)
360 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700361 }
362
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700363 if (t != NULL) {
364 *governor = t;
365 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700367
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800368 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
Dave Jones29464f22009-01-18 01:37:11 -0500370out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700371 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530376 * cpufreq_per_cpu_attr_read() / show_##file_name() -
377 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 *
379 * Write out information from cpufreq_driver->policy[cpu]; object must be
380 * "unsigned int".
381 */
382
Dave Jones32ee8c32006-02-28 00:43:23 -0500383#define show_one(file_name, object) \
384static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500385(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500386{ \
Dave Jones29464f22009-01-18 01:37:11 -0500387 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388}
389
390show_one(cpuinfo_min_freq, cpuinfo.min_freq);
391show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100392show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393show_one(scaling_min_freq, min);
394show_one(scaling_max_freq, max);
395show_one(scaling_cur_freq, cur);
396
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530397static int __cpufreq_set_policy(struct cpufreq_policy *data,
398 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400/**
401 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
402 */
403#define store_one(file_name, object) \
404static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500405(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000407 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 struct cpufreq_policy new_policy; \
409 \
410 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
411 if (ret) \
412 return -EINVAL; \
413 \
Dave Jones29464f22009-01-18 01:37:11 -0500414 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 if (ret != 1) \
416 return -EINVAL; \
417 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200418 ret = __cpufreq_set_policy(policy, &new_policy); \
419 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 \
421 return ret ? ret : count; \
422}
423
Dave Jones29464f22009-01-18 01:37:11 -0500424store_one(scaling_min_freq, min);
425store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
427/**
428 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
429 */
Dave Jones905d77c2008-03-05 14:28:32 -0500430static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
431 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800433 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 if (!cur_freq)
435 return sprintf(buf, "<unknown>");
436 return sprintf(buf, "%u\n", cur_freq);
437}
438
439
440/**
441 * show_scaling_governor - show the current policy for the specified CPU
442 */
Dave Jones905d77c2008-03-05 14:28:32 -0500443static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444{
Dave Jones29464f22009-01-18 01:37:11 -0500445 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 return sprintf(buf, "powersave\n");
447 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
448 return sprintf(buf, "performance\n");
449 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200450 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500451 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 return -EINVAL;
453}
454
455
456/**
457 * store_scaling_governor - store policy for the specified CPU
458 */
Dave Jones905d77c2008-03-05 14:28:32 -0500459static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
460 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000462 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 char str_governor[16];
464 struct cpufreq_policy new_policy;
465
466 ret = cpufreq_get_policy(&new_policy, policy->cpu);
467 if (ret)
468 return ret;
469
Dave Jones29464f22009-01-18 01:37:11 -0500470 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 if (ret != 1)
472 return -EINVAL;
473
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530474 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
475 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 return -EINVAL;
477
Thomas Renninger7970e082006-04-13 15:14:04 +0200478 /* Do not use cpufreq_set_policy here or the user_policy.max
479 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200480 ret = __cpufreq_set_policy(policy, &new_policy);
481
482 policy->user_policy.policy = policy->policy;
483 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200484
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530485 if (ret)
486 return ret;
487 else
488 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489}
490
491/**
492 * show_scaling_driver - show the cpufreq driver currently loaded
493 */
Dave Jones905d77c2008-03-05 14:28:32 -0500494static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495{
viresh kumar4b972f02012-10-23 01:23:43 +0200496 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497}
498
499/**
500 * show_scaling_available_governors - show the available CPUfreq governors
501 */
Dave Jones905d77c2008-03-05 14:28:32 -0500502static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
503 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504{
505 ssize_t i = 0;
506 struct cpufreq_governor *t;
507
508 if (!cpufreq_driver->target) {
509 i += sprintf(buf, "performance powersave");
510 goto out;
511 }
512
513 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500514 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
515 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200517 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500519out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 i += sprintf(&buf[i], "\n");
521 return i;
522}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700523
Rusty Russell835481d2009-01-04 05:18:06 -0800524static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525{
526 ssize_t i = 0;
527 unsigned int cpu;
528
Rusty Russell835481d2009-01-04 05:18:06 -0800529 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 if (i)
531 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
532 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
533 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500534 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 }
536 i += sprintf(&buf[i], "\n");
537 return i;
538}
539
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700540/**
541 * show_related_cpus - show the CPUs affected by each transition even if
542 * hw coordination is in use
543 */
544static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
545{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700546 return show_cpus(policy->related_cpus, buf);
547}
548
549/**
550 * show_affected_cpus - show the CPUs affected by each transition
551 */
552static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
553{
554 return show_cpus(policy->cpus, buf);
555}
556
Venki Pallipadi9e769882007-10-26 10:18:21 -0700557static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500558 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700559{
560 unsigned int freq = 0;
561 unsigned int ret;
562
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700563 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700564 return -EINVAL;
565
566 ret = sscanf(buf, "%u", &freq);
567 if (ret != 1)
568 return -EINVAL;
569
570 policy->governor->store_setspeed(policy, freq);
571
572 return count;
573}
574
575static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
576{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700577 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700578 return sprintf(buf, "<unsupported>\n");
579
580 return policy->governor->show_setspeed(policy, buf);
581}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
Thomas Renningere2f74f32009-11-19 12:31:01 +0100583/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200584 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100585 */
586static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
587{
588 unsigned int limit;
589 int ret;
590 if (cpufreq_driver->bios_limit) {
591 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
592 if (!ret)
593 return sprintf(buf, "%u\n", limit);
594 }
595 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
596}
597
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200598cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
599cpufreq_freq_attr_ro(cpuinfo_min_freq);
600cpufreq_freq_attr_ro(cpuinfo_max_freq);
601cpufreq_freq_attr_ro(cpuinfo_transition_latency);
602cpufreq_freq_attr_ro(scaling_available_governors);
603cpufreq_freq_attr_ro(scaling_driver);
604cpufreq_freq_attr_ro(scaling_cur_freq);
605cpufreq_freq_attr_ro(bios_limit);
606cpufreq_freq_attr_ro(related_cpus);
607cpufreq_freq_attr_ro(affected_cpus);
608cpufreq_freq_attr_rw(scaling_min_freq);
609cpufreq_freq_attr_rw(scaling_max_freq);
610cpufreq_freq_attr_rw(scaling_governor);
611cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Dave Jones905d77c2008-03-05 14:28:32 -0500613static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 &cpuinfo_min_freq.attr,
615 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100616 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 &scaling_min_freq.attr,
618 &scaling_max_freq.attr,
619 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700620 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 &scaling_governor.attr,
622 &scaling_driver.attr,
623 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700624 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 NULL
626};
627
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200628struct kobject *cpufreq_global_kobject;
629EXPORT_SYMBOL(cpufreq_global_kobject);
630
Dave Jones29464f22009-01-18 01:37:11 -0500631#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
632#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
Dave Jones29464f22009-01-18 01:37:11 -0500634static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635{
Dave Jones905d77c2008-03-05 14:28:32 -0500636 struct cpufreq_policy *policy = to_policy(kobj);
637 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500638 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000639 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500641 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800642
643 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500644 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800645
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530646 if (fattr->show)
647 ret = fattr->show(policy, buf);
648 else
649 ret = -EIO;
650
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800651 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500652fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000653 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500654no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 return ret;
656}
657
Dave Jones905d77c2008-03-05 14:28:32 -0500658static ssize_t store(struct kobject *kobj, struct attribute *attr,
659 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
Dave Jones905d77c2008-03-05 14:28:32 -0500661 struct cpufreq_policy *policy = to_policy(kobj);
662 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500663 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000664 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500666 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800667
668 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500669 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800670
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530671 if (fattr->store)
672 ret = fattr->store(policy, buf, count);
673 else
674 ret = -EIO;
675
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800676 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500677fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000678 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500679no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 return ret;
681}
682
Dave Jones905d77c2008-03-05 14:28:32 -0500683static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684{
Dave Jones905d77c2008-03-05 14:28:32 -0500685 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200686 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 complete(&policy->kobj_unregister);
688}
689
Emese Revfy52cf25d2010-01-19 02:58:23 +0100690static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 .show = show,
692 .store = store,
693};
694
695static struct kobj_type ktype_cpufreq = {
696 .sysfs_ops = &sysfs_ops,
697 .default_attrs = default_attrs,
698 .release = cpufreq_sysfs_release,
699};
700
Dave Jones19d6f7e2009-07-08 17:35:39 -0400701/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700702static int cpufreq_add_dev_symlink(unsigned int cpu,
703 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400704{
705 unsigned int j;
706 int ret = 0;
707
708 for_each_cpu(j, policy->cpus) {
709 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800710 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400711
712 if (j == cpu)
713 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400714
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200715 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400716 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800717 cpu_dev = get_cpu_device(j);
718 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400719 "cpufreq");
720 if (ret) {
721 cpufreq_cpu_put(managed_policy);
722 return ret;
723 }
724 }
725 return ret;
726}
727
Alex Chiangcf3289d02009-11-17 20:27:08 -0700728static int cpufreq_add_dev_interface(unsigned int cpu,
729 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800730 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400731{
Dave Jonesecf7e462009-07-08 18:48:47 -0400732 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400733 struct freq_attr **drv_attr;
734 unsigned long flags;
735 int ret = 0;
736 unsigned int j;
737
738 /* prepare interface data */
739 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800740 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400741 if (ret)
742 return ret;
743
744 /* set up files for this cpu device */
745 drv_attr = cpufreq_driver->attr;
746 while ((drv_attr) && (*drv_attr)) {
747 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
748 if (ret)
749 goto err_out_kobj_put;
750 drv_attr++;
751 }
752 if (cpufreq_driver->get) {
753 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
754 if (ret)
755 goto err_out_kobj_put;
756 }
757 if (cpufreq_driver->target) {
758 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
759 if (ret)
760 goto err_out_kobj_put;
761 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100762 if (cpufreq_driver->bios_limit) {
763 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
764 if (ret)
765 goto err_out_kobj_put;
766 }
Dave Jones909a6942009-07-08 18:05:42 -0400767
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000768 write_lock_irqsave(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400769 for_each_cpu(j, policy->cpus) {
Dave Jones909a6942009-07-08 18:05:42 -0400770 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900771 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400772 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000773 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400774
775 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400776 if (ret)
777 goto err_out_kobj_put;
778
779 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
780 /* assure that the starting sequence is run in __cpufreq_set_policy */
781 policy->governor = NULL;
782
783 /* set default policy */
784 ret = __cpufreq_set_policy(policy, &new_policy);
785 policy->user_policy.policy = policy->policy;
786 policy->user_policy.governor = policy->governor;
787
788 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200789 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400790 if (cpufreq_driver->exit)
791 cpufreq_driver->exit(policy);
792 }
Dave Jones909a6942009-07-08 18:05:42 -0400793 return ret;
794
795err_out_kobj_put:
796 kobject_put(&policy->kobj);
797 wait_for_completion(&policy->kobj_unregister);
798 return ret;
799}
800
Viresh Kumarfcf80582013-01-29 14:39:08 +0000801#ifdef CONFIG_HOTPLUG_CPU
802static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
803 struct device *dev)
804{
805 struct cpufreq_policy *policy;
806 int ret = 0;
807 unsigned long flags;
808
809 policy = cpufreq_cpu_get(sibling);
810 WARN_ON(!policy);
811
Viresh Kumarfcf80582013-01-29 14:39:08 +0000812 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
813
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530814 lock_policy_rwsem_write(sibling);
815
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000816 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530817
Viresh Kumarfcf80582013-01-29 14:39:08 +0000818 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530819 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000820 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000821 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000822
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530823 unlock_policy_rwsem_write(sibling);
824
Viresh Kumarfcf80582013-01-29 14:39:08 +0000825 __cpufreq_governor(policy, CPUFREQ_GOV_START);
826 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
827
Viresh Kumarfcf80582013-01-29 14:39:08 +0000828 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
829 if (ret) {
830 cpufreq_cpu_put(policy);
831 return ret;
832 }
833
834 return 0;
835}
836#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
838/**
839 * cpufreq_add_dev - add a CPU device
840 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500841 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400842 *
843 * The Oracle says: try running cpufreq registration/unregistration concurrently
844 * with with cpu hotplugging and all hell will break loose. Tried to clean this
845 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800847static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000849 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530850 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500853#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000854 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500855 int sibling;
856#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857
Ashok Rajc32b6b82005-10-30 14:59:54 -0800858 if (cpu_is_offline(cpu))
859 return 0;
860
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200861 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862
863#ifdef CONFIG_SMP
864 /* check whether a different CPU already registered this
865 * CPU because it is in the same boat. */
866 policy = cpufreq_cpu_get(cpu);
867 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500868 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 return 0;
870 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000871
872#ifdef CONFIG_HOTPLUG_CPU
873 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000874 read_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000875 for_each_online_cpu(sibling) {
876 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530877 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000878 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000879 return cpufreq_add_policy_cpu(cpu, sibling, dev);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530880 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000881 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000882 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000883#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884#endif
885
886 if (!try_module_get(cpufreq_driver->owner)) {
887 ret = -EINVAL;
888 goto module_out;
889 }
890
Dave Jonese98df502005-10-20 15:17:43 -0700891 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400892 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400894
895 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400896 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400897
898 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400899 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900
901 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +0530902 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -0800903 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800905 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900906 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800907
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000909 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910
911 /* call driver. From then on the cpufreq must be able
912 * to accept all calls to ->verify and ->setpolicy for this CPU
913 */
914 ret = cpufreq_driver->init(policy);
915 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200916 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530917 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000919
Viresh Kumarfcf80582013-01-29 14:39:08 +0000920 /* related cpus should atleast have policy->cpus */
921 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
922
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000923 /*
924 * affected cpus must always be the one, which are online. We aren't
925 * managing offline cpus here.
926 */
927 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
928
Mike Chan187d9f42008-12-04 12:19:17 -0800929 policy->user_policy.min = policy->min;
930 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Thomas Renningera1531ac2008-07-29 22:32:58 -0700932 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
933 CPUFREQ_START, policy);
934
Viresh Kumarfcf80582013-01-29 14:39:08 +0000935#ifdef CONFIG_HOTPLUG_CPU
936 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
937 if (gov) {
938 policy->governor = gov;
939 pr_debug("Restoring governor %s for cpu %d\n",
940 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200941 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000942#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800944 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400945 if (ret)
946 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500947
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400948 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200950 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500951
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 return 0;
953
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000955 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -0800956 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -0700957 per_cpu(cpufreq_cpu_data, j) = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000958 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -0800960 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 wait_for_completion(&policy->kobj_unregister);
962
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530963err_set_policy_cpu:
964 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Xiaotian Fengcad70a62010-07-20 20:11:02 +0800965 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400966err_free_cpumask:
967 free_cpumask_var(policy->cpus);
968err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970nomem_out:
971 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -0800972module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 return ret;
974}
975
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000976static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
977{
978 int j;
979
980 policy->last_cpu = policy->cpu;
981 policy->cpu = cpu;
982
Viresh Kumar3361b7b2013-02-04 11:38:51 +0000983 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000984 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000985
986#ifdef CONFIG_CPU_FREQ_TABLE
987 cpufreq_frequency_table_update_policy_cpu(policy);
988#endif
989 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
990 CPUFREQ_UPDATE_POLICY_CPU, policy);
991}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
993/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800994 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 *
996 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800997 * Caller should already have policy_rwsem in write mode for this CPU.
998 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001000static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001002 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 unsigned long flags;
1004 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001005 struct kobject *kobj;
1006 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001007 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001009 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001011 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 data = per_cpu(cpufreq_cpu_data, cpu);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001014 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001016 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001019 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 if (cpufreq_driver->target)
1024 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001025
Jacob Shin27ecddc2011-04-27 13:32:11 -05001026#ifdef CONFIG_HOTPLUG_CPU
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001027 if (!cpufreq_driver->setpolicy)
1028 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
1029 data->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001030#endif
1031
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301032 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001033 cpus = cpumask_weight(data->cpus);
1034 cpumask_clear_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301035 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001037 if (cpu != data->cpu) {
1038 sysfs_remove_link(&dev->kobj, "cpufreq");
1039 } else if (cpus > 1) {
Venki Pallipadiec282972007-03-26 12:03:19 -07001040 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001041 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1042 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1043 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1044 if (ret) {
1045 pr_err("%s: Failed to move kobj: %d", __func__, ret);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301046
1047 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001048 cpumask_set_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301049
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001050 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301051 per_cpu(cpufreq_cpu_data, cpu) = data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001052 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301053
1054 unlock_policy_rwsem_write(cpu);
1055
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001056 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1057 "cpufreq");
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001058 return -EINVAL;
1059 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001060
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301061 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001062 update_policy_cpu(data, cpu_dev->id);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301063 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001064 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1065 __func__, cpu_dev->id, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001066 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001067
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001068 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1069 cpufreq_cpu_put(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001070
1071 /* If cpu is last user of policy, free policy */
1072 if (cpus == 1) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301073 lock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001074 kobj = &data->kobj;
1075 cmp = &data->kobj_unregister;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301076 unlock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001077 kobject_put(kobj);
1078
1079 /* we need to make sure that the underlying kobj is actually
1080 * not referenced anymore by anybody before we proceed with
1081 * unloading.
1082 */
1083 pr_debug("waiting for dropping of refcount\n");
1084 wait_for_completion(cmp);
1085 pr_debug("wait complete\n");
1086
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001087 if (cpufreq_driver->exit)
1088 cpufreq_driver->exit(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001089
1090 free_cpumask_var(data->related_cpus);
1091 free_cpumask_var(data->cpus);
1092 kfree(data);
1093 } else if (cpufreq_driver->target) {
1094 __cpufreq_governor(data, CPUFREQ_GOV_START);
1095 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1096 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301098 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 return 0;
1100}
1101
1102
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001103static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001104{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001105 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001106 int retval;
1107
1108 if (cpu_is_offline(cpu))
1109 return 0;
1110
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001111 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001112 return retval;
1113}
1114
1115
David Howells65f27f32006-11-22 14:55:48 +00001116static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117{
David Howells65f27f32006-11-22 14:55:48 +00001118 struct cpufreq_policy *policy =
1119 container_of(work, struct cpufreq_policy, update);
1120 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001121 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 cpufreq_update_policy(cpu);
1123}
1124
1125/**
1126 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1127 * @cpu: cpu number
1128 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1129 * @new_freq: CPU frequency the CPU actually runs at
1130 *
Dave Jones29464f22009-01-18 01:37:11 -05001131 * We adjust to current frequency first, and need to clean up later.
1132 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301134static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1135 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136{
1137 struct cpufreq_freqs freqs;
1138
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001139 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1141
1142 freqs.cpu = cpu;
1143 freqs.old = old_freq;
1144 freqs.new = new_freq;
1145 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1146 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1147}
1148
1149
Dave Jones32ee8c32006-02-28 00:43:23 -05001150/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301151 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001152 * @cpu: CPU number
1153 *
1154 * This is the last known freq, without actually getting it from the driver.
1155 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1156 */
1157unsigned int cpufreq_quick_get(unsigned int cpu)
1158{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001159 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301160 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001161
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001162 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1163 return cpufreq_driver->get(cpu);
1164
1165 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001166 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301167 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001168 cpufreq_cpu_put(policy);
1169 }
1170
Dave Jones4d34a672008-02-07 16:33:49 -05001171 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001172}
1173EXPORT_SYMBOL(cpufreq_quick_get);
1174
Jesse Barnes3d737102011-06-28 10:59:12 -07001175/**
1176 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1177 * @cpu: CPU number
1178 *
1179 * Just return the max possible frequency for a given CPU.
1180 */
1181unsigned int cpufreq_quick_get_max(unsigned int cpu)
1182{
1183 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1184 unsigned int ret_freq = 0;
1185
1186 if (policy) {
1187 ret_freq = policy->max;
1188 cpufreq_cpu_put(policy);
1189 }
1190
1191 return ret_freq;
1192}
1193EXPORT_SYMBOL(cpufreq_quick_get_max);
1194
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001195
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001196static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001198 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301199 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001202 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301204 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301206 if (ret_freq && policy->cur &&
1207 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1208 /* verify no discrepancy between actual and
1209 saved value exists */
1210 if (unlikely(ret_freq != policy->cur)) {
1211 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 schedule_work(&policy->update);
1213 }
1214 }
1215
Dave Jones4d34a672008-02-07 16:33:49 -05001216 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001217}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001219/**
1220 * cpufreq_get - get the current CPU frequency (in kHz)
1221 * @cpu: CPU number
1222 *
1223 * Get the CPU current (static) CPU frequency
1224 */
1225unsigned int cpufreq_get(unsigned int cpu)
1226{
1227 unsigned int ret_freq = 0;
1228 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1229
1230 if (!policy)
1231 goto out;
1232
1233 if (unlikely(lock_policy_rwsem_read(cpu)))
1234 goto out_policy;
1235
1236 ret_freq = __cpufreq_get(cpu);
1237
1238 unlock_policy_rwsem_read(cpu);
1239
1240out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001242out:
Dave Jones4d34a672008-02-07 16:33:49 -05001243 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244}
1245EXPORT_SYMBOL(cpufreq_get);
1246
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001247static struct subsys_interface cpufreq_interface = {
1248 .name = "cpufreq",
1249 .subsys = &cpu_subsys,
1250 .add_dev = cpufreq_add_dev,
1251 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001252};
1253
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254
1255/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001256 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1257 *
1258 * This function is only executed for the boot processor. The other CPUs
1259 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001260 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001261static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001262{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301263 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001264
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001265 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001266 struct cpufreq_policy *cpu_policy;
1267
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001268 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001269
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001270 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001271 cpu_policy = cpufreq_cpu_get(cpu);
1272 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001273 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001274
1275 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001276 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001277 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001278 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1279 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001280 }
1281
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001282 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001283 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001284}
1285
1286/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001287 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 *
1289 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001290 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1291 * restored. It will verify that the current freq is in sync with
1292 * what we believe it to be. This is a bit later than when it
1293 * should be, but nonethteless it's better than calling
1294 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001295 *
1296 * This function is only executed for the boot CPU. The other CPUs have not
1297 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001299static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301301 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001302
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001303 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 struct cpufreq_policy *cpu_policy;
1305
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001306 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001308 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309 cpu_policy = cpufreq_cpu_get(cpu);
1310 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001311 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312
1313 if (cpufreq_driver->resume) {
1314 ret = cpufreq_driver->resume(cpu_policy);
1315 if (ret) {
1316 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1317 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001318 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 }
1320 }
1321
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001323
Dave Jonesc9060492008-02-07 16:32:18 -05001324fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326}
1327
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001328static struct syscore_ops cpufreq_syscore_ops = {
1329 .suspend = cpufreq_bp_suspend,
1330 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331};
1332
Borislav Petkov9d950462013-01-20 10:24:28 +00001333/**
1334 * cpufreq_get_current_driver - return current driver's name
1335 *
1336 * Return the name string of the currently loaded cpufreq driver
1337 * or NULL, if none.
1338 */
1339const char *cpufreq_get_current_driver(void)
1340{
1341 if (cpufreq_driver)
1342 return cpufreq_driver->name;
1343
1344 return NULL;
1345}
1346EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347
1348/*********************************************************************
1349 * NOTIFIER LISTS INTERFACE *
1350 *********************************************************************/
1351
1352/**
1353 * cpufreq_register_notifier - register a driver with cpufreq
1354 * @nb: notifier function to register
1355 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1356 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001357 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 * are notified about clock rate changes (once before and once after
1359 * the transition), or a list of drivers that are notified about
1360 * changes in cpufreq policy.
1361 *
1362 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001363 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 */
1365int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1366{
1367 int ret;
1368
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001369 if (cpufreq_disabled())
1370 return -EINVAL;
1371
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001372 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1373
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 switch (list) {
1375 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001376 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001377 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 break;
1379 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001380 ret = blocking_notifier_chain_register(
1381 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 break;
1383 default:
1384 ret = -EINVAL;
1385 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386
1387 return ret;
1388}
1389EXPORT_SYMBOL(cpufreq_register_notifier);
1390
1391
1392/**
1393 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1394 * @nb: notifier block to be unregistered
1395 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1396 *
1397 * Remove a driver from the CPU frequency notifier list.
1398 *
1399 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001400 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 */
1402int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1403{
1404 int ret;
1405
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001406 if (cpufreq_disabled())
1407 return -EINVAL;
1408
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 switch (list) {
1410 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001411 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001412 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 break;
1414 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001415 ret = blocking_notifier_chain_unregister(
1416 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 break;
1418 default:
1419 ret = -EINVAL;
1420 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
1422 return ret;
1423}
1424EXPORT_SYMBOL(cpufreq_unregister_notifier);
1425
1426
1427/*********************************************************************
1428 * GOVERNORS *
1429 *********************************************************************/
1430
1431
1432int __cpufreq_driver_target(struct cpufreq_policy *policy,
1433 unsigned int target_freq,
1434 unsigned int relation)
1435{
1436 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001437 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001438
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001439 if (cpufreq_disabled())
1440 return -ENODEV;
1441
Viresh Kumar72499242012-10-31 01:28:21 +01001442 /* Make sure that target_freq is within supported range */
1443 if (target_freq > policy->max)
1444 target_freq = policy->max;
1445 if (target_freq < policy->min)
1446 target_freq = policy->min;
1447
1448 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1449 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001450
1451 if (target_freq == policy->cur)
1452 return 0;
1453
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001454 if (cpufreq_driver->target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001456
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 return retval;
1458}
1459EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1460
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461int cpufreq_driver_target(struct cpufreq_policy *policy,
1462 unsigned int target_freq,
1463 unsigned int relation)
1464{
Julia Lawallf1829e42008-07-25 22:44:53 +02001465 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
1467 policy = cpufreq_cpu_get(policy->cpu);
1468 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001469 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001471 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001472 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
1474 ret = __cpufreq_driver_target(policy, target_freq, relation);
1475
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001476 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477
Julia Lawallf1829e42008-07-25 22:44:53 +02001478fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001480no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 return ret;
1482}
1483EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1484
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001485int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001486{
1487 int ret = 0;
1488
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001489 if (cpufreq_disabled())
1490 return ret;
1491
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001492 if (!cpufreq_driver->getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001493 return 0;
1494
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001495 policy = cpufreq_cpu_get(policy->cpu);
1496 if (!policy)
1497 return -EINVAL;
1498
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001499 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001500
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001501 cpufreq_cpu_put(policy);
1502 return ret;
1503}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001504EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001505
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001506/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001507 * when "event" is CPUFREQ_GOV_LIMITS
1508 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301510static int __cpufreq_governor(struct cpufreq_policy *policy,
1511 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512{
Dave Jonescc993ca2005-07-28 09:43:56 -07001513 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001514
1515 /* Only must be defined when default governor is known to have latency
1516 restrictions, like e.g. conservative or ondemand.
1517 That this is the case is already ensured in Kconfig
1518 */
1519#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1520 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1521#else
1522 struct cpufreq_governor *gov = NULL;
1523#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001524
1525 if (policy->governor->max_transition_latency &&
1526 policy->cpuinfo.transition_latency >
1527 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001528 if (!gov)
1529 return -EINVAL;
1530 else {
1531 printk(KERN_WARNING "%s governor failed, too long"
1532 " transition latency of HW, fallback"
1533 " to %s governor\n",
1534 policy->governor->name,
1535 gov->name);
1536 policy->governor = gov;
1537 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001538 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
1540 if (!try_module_get(policy->governor->owner))
1541 return -EINVAL;
1542
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001543 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301544 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 ret = policy->governor->governor(policy, event);
1546
Viresh Kumar8e536952013-02-07 12:51:27 +05301547 if (event == CPUFREQ_GOV_START)
1548 policy->governor->initialized++;
1549 else if (event == CPUFREQ_GOV_STOP)
1550 policy->governor->initialized--;
Viresh Kumarb3940582013-02-01 05:42:58 +00001551
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301552 /* we keep one module reference alive for
1553 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 if ((event != CPUFREQ_GOV_START) || ret)
1555 module_put(policy->governor->owner);
1556 if ((event == CPUFREQ_GOV_STOP) && !ret)
1557 module_put(policy->governor->owner);
1558
1559 return ret;
1560}
1561
1562
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563int cpufreq_register_governor(struct cpufreq_governor *governor)
1564{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001565 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566
1567 if (!governor)
1568 return -EINVAL;
1569
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001570 if (cpufreq_disabled())
1571 return -ENODEV;
1572
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001573 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001574
Viresh Kumarb3940582013-02-01 05:42:58 +00001575 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001576 err = -EBUSY;
1577 if (__find_governor(governor->name) == NULL) {
1578 err = 0;
1579 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Dave Jones32ee8c32006-02-28 00:43:23 -05001582 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001583 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584}
1585EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1586
1587
1588void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1589{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001590#ifdef CONFIG_HOTPLUG_CPU
1591 int cpu;
1592#endif
1593
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 if (!governor)
1595 return;
1596
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001597 if (cpufreq_disabled())
1598 return;
1599
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001600#ifdef CONFIG_HOTPLUG_CPU
1601 for_each_present_cpu(cpu) {
1602 if (cpu_online(cpu))
1603 continue;
1604 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1605 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1606 }
1607#endif
1608
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001609 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001611 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 return;
1613}
1614EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1615
1616
1617
1618/*********************************************************************
1619 * POLICY INTERFACE *
1620 *********************************************************************/
1621
1622/**
1623 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001624 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1625 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 *
1627 * Reads the current cpufreq policy.
1628 */
1629int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1630{
1631 struct cpufreq_policy *cpu_policy;
1632 if (!policy)
1633 return -EINVAL;
1634
1635 cpu_policy = cpufreq_cpu_get(cpu);
1636 if (!cpu_policy)
1637 return -EINVAL;
1638
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640
1641 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 return 0;
1643}
1644EXPORT_SYMBOL(cpufreq_get_policy);
1645
1646
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001647/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301648 * data : current policy.
1649 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001650 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301651static int __cpufreq_set_policy(struct cpufreq_policy *data,
1652 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653{
1654 int ret = 0;
1655
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001656 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 policy->min, policy->max);
1658
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301659 memcpy(&policy->cpuinfo, &data->cpuinfo,
1660 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661
Yi Yang53391fa2008-01-30 13:33:34 +01001662 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001663 ret = -EINVAL;
1664 goto error_out;
1665 }
1666
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 /* verify the cpu speed can be set within this limit */
1668 ret = cpufreq_driver->verify(policy);
1669 if (ret)
1670 goto error_out;
1671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001673 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1674 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
1676 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001677 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1678 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
1680 /* verify the cpu speed can be set within this limit,
1681 which might be different to the first one */
1682 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001683 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
1686 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001687 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1688 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
Dave Jones7d5e3502006-02-02 17:03:42 -05001690 data->min = policy->min;
1691 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001693 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301694 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
1696 if (cpufreq_driver->setpolicy) {
1697 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001698 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 ret = cpufreq_driver->setpolicy(policy);
1700 } else {
1701 if (policy->governor != data->governor) {
1702 /* save old, working values */
1703 struct cpufreq_governor *old_gov = data->governor;
1704
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001705 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706
1707 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001708 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1710
1711 /* start new governor */
1712 data->governor = policy->governor;
1713 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1714 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001715 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301716 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 if (old_gov) {
1718 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301719 __cpufreq_governor(data,
1720 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 }
1722 ret = -EINVAL;
1723 goto error_out;
1724 }
1725 /* might be a policy change, too, so fall through */
1726 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001727 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1729 }
1730
Dave Jones7d5e3502006-02-02 17:03:42 -05001731error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 return ret;
1733}
1734
1735/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1737 * @cpu: CPU which shall be re-evaluated
1738 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001739 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 * at different times.
1741 */
1742int cpufreq_update_policy(unsigned int cpu)
1743{
1744 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1745 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001746 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
Julia Lawallf1829e42008-07-25 22:44:53 +02001748 if (!data) {
1749 ret = -ENODEV;
1750 goto no_policy;
1751 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
Julia Lawallf1829e42008-07-25 22:44:53 +02001753 if (unlikely(lock_policy_rwsem_write(cpu))) {
1754 ret = -EINVAL;
1755 goto fail;
1756 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001758 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001759 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 policy.min = data->user_policy.min;
1761 policy.max = data->user_policy.max;
1762 policy.policy = data->user_policy.policy;
1763 policy.governor = data->user_policy.governor;
1764
Thomas Renninger0961dd02006-01-26 18:46:33 +01001765 /* BIOS might change freq behind our back
1766 -> ask driver for current freq and notify governors about a change */
1767 if (cpufreq_driver->get) {
1768 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001769 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001770 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001771 data->cur = policy.cur;
1772 } else {
Dirk Brandewief6b05152013-02-06 09:02:09 -08001773 if (data->cur != policy.cur && cpufreq_driver->target)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301774 cpufreq_out_of_sync(cpu, data->cur,
1775 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001776 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001777 }
1778
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 ret = __cpufreq_set_policy(data, &policy);
1780
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001781 unlock_policy_rwsem_write(cpu);
1782
Julia Lawallf1829e42008-07-25 22:44:53 +02001783fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001785no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 return ret;
1787}
1788EXPORT_SYMBOL(cpufreq_update_policy);
1789
Satyam Sharmadd184a02007-10-02 13:28:14 -07001790static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001791 unsigned long action, void *hcpu)
1792{
1793 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001794 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001795
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001796 dev = get_cpu_device(cpu);
1797 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001798 switch (action) {
1799 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001800 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001801 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001802 break;
1803 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001804 case CPU_DOWN_PREPARE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001805 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001806 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001807 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001808 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001809 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001810 break;
1811 }
1812 }
1813 return NOTIFY_OK;
1814}
1815
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001816static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001817 .notifier_call = cpufreq_cpu_callback,
1818};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819
1820/*********************************************************************
1821 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1822 *********************************************************************/
1823
1824/**
1825 * cpufreq_register_driver - register a CPU Frequency driver
1826 * @driver_data: A struct cpufreq_driver containing the values#
1827 * submitted by the CPU Frequency driver.
1828 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001829 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001831 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 *
1833 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001834int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835{
1836 unsigned long flags;
1837 int ret;
1838
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001839 if (cpufreq_disabled())
1840 return -ENODEV;
1841
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 if (!driver_data || !driver_data->verify || !driver_data->init ||
1843 ((!driver_data->setpolicy) && (!driver_data->target)))
1844 return -EINVAL;
1845
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001846 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847
1848 if (driver_data->setpolicy)
1849 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1850
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001851 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 if (cpufreq_driver) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001853 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 return -EBUSY;
1855 }
1856 cpufreq_driver = driver_data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001857 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001859 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001860 if (ret)
1861 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001863 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 int i;
1865 ret = -ENODEV;
1866
1867 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001868 for (i = 0; i < nr_cpu_ids; i++)
1869 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001871 break;
1872 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 /* if all ->init() calls failed, unregister */
1875 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001876 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301877 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001878 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 }
1880 }
1881
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001882 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001883 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001885 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001886err_if_unreg:
1887 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001888err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001889 write_lock_irqsave(&cpufreq_driver_lock, flags);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001890 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001891 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001892 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893}
1894EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1895
1896
1897/**
1898 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1899 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001900 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 * the right to do so, i.e. if you have succeeded in initialising before!
1902 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1903 * currently not initialised.
1904 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001905int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906{
1907 unsigned long flags;
1908
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001909 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001912 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001914 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001915 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001917 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001919 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920
1921 return 0;
1922}
1923EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001924
1925static int __init cpufreq_core_init(void)
1926{
1927 int cpu;
1928
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001929 if (cpufreq_disabled())
1930 return -ENODEV;
1931
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001932 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001933 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001934 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1935 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001936
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001937 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001938 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001939 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001940
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001941 return 0;
1942}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001943core_initcall(cpufreq_core_init);