blob: 2417576393a68efdee5575c3026823442ca1ce42 [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 kumar8bf1ac722012-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
1398
1399/*********************************************************************
1400 * NOTIFIER LISTS INTERFACE *
1401 *********************************************************************/
1402
1403/**
1404 * cpufreq_register_notifier - register a driver with cpufreq
1405 * @nb: notifier function to register
1406 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1407 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001408 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 * are notified about clock rate changes (once before and once after
1410 * the transition), or a list of drivers that are notified about
1411 * changes in cpufreq policy.
1412 *
1413 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001414 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 */
1416int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1417{
1418 int ret;
1419
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001420 if (cpufreq_disabled())
1421 return -EINVAL;
1422
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001423 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1424
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 switch (list) {
1426 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001427 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001428 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 break;
1430 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001431 ret = blocking_notifier_chain_register(
1432 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 break;
1434 default:
1435 ret = -EINVAL;
1436 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
1438 return ret;
1439}
1440EXPORT_SYMBOL(cpufreq_register_notifier);
1441
1442
1443/**
1444 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1445 * @nb: notifier block to be unregistered
1446 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1447 *
1448 * Remove a driver from the CPU frequency notifier list.
1449 *
1450 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001451 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 */
1453int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1454{
1455 int ret;
1456
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001457 if (cpufreq_disabled())
1458 return -EINVAL;
1459
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 switch (list) {
1461 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001462 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001463 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 break;
1465 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001466 ret = blocking_notifier_chain_unregister(
1467 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 break;
1469 default:
1470 ret = -EINVAL;
1471 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
1473 return ret;
1474}
1475EXPORT_SYMBOL(cpufreq_unregister_notifier);
1476
1477
1478/*********************************************************************
1479 * GOVERNORS *
1480 *********************************************************************/
1481
1482
1483int __cpufreq_driver_target(struct cpufreq_policy *policy,
1484 unsigned int target_freq,
1485 unsigned int relation)
1486{
1487 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001488 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001489
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001490 if (cpufreq_disabled())
1491 return -ENODEV;
1492
Viresh Kumar72499242012-10-31 01:28:21 +01001493 /* Make sure that target_freq is within supported range */
1494 if (target_freq > policy->max)
1495 target_freq = policy->max;
1496 if (target_freq < policy->min)
1497 target_freq = policy->min;
1498
1499 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1500 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001501
1502 if (target_freq == policy->cur)
1503 return 0;
1504
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1506 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001507
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 return retval;
1509}
1510EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1511
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512int cpufreq_driver_target(struct cpufreq_policy *policy,
1513 unsigned int target_freq,
1514 unsigned int relation)
1515{
Julia Lawallf1829e42008-07-25 22:44:53 +02001516 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517
1518 policy = cpufreq_cpu_get(policy->cpu);
1519 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001520 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001522 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001523 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524
1525 ret = __cpufreq_driver_target(policy, target_freq, relation);
1526
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001527 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528
Julia Lawallf1829e42008-07-25 22:44:53 +02001529fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001531no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 return ret;
1533}
1534EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1535
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001536int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001537{
1538 int ret = 0;
1539
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001540 if (cpufreq_disabled())
1541 return ret;
1542
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001543 if (!(cpu_online(cpu) && cpufreq_driver->getavg))
1544 return 0;
1545
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001546 policy = cpufreq_cpu_get(policy->cpu);
1547 if (!policy)
1548 return -EINVAL;
1549
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001550 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001551
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001552 cpufreq_cpu_put(policy);
1553 return ret;
1554}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001555EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001556
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001557/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001558 * when "event" is CPUFREQ_GOV_LIMITS
1559 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301561static int __cpufreq_governor(struct cpufreq_policy *policy,
1562 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563{
Dave Jonescc993ca2005-07-28 09:43:56 -07001564 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001565
1566 /* Only must be defined when default governor is known to have latency
1567 restrictions, like e.g. conservative or ondemand.
1568 That this is the case is already ensured in Kconfig
1569 */
1570#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1571 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1572#else
1573 struct cpufreq_governor *gov = NULL;
1574#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001575
1576 if (policy->governor->max_transition_latency &&
1577 policy->cpuinfo.transition_latency >
1578 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001579 if (!gov)
1580 return -EINVAL;
1581 else {
1582 printk(KERN_WARNING "%s governor failed, too long"
1583 " transition latency of HW, fallback"
1584 " to %s governor\n",
1585 policy->governor->name,
1586 gov->name);
1587 policy->governor = gov;
1588 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001589 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590
1591 if (!try_module_get(policy->governor->owner))
1592 return -EINVAL;
1593
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001594 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301595 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 ret = policy->governor->governor(policy, event);
1597
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301598 /* we keep one module reference alive for
1599 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 if ((event != CPUFREQ_GOV_START) || ret)
1601 module_put(policy->governor->owner);
1602 if ((event == CPUFREQ_GOV_STOP) && !ret)
1603 module_put(policy->governor->owner);
1604
1605 return ret;
1606}
1607
1608
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609int cpufreq_register_governor(struct cpufreq_governor *governor)
1610{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001611 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612
1613 if (!governor)
1614 return -EINVAL;
1615
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001616 if (cpufreq_disabled())
1617 return -ENODEV;
1618
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001619 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001620
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001621 err = -EBUSY;
1622 if (__find_governor(governor->name) == NULL) {
1623 err = 0;
1624 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626
Dave Jones32ee8c32006-02-28 00:43:23 -05001627 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001628 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629}
1630EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1631
1632
1633void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1634{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001635#ifdef CONFIG_HOTPLUG_CPU
1636 int cpu;
1637#endif
1638
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 if (!governor)
1640 return;
1641
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001642 if (cpufreq_disabled())
1643 return;
1644
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001645#ifdef CONFIG_HOTPLUG_CPU
1646 for_each_present_cpu(cpu) {
1647 if (cpu_online(cpu))
1648 continue;
1649 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1650 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1651 }
1652#endif
1653
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001654 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001656 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657 return;
1658}
1659EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1660
1661
1662
1663/*********************************************************************
1664 * POLICY INTERFACE *
1665 *********************************************************************/
1666
1667/**
1668 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001669 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1670 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 *
1672 * Reads the current cpufreq policy.
1673 */
1674int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1675{
1676 struct cpufreq_policy *cpu_policy;
1677 if (!policy)
1678 return -EINVAL;
1679
1680 cpu_policy = cpufreq_cpu_get(cpu);
1681 if (!cpu_policy)
1682 return -EINVAL;
1683
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
1686 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687 return 0;
1688}
1689EXPORT_SYMBOL(cpufreq_get_policy);
1690
1691
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001692/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301693 * data : current policy.
1694 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001695 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301696static int __cpufreq_set_policy(struct cpufreq_policy *data,
1697 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698{
1699 int ret = 0;
1700
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001701 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702 policy->min, policy->max);
1703
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301704 memcpy(&policy->cpuinfo, &data->cpuinfo,
1705 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706
Yi Yang53391fa2008-01-30 13:33:34 +01001707 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001708 ret = -EINVAL;
1709 goto error_out;
1710 }
1711
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 /* verify the cpu speed can be set within this limit */
1713 ret = cpufreq_driver->verify(policy);
1714 if (ret)
1715 goto error_out;
1716
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001718 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1719 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
1721 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001722 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1723 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724
1725 /* verify the cpu speed can be set within this limit,
1726 which might be different to the first one */
1727 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001728 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730
1731 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001732 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1733 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734
Dave Jones7d5e3502006-02-02 17:03:42 -05001735 data->min = policy->min;
1736 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001738 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301739 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
1741 if (cpufreq_driver->setpolicy) {
1742 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001743 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 ret = cpufreq_driver->setpolicy(policy);
1745 } else {
1746 if (policy->governor != data->governor) {
1747 /* save old, working values */
1748 struct cpufreq_governor *old_gov = data->governor;
1749
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001750 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751
1752 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001753 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1755
1756 /* start new governor */
1757 data->governor = policy->governor;
1758 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1759 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001760 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301761 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 if (old_gov) {
1763 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301764 __cpufreq_governor(data,
1765 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 }
1767 ret = -EINVAL;
1768 goto error_out;
1769 }
1770 /* might be a policy change, too, so fall through */
1771 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001772 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1774 }
1775
Dave Jones7d5e3502006-02-02 17:03:42 -05001776error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777 return ret;
1778}
1779
1780/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1782 * @cpu: CPU which shall be re-evaluated
1783 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001784 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 * at different times.
1786 */
1787int cpufreq_update_policy(unsigned int cpu)
1788{
1789 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1790 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001791 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792
Julia Lawallf1829e42008-07-25 22:44:53 +02001793 if (!data) {
1794 ret = -ENODEV;
1795 goto no_policy;
1796 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
Julia Lawallf1829e42008-07-25 22:44:53 +02001798 if (unlikely(lock_policy_rwsem_write(cpu))) {
1799 ret = -EINVAL;
1800 goto fail;
1801 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001803 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001804 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 policy.min = data->user_policy.min;
1806 policy.max = data->user_policy.max;
1807 policy.policy = data->user_policy.policy;
1808 policy.governor = data->user_policy.governor;
1809
Thomas Renninger0961dd02006-01-26 18:46:33 +01001810 /* BIOS might change freq behind our back
1811 -> ask driver for current freq and notify governors about a change */
1812 if (cpufreq_driver->get) {
1813 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001814 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001815 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001816 data->cur = policy.cur;
1817 } else {
1818 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301819 cpufreq_out_of_sync(cpu, data->cur,
1820 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001821 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001822 }
1823
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 ret = __cpufreq_set_policy(data, &policy);
1825
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001826 unlock_policy_rwsem_write(cpu);
1827
Julia Lawallf1829e42008-07-25 22:44:53 +02001828fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001830no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 return ret;
1832}
1833EXPORT_SYMBOL(cpufreq_update_policy);
1834
Satyam Sharmadd184a02007-10-02 13:28:14 -07001835static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001836 unsigned long action, void *hcpu)
1837{
1838 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001839 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001840
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001841 dev = get_cpu_device(cpu);
1842 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001843 switch (action) {
1844 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001845 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001846 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001847 break;
1848 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001849 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001850 if (unlikely(lock_policy_rwsem_write(cpu)))
1851 BUG();
1852
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001853 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001854 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001855 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001856 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001857 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001858 break;
1859 }
1860 }
1861 return NOTIFY_OK;
1862}
1863
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001864static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001865 .notifier_call = cpufreq_cpu_callback,
1866};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
1868/*********************************************************************
1869 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1870 *********************************************************************/
1871
1872/**
1873 * cpufreq_register_driver - register a CPU Frequency driver
1874 * @driver_data: A struct cpufreq_driver containing the values#
1875 * submitted by the CPU Frequency driver.
1876 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001877 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001879 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 *
1881 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001882int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883{
1884 unsigned long flags;
1885 int ret;
1886
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001887 if (cpufreq_disabled())
1888 return -ENODEV;
1889
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 if (!driver_data || !driver_data->verify || !driver_data->init ||
1891 ((!driver_data->setpolicy) && (!driver_data->target)))
1892 return -EINVAL;
1893
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001894 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895
1896 if (driver_data->setpolicy)
1897 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1898
1899 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1900 if (cpufreq_driver) {
1901 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1902 return -EBUSY;
1903 }
1904 cpufreq_driver = driver_data;
1905 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1906
Viresh Kumar6954ca92013-01-12 05:14:40 +00001907 cpumask_setall(&cpufreq_online_mask);
1908
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001909 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001910 if (ret)
1911 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001913 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 int i;
1915 ret = -ENODEV;
1916
1917 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001918 for (i = 0; i < nr_cpu_ids; i++)
1919 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001921 break;
1922 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923
1924 /* if all ->init() calls failed, unregister */
1925 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001926 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301927 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001928 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 }
1930 }
1931
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001932 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001933 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001935 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001936err_if_unreg:
1937 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001938err_null_driver:
1939 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1940 cpufreq_driver = NULL;
1941 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001942 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943}
1944EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1945
1946
1947/**
1948 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1949 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001950 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 * the right to do so, i.e. if you have succeeded in initialising before!
1952 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1953 * currently not initialised.
1954 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001955int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956{
1957 unsigned long flags;
1958
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001959 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001962 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001964 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001965 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966
1967 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1968 cpufreq_driver = NULL;
1969 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1970
1971 return 0;
1972}
1973EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001974
1975static int __init cpufreq_core_init(void)
1976{
1977 int cpu;
1978
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001979 if (cpufreq_disabled())
1980 return -ENODEV;
1981
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001982 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001983 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001984 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1985 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001986
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001987 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001988 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001989 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001990
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001991 return 0;
1992}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001993core_initcall(cpufreq_core_init);