blob: 216c104d51add116ad66ff9a5d5a425fe5bc8bb1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/cpufreq/cpufreq.c
3 *
4 * Copyright (C) 2001 Russell King
5 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08007 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05008 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -05009 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
10 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080011 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/notifier.h>
24#include <linux/cpufreq.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/spinlock.h>
28#include <linux/device.h>
29#include <linux/slab.h>
30#include <linux/cpu.h>
31#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080032#include <linux/mutex.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010033#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Thomas Renninger6f4f2722010-04-20 13:17:36 +020035#include <trace/events/power.h>
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037/**
Dave Jonescd878472006-08-11 17:59:28 -040038 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 * level driver of CPUFreq support, and its spinlock. This lock
40 * also protects the cpufreq_cpu_data array.
41 */
Dave Jones7d5e3502006-02-02 17:03:42 -050042static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070043static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070044#ifdef CONFIG_HOTPLUG_CPU
45/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040046static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070047#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070048static DEFINE_SPINLOCK(cpufreq_driver_lock);
49
Viresh Kumar6954ca92013-01-12 05:14:40 +000050/* Used when we unregister cpufreq driver */
51static struct cpumask cpufreq_online_mask;
52
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080053/*
54 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
55 * all cpufreq/hotplug/workqueue/etc related lock issues.
56 *
57 * The rules for this semaphore:
58 * - Any routine that wants to read from the policy structure will
59 * do a down_read on this semaphore.
60 * - Any routine that will write to the policy structure and/or may take away
61 * the policy altogether (eg. CPU hotplug), will hold this lock in write
62 * mode before doing so.
63 *
64 * Additional rules:
65 * - All holders of the lock should check to make sure that the CPU they
66 * are concerned with are online after they get the lock.
67 * - Governor routines that can be called in cpufreq hotplug path should not
68 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040069 * - Lock should not be held across
70 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080071 */
Tejun Heof1625062009-10-29 22:34:13 +090072static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080073static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
74
75#define lock_policy_rwsem(mode, cpu) \
Amerigo Wang226528c2010-03-04 03:23:36 -050076static int lock_policy_rwsem_##mode \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080077(int cpu) \
78{ \
Tejun Heof1625062009-10-29 22:34:13 +090079 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080080 BUG_ON(policy_cpu == -1); \
81 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
82 if (unlikely(!cpu_online(cpu))) { \
83 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
84 return -1; \
85 } \
86 \
87 return 0; \
88}
89
90lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080091
92lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Amerigo Wang226528c2010-03-04 03:23:36 -050094static void unlock_policy_rwsem_read(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080095{
Tejun Heof1625062009-10-29 22:34:13 +090096 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097 BUG_ON(policy_cpu == -1);
98 up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
99}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800100
Amerigo Wang226528c2010-03-04 03:23:36 -0500101static void unlock_policy_rwsem_write(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800102{
Tejun Heof1625062009-10-29 22:34:13 +0900103 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800104 BUG_ON(policy_cpu == -1);
105 up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
106}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800107
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500110static int __cpufreq_governor(struct cpufreq_policy *policy,
111 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800112static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000113static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
115/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500116 * Two notifier lists: the "policy" list is involved in the
117 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 * "transition" list for kernel code that needs to handle
119 * changes to devices when the CPU clock speed changes.
120 * The mutex locks both lists.
121 */
Alan Sterne041c682006-03-27 01:16:30 -0800122static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700123static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200125static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700126static int __init init_cpufreq_transition_notifier_list(void)
127{
128 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200129 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700130 return 0;
131}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800132pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400134static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200135static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400136{
137 return off;
138}
139void disable_cpufreq(void)
140{
141 off = 1;
142}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500144static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
Stephen Boyda9144432012-07-20 18:14:38 +0000146static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147{
148 struct cpufreq_policy *data;
149 unsigned long flags;
150
Mike Travis7a6aedf2008-03-25 15:06:53 -0700151 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 goto err_out;
153
154 /* get the cpufreq driver */
155 spin_lock_irqsave(&cpufreq_driver_lock, flags);
156
157 if (!cpufreq_driver)
158 goto err_out_unlock;
159
160 if (!try_module_get(cpufreq_driver->owner))
161 goto err_out_unlock;
162
163
164 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700165 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166
167 if (!data)
168 goto err_out_put_module;
169
Stephen Boyda9144432012-07-20 18:14:38 +0000170 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 goto err_out_put_module;
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 return data;
175
Dave Jones7d5e3502006-02-02 17:03:42 -0500176err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500178err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500180err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 return NULL;
182}
Stephen Boyda9144432012-07-20 18:14:38 +0000183
184struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
185{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000186 if (cpufreq_disabled())
187 return NULL;
188
Stephen Boyda9144432012-07-20 18:14:38 +0000189 return __cpufreq_cpu_get(cpu, false);
190}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
192
Stephen Boyda9144432012-07-20 18:14:38 +0000193static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
194{
195 return __cpufreq_cpu_get(cpu, true);
196}
197
198static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
199{
200 if (!sysfs)
201 kobject_put(&data->kobj);
202 module_put(cpufreq_driver->owner);
203}
Dave Jones7d5e3502006-02-02 17:03:42 -0500204
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205void cpufreq_cpu_put(struct cpufreq_policy *data)
206{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000207 if (cpufreq_disabled())
208 return;
209
Stephen Boyda9144432012-07-20 18:14:38 +0000210 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211}
212EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
213
Stephen Boyda9144432012-07-20 18:14:38 +0000214static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
215{
216 __cpufreq_cpu_put(data, true);
217}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218
219/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
221 *********************************************************************/
222
223/**
224 * adjust_jiffies - adjust the system "loops_per_jiffy"
225 *
226 * This function alters the system "loops_per_jiffy" for the clock
227 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500228 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 * per-CPU loops_per_jiffy value wherever possible.
230 */
231#ifndef CONFIG_SMP
232static unsigned long l_p_j_ref;
233static unsigned int l_p_j_ref_freq;
234
Arjan van de Ven858119e2006-01-14 13:20:43 -0800235static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236{
237 if (ci->flags & CPUFREQ_CONST_LOOPS)
238 return;
239
240 if (!l_p_j_ref_freq) {
241 l_p_j_ref = loops_per_jiffy;
242 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200243 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530244 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530246 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700247 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530248 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
249 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200250 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530251 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 }
253}
254#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530255static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
256{
257 return;
258}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259#endif
260
261
262/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800263 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
264 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800266 * This function calls the transition notifiers and the "adjust_jiffies"
267 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500268 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 */
270void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
271{
Dave Jonese4472cb2006-01-31 15:53:55 -0800272 struct cpufreq_policy *policy;
273
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 BUG_ON(irqs_disabled());
275
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000276 if (cpufreq_disabled())
277 return;
278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200280 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800281 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282
Mike Travis7a6aedf2008-03-25 15:06:53 -0700283 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500287 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800288 * which is not equal to what the cpufreq core thinks is
289 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 */
291 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800292 if ((policy) && (policy->cpu == freqs->cpu) &&
293 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200294 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800295 " %u, cpufreq assumed %u kHz.\n",
296 freqs->old, policy->cur);
297 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 }
299 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700300 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800301 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
303 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800304
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 case CPUFREQ_POSTCHANGE:
306 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200307 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200308 (unsigned long)freqs->cpu);
309 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100310 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700311 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800312 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800313 if (likely(policy) && likely(policy->cpu == freqs->cpu))
314 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 break;
316 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317}
318EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
319
320
321
322/*********************************************************************
323 * SYSFS INTERFACE *
324 *********************************************************************/
325
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700326static struct cpufreq_governor *__find_governor(const char *str_governor)
327{
328 struct cpufreq_governor *t;
329
330 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500331 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700332 return t;
333
334 return NULL;
335}
336
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337/**
338 * cpufreq_parse_governor - parse a governor string
339 */
Dave Jones905d77c2008-03-05 14:28:32 -0500340static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 struct cpufreq_governor **governor)
342{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700343 int err = -EINVAL;
344
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700346 goto out;
347
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 if (cpufreq_driver->setpolicy) {
349 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
350 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700351 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530352 } else if (!strnicmp(str_governor, "powersave",
353 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700355 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700357 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700359
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800360 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700361
362 t = __find_governor(str_governor);
363
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700364 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700365 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700366
Kees Cook1a8e1462011-05-04 08:38:56 -0700367 mutex_unlock(&cpufreq_governor_mutex);
368 ret = request_module("cpufreq_%s", str_governor);
369 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700370
Kees Cook1a8e1462011-05-04 08:38:56 -0700371 if (ret == 0)
372 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700373 }
374
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700375 if (t != NULL) {
376 *governor = t;
377 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700379
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800380 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 }
Dave Jones29464f22009-01-18 01:37:11 -0500382out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700383 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
386
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530388 * cpufreq_per_cpu_attr_read() / show_##file_name() -
389 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 *
391 * Write out information from cpufreq_driver->policy[cpu]; object must be
392 * "unsigned int".
393 */
394
Dave Jones32ee8c32006-02-28 00:43:23 -0500395#define show_one(file_name, object) \
396static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500397(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500398{ \
Dave Jones29464f22009-01-18 01:37:11 -0500399 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400}
401
402show_one(cpuinfo_min_freq, cpuinfo.min_freq);
403show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100404show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405show_one(scaling_min_freq, min);
406show_one(scaling_max_freq, max);
407show_one(scaling_cur_freq, cur);
408
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530409static int __cpufreq_set_policy(struct cpufreq_policy *data,
410 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200411
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412/**
413 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
414 */
415#define store_one(file_name, object) \
416static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500417(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000419 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 struct cpufreq_policy new_policy; \
421 \
422 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
423 if (ret) \
424 return -EINVAL; \
425 \
Dave Jones29464f22009-01-18 01:37:11 -0500426 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 if (ret != 1) \
428 return -EINVAL; \
429 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200430 ret = __cpufreq_set_policy(policy, &new_policy); \
431 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 \
433 return ret ? ret : count; \
434}
435
Dave Jones29464f22009-01-18 01:37:11 -0500436store_one(scaling_min_freq, min);
437store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438
439/**
440 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
441 */
Dave Jones905d77c2008-03-05 14:28:32 -0500442static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
443 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800445 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 if (!cur_freq)
447 return sprintf(buf, "<unknown>");
448 return sprintf(buf, "%u\n", cur_freq);
449}
450
451
452/**
453 * show_scaling_governor - show the current policy for the specified CPU
454 */
Dave Jones905d77c2008-03-05 14:28:32 -0500455static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456{
Dave Jones29464f22009-01-18 01:37:11 -0500457 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 return sprintf(buf, "powersave\n");
459 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
460 return sprintf(buf, "performance\n");
461 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200462 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500463 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 return -EINVAL;
465}
466
467
468/**
469 * store_scaling_governor - store policy for the specified CPU
470 */
Dave Jones905d77c2008-03-05 14:28:32 -0500471static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
472 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000474 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 char str_governor[16];
476 struct cpufreq_policy new_policy;
477
478 ret = cpufreq_get_policy(&new_policy, policy->cpu);
479 if (ret)
480 return ret;
481
Dave Jones29464f22009-01-18 01:37:11 -0500482 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 if (ret != 1)
484 return -EINVAL;
485
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530486 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
487 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 return -EINVAL;
489
Thomas Renninger7970e082006-04-13 15:14:04 +0200490 /* Do not use cpufreq_set_policy here or the user_policy.max
491 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200492 ret = __cpufreq_set_policy(policy, &new_policy);
493
494 policy->user_policy.policy = policy->policy;
495 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200496
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530497 if (ret)
498 return ret;
499 else
500 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501}
502
503/**
504 * show_scaling_driver - show the cpufreq driver currently loaded
505 */
Dave Jones905d77c2008-03-05 14:28:32 -0500506static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507{
viresh kumar4b972f02012-10-23 01:23:43 +0200508 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509}
510
511/**
512 * show_scaling_available_governors - show the available CPUfreq governors
513 */
Dave Jones905d77c2008-03-05 14:28:32 -0500514static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
515 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516{
517 ssize_t i = 0;
518 struct cpufreq_governor *t;
519
520 if (!cpufreq_driver->target) {
521 i += sprintf(buf, "performance powersave");
522 goto out;
523 }
524
525 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500526 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
527 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200529 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500531out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 i += sprintf(&buf[i], "\n");
533 return i;
534}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700535
Rusty Russell835481d2009-01-04 05:18:06 -0800536static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537{
538 ssize_t i = 0;
539 unsigned int cpu;
540
Rusty Russell835481d2009-01-04 05:18:06 -0800541 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 if (i)
543 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
544 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
545 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500546 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 }
548 i += sprintf(&buf[i], "\n");
549 return i;
550}
551
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700552/**
553 * show_related_cpus - show the CPUs affected by each transition even if
554 * hw coordination is in use
555 */
556static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
557{
Rusty Russell835481d2009-01-04 05:18:06 -0800558 if (cpumask_empty(policy->related_cpus))
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700559 return show_cpus(policy->cpus, buf);
560 return show_cpus(policy->related_cpus, buf);
561}
562
563/**
564 * show_affected_cpus - show the CPUs affected by each transition
565 */
566static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
567{
568 return show_cpus(policy->cpus, buf);
569}
570
Venki Pallipadi9e769882007-10-26 10:18:21 -0700571static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500572 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700573{
574 unsigned int freq = 0;
575 unsigned int ret;
576
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700577 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700578 return -EINVAL;
579
580 ret = sscanf(buf, "%u", &freq);
581 if (ret != 1)
582 return -EINVAL;
583
584 policy->governor->store_setspeed(policy, freq);
585
586 return count;
587}
588
589static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
590{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700591 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700592 return sprintf(buf, "<unsupported>\n");
593
594 return policy->governor->show_setspeed(policy, buf);
595}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
Thomas Renningere2f74f32009-11-19 12:31:01 +0100597/**
viresh kumar8bf1ac72012-10-23 01:23:33 +0200598 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100599 */
600static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
601{
602 unsigned int limit;
603 int ret;
604 if (cpufreq_driver->bios_limit) {
605 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
606 if (!ret)
607 return sprintf(buf, "%u\n", limit);
608 }
609 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
610}
611
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200612cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
613cpufreq_freq_attr_ro(cpuinfo_min_freq);
614cpufreq_freq_attr_ro(cpuinfo_max_freq);
615cpufreq_freq_attr_ro(cpuinfo_transition_latency);
616cpufreq_freq_attr_ro(scaling_available_governors);
617cpufreq_freq_attr_ro(scaling_driver);
618cpufreq_freq_attr_ro(scaling_cur_freq);
619cpufreq_freq_attr_ro(bios_limit);
620cpufreq_freq_attr_ro(related_cpus);
621cpufreq_freq_attr_ro(affected_cpus);
622cpufreq_freq_attr_rw(scaling_min_freq);
623cpufreq_freq_attr_rw(scaling_max_freq);
624cpufreq_freq_attr_rw(scaling_governor);
625cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626
Dave Jones905d77c2008-03-05 14:28:32 -0500627static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 &cpuinfo_min_freq.attr,
629 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100630 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 &scaling_min_freq.attr,
632 &scaling_max_freq.attr,
633 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700634 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 &scaling_governor.attr,
636 &scaling_driver.attr,
637 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700638 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 NULL
640};
641
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200642struct kobject *cpufreq_global_kobject;
643EXPORT_SYMBOL(cpufreq_global_kobject);
644
Dave Jones29464f22009-01-18 01:37:11 -0500645#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
646#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Dave Jones29464f22009-01-18 01:37:11 -0500648static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649{
Dave Jones905d77c2008-03-05 14:28:32 -0500650 struct cpufreq_policy *policy = to_policy(kobj);
651 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500652 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000653 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500655 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800656
657 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500658 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800659
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530660 if (fattr->show)
661 ret = fattr->show(policy, buf);
662 else
663 ret = -EIO;
664
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800665 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500666fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000667 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500668no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 return ret;
670}
671
Dave Jones905d77c2008-03-05 14:28:32 -0500672static ssize_t store(struct kobject *kobj, struct attribute *attr,
673 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674{
Dave Jones905d77c2008-03-05 14:28:32 -0500675 struct cpufreq_policy *policy = to_policy(kobj);
676 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500677 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000678 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500680 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800681
682 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500683 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800684
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530685 if (fattr->store)
686 ret = fattr->store(policy, buf, count);
687 else
688 ret = -EIO;
689
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800690 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500691fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000692 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500693no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 return ret;
695}
696
Dave Jones905d77c2008-03-05 14:28:32 -0500697static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698{
Dave Jones905d77c2008-03-05 14:28:32 -0500699 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200700 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 complete(&policy->kobj_unregister);
702}
703
Emese Revfy52cf25d2010-01-19 02:58:23 +0100704static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 .show = show,
706 .store = store,
707};
708
709static struct kobj_type ktype_cpufreq = {
710 .sysfs_ops = &sysfs_ops,
711 .default_attrs = default_attrs,
712 .release = cpufreq_sysfs_release,
713};
714
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200715/*
716 * Returns:
717 * Negative: Failure
718 * 0: Success
719 * Positive: When we have a managed CPU and the sysfs got symlinked
720 */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700721static int cpufreq_add_dev_policy(unsigned int cpu,
722 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800723 struct device *dev)
Dave Jonesecf7e462009-07-08 18:48:47 -0400724{
725 int ret = 0;
726#ifdef CONFIG_SMP
727 unsigned long flags;
728 unsigned int j;
Dave Jonesecf7e462009-07-08 18:48:47 -0400729#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400730 struct cpufreq_governor *gov;
731
732 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
733 if (gov) {
734 policy->governor = gov;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200735 pr_debug("Restoring governor %s for cpu %d\n",
Dave Jonesecf7e462009-07-08 18:48:47 -0400736 policy->governor->name, cpu);
737 }
738#endif
739
740 for_each_cpu(j, policy->cpus) {
741 struct cpufreq_policy *managed_policy;
742
743 if (cpu == j)
744 continue;
745
746 /* Check for existing affected CPUs.
747 * They may not be aware of it due to CPU Hotplug.
748 * cpufreq_cpu_put is called when the device is removed
749 * in __cpufreq_remove_dev()
750 */
751 managed_policy = cpufreq_cpu_get(j);
752 if (unlikely(managed_policy)) {
753
754 /* Set proper policy_cpu */
755 unlock_policy_rwsem_write(cpu);
Tejun Heof1625062009-10-29 22:34:13 +0900756 per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
Dave Jonesecf7e462009-07-08 18:48:47 -0400757
758 if (lock_policy_rwsem_write(cpu) < 0) {
759 /* Should not go through policy unlock path */
760 if (cpufreq_driver->exit)
761 cpufreq_driver->exit(policy);
762 cpufreq_cpu_put(managed_policy);
763 return -EBUSY;
764 }
765
Viresh Kumarf6a74092013-01-12 05:14:39 +0000766 __cpufreq_governor(managed_policy, CPUFREQ_GOV_STOP);
767
Dave Jonesecf7e462009-07-08 18:48:47 -0400768 spin_lock_irqsave(&cpufreq_driver_lock, flags);
769 cpumask_copy(managed_policy->cpus, policy->cpus);
770 per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
771 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
772
Viresh Kumarf6a74092013-01-12 05:14:39 +0000773 __cpufreq_governor(managed_policy, CPUFREQ_GOV_START);
774 __cpufreq_governor(managed_policy, CPUFREQ_GOV_LIMITS);
775
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200776 pr_debug("CPU already managed, adding link\n");
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800777 ret = sysfs_create_link(&dev->kobj,
Dave Jonesecf7e462009-07-08 18:48:47 -0400778 &managed_policy->kobj,
779 "cpufreq");
780 if (ret)
781 cpufreq_cpu_put(managed_policy);
782 /*
783 * Success. We only needed to be added to the mask.
784 * Call driver->exit() because only the cpu parent of
785 * the kobj needed to call init().
786 */
787 if (cpufreq_driver->exit)
788 cpufreq_driver->exit(policy);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200789
790 if (!ret)
791 return 1;
792 else
793 return ret;
Dave Jonesecf7e462009-07-08 18:48:47 -0400794 }
795 }
796#endif
797 return ret;
798}
799
800
Dave Jones19d6f7e2009-07-08 17:35:39 -0400801/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700802static int cpufreq_add_dev_symlink(unsigned int cpu,
803 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400804{
805 unsigned int j;
806 int ret = 0;
807
808 for_each_cpu(j, policy->cpus) {
809 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800810 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400811
812 if (j == cpu)
813 continue;
814 if (!cpu_online(j))
815 continue;
816
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200817 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400818 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800819 cpu_dev = get_cpu_device(j);
820 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400821 "cpufreq");
822 if (ret) {
823 cpufreq_cpu_put(managed_policy);
824 return ret;
825 }
826 }
827 return ret;
828}
829
Alex Chiangcf3289d02009-11-17 20:27:08 -0700830static int cpufreq_add_dev_interface(unsigned int cpu,
831 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800832 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400833{
Dave Jonesecf7e462009-07-08 18:48:47 -0400834 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400835 struct freq_attr **drv_attr;
836 unsigned long flags;
837 int ret = 0;
838 unsigned int j;
839
840 /* prepare interface data */
841 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800842 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400843 if (ret)
844 return ret;
845
846 /* set up files for this cpu device */
847 drv_attr = cpufreq_driver->attr;
848 while ((drv_attr) && (*drv_attr)) {
849 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
850 if (ret)
851 goto err_out_kobj_put;
852 drv_attr++;
853 }
854 if (cpufreq_driver->get) {
855 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
856 if (ret)
857 goto err_out_kobj_put;
858 }
859 if (cpufreq_driver->target) {
860 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
861 if (ret)
862 goto err_out_kobj_put;
863 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100864 if (cpufreq_driver->bios_limit) {
865 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
866 if (ret)
867 goto err_out_kobj_put;
868 }
Dave Jones909a6942009-07-08 18:05:42 -0400869
870 spin_lock_irqsave(&cpufreq_driver_lock, flags);
871 for_each_cpu(j, policy->cpus) {
Julia Lawallbec037a2010-08-05 22:23:00 +0200872 if (!cpu_online(j))
873 continue;
Dave Jones909a6942009-07-08 18:05:42 -0400874 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900875 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400876 }
877 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
878
879 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400880 if (ret)
881 goto err_out_kobj_put;
882
883 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
884 /* assure that the starting sequence is run in __cpufreq_set_policy */
885 policy->governor = NULL;
886
887 /* set default policy */
888 ret = __cpufreq_set_policy(policy, &new_policy);
889 policy->user_policy.policy = policy->policy;
890 policy->user_policy.governor = policy->governor;
891
892 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200893 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400894 if (cpufreq_driver->exit)
895 cpufreq_driver->exit(policy);
896 }
Dave Jones909a6942009-07-08 18:05:42 -0400897 return ret;
898
899err_out_kobj_put:
900 kobject_put(&policy->kobj);
901 wait_for_completion(&policy->kobj_unregister);
902 return ret;
903}
904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905
906/**
907 * cpufreq_add_dev - add a CPU device
908 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500909 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400910 *
911 * The Oracle says: try running cpufreq registration/unregistration concurrently
912 * with with cpu hotplugging and all hell will break loose. Tried to clean this
913 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800915static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916{
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800917 unsigned int cpu = dev->id;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500918 int ret = 0, found = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 unsigned long flags;
921 unsigned int j;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500922#ifdef CONFIG_HOTPLUG_CPU
923 int sibling;
924#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925
Ashok Rajc32b6b82005-10-30 14:59:54 -0800926 if (cpu_is_offline(cpu))
927 return 0;
928
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200929 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931#ifdef CONFIG_SMP
932 /* check whether a different CPU already registered this
933 * CPU because it is in the same boat. */
934 policy = cpufreq_cpu_get(cpu);
935 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500936 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 return 0;
938 }
939#endif
940
941 if (!try_module_get(cpufreq_driver->owner)) {
942 ret = -EINVAL;
943 goto module_out;
944 }
945
Dave Jones059019a2009-07-08 16:30:03 -0400946 ret = -ENOMEM;
Dave Jonese98df502005-10-20 15:17:43 -0700947 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400948 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400950
951 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400952 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400953
954 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400955 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
957 policy->cpu = cpu;
Rusty Russell835481d2009-01-04 05:18:06 -0800958 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800960 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900961 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400962 ret = (lock_policy_rwsem_write(cpu) < 0);
963 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800964
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000966 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700968 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500969#ifdef CONFIG_HOTPLUG_CPU
970 for_each_online_cpu(sibling) {
971 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
972 if (cp && cp->governor &&
973 (cpumask_test_cpu(cpu, cp->related_cpus))) {
974 policy->governor = cp->governor;
975 found = 1;
976 break;
977 }
978 }
979#endif
980 if (!found)
981 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 /* call driver. From then on the cpufreq must be able
983 * to accept all calls to ->verify and ->setpolicy for this CPU
984 */
985 ret = cpufreq_driver->init(policy);
986 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200987 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400988 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000990
991 /*
992 * affected cpus must always be the one, which are online. We aren't
993 * managing offline cpus here.
994 */
995 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
Viresh Kumar6954ca92013-01-12 05:14:40 +0000996 cpumask_and(policy->cpus, policy->cpus, &cpufreq_online_mask);
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000997
Mike Chan187d9f42008-12-04 12:19:17 -0800998 policy->user_policy.min = policy->min;
999 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000
Thomas Renningera1531ac2008-07-29 22:32:58 -07001001 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1002 CPUFREQ_START, policy);
1003
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001004 ret = cpufreq_add_dev_policy(cpu, policy, dev);
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001005 if (ret) {
1006 if (ret > 0)
1007 /* This is a managed cpu, symlink created,
1008 exit with 0 */
1009 ret = 0;
Dave Jonesecf7e462009-07-08 18:48:47 -04001010 goto err_unlock_policy;
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001011 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001013 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -04001014 if (ret)
1015 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -05001016
Lothar Waßmanndca02612008-05-29 17:54:52 +02001017 unlock_policy_rwsem_write(cpu);
1018
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001019 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001021 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001022
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 return 0;
1024
1025
1026err_out_unregister:
1027 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001028 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001029 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1031
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001032 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 wait_for_completion(&policy->kobj_unregister);
1034
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001035err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -05001036 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001037 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001038err_free_cpumask:
1039 free_cpumask_var(policy->cpus);
1040err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042nomem_out:
1043 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001044module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 return ret;
1046}
1047
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001048static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1049{
1050 int j;
1051
1052 policy->last_cpu = policy->cpu;
1053 policy->cpu = cpu;
1054
1055 for_each_cpu(j, policy->cpus) {
1056 if (!cpu_online(j))
1057 continue;
1058 per_cpu(cpufreq_policy_cpu, j) = cpu;
1059 }
1060
1061#ifdef CONFIG_CPU_FREQ_TABLE
1062 cpufreq_frequency_table_update_policy_cpu(policy);
1063#endif
1064 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1065 CPUFREQ_UPDATE_POLICY_CPU, policy);
1066}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067
1068/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001069 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 *
1071 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001072 * Caller should already have policy_rwsem in write mode for this CPU.
1073 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001075static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001077 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 unsigned long flags;
1079 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001080 struct kobject *kobj;
1081 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001082 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001084 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
1086 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001087 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001090 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001092 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 return -EINVAL;
1094 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001096 if (cpufreq_driver->target)
Viresh Kumarf6a74092013-01-12 05:14:39 +00001097 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Thomas Renninger084f3492007-07-09 11:35:28 -07001098
1099#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001100 strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
1101 CPUFREQ_NAME_LEN);
Thomas Renninger084f3492007-07-09 11:35:28 -07001102#endif
1103
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001104 per_cpu(cpufreq_cpu_data, cpu) = NULL;
1105 cpus = cpumask_weight(data->cpus);
1106 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001108 if (unlikely((cpu == data->cpu) && (cpus > 1))) {
Jacob Shin27ecddc2011-04-27 13:32:11 -05001109 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001110 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1111 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1112 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1113 if (ret) {
1114 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1115 cpumask_set_cpu(cpu, data->cpus);
1116 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1117 "cpufreq");
1118 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1119 unlock_policy_rwsem_write(cpu);
1120 return -EINVAL;
1121 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001122
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001123 update_policy_cpu(data, cpu_dev->id);
1124 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1125 __func__, cpu_dev->id, cpu);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001126 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001127
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001128 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1129
1130 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1131 cpufreq_cpu_put(data);
1132 unlock_policy_rwsem_write(cpu);
1133 sysfs_remove_link(&dev->kobj, "cpufreq");
1134
1135 /* If cpu is last user of policy, free policy */
1136 if (cpus == 1) {
1137 lock_policy_rwsem_write(cpu);
1138 kobj = &data->kobj;
1139 cmp = &data->kobj_unregister;
1140 unlock_policy_rwsem_write(cpu);
1141 kobject_put(kobj);
1142
1143 /* we need to make sure that the underlying kobj is actually
1144 * not referenced anymore by anybody before we proceed with
1145 * unloading.
1146 */
1147 pr_debug("waiting for dropping of refcount\n");
1148 wait_for_completion(cmp);
1149 pr_debug("wait complete\n");
1150
1151 lock_policy_rwsem_write(cpu);
1152 if (cpufreq_driver->exit)
1153 cpufreq_driver->exit(data);
1154 unlock_policy_rwsem_write(cpu);
1155
1156 free_cpumask_var(data->related_cpus);
1157 free_cpumask_var(data->cpus);
1158 kfree(data);
1159 } else if (cpufreq_driver->target) {
1160 __cpufreq_governor(data, CPUFREQ_GOV_START);
1161 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1162 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 return 0;
1165}
1166
1167
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001168static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001169{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001170 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001171 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001172
1173 if (cpu_is_offline(cpu))
1174 return 0;
1175
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001176 if (unlikely(lock_policy_rwsem_write(cpu)))
1177 BUG();
1178
Viresh Kumar6954ca92013-01-12 05:14:40 +00001179 cpumask_clear_cpu(cpu, &cpufreq_online_mask);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001180 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001181 return retval;
1182}
1183
1184
David Howells65f27f32006-11-22 14:55:48 +00001185static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186{
David Howells65f27f32006-11-22 14:55:48 +00001187 struct cpufreq_policy *policy =
1188 container_of(work, struct cpufreq_policy, update);
1189 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001190 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 cpufreq_update_policy(cpu);
1192}
1193
1194/**
1195 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1196 * @cpu: cpu number
1197 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1198 * @new_freq: CPU frequency the CPU actually runs at
1199 *
Dave Jones29464f22009-01-18 01:37:11 -05001200 * We adjust to current frequency first, and need to clean up later.
1201 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301203static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1204 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205{
1206 struct cpufreq_freqs freqs;
1207
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001208 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1210
1211 freqs.cpu = cpu;
1212 freqs.old = old_freq;
1213 freqs.new = new_freq;
1214 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1215 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1216}
1217
1218
Dave Jones32ee8c32006-02-28 00:43:23 -05001219/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301220 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001221 * @cpu: CPU number
1222 *
1223 * This is the last known freq, without actually getting it from the driver.
1224 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1225 */
1226unsigned int cpufreq_quick_get(unsigned int cpu)
1227{
1228 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301229 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001230
1231 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301232 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001233 cpufreq_cpu_put(policy);
1234 }
1235
Dave Jones4d34a672008-02-07 16:33:49 -05001236 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001237}
1238EXPORT_SYMBOL(cpufreq_quick_get);
1239
Jesse Barnes3d737102011-06-28 10:59:12 -07001240/**
1241 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1242 * @cpu: CPU number
1243 *
1244 * Just return the max possible frequency for a given CPU.
1245 */
1246unsigned int cpufreq_quick_get_max(unsigned int cpu)
1247{
1248 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1249 unsigned int ret_freq = 0;
1250
1251 if (policy) {
1252 ret_freq = policy->max;
1253 cpufreq_cpu_put(policy);
1254 }
1255
1256 return ret_freq;
1257}
1258EXPORT_SYMBOL(cpufreq_quick_get_max);
1259
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001260
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001261static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001263 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301264 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001267 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301269 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301271 if (ret_freq && policy->cur &&
1272 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1273 /* verify no discrepancy between actual and
1274 saved value exists */
1275 if (unlikely(ret_freq != policy->cur)) {
1276 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 schedule_work(&policy->update);
1278 }
1279 }
1280
Dave Jones4d34a672008-02-07 16:33:49 -05001281 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001282}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001284/**
1285 * cpufreq_get - get the current CPU frequency (in kHz)
1286 * @cpu: CPU number
1287 *
1288 * Get the CPU current (static) CPU frequency
1289 */
1290unsigned int cpufreq_get(unsigned int cpu)
1291{
1292 unsigned int ret_freq = 0;
1293 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1294
1295 if (!policy)
1296 goto out;
1297
1298 if (unlikely(lock_policy_rwsem_read(cpu)))
1299 goto out_policy;
1300
1301 ret_freq = __cpufreq_get(cpu);
1302
1303 unlock_policy_rwsem_read(cpu);
1304
1305out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001307out:
Dave Jones4d34a672008-02-07 16:33:49 -05001308 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309}
1310EXPORT_SYMBOL(cpufreq_get);
1311
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001312static struct subsys_interface cpufreq_interface = {
1313 .name = "cpufreq",
1314 .subsys = &cpu_subsys,
1315 .add_dev = cpufreq_add_dev,
1316 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001317};
1318
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319
1320/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001321 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1322 *
1323 * This function is only executed for the boot processor. The other CPUs
1324 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001325 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001326static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001327{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301328 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001329
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001330 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001331 struct cpufreq_policy *cpu_policy;
1332
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001333 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001334
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001335 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001336 cpu_policy = cpufreq_cpu_get(cpu);
1337 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001338 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001339
1340 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001341 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001342 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001343 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1344 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001345 }
1346
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001347 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001348 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001349}
1350
1351/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001352 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 *
1354 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001355 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1356 * restored. It will verify that the current freq is in sync with
1357 * what we believe it to be. This is a bit later than when it
1358 * should be, but nonethteless it's better than calling
1359 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001360 *
1361 * This function is only executed for the boot CPU. The other CPUs have not
1362 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001364static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301366 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001367
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001368 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 struct cpufreq_policy *cpu_policy;
1370
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001371 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001373 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 cpu_policy = cpufreq_cpu_get(cpu);
1375 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001376 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377
1378 if (cpufreq_driver->resume) {
1379 ret = cpufreq_driver->resume(cpu_policy);
1380 if (ret) {
1381 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1382 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001383 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 }
1385 }
1386
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001388
Dave Jonesc9060492008-02-07 16:32:18 -05001389fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391}
1392
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001393static struct syscore_ops cpufreq_syscore_ops = {
1394 .suspend = cpufreq_bp_suspend,
1395 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396};
1397
Borislav Petkov9d950462013-01-20 10:24:28 +00001398/**
1399 * cpufreq_get_current_driver - return current driver's name
1400 *
1401 * Return the name string of the currently loaded cpufreq driver
1402 * or NULL, if none.
1403 */
1404const char *cpufreq_get_current_driver(void)
1405{
1406 if (cpufreq_driver)
1407 return cpufreq_driver->name;
1408
1409 return NULL;
1410}
1411EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412
1413/*********************************************************************
1414 * NOTIFIER LISTS INTERFACE *
1415 *********************************************************************/
1416
1417/**
1418 * cpufreq_register_notifier - register a driver with cpufreq
1419 * @nb: notifier function to register
1420 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1421 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001422 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 * are notified about clock rate changes (once before and once after
1424 * the transition), or a list of drivers that are notified about
1425 * changes in cpufreq policy.
1426 *
1427 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001428 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 */
1430int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1431{
1432 int ret;
1433
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001434 if (cpufreq_disabled())
1435 return -EINVAL;
1436
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001437 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1438
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 switch (list) {
1440 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001441 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001442 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 break;
1444 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001445 ret = blocking_notifier_chain_register(
1446 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 break;
1448 default:
1449 ret = -EINVAL;
1450 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451
1452 return ret;
1453}
1454EXPORT_SYMBOL(cpufreq_register_notifier);
1455
1456
1457/**
1458 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1459 * @nb: notifier block to be unregistered
1460 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1461 *
1462 * Remove a driver from the CPU frequency notifier list.
1463 *
1464 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001465 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 */
1467int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1468{
1469 int ret;
1470
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001471 if (cpufreq_disabled())
1472 return -EINVAL;
1473
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 switch (list) {
1475 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001476 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001477 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 break;
1479 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001480 ret = blocking_notifier_chain_unregister(
1481 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 break;
1483 default:
1484 ret = -EINVAL;
1485 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486
1487 return ret;
1488}
1489EXPORT_SYMBOL(cpufreq_unregister_notifier);
1490
1491
1492/*********************************************************************
1493 * GOVERNORS *
1494 *********************************************************************/
1495
1496
1497int __cpufreq_driver_target(struct cpufreq_policy *policy,
1498 unsigned int target_freq,
1499 unsigned int relation)
1500{
1501 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001502 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001503
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001504 if (cpufreq_disabled())
1505 return -ENODEV;
1506
Viresh Kumar72499242012-10-31 01:28:21 +01001507 /* Make sure that target_freq is within supported range */
1508 if (target_freq > policy->max)
1509 target_freq = policy->max;
1510 if (target_freq < policy->min)
1511 target_freq = policy->min;
1512
1513 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1514 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001515
1516 if (target_freq == policy->cur)
1517 return 0;
1518
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1520 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001521
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 return retval;
1523}
1524EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1525
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526int cpufreq_driver_target(struct cpufreq_policy *policy,
1527 unsigned int target_freq,
1528 unsigned int relation)
1529{
Julia Lawallf1829e42008-07-25 22:44:53 +02001530 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
1532 policy = cpufreq_cpu_get(policy->cpu);
1533 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001534 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001536 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001537 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538
1539 ret = __cpufreq_driver_target(policy, target_freq, relation);
1540
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001541 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542
Julia Lawallf1829e42008-07-25 22:44:53 +02001543fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001545no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 return ret;
1547}
1548EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1549
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001550int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001551{
1552 int ret = 0;
1553
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001554 if (cpufreq_disabled())
1555 return ret;
1556
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001557 if (!(cpu_online(cpu) && cpufreq_driver->getavg))
1558 return 0;
1559
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001560 policy = cpufreq_cpu_get(policy->cpu);
1561 if (!policy)
1562 return -EINVAL;
1563
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001564 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001565
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001566 cpufreq_cpu_put(policy);
1567 return ret;
1568}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001569EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001570
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001571/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001572 * when "event" is CPUFREQ_GOV_LIMITS
1573 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301575static int __cpufreq_governor(struct cpufreq_policy *policy,
1576 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577{
Dave Jonescc993ca2005-07-28 09:43:56 -07001578 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001579
1580 /* Only must be defined when default governor is known to have latency
1581 restrictions, like e.g. conservative or ondemand.
1582 That this is the case is already ensured in Kconfig
1583 */
1584#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1585 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1586#else
1587 struct cpufreq_governor *gov = NULL;
1588#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001589
1590 if (policy->governor->max_transition_latency &&
1591 policy->cpuinfo.transition_latency >
1592 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001593 if (!gov)
1594 return -EINVAL;
1595 else {
1596 printk(KERN_WARNING "%s governor failed, too long"
1597 " transition latency of HW, fallback"
1598 " to %s governor\n",
1599 policy->governor->name,
1600 gov->name);
1601 policy->governor = gov;
1602 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001603 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
1605 if (!try_module_get(policy->governor->owner))
1606 return -EINVAL;
1607
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001608 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301609 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610 ret = policy->governor->governor(policy, event);
1611
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301612 /* we keep one module reference alive for
1613 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 if ((event != CPUFREQ_GOV_START) || ret)
1615 module_put(policy->governor->owner);
1616 if ((event == CPUFREQ_GOV_STOP) && !ret)
1617 module_put(policy->governor->owner);
1618
1619 return ret;
1620}
1621
1622
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623int cpufreq_register_governor(struct cpufreq_governor *governor)
1624{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001625 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626
1627 if (!governor)
1628 return -EINVAL;
1629
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001630 if (cpufreq_disabled())
1631 return -ENODEV;
1632
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001633 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001634
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001635 err = -EBUSY;
1636 if (__find_governor(governor->name) == NULL) {
1637 err = 0;
1638 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640
Dave Jones32ee8c32006-02-28 00:43:23 -05001641 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001642 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643}
1644EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1645
1646
1647void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1648{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001649#ifdef CONFIG_HOTPLUG_CPU
1650 int cpu;
1651#endif
1652
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653 if (!governor)
1654 return;
1655
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001656 if (cpufreq_disabled())
1657 return;
1658
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001659#ifdef CONFIG_HOTPLUG_CPU
1660 for_each_present_cpu(cpu) {
1661 if (cpu_online(cpu))
1662 continue;
1663 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1664 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1665 }
1666#endif
1667
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001668 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001670 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 return;
1672}
1673EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1674
1675
1676
1677/*********************************************************************
1678 * POLICY INTERFACE *
1679 *********************************************************************/
1680
1681/**
1682 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001683 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1684 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 *
1686 * Reads the current cpufreq policy.
1687 */
1688int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1689{
1690 struct cpufreq_policy *cpu_policy;
1691 if (!policy)
1692 return -EINVAL;
1693
1694 cpu_policy = cpufreq_cpu_get(cpu);
1695 if (!cpu_policy)
1696 return -EINVAL;
1697
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
1700 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 return 0;
1702}
1703EXPORT_SYMBOL(cpufreq_get_policy);
1704
1705
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001706/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301707 * data : current policy.
1708 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001709 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301710static int __cpufreq_set_policy(struct cpufreq_policy *data,
1711 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712{
1713 int ret = 0;
1714
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001715 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 policy->min, policy->max);
1717
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301718 memcpy(&policy->cpuinfo, &data->cpuinfo,
1719 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
Yi Yang53391fa2008-01-30 13:33:34 +01001721 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001722 ret = -EINVAL;
1723 goto error_out;
1724 }
1725
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 /* verify the cpu speed can be set within this limit */
1727 ret = cpufreq_driver->verify(policy);
1728 if (ret)
1729 goto error_out;
1730
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001732 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1733 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
1735 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001736 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1737 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
1739 /* verify the cpu speed can be set within this limit,
1740 which might be different to the first one */
1741 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001742 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
1745 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001746 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1747 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748
Dave Jones7d5e3502006-02-02 17:03:42 -05001749 data->min = policy->min;
1750 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001752 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301753 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754
1755 if (cpufreq_driver->setpolicy) {
1756 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001757 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 ret = cpufreq_driver->setpolicy(policy);
1759 } else {
1760 if (policy->governor != data->governor) {
1761 /* save old, working values */
1762 struct cpufreq_governor *old_gov = data->governor;
1763
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001764 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
1766 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001767 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1769
1770 /* start new governor */
1771 data->governor = policy->governor;
1772 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1773 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001774 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301775 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 if (old_gov) {
1777 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301778 __cpufreq_governor(data,
1779 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 }
1781 ret = -EINVAL;
1782 goto error_out;
1783 }
1784 /* might be a policy change, too, so fall through */
1785 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001786 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1788 }
1789
Dave Jones7d5e3502006-02-02 17:03:42 -05001790error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 return ret;
1792}
1793
1794/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1796 * @cpu: CPU which shall be re-evaluated
1797 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001798 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 * at different times.
1800 */
1801int cpufreq_update_policy(unsigned int cpu)
1802{
1803 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1804 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001805 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806
Julia Lawallf1829e42008-07-25 22:44:53 +02001807 if (!data) {
1808 ret = -ENODEV;
1809 goto no_policy;
1810 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
Julia Lawallf1829e42008-07-25 22:44:53 +02001812 if (unlikely(lock_policy_rwsem_write(cpu))) {
1813 ret = -EINVAL;
1814 goto fail;
1815 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001817 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001818 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 policy.min = data->user_policy.min;
1820 policy.max = data->user_policy.max;
1821 policy.policy = data->user_policy.policy;
1822 policy.governor = data->user_policy.governor;
1823
Thomas Renninger0961dd02006-01-26 18:46:33 +01001824 /* BIOS might change freq behind our back
1825 -> ask driver for current freq and notify governors about a change */
1826 if (cpufreq_driver->get) {
1827 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001828 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001829 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001830 data->cur = policy.cur;
1831 } else {
1832 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301833 cpufreq_out_of_sync(cpu, data->cur,
1834 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001835 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001836 }
1837
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 ret = __cpufreq_set_policy(data, &policy);
1839
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001840 unlock_policy_rwsem_write(cpu);
1841
Julia Lawallf1829e42008-07-25 22:44:53 +02001842fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001844no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 return ret;
1846}
1847EXPORT_SYMBOL(cpufreq_update_policy);
1848
Satyam Sharmadd184a02007-10-02 13:28:14 -07001849static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001850 unsigned long action, void *hcpu)
1851{
1852 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001853 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001854
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001855 dev = get_cpu_device(cpu);
1856 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001857 switch (action) {
1858 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001859 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001860 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001861 break;
1862 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001863 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001864 if (unlikely(lock_policy_rwsem_write(cpu)))
1865 BUG();
1866
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001867 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001868 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001869 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001870 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001871 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001872 break;
1873 }
1874 }
1875 return NOTIFY_OK;
1876}
1877
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001878static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001879 .notifier_call = cpufreq_cpu_callback,
1880};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881
1882/*********************************************************************
1883 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1884 *********************************************************************/
1885
1886/**
1887 * cpufreq_register_driver - register a CPU Frequency driver
1888 * @driver_data: A struct cpufreq_driver containing the values#
1889 * submitted by the CPU Frequency driver.
1890 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001891 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001893 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 *
1895 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001896int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897{
1898 unsigned long flags;
1899 int ret;
1900
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001901 if (cpufreq_disabled())
1902 return -ENODEV;
1903
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 if (!driver_data || !driver_data->verify || !driver_data->init ||
1905 ((!driver_data->setpolicy) && (!driver_data->target)))
1906 return -EINVAL;
1907
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001908 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
1910 if (driver_data->setpolicy)
1911 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1912
1913 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1914 if (cpufreq_driver) {
1915 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1916 return -EBUSY;
1917 }
1918 cpufreq_driver = driver_data;
1919 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1920
Viresh Kumar6954ca92013-01-12 05:14:40 +00001921 cpumask_setall(&cpufreq_online_mask);
1922
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001923 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001924 if (ret)
1925 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001927 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 int i;
1929 ret = -ENODEV;
1930
1931 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001932 for (i = 0; i < nr_cpu_ids; i++)
1933 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001935 break;
1936 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937
1938 /* if all ->init() calls failed, unregister */
1939 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001940 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301941 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001942 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 }
1944 }
1945
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001946 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001947 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001949 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001950err_if_unreg:
1951 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001952err_null_driver:
1953 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1954 cpufreq_driver = NULL;
1955 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001956 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957}
1958EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1959
1960
1961/**
1962 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1963 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001964 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 * the right to do so, i.e. if you have succeeded in initialising before!
1966 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1967 * currently not initialised.
1968 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001969int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970{
1971 unsigned long flags;
1972
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001973 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001976 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001978 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001979 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980
1981 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1982 cpufreq_driver = NULL;
1983 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1984
1985 return 0;
1986}
1987EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001988
1989static int __init cpufreq_core_init(void)
1990{
1991 int cpu;
1992
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001993 if (cpufreq_disabled())
1994 return -ENODEV;
1995
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001996 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001997 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001998 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1999 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002000
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002001 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002002 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002003 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002004
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002005 return 0;
2006}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002007core_initcall(cpufreq_core_init);