blob: 94117a7f219b30726894d68e72f0eefd8d1a416a [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
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080050/*
51 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
52 * all cpufreq/hotplug/workqueue/etc related lock issues.
53 *
54 * The rules for this semaphore:
55 * - Any routine that wants to read from the policy structure will
56 * do a down_read on this semaphore.
57 * - Any routine that will write to the policy structure and/or may take away
58 * the policy altogether (eg. CPU hotplug), will hold this lock in write
59 * mode before doing so.
60 *
61 * Additional rules:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080062 * - Governor routines that can be called in cpufreq hotplug path should not
63 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040064 * - Lock should not be held across
65 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080066 */
Tejun Heof1625062009-10-29 22:34:13 +090067static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080068static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
69
70#define lock_policy_rwsem(mode, cpu) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053071static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072{ \
Tejun Heof1625062009-10-29 22:34:13 +090073 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080074 BUG_ON(policy_cpu == -1); \
75 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076 \
77 return 0; \
78}
79
80lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080081lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080082
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053083#define unlock_policy_rwsem(mode, cpu) \
84static void unlock_policy_rwsem_##mode(int cpu) \
85{ \
86 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
87 BUG_ON(policy_cpu == -1); \
88 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080089}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053091unlock_policy_rwsem(read, cpu);
92unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Linus Torvalds1da177e2005-04-16 15:20:36 -070094/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -050095static int __cpufreq_governor(struct cpufreq_policy *policy,
96 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +000098static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500101 * Two notifier lists: the "policy" list is involved in the
102 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 * "transition" list for kernel code that needs to handle
104 * changes to devices when the CPU clock speed changes.
105 * The mutex locks both lists.
106 */
Alan Sterne041c682006-03-27 01:16:30 -0800107static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700108static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200110static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700111static int __init init_cpufreq_transition_notifier_list(void)
112{
113 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200114 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700115 return 0;
116}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800117pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400119static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200120static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400121{
122 return off;
123}
124void disable_cpufreq(void)
125{
126 off = 1;
127}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500129static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Stephen Boyda9144432012-07-20 18:14:38 +0000131static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132{
133 struct cpufreq_policy *data;
134 unsigned long flags;
135
Mike Travis7a6aedf2008-03-25 15:06:53 -0700136 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 goto err_out;
138
139 /* get the cpufreq driver */
140 spin_lock_irqsave(&cpufreq_driver_lock, flags);
141
142 if (!cpufreq_driver)
143 goto err_out_unlock;
144
145 if (!try_module_get(cpufreq_driver->owner))
146 goto err_out_unlock;
147
148
149 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700150 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
152 if (!data)
153 goto err_out_put_module;
154
Stephen Boyda9144432012-07-20 18:14:38 +0000155 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 goto err_out_put_module;
157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 return data;
160
Dave Jones7d5e3502006-02-02 17:03:42 -0500161err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500163err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500165err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 return NULL;
167}
Stephen Boyda9144432012-07-20 18:14:38 +0000168
169struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
170{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000171 if (cpufreq_disabled())
172 return NULL;
173
Stephen Boyda9144432012-07-20 18:14:38 +0000174 return __cpufreq_cpu_get(cpu, false);
175}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
177
Stephen Boyda9144432012-07-20 18:14:38 +0000178static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
179{
180 return __cpufreq_cpu_get(cpu, true);
181}
182
183static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
184{
185 if (!sysfs)
186 kobject_put(&data->kobj);
187 module_put(cpufreq_driver->owner);
188}
Dave Jones7d5e3502006-02-02 17:03:42 -0500189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190void cpufreq_cpu_put(struct cpufreq_policy *data)
191{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000192 if (cpufreq_disabled())
193 return;
194
Stephen Boyda9144432012-07-20 18:14:38 +0000195 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196}
197EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
198
Stephen Boyda9144432012-07-20 18:14:38 +0000199static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
200{
201 __cpufreq_cpu_put(data, true);
202}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
206 *********************************************************************/
207
208/**
209 * adjust_jiffies - adjust the system "loops_per_jiffy"
210 *
211 * This function alters the system "loops_per_jiffy" for the clock
212 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500213 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 * per-CPU loops_per_jiffy value wherever possible.
215 */
216#ifndef CONFIG_SMP
217static unsigned long l_p_j_ref;
218static unsigned int l_p_j_ref_freq;
219
Arjan van de Ven858119e2006-01-14 13:20:43 -0800220static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221{
222 if (ci->flags & CPUFREQ_CONST_LOOPS)
223 return;
224
225 if (!l_p_j_ref_freq) {
226 l_p_j_ref = loops_per_jiffy;
227 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200228 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530229 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530231 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700232 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530233 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
234 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200235 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530236 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 }
238}
239#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530240static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
241{
242 return;
243}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244#endif
245
246
247/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800248 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
249 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800251 * This function calls the transition notifiers and the "adjust_jiffies"
252 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500253 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 */
255void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
256{
Dave Jonese4472cb2006-01-31 15:53:55 -0800257 struct cpufreq_policy *policy;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530258 unsigned long flags;
Dave Jonese4472cb2006-01-31 15:53:55 -0800259
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 BUG_ON(irqs_disabled());
261
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000262 if (cpufreq_disabled())
263 return;
264
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200266 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800267 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530269 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -0700270 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530271 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800274
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500276 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800277 * which is not equal to what the cpufreq core thinks is
278 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 */
280 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800281 if ((policy) && (policy->cpu == freqs->cpu) &&
282 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200283 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800284 " %u, cpufreq assumed %u kHz.\n",
285 freqs->old, policy->cur);
286 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 }
288 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700289 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800290 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
292 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 case CPUFREQ_POSTCHANGE:
295 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200296 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200297 (unsigned long)freqs->cpu);
298 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100299 trace_cpu_frequency(freqs->new, freqs->cpu);
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_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800302 if (likely(policy) && likely(policy->cpu == freqs->cpu))
303 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 break;
305 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306}
307EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
308
309
310
311/*********************************************************************
312 * SYSFS INTERFACE *
313 *********************************************************************/
314
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700315static struct cpufreq_governor *__find_governor(const char *str_governor)
316{
317 struct cpufreq_governor *t;
318
319 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500320 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700321 return t;
322
323 return NULL;
324}
325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326/**
327 * cpufreq_parse_governor - parse a governor string
328 */
Dave Jones905d77c2008-03-05 14:28:32 -0500329static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 struct cpufreq_governor **governor)
331{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700332 int err = -EINVAL;
333
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700335 goto out;
336
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 if (cpufreq_driver->setpolicy) {
338 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
339 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700340 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530341 } else if (!strnicmp(str_governor, "powersave",
342 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700344 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700346 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700348
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800349 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700350
351 t = __find_governor(str_governor);
352
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700353 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700354 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700355
Kees Cook1a8e1462011-05-04 08:38:56 -0700356 mutex_unlock(&cpufreq_governor_mutex);
357 ret = request_module("cpufreq_%s", str_governor);
358 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700359
Kees Cook1a8e1462011-05-04 08:38:56 -0700360 if (ret == 0)
361 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700362 }
363
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700364 if (t != NULL) {
365 *governor = t;
366 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700368
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800369 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 }
Dave Jones29464f22009-01-18 01:37:11 -0500371out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700372 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
375
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530377 * cpufreq_per_cpu_attr_read() / show_##file_name() -
378 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 *
380 * Write out information from cpufreq_driver->policy[cpu]; object must be
381 * "unsigned int".
382 */
383
Dave Jones32ee8c32006-02-28 00:43:23 -0500384#define show_one(file_name, object) \
385static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500386(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500387{ \
Dave Jones29464f22009-01-18 01:37:11 -0500388 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389}
390
391show_one(cpuinfo_min_freq, cpuinfo.min_freq);
392show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100393show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394show_one(scaling_min_freq, min);
395show_one(scaling_max_freq, max);
396show_one(scaling_cur_freq, cur);
397
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530398static int __cpufreq_set_policy(struct cpufreq_policy *data,
399 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401/**
402 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
403 */
404#define store_one(file_name, object) \
405static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500406(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000408 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 struct cpufreq_policy new_policy; \
410 \
411 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
412 if (ret) \
413 return -EINVAL; \
414 \
Dave Jones29464f22009-01-18 01:37:11 -0500415 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 if (ret != 1) \
417 return -EINVAL; \
418 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200419 ret = __cpufreq_set_policy(policy, &new_policy); \
420 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 \
422 return ret ? ret : count; \
423}
424
Dave Jones29464f22009-01-18 01:37:11 -0500425store_one(scaling_min_freq, min);
426store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
428/**
429 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
430 */
Dave Jones905d77c2008-03-05 14:28:32 -0500431static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
432 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800434 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 if (!cur_freq)
436 return sprintf(buf, "<unknown>");
437 return sprintf(buf, "%u\n", cur_freq);
438}
439
440
441/**
442 * show_scaling_governor - show the current policy for the specified CPU
443 */
Dave Jones905d77c2008-03-05 14:28:32 -0500444static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445{
Dave Jones29464f22009-01-18 01:37:11 -0500446 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 return sprintf(buf, "powersave\n");
448 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
449 return sprintf(buf, "performance\n");
450 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200451 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500452 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 return -EINVAL;
454}
455
456
457/**
458 * store_scaling_governor - store policy for the specified CPU
459 */
Dave Jones905d77c2008-03-05 14:28:32 -0500460static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
461 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000463 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 char str_governor[16];
465 struct cpufreq_policy new_policy;
466
467 ret = cpufreq_get_policy(&new_policy, policy->cpu);
468 if (ret)
469 return ret;
470
Dave Jones29464f22009-01-18 01:37:11 -0500471 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 if (ret != 1)
473 return -EINVAL;
474
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530475 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
476 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 return -EINVAL;
478
Thomas Renninger7970e082006-04-13 15:14:04 +0200479 /* Do not use cpufreq_set_policy here or the user_policy.max
480 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200481 ret = __cpufreq_set_policy(policy, &new_policy);
482
483 policy->user_policy.policy = policy->policy;
484 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200485
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530486 if (ret)
487 return ret;
488 else
489 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490}
491
492/**
493 * show_scaling_driver - show the cpufreq driver currently loaded
494 */
Dave Jones905d77c2008-03-05 14:28:32 -0500495static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496{
viresh kumar4b972f02012-10-23 01:23:43 +0200497 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498}
499
500/**
501 * show_scaling_available_governors - show the available CPUfreq governors
502 */
Dave Jones905d77c2008-03-05 14:28:32 -0500503static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
504 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505{
506 ssize_t i = 0;
507 struct cpufreq_governor *t;
508
509 if (!cpufreq_driver->target) {
510 i += sprintf(buf, "performance powersave");
511 goto out;
512 }
513
514 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500515 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
516 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200518 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500520out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 i += sprintf(&buf[i], "\n");
522 return i;
523}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700524
Rusty Russell835481d2009-01-04 05:18:06 -0800525static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526{
527 ssize_t i = 0;
528 unsigned int cpu;
529
Rusty Russell835481d2009-01-04 05:18:06 -0800530 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 if (i)
532 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
533 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
534 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500535 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 }
537 i += sprintf(&buf[i], "\n");
538 return i;
539}
540
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700541/**
542 * show_related_cpus - show the CPUs affected by each transition even if
543 * hw coordination is in use
544 */
545static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
546{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700547 return show_cpus(policy->related_cpus, buf);
548}
549
550/**
551 * show_affected_cpus - show the CPUs affected by each transition
552 */
553static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
554{
555 return show_cpus(policy->cpus, buf);
556}
557
Venki Pallipadi9e769882007-10-26 10:18:21 -0700558static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500559 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700560{
561 unsigned int freq = 0;
562 unsigned int ret;
563
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700564 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700565 return -EINVAL;
566
567 ret = sscanf(buf, "%u", &freq);
568 if (ret != 1)
569 return -EINVAL;
570
571 policy->governor->store_setspeed(policy, freq);
572
573 return count;
574}
575
576static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
577{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700578 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700579 return sprintf(buf, "<unsupported>\n");
580
581 return policy->governor->show_setspeed(policy, buf);
582}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583
Thomas Renningere2f74f32009-11-19 12:31:01 +0100584/**
viresh kumar8bf1ac72012-10-23 01:23:33 +0200585 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100586 */
587static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
588{
589 unsigned int limit;
590 int ret;
591 if (cpufreq_driver->bios_limit) {
592 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
593 if (!ret)
594 return sprintf(buf, "%u\n", limit);
595 }
596 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
597}
598
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200599cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
600cpufreq_freq_attr_ro(cpuinfo_min_freq);
601cpufreq_freq_attr_ro(cpuinfo_max_freq);
602cpufreq_freq_attr_ro(cpuinfo_transition_latency);
603cpufreq_freq_attr_ro(scaling_available_governors);
604cpufreq_freq_attr_ro(scaling_driver);
605cpufreq_freq_attr_ro(scaling_cur_freq);
606cpufreq_freq_attr_ro(bios_limit);
607cpufreq_freq_attr_ro(related_cpus);
608cpufreq_freq_attr_ro(affected_cpus);
609cpufreq_freq_attr_rw(scaling_min_freq);
610cpufreq_freq_attr_rw(scaling_max_freq);
611cpufreq_freq_attr_rw(scaling_governor);
612cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
Dave Jones905d77c2008-03-05 14:28:32 -0500614static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 &cpuinfo_min_freq.attr,
616 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100617 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 &scaling_min_freq.attr,
619 &scaling_max_freq.attr,
620 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700621 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 &scaling_governor.attr,
623 &scaling_driver.attr,
624 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700625 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 NULL
627};
628
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200629struct kobject *cpufreq_global_kobject;
630EXPORT_SYMBOL(cpufreq_global_kobject);
631
Dave Jones29464f22009-01-18 01:37:11 -0500632#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
633#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
Dave Jones29464f22009-01-18 01:37:11 -0500635static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636{
Dave Jones905d77c2008-03-05 14:28:32 -0500637 struct cpufreq_policy *policy = to_policy(kobj);
638 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500639 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000640 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500642 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800643
644 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500645 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800646
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530647 if (fattr->show)
648 ret = fattr->show(policy, buf);
649 else
650 ret = -EIO;
651
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800652 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500653fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000654 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500655no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 return ret;
657}
658
Dave Jones905d77c2008-03-05 14:28:32 -0500659static ssize_t store(struct kobject *kobj, struct attribute *attr,
660 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661{
Dave Jones905d77c2008-03-05 14:28:32 -0500662 struct cpufreq_policy *policy = to_policy(kobj);
663 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500664 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000665 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500667 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800668
669 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500670 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800671
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530672 if (fattr->store)
673 ret = fattr->store(policy, buf, count);
674 else
675 ret = -EIO;
676
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800677 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500678fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000679 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500680no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 return ret;
682}
683
Dave Jones905d77c2008-03-05 14:28:32 -0500684static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685{
Dave Jones905d77c2008-03-05 14:28:32 -0500686 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200687 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 complete(&policy->kobj_unregister);
689}
690
Emese Revfy52cf25d2010-01-19 02:58:23 +0100691static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 .show = show,
693 .store = store,
694};
695
696static struct kobj_type ktype_cpufreq = {
697 .sysfs_ops = &sysfs_ops,
698 .default_attrs = default_attrs,
699 .release = cpufreq_sysfs_release,
700};
701
Dave Jones19d6f7e2009-07-08 17:35:39 -0400702/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700703static int cpufreq_add_dev_symlink(unsigned int cpu,
704 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400705{
706 unsigned int j;
707 int ret = 0;
708
709 for_each_cpu(j, policy->cpus) {
710 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800711 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400712
713 if (j == cpu)
714 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400715
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200716 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400717 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800718 cpu_dev = get_cpu_device(j);
719 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400720 "cpufreq");
721 if (ret) {
722 cpufreq_cpu_put(managed_policy);
723 return ret;
724 }
725 }
726 return ret;
727}
728
Alex Chiangcf3289d02009-11-17 20:27:08 -0700729static int cpufreq_add_dev_interface(unsigned int cpu,
730 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800731 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400732{
Dave Jonesecf7e462009-07-08 18:48:47 -0400733 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400734 struct freq_attr **drv_attr;
735 unsigned long flags;
736 int ret = 0;
737 unsigned int j;
738
739 /* prepare interface data */
740 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800741 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400742 if (ret)
743 return ret;
744
745 /* set up files for this cpu device */
746 drv_attr = cpufreq_driver->attr;
747 while ((drv_attr) && (*drv_attr)) {
748 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
749 if (ret)
750 goto err_out_kobj_put;
751 drv_attr++;
752 }
753 if (cpufreq_driver->get) {
754 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
755 if (ret)
756 goto err_out_kobj_put;
757 }
758 if (cpufreq_driver->target) {
759 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
760 if (ret)
761 goto err_out_kobj_put;
762 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100763 if (cpufreq_driver->bios_limit) {
764 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
765 if (ret)
766 goto err_out_kobj_put;
767 }
Dave Jones909a6942009-07-08 18:05:42 -0400768
769 spin_lock_irqsave(&cpufreq_driver_lock, flags);
770 for_each_cpu(j, policy->cpus) {
Dave Jones909a6942009-07-08 18:05:42 -0400771 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900772 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400773 }
774 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
775
776 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400777 if (ret)
778 goto err_out_kobj_put;
779
780 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
781 /* assure that the starting sequence is run in __cpufreq_set_policy */
782 policy->governor = NULL;
783
784 /* set default policy */
785 ret = __cpufreq_set_policy(policy, &new_policy);
786 policy->user_policy.policy = policy->policy;
787 policy->user_policy.governor = policy->governor;
788
789 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200790 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400791 if (cpufreq_driver->exit)
792 cpufreq_driver->exit(policy);
793 }
Dave Jones909a6942009-07-08 18:05:42 -0400794 return ret;
795
796err_out_kobj_put:
797 kobject_put(&policy->kobj);
798 wait_for_completion(&policy->kobj_unregister);
799 return ret;
800}
801
Viresh Kumarfcf80582013-01-29 14:39:08 +0000802#ifdef CONFIG_HOTPLUG_CPU
803static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
804 struct device *dev)
805{
806 struct cpufreq_policy *policy;
807 int ret = 0;
808 unsigned long flags;
809
810 policy = cpufreq_cpu_get(sibling);
811 WARN_ON(!policy);
812
Viresh Kumarfcf80582013-01-29 14:39:08 +0000813 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
814
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530815 lock_policy_rwsem_write(sibling);
816
Viresh Kumarfcf80582013-01-29 14:39:08 +0000817 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530818
Viresh Kumarfcf80582013-01-29 14:39:08 +0000819 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530820 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000821 per_cpu(cpufreq_cpu_data, cpu) = policy;
822 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
823
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530824 unlock_policy_rwsem_write(sibling);
825
Viresh Kumarfcf80582013-01-29 14:39:08 +0000826 __cpufreq_governor(policy, CPUFREQ_GOV_START);
827 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
828
Viresh Kumarfcf80582013-01-29 14:39:08 +0000829 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
830 if (ret) {
831 cpufreq_cpu_put(policy);
832 return ret;
833 }
834
835 return 0;
836}
837#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838
839/**
840 * cpufreq_add_dev - add a CPU device
841 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500842 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400843 *
844 * The Oracle says: try running cpufreq registration/unregistration concurrently
845 * with with cpu hotplugging and all hell will break loose. Tried to clean this
846 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800848static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000850 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530851 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500854#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000855 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500856 int sibling;
857#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
Ashok Rajc32b6b82005-10-30 14:59:54 -0800859 if (cpu_is_offline(cpu))
860 return 0;
861
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200862 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863
864#ifdef CONFIG_SMP
865 /* check whether a different CPU already registered this
866 * CPU because it is in the same boat. */
867 policy = cpufreq_cpu_get(cpu);
868 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500869 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 return 0;
871 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000872
873#ifdef CONFIG_HOTPLUG_CPU
874 /* Check if this cpu was hot-unplugged earlier and has siblings */
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530875 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000876 for_each_online_cpu(sibling) {
877 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530878 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
879 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000880 return cpufreq_add_policy_cpu(cpu, sibling, dev);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530881 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000882 }
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530883 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000884#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885#endif
886
887 if (!try_module_get(cpufreq_driver->owner)) {
888 ret = -EINVAL;
889 goto module_out;
890 }
891
Dave Jonese98df502005-10-20 15:17:43 -0700892 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400893 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400895
896 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400897 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400898
899 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400900 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901
902 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +0530903 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -0800904 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800906 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900907 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800908
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000910 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911
912 /* call driver. From then on the cpufreq must be able
913 * to accept all calls to ->verify and ->setpolicy for this CPU
914 */
915 ret = cpufreq_driver->init(policy);
916 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200917 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530918 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000920
Viresh Kumarfcf80582013-01-29 14:39:08 +0000921 /* related cpus should atleast have policy->cpus */
922 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
923
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000924 /*
925 * affected cpus must always be the one, which are online. We aren't
926 * managing offline cpus here.
927 */
928 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
929
Mike Chan187d9f42008-12-04 12:19:17 -0800930 policy->user_policy.min = policy->min;
931 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932
Thomas Renningera1531ac2008-07-29 22:32:58 -0700933 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
934 CPUFREQ_START, policy);
935
Viresh Kumarfcf80582013-01-29 14:39:08 +0000936#ifdef CONFIG_HOTPLUG_CPU
937 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
938 if (gov) {
939 policy->governor = gov;
940 pr_debug("Restoring governor %s for cpu %d\n",
941 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200942 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000943#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800945 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400946 if (ret)
947 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500948
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400949 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200951 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500952
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 return 0;
954
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955err_out_unregister:
956 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -0800957 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -0700958 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
960
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -0800961 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 wait_for_completion(&policy->kobj_unregister);
963
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530964err_set_policy_cpu:
965 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Xiaotian Fengcad70a62010-07-20 20:11:02 +0800966 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400967err_free_cpumask:
968 free_cpumask_var(policy->cpus);
969err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971nomem_out:
972 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -0800973module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 return ret;
975}
976
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000977static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
978{
979 int j;
980
981 policy->last_cpu = policy->cpu;
982 policy->cpu = cpu;
983
Viresh Kumar3361b7b2013-02-04 11:38:51 +0000984 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000985 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000986
987#ifdef CONFIG_CPU_FREQ_TABLE
988 cpufreq_frequency_table_update_policy_cpu(policy);
989#endif
990 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
991 CPUFREQ_UPDATE_POLICY_CPU, policy);
992}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
994/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800995 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996 *
997 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800998 * Caller should already have policy_rwsem in write mode for this CPU.
999 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001001static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001003 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 unsigned long flags;
1005 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001006 struct kobject *kobj;
1007 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001008 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001010 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011
1012 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301013
Mike Travis7a6aedf2008-03-25 15:06:53 -07001014 data = per_cpu(cpufreq_cpu_data, cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301015 per_cpu(cpufreq_cpu_data, cpu) = NULL;
1016
1017 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001020 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 return -EINVAL;
1022 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001024 if (cpufreq_driver->target)
Viresh Kumarf6a74092013-01-12 05:14:39 +00001025 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Thomas Renninger084f3492007-07-09 11:35:28 -07001026
1027#ifdef CONFIG_HOTPLUG_CPU
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001028 if (!cpufreq_driver->setpolicy)
1029 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
1030 data->governor->name, CPUFREQ_NAME_LEN);
Thomas Renninger084f3492007-07-09 11:35:28 -07001031#endif
1032
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301033 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001034 cpus = cpumask_weight(data->cpus);
1035 cpumask_clear_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301036 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001038 if (cpu != data->cpu) {
1039 sysfs_remove_link(&dev->kobj, "cpufreq");
1040 } else if (cpus > 1) {
Jacob Shin27ecddc2011-04-27 13:32:11 -05001041 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001042 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1043 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1044 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1045 if (ret) {
1046 pr_err("%s: Failed to move kobj: %d", __func__, ret);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301047
1048 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001049 cpumask_set_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301050
1051 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1052 per_cpu(cpufreq_cpu_data, cpu) = data;
1053 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1054
1055 unlock_policy_rwsem_write(cpu);
1056
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001057 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1058 "cpufreq");
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001059 return -EINVAL;
1060 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001061
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301062 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001063 update_policy_cpu(data, cpu_dev->id);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301064 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001065 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1066 __func__, cpu_dev->id, cpu);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001067 }
Jacob Shin27ecddc2011-04-27 13:32:11 -05001068
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001069 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1070 cpufreq_cpu_put(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001071
1072 /* If cpu is last user of policy, free policy */
1073 if (cpus == 1) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301074 lock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001075 kobj = &data->kobj;
1076 cmp = &data->kobj_unregister;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301077 unlock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001078 kobject_put(kobj);
1079
1080 /* we need to make sure that the underlying kobj is actually
1081 * not referenced anymore by anybody before we proceed with
1082 * unloading.
1083 */
1084 pr_debug("waiting for dropping of refcount\n");
1085 wait_for_completion(cmp);
1086 pr_debug("wait complete\n");
1087
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001088 if (cpufreq_driver->exit)
1089 cpufreq_driver->exit(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001090
1091 free_cpumask_var(data->related_cpus);
1092 free_cpumask_var(data->cpus);
1093 kfree(data);
1094 } else if (cpufreq_driver->target) {
1095 __cpufreq_governor(data, CPUFREQ_GOV_START);
1096 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1097 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301099 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 return 0;
1101}
1102
1103
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001104static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001105{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001106 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001107 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001108
1109 if (cpu_is_offline(cpu))
1110 return 0;
1111
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001112 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001113 return retval;
1114}
1115
1116
David Howells65f27f32006-11-22 14:55:48 +00001117static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118{
David Howells65f27f32006-11-22 14:55:48 +00001119 struct cpufreq_policy *policy =
1120 container_of(work, struct cpufreq_policy, update);
1121 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001122 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 cpufreq_update_policy(cpu);
1124}
1125
1126/**
1127 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1128 * @cpu: cpu number
1129 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1130 * @new_freq: CPU frequency the CPU actually runs at
1131 *
Dave Jones29464f22009-01-18 01:37:11 -05001132 * We adjust to current frequency first, and need to clean up later.
1133 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301135static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1136 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137{
1138 struct cpufreq_freqs freqs;
1139
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001140 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1142
1143 freqs.cpu = cpu;
1144 freqs.old = old_freq;
1145 freqs.new = new_freq;
1146 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1147 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1148}
1149
1150
Dave Jones32ee8c32006-02-28 00:43:23 -05001151/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301152 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001153 * @cpu: CPU number
1154 *
1155 * This is the last known freq, without actually getting it from the driver.
1156 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1157 */
1158unsigned int cpufreq_quick_get(unsigned int cpu)
1159{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001160 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301161 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001162
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001163 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1164 return cpufreq_driver->get(cpu);
1165
1166 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001167 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301168 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001169 cpufreq_cpu_put(policy);
1170 }
1171
Dave Jones4d34a672008-02-07 16:33:49 -05001172 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001173}
1174EXPORT_SYMBOL(cpufreq_quick_get);
1175
Jesse Barnes3d737102011-06-28 10:59:12 -07001176/**
1177 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1178 * @cpu: CPU number
1179 *
1180 * Just return the max possible frequency for a given CPU.
1181 */
1182unsigned int cpufreq_quick_get_max(unsigned int cpu)
1183{
1184 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1185 unsigned int ret_freq = 0;
1186
1187 if (policy) {
1188 ret_freq = policy->max;
1189 cpufreq_cpu_put(policy);
1190 }
1191
1192 return ret_freq;
1193}
1194EXPORT_SYMBOL(cpufreq_quick_get_max);
1195
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001196
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001197static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001199 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301200 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001203 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301205 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301207 if (ret_freq && policy->cur &&
1208 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1209 /* verify no discrepancy between actual and
1210 saved value exists */
1211 if (unlikely(ret_freq != policy->cur)) {
1212 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 schedule_work(&policy->update);
1214 }
1215 }
1216
Dave Jones4d34a672008-02-07 16:33:49 -05001217 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001218}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001220/**
1221 * cpufreq_get - get the current CPU frequency (in kHz)
1222 * @cpu: CPU number
1223 *
1224 * Get the CPU current (static) CPU frequency
1225 */
1226unsigned int cpufreq_get(unsigned int cpu)
1227{
1228 unsigned int ret_freq = 0;
1229 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1230
1231 if (!policy)
1232 goto out;
1233
1234 if (unlikely(lock_policy_rwsem_read(cpu)))
1235 goto out_policy;
1236
1237 ret_freq = __cpufreq_get(cpu);
1238
1239 unlock_policy_rwsem_read(cpu);
1240
1241out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001243out:
Dave Jones4d34a672008-02-07 16:33:49 -05001244 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245}
1246EXPORT_SYMBOL(cpufreq_get);
1247
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001248static struct subsys_interface cpufreq_interface = {
1249 .name = "cpufreq",
1250 .subsys = &cpu_subsys,
1251 .add_dev = cpufreq_add_dev,
1252 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001253};
1254
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
1256/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001257 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1258 *
1259 * This function is only executed for the boot processor. The other CPUs
1260 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001261 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001262static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001263{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301264 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001265
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001266 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001267 struct cpufreq_policy *cpu_policy;
1268
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001269 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001270
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001271 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001272 cpu_policy = cpufreq_cpu_get(cpu);
1273 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001274 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001275
1276 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001277 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001278 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001279 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1280 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001281 }
1282
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001283 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001284 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001285}
1286
1287/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001288 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 *
1290 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001291 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1292 * restored. It will verify that the current freq is in sync with
1293 * what we believe it to be. This is a bit later than when it
1294 * should be, but nonethteless it's better than calling
1295 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001296 *
1297 * This function is only executed for the boot CPU. The other CPUs have not
1298 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001300static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301302 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001303
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001304 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 struct cpufreq_policy *cpu_policy;
1306
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001307 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001309 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310 cpu_policy = cpufreq_cpu_get(cpu);
1311 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001312 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313
1314 if (cpufreq_driver->resume) {
1315 ret = cpufreq_driver->resume(cpu_policy);
1316 if (ret) {
1317 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1318 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001319 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 }
1321 }
1322
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001324
Dave Jonesc9060492008-02-07 16:32:18 -05001325fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327}
1328
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001329static struct syscore_ops cpufreq_syscore_ops = {
1330 .suspend = cpufreq_bp_suspend,
1331 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332};
1333
Borislav Petkov9d950462013-01-20 10:24:28 +00001334/**
1335 * cpufreq_get_current_driver - return current driver's name
1336 *
1337 * Return the name string of the currently loaded cpufreq driver
1338 * or NULL, if none.
1339 */
1340const char *cpufreq_get_current_driver(void)
1341{
1342 if (cpufreq_driver)
1343 return cpufreq_driver->name;
1344
1345 return NULL;
1346}
1347EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348
1349/*********************************************************************
1350 * NOTIFIER LISTS INTERFACE *
1351 *********************************************************************/
1352
1353/**
1354 * cpufreq_register_notifier - register a driver with cpufreq
1355 * @nb: notifier function to register
1356 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1357 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001358 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 * are notified about clock rate changes (once before and once after
1360 * the transition), or a list of drivers that are notified about
1361 * changes in cpufreq policy.
1362 *
1363 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001364 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 */
1366int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1367{
1368 int ret;
1369
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001370 if (cpufreq_disabled())
1371 return -EINVAL;
1372
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001373 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1374
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 switch (list) {
1376 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001377 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001378 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 break;
1380 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001381 ret = blocking_notifier_chain_register(
1382 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 break;
1384 default:
1385 ret = -EINVAL;
1386 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387
1388 return ret;
1389}
1390EXPORT_SYMBOL(cpufreq_register_notifier);
1391
1392
1393/**
1394 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1395 * @nb: notifier block to be unregistered
1396 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1397 *
1398 * Remove a driver from the CPU frequency notifier list.
1399 *
1400 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001401 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 */
1403int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1404{
1405 int ret;
1406
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001407 if (cpufreq_disabled())
1408 return -EINVAL;
1409
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 switch (list) {
1411 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001412 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001413 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 break;
1415 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001416 ret = blocking_notifier_chain_unregister(
1417 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 break;
1419 default:
1420 ret = -EINVAL;
1421 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001422
1423 return ret;
1424}
1425EXPORT_SYMBOL(cpufreq_unregister_notifier);
1426
1427
1428/*********************************************************************
1429 * GOVERNORS *
1430 *********************************************************************/
1431
1432
1433int __cpufreq_driver_target(struct cpufreq_policy *policy,
1434 unsigned int target_freq,
1435 unsigned int relation)
1436{
1437 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001438 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001439
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001440 if (cpufreq_disabled())
1441 return -ENODEV;
1442
Viresh Kumar72499242012-10-31 01:28:21 +01001443 /* Make sure that target_freq is within supported range */
1444 if (target_freq > policy->max)
1445 target_freq = policy->max;
1446 if (target_freq < policy->min)
1447 target_freq = policy->min;
1448
1449 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1450 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001451
1452 if (target_freq == policy->cur)
1453 return 0;
1454
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001455 if (cpufreq_driver->target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001457
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 return retval;
1459}
1460EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1461
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462int cpufreq_driver_target(struct cpufreq_policy *policy,
1463 unsigned int target_freq,
1464 unsigned int relation)
1465{
Julia Lawallf1829e42008-07-25 22:44:53 +02001466 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467
1468 policy = cpufreq_cpu_get(policy->cpu);
1469 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001470 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001472 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001473 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
1475 ret = __cpufreq_driver_target(policy, target_freq, relation);
1476
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001477 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478
Julia Lawallf1829e42008-07-25 22:44:53 +02001479fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001481no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 return ret;
1483}
1484EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1485
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001486int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001487{
1488 int ret = 0;
1489
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001490 if (cpufreq_disabled())
1491 return ret;
1492
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001493 if (!cpufreq_driver->getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001494 return 0;
1495
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001496 policy = cpufreq_cpu_get(policy->cpu);
1497 if (!policy)
1498 return -EINVAL;
1499
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001500 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001501
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001502 cpufreq_cpu_put(policy);
1503 return ret;
1504}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001505EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001506
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001507/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001508 * when "event" is CPUFREQ_GOV_LIMITS
1509 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301511static int __cpufreq_governor(struct cpufreq_policy *policy,
1512 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513{
Dave Jonescc993ca2005-07-28 09:43:56 -07001514 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001515
1516 /* Only must be defined when default governor is known to have latency
1517 restrictions, like e.g. conservative or ondemand.
1518 That this is the case is already ensured in Kconfig
1519 */
1520#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1521 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1522#else
1523 struct cpufreq_governor *gov = NULL;
1524#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001525
1526 if (policy->governor->max_transition_latency &&
1527 policy->cpuinfo.transition_latency >
1528 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001529 if (!gov)
1530 return -EINVAL;
1531 else {
1532 printk(KERN_WARNING "%s governor failed, too long"
1533 " transition latency of HW, fallback"
1534 " to %s governor\n",
1535 policy->governor->name,
1536 gov->name);
1537 policy->governor = gov;
1538 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001539 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540
1541 if (!try_module_get(policy->governor->owner))
1542 return -EINVAL;
1543
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001544 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301545 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 ret = policy->governor->governor(policy, event);
1547
Viresh Kumar8e536952013-02-07 12:51:27 +05301548 if (event == CPUFREQ_GOV_START)
1549 policy->governor->initialized++;
1550 else if (event == CPUFREQ_GOV_STOP)
1551 policy->governor->initialized--;
Viresh Kumarb3940582013-02-01 05:42:58 +00001552
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301553 /* we keep one module reference alive for
1554 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 if ((event != CPUFREQ_GOV_START) || ret)
1556 module_put(policy->governor->owner);
1557 if ((event == CPUFREQ_GOV_STOP) && !ret)
1558 module_put(policy->governor->owner);
1559
1560 return ret;
1561}
1562
1563
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564int cpufreq_register_governor(struct cpufreq_governor *governor)
1565{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001566 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
1568 if (!governor)
1569 return -EINVAL;
1570
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001571 if (cpufreq_disabled())
1572 return -ENODEV;
1573
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001574 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001575
Viresh Kumarb3940582013-02-01 05:42:58 +00001576 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001577 err = -EBUSY;
1578 if (__find_governor(governor->name) == NULL) {
1579 err = 0;
1580 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582
Dave Jones32ee8c32006-02-28 00:43:23 -05001583 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001584 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585}
1586EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1587
1588
1589void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1590{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001591#ifdef CONFIG_HOTPLUG_CPU
1592 int cpu;
1593#endif
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 if (!governor)
1596 return;
1597
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001598 if (cpufreq_disabled())
1599 return;
1600
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001601#ifdef CONFIG_HOTPLUG_CPU
1602 for_each_present_cpu(cpu) {
1603 if (cpu_online(cpu))
1604 continue;
1605 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1606 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1607 }
1608#endif
1609
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001610 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001612 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 return;
1614}
1615EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1616
1617
1618
1619/*********************************************************************
1620 * POLICY INTERFACE *
1621 *********************************************************************/
1622
1623/**
1624 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001625 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1626 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 *
1628 * Reads the current cpufreq policy.
1629 */
1630int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1631{
1632 struct cpufreq_policy *cpu_policy;
1633 if (!policy)
1634 return -EINVAL;
1635
1636 cpu_policy = cpufreq_cpu_get(cpu);
1637 if (!cpu_policy)
1638 return -EINVAL;
1639
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
1642 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 return 0;
1644}
1645EXPORT_SYMBOL(cpufreq_get_policy);
1646
1647
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001648/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301649 * data : current policy.
1650 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001651 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301652static int __cpufreq_set_policy(struct cpufreq_policy *data,
1653 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654{
1655 int ret = 0;
1656
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001657 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 policy->min, policy->max);
1659
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301660 memcpy(&policy->cpuinfo, &data->cpuinfo,
1661 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
Yi Yang53391fa2008-01-30 13:33:34 +01001663 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001664 ret = -EINVAL;
1665 goto error_out;
1666 }
1667
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 /* verify the cpu speed can be set within this limit */
1669 ret = cpufreq_driver->verify(policy);
1670 if (ret)
1671 goto error_out;
1672
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001674 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1675 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001678 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1679 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
1681 /* verify the cpu speed can be set within this limit,
1682 which might be different to the first one */
1683 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001684 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
1687 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001688 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1689 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
Dave Jones7d5e3502006-02-02 17:03:42 -05001691 data->min = policy->min;
1692 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001694 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301695 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
1697 if (cpufreq_driver->setpolicy) {
1698 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001699 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 ret = cpufreq_driver->setpolicy(policy);
1701 } else {
1702 if (policy->governor != data->governor) {
1703 /* save old, working values */
1704 struct cpufreq_governor *old_gov = data->governor;
1705
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001706 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707
1708 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001709 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1711
1712 /* start new governor */
1713 data->governor = policy->governor;
1714 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1715 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001716 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301717 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 if (old_gov) {
1719 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301720 __cpufreq_governor(data,
1721 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 }
1723 ret = -EINVAL;
1724 goto error_out;
1725 }
1726 /* might be a policy change, too, so fall through */
1727 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001728 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1730 }
1731
Dave Jones7d5e3502006-02-02 17:03:42 -05001732error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 return ret;
1734}
1735
1736/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1738 * @cpu: CPU which shall be re-evaluated
1739 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001740 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 * at different times.
1742 */
1743int cpufreq_update_policy(unsigned int cpu)
1744{
1745 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1746 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001747 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748
Julia Lawallf1829e42008-07-25 22:44:53 +02001749 if (!data) {
1750 ret = -ENODEV;
1751 goto no_policy;
1752 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
Julia Lawallf1829e42008-07-25 22:44:53 +02001754 if (unlikely(lock_policy_rwsem_write(cpu))) {
1755 ret = -EINVAL;
1756 goto fail;
1757 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001759 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001760 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 policy.min = data->user_policy.min;
1762 policy.max = data->user_policy.max;
1763 policy.policy = data->user_policy.policy;
1764 policy.governor = data->user_policy.governor;
1765
Thomas Renninger0961dd02006-01-26 18:46:33 +01001766 /* BIOS might change freq behind our back
1767 -> ask driver for current freq and notify governors about a change */
1768 if (cpufreq_driver->get) {
1769 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001770 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001771 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001772 data->cur = policy.cur;
1773 } else {
Dirk Brandewief6b05152013-02-06 09:02:09 -08001774 if (data->cur != policy.cur && cpufreq_driver->target)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301775 cpufreq_out_of_sync(cpu, data->cur,
1776 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001777 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001778 }
1779
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 ret = __cpufreq_set_policy(data, &policy);
1781
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001782 unlock_policy_rwsem_write(cpu);
1783
Julia Lawallf1829e42008-07-25 22:44:53 +02001784fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001786no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 return ret;
1788}
1789EXPORT_SYMBOL(cpufreq_update_policy);
1790
Satyam Sharmadd184a02007-10-02 13:28:14 -07001791static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001792 unsigned long action, void *hcpu)
1793{
1794 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001795 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001796
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001797 dev = get_cpu_device(cpu);
1798 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001799 switch (action) {
1800 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001801 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001802 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001803 break;
1804 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001805 case CPU_DOWN_PREPARE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001806 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001807 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001808 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001809 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001810 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001811 break;
1812 }
1813 }
1814 return NOTIFY_OK;
1815}
1816
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001817static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001818 .notifier_call = cpufreq_cpu_callback,
1819};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821/*********************************************************************
1822 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1823 *********************************************************************/
1824
1825/**
1826 * cpufreq_register_driver - register a CPU Frequency driver
1827 * @driver_data: A struct cpufreq_driver containing the values#
1828 * submitted by the CPU Frequency driver.
1829 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001830 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001832 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 *
1834 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001835int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836{
1837 unsigned long flags;
1838 int ret;
1839
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001840 if (cpufreq_disabled())
1841 return -ENODEV;
1842
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 if (!driver_data || !driver_data->verify || !driver_data->init ||
1844 ((!driver_data->setpolicy) && (!driver_data->target)))
1845 return -EINVAL;
1846
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001847 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848
1849 if (driver_data->setpolicy)
1850 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1851
1852 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1853 if (cpufreq_driver) {
1854 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1855 return -EBUSY;
1856 }
1857 cpufreq_driver = driver_data;
1858 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1859
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001860 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001861 if (ret)
1862 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001864 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 int i;
1866 ret = -ENODEV;
1867
1868 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001869 for (i = 0; i < nr_cpu_ids; i++)
1870 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001872 break;
1873 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874
1875 /* if all ->init() calls failed, unregister */
1876 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001877 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301878 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001879 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 }
1881 }
1882
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001883 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001884 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001886 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001887err_if_unreg:
1888 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001889err_null_driver:
1890 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1891 cpufreq_driver = NULL;
1892 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001893 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894}
1895EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1896
1897
1898/**
1899 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1900 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001901 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 * the right to do so, i.e. if you have succeeded in initialising before!
1903 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1904 * currently not initialised.
1905 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001906int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907{
1908 unsigned long flags;
1909
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001910 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001913 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001915 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001916 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917
1918 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1919 cpufreq_driver = NULL;
1920 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1921
1922 return 0;
1923}
1924EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001925
1926static int __init cpufreq_core_init(void)
1927{
1928 int cpu;
1929
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001930 if (cpufreq_disabled())
1931 return -ENODEV;
1932
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001933 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001934 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001935 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1936 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001937
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001938 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001939 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001940 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001941
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001942 return 0;
1943}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001944core_initcall(cpufreq_core_init);