blob: 08df7a196116805df622b2d4938077fa2848f155 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/cpufreq/cpufreq.c
3 *
4 * Copyright (C) 2001 Russell King
5 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08007 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05008 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -05009 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
10 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080011 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/notifier.h>
24#include <linux/cpufreq.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/spinlock.h>
28#include <linux/device.h>
29#include <linux/slab.h>
30#include <linux/cpu.h>
31#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080032#include <linux/mutex.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010033#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Thomas Renninger6f4f2722010-04-20 13:17:36 +020035#include <trace/events/power.h>
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037/**
Dave Jonescd878472006-08-11 17:59:28 -040038 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070039 * level driver of CPUFreq support, and its spinlock. This lock
40 * also protects the cpufreq_cpu_data array.
41 */
Dave Jones7d5e3502006-02-02 17:03:42 -050042static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070043static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070044#ifdef CONFIG_HOTPLUG_CPU
45/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040046static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070047#endif
Nathan Zimmer0d1857a2013-02-22 16:24:34 +000048static DEFINE_RWLOCK(cpufreq_driver_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080050/*
51 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
52 * all cpufreq/hotplug/workqueue/etc related lock issues.
53 *
54 * The rules for this semaphore:
55 * - Any routine that wants to read from the policy structure will
56 * do a down_read on this semaphore.
57 * - Any routine that will write to the policy structure and/or may take away
58 * the policy altogether (eg. CPU hotplug), will hold this lock in write
59 * mode before doing so.
60 *
61 * Additional rules:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080062 * - Governor routines that can be called in cpufreq hotplug path should not
63 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040064 * - Lock should not be held across
65 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080066 */
Tejun Heof1625062009-10-29 22:34:13 +090067static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080068static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
69
70#define lock_policy_rwsem(mode, cpu) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053071static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072{ \
Tejun Heof1625062009-10-29 22:34:13 +090073 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080074 BUG_ON(policy_cpu == -1); \
75 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076 \
77 return 0; \
78}
79
80lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080081lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080082
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053083#define unlock_policy_rwsem(mode, cpu) \
84static void unlock_policy_rwsem_##mode(int cpu) \
85{ \
86 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
87 BUG_ON(policy_cpu == -1); \
88 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080089}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053091unlock_policy_rwsem(read, cpu);
92unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Linus Torvalds1da177e2005-04-16 15:20:36 -070094/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -050095static int __cpufreq_governor(struct cpufreq_policy *policy,
96 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +000098static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500101 * Two notifier lists: the "policy" list is involved in the
102 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 * "transition" list for kernel code that needs to handle
104 * changes to devices when the CPU clock speed changes.
105 * The mutex locks both lists.
106 */
Alan Sterne041c682006-03-27 01:16:30 -0800107static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700108static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200110static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700111static int __init init_cpufreq_transition_notifier_list(void)
112{
113 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200114 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700115 return 0;
116}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800117pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400119static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200120static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400121{
122 return off;
123}
124void disable_cpufreq(void)
125{
126 off = 1;
127}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500129static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Stephen Boyda9144432012-07-20 18:14:38 +0000131static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132{
133 struct cpufreq_policy *data;
134 unsigned long flags;
135
Mike Travis7a6aedf2008-03-25 15:06:53 -0700136 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 goto err_out;
138
139 /* get the cpufreq driver */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000140 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 if (!cpufreq_driver)
143 goto err_out_unlock;
144
145 if (!try_module_get(cpufreq_driver->owner))
146 goto err_out_unlock;
147
148
149 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700150 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
152 if (!data)
153 goto err_out_put_module;
154
Stephen Boyda9144432012-07-20 18:14:38 +0000155 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 goto err_out_put_module;
157
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000158 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 return data;
160
Dave Jones7d5e3502006-02-02 17:03:42 -0500161err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500163err_out_unlock:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000164 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500165err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 return NULL;
167}
Stephen Boyda9144432012-07-20 18:14:38 +0000168
169struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
170{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000171 if (cpufreq_disabled())
172 return NULL;
173
Stephen Boyda9144432012-07-20 18:14:38 +0000174 return __cpufreq_cpu_get(cpu, false);
175}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
177
Stephen Boyda9144432012-07-20 18:14:38 +0000178static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
179{
180 return __cpufreq_cpu_get(cpu, true);
181}
182
183static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
184{
185 if (!sysfs)
186 kobject_put(&data->kobj);
187 module_put(cpufreq_driver->owner);
188}
Dave Jones7d5e3502006-02-02 17:03:42 -0500189
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190void cpufreq_cpu_put(struct cpufreq_policy *data)
191{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000192 if (cpufreq_disabled())
193 return;
194
Stephen Boyda9144432012-07-20 18:14:38 +0000195 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196}
197EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
198
Stephen Boyda9144432012-07-20 18:14:38 +0000199static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
200{
201 __cpufreq_cpu_put(data, true);
202}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
206 *********************************************************************/
207
208/**
209 * adjust_jiffies - adjust the system "loops_per_jiffy"
210 *
211 * This function alters the system "loops_per_jiffy" for the clock
212 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500213 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 * per-CPU loops_per_jiffy value wherever possible.
215 */
216#ifndef CONFIG_SMP
217static unsigned long l_p_j_ref;
218static unsigned int l_p_j_ref_freq;
219
Arjan van de Ven858119e2006-01-14 13:20:43 -0800220static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221{
222 if (ci->flags & CPUFREQ_CONST_LOOPS)
223 return;
224
225 if (!l_p_j_ref_freq) {
226 l_p_j_ref = loops_per_jiffy;
227 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200228 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530229 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530231 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700232 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530233 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
234 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200235 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530236 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 }
238}
239#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530240static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
241{
242 return;
243}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244#endif
245
246
247/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800248 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
249 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800251 * This function calls the transition notifiers and the "adjust_jiffies"
252 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500253 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 */
255void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
256{
Dave Jonese4472cb2006-01-31 15:53:55 -0800257 struct cpufreq_policy *policy;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530258 unsigned long flags;
Dave Jonese4472cb2006-01-31 15:53:55 -0800259
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 BUG_ON(irqs_disabled());
261
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000262 if (cpufreq_disabled())
263 return;
264
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200266 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800267 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000269 read_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -0700270 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000271 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530272
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800274
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500276 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800277 * which is not equal to what the cpufreq core thinks is
278 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 */
280 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800281 if ((policy) && (policy->cpu == freqs->cpu) &&
282 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200283 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800284 " %u, cpufreq assumed %u kHz.\n",
285 freqs->old, policy->cur);
286 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 }
288 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700289 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800290 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
292 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 case CPUFREQ_POSTCHANGE:
295 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200296 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200297 (unsigned long)freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100298 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700299 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800300 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800301 if (likely(policy) && likely(policy->cpu == freqs->cpu))
302 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 break;
304 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305}
306EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
307
308
309
310/*********************************************************************
311 * SYSFS INTERFACE *
312 *********************************************************************/
313
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700314static struct cpufreq_governor *__find_governor(const char *str_governor)
315{
316 struct cpufreq_governor *t;
317
318 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500319 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700320 return t;
321
322 return NULL;
323}
324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325/**
326 * cpufreq_parse_governor - parse a governor string
327 */
Dave Jones905d77c2008-03-05 14:28:32 -0500328static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 struct cpufreq_governor **governor)
330{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700331 int err = -EINVAL;
332
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700334 goto out;
335
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 if (cpufreq_driver->setpolicy) {
337 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
338 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700339 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530340 } else if (!strnicmp(str_governor, "powersave",
341 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700343 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700345 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700347
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800348 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700349
350 t = __find_governor(str_governor);
351
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700352 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700353 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700354
Kees Cook1a8e1462011-05-04 08:38:56 -0700355 mutex_unlock(&cpufreq_governor_mutex);
356 ret = request_module("cpufreq_%s", str_governor);
357 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700358
Kees Cook1a8e1462011-05-04 08:38:56 -0700359 if (ret == 0)
360 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700361 }
362
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700363 if (t != NULL) {
364 *governor = t;
365 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700367
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800368 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
Dave Jones29464f22009-01-18 01:37:11 -0500370out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700371 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530376 * cpufreq_per_cpu_attr_read() / show_##file_name() -
377 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 *
379 * Write out information from cpufreq_driver->policy[cpu]; object must be
380 * "unsigned int".
381 */
382
Dave Jones32ee8c32006-02-28 00:43:23 -0500383#define show_one(file_name, object) \
384static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500385(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500386{ \
Dave Jones29464f22009-01-18 01:37:11 -0500387 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388}
389
390show_one(cpuinfo_min_freq, cpuinfo.min_freq);
391show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100392show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393show_one(scaling_min_freq, min);
394show_one(scaling_max_freq, max);
395show_one(scaling_cur_freq, cur);
396
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530397static int __cpufreq_set_policy(struct cpufreq_policy *data,
398 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400/**
401 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
402 */
403#define store_one(file_name, object) \
404static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500405(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000407 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 struct cpufreq_policy new_policy; \
409 \
410 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
411 if (ret) \
412 return -EINVAL; \
413 \
Dave Jones29464f22009-01-18 01:37:11 -0500414 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 if (ret != 1) \
416 return -EINVAL; \
417 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200418 ret = __cpufreq_set_policy(policy, &new_policy); \
419 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 \
421 return ret ? ret : count; \
422}
423
Dave Jones29464f22009-01-18 01:37:11 -0500424store_one(scaling_min_freq, min);
425store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
427/**
428 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
429 */
Dave Jones905d77c2008-03-05 14:28:32 -0500430static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
431 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800433 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 if (!cur_freq)
435 return sprintf(buf, "<unknown>");
436 return sprintf(buf, "%u\n", cur_freq);
437}
438
439
440/**
441 * show_scaling_governor - show the current policy for the specified CPU
442 */
Dave Jones905d77c2008-03-05 14:28:32 -0500443static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444{
Dave Jones29464f22009-01-18 01:37:11 -0500445 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 return sprintf(buf, "powersave\n");
447 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
448 return sprintf(buf, "performance\n");
449 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200450 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500451 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 return -EINVAL;
453}
454
455
456/**
457 * store_scaling_governor - store policy for the specified CPU
458 */
Dave Jones905d77c2008-03-05 14:28:32 -0500459static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
460 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000462 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 char str_governor[16];
464 struct cpufreq_policy new_policy;
465
466 ret = cpufreq_get_policy(&new_policy, policy->cpu);
467 if (ret)
468 return ret;
469
Dave Jones29464f22009-01-18 01:37:11 -0500470 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 if (ret != 1)
472 return -EINVAL;
473
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530474 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
475 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 return -EINVAL;
477
Thomas Renninger7970e082006-04-13 15:14:04 +0200478 /* Do not use cpufreq_set_policy here or the user_policy.max
479 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200480 ret = __cpufreq_set_policy(policy, &new_policy);
481
482 policy->user_policy.policy = policy->policy;
483 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200484
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530485 if (ret)
486 return ret;
487 else
488 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489}
490
491/**
492 * show_scaling_driver - show the cpufreq driver currently loaded
493 */
Dave Jones905d77c2008-03-05 14:28:32 -0500494static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495{
viresh kumar4b972f02012-10-23 01:23:43 +0200496 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497}
498
499/**
500 * show_scaling_available_governors - show the available CPUfreq governors
501 */
Dave Jones905d77c2008-03-05 14:28:32 -0500502static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
503 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504{
505 ssize_t i = 0;
506 struct cpufreq_governor *t;
507
508 if (!cpufreq_driver->target) {
509 i += sprintf(buf, "performance powersave");
510 goto out;
511 }
512
513 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500514 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
515 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200517 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500519out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 i += sprintf(&buf[i], "\n");
521 return i;
522}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700523
Rusty Russell835481d2009-01-04 05:18:06 -0800524static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525{
526 ssize_t i = 0;
527 unsigned int cpu;
528
Rusty Russell835481d2009-01-04 05:18:06 -0800529 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 if (i)
531 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
532 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
533 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500534 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 }
536 i += sprintf(&buf[i], "\n");
537 return i;
538}
539
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700540/**
541 * show_related_cpus - show the CPUs affected by each transition even if
542 * hw coordination is in use
543 */
544static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
545{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700546 return show_cpus(policy->related_cpus, buf);
547}
548
549/**
550 * show_affected_cpus - show the CPUs affected by each transition
551 */
552static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
553{
554 return show_cpus(policy->cpus, buf);
555}
556
Venki Pallipadi9e769882007-10-26 10:18:21 -0700557static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500558 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700559{
560 unsigned int freq = 0;
561 unsigned int ret;
562
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700563 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700564 return -EINVAL;
565
566 ret = sscanf(buf, "%u", &freq);
567 if (ret != 1)
568 return -EINVAL;
569
570 policy->governor->store_setspeed(policy, freq);
571
572 return count;
573}
574
575static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
576{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700577 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700578 return sprintf(buf, "<unsupported>\n");
579
580 return policy->governor->show_setspeed(policy, buf);
581}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582
Thomas Renningere2f74f32009-11-19 12:31:01 +0100583/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200584 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100585 */
586static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
587{
588 unsigned int limit;
589 int ret;
590 if (cpufreq_driver->bios_limit) {
591 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
592 if (!ret)
593 return sprintf(buf, "%u\n", limit);
594 }
595 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
596}
597
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200598cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
599cpufreq_freq_attr_ro(cpuinfo_min_freq);
600cpufreq_freq_attr_ro(cpuinfo_max_freq);
601cpufreq_freq_attr_ro(cpuinfo_transition_latency);
602cpufreq_freq_attr_ro(scaling_available_governors);
603cpufreq_freq_attr_ro(scaling_driver);
604cpufreq_freq_attr_ro(scaling_cur_freq);
605cpufreq_freq_attr_ro(bios_limit);
606cpufreq_freq_attr_ro(related_cpus);
607cpufreq_freq_attr_ro(affected_cpus);
608cpufreq_freq_attr_rw(scaling_min_freq);
609cpufreq_freq_attr_rw(scaling_max_freq);
610cpufreq_freq_attr_rw(scaling_governor);
611cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
Dave Jones905d77c2008-03-05 14:28:32 -0500613static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 &cpuinfo_min_freq.attr,
615 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100616 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 &scaling_min_freq.attr,
618 &scaling_max_freq.attr,
619 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700620 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 &scaling_governor.attr,
622 &scaling_driver.attr,
623 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700624 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 NULL
626};
627
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200628struct kobject *cpufreq_global_kobject;
629EXPORT_SYMBOL(cpufreq_global_kobject);
630
Dave Jones29464f22009-01-18 01:37:11 -0500631#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
632#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
Dave Jones29464f22009-01-18 01:37:11 -0500634static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635{
Dave Jones905d77c2008-03-05 14:28:32 -0500636 struct cpufreq_policy *policy = to_policy(kobj);
637 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500638 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000639 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500641 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800642
643 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500644 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800645
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530646 if (fattr->show)
647 ret = fattr->show(policy, buf);
648 else
649 ret = -EIO;
650
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800651 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500652fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000653 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500654no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 return ret;
656}
657
Dave Jones905d77c2008-03-05 14:28:32 -0500658static ssize_t store(struct kobject *kobj, struct attribute *attr,
659 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
Dave Jones905d77c2008-03-05 14:28:32 -0500661 struct cpufreq_policy *policy = to_policy(kobj);
662 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500663 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000664 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500666 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800667
668 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500669 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800670
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530671 if (fattr->store)
672 ret = fattr->store(policy, buf, count);
673 else
674 ret = -EIO;
675
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800676 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500677fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000678 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500679no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 return ret;
681}
682
Dave Jones905d77c2008-03-05 14:28:32 -0500683static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684{
Dave Jones905d77c2008-03-05 14:28:32 -0500685 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200686 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 complete(&policy->kobj_unregister);
688}
689
Emese Revfy52cf25d2010-01-19 02:58:23 +0100690static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 .show = show,
692 .store = store,
693};
694
695static struct kobj_type ktype_cpufreq = {
696 .sysfs_ops = &sysfs_ops,
697 .default_attrs = default_attrs,
698 .release = cpufreq_sysfs_release,
699};
700
Dave Jones19d6f7e2009-07-08 17:35:39 -0400701/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700702static int cpufreq_add_dev_symlink(unsigned int cpu,
703 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400704{
705 unsigned int j;
706 int ret = 0;
707
708 for_each_cpu(j, policy->cpus) {
709 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800710 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400711
712 if (j == cpu)
713 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400714
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200715 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400716 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800717 cpu_dev = get_cpu_device(j);
718 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400719 "cpufreq");
720 if (ret) {
721 cpufreq_cpu_put(managed_policy);
722 return ret;
723 }
724 }
725 return ret;
726}
727
Alex Chiangcf3289d02009-11-17 20:27:08 -0700728static int cpufreq_add_dev_interface(unsigned int cpu,
729 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800730 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400731{
Dave Jonesecf7e462009-07-08 18:48:47 -0400732 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400733 struct freq_attr **drv_attr;
734 unsigned long flags;
735 int ret = 0;
736 unsigned int j;
737
738 /* prepare interface data */
739 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800740 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400741 if (ret)
742 return ret;
743
744 /* set up files for this cpu device */
745 drv_attr = cpufreq_driver->attr;
746 while ((drv_attr) && (*drv_attr)) {
747 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
748 if (ret)
749 goto err_out_kobj_put;
750 drv_attr++;
751 }
752 if (cpufreq_driver->get) {
753 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
754 if (ret)
755 goto err_out_kobj_put;
756 }
757 if (cpufreq_driver->target) {
758 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
759 if (ret)
760 goto err_out_kobj_put;
761 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100762 if (cpufreq_driver->bios_limit) {
763 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
764 if (ret)
765 goto err_out_kobj_put;
766 }
Dave Jones909a6942009-07-08 18:05:42 -0400767
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000768 write_lock_irqsave(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400769 for_each_cpu(j, policy->cpus) {
Dave Jones909a6942009-07-08 18:05:42 -0400770 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900771 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400772 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000773 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400774
775 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400776 if (ret)
777 goto err_out_kobj_put;
778
779 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
780 /* assure that the starting sequence is run in __cpufreq_set_policy */
781 policy->governor = NULL;
782
783 /* set default policy */
784 ret = __cpufreq_set_policy(policy, &new_policy);
785 policy->user_policy.policy = policy->policy;
786 policy->user_policy.governor = policy->governor;
787
788 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200789 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400790 if (cpufreq_driver->exit)
791 cpufreq_driver->exit(policy);
792 }
Dave Jones909a6942009-07-08 18:05:42 -0400793 return ret;
794
795err_out_kobj_put:
796 kobject_put(&policy->kobj);
797 wait_for_completion(&policy->kobj_unregister);
798 return ret;
799}
800
Viresh Kumarfcf80582013-01-29 14:39:08 +0000801#ifdef CONFIG_HOTPLUG_CPU
802static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
803 struct device *dev)
804{
805 struct cpufreq_policy *policy;
806 int ret = 0;
807 unsigned long flags;
808
809 policy = cpufreq_cpu_get(sibling);
810 WARN_ON(!policy);
811
Viresh Kumarfcf80582013-01-29 14:39:08 +0000812 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
813
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530814 lock_policy_rwsem_write(sibling);
815
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000816 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530817
Viresh Kumarfcf80582013-01-29 14:39:08 +0000818 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530819 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000820 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000821 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000822
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530823 unlock_policy_rwsem_write(sibling);
824
Viresh Kumarfcf80582013-01-29 14:39:08 +0000825 __cpufreq_governor(policy, CPUFREQ_GOV_START);
826 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
827
Viresh Kumarfcf80582013-01-29 14:39:08 +0000828 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
829 if (ret) {
830 cpufreq_cpu_put(policy);
831 return ret;
832 }
833
834 return 0;
835}
836#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
838/**
839 * cpufreq_add_dev - add a CPU device
840 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500841 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400842 *
843 * The Oracle says: try running cpufreq registration/unregistration concurrently
844 * with with cpu hotplugging and all hell will break loose. Tried to clean this
845 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800847static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000849 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530850 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500853#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000854 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500855 int sibling;
856#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857
Ashok Rajc32b6b82005-10-30 14:59:54 -0800858 if (cpu_is_offline(cpu))
859 return 0;
860
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200861 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862
863#ifdef CONFIG_SMP
864 /* check whether a different CPU already registered this
865 * CPU because it is in the same boat. */
866 policy = cpufreq_cpu_get(cpu);
867 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500868 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 return 0;
870 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000871
872#ifdef CONFIG_HOTPLUG_CPU
873 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000874 read_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000875 for_each_online_cpu(sibling) {
876 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530877 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000878 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000879 return cpufreq_add_policy_cpu(cpu, sibling, dev);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530880 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000881 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000882 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000883#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884#endif
885
886 if (!try_module_get(cpufreq_driver->owner)) {
887 ret = -EINVAL;
888 goto module_out;
889 }
890
Dave Jonese98df502005-10-20 15:17:43 -0700891 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400892 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400894
895 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400896 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400897
898 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400899 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900
901 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +0530902 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -0800903 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800905 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900906 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800907
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000909 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910
911 /* call driver. From then on the cpufreq must be able
912 * to accept all calls to ->verify and ->setpolicy for this CPU
913 */
914 ret = cpufreq_driver->init(policy);
915 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200916 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530917 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000919
Viresh Kumarfcf80582013-01-29 14:39:08 +0000920 /* related cpus should atleast have policy->cpus */
921 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
922
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000923 /*
924 * affected cpus must always be the one, which are online. We aren't
925 * managing offline cpus here.
926 */
927 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
928
Mike Chan187d9f42008-12-04 12:19:17 -0800929 policy->user_policy.min = policy->min;
930 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
Thomas Renningera1531ac2008-07-29 22:32:58 -0700932 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
933 CPUFREQ_START, policy);
934
Viresh Kumarfcf80582013-01-29 14:39:08 +0000935#ifdef CONFIG_HOTPLUG_CPU
936 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
937 if (gov) {
938 policy->governor = gov;
939 pr_debug("Restoring governor %s for cpu %d\n",
940 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200941 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000942#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800944 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400945 if (ret)
946 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500947
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400948 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200950 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -0500951
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 return 0;
953
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000955 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -0800956 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -0700957 per_cpu(cpufreq_cpu_data, j) = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000958 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -0800960 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 wait_for_completion(&policy->kobj_unregister);
962
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530963err_set_policy_cpu:
964 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Xiaotian Fengcad70a62010-07-20 20:11:02 +0800965 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400966err_free_cpumask:
967 free_cpumask_var(policy->cpus);
968err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970nomem_out:
971 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -0800972module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 return ret;
974}
975
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000976static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
977{
978 int j;
979
980 policy->last_cpu = policy->cpu;
981 policy->cpu = cpu;
982
Viresh Kumar3361b7b2013-02-04 11:38:51 +0000983 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000984 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +0000985
986#ifdef CONFIG_CPU_FREQ_TABLE
987 cpufreq_frequency_table_update_policy_cpu(policy);
988#endif
989 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
990 CPUFREQ_UPDATE_POLICY_CPU, policy);
991}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
993/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800994 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 *
996 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800997 * Caller should already have policy_rwsem in write mode for this CPU.
998 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001000static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001002 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 unsigned long flags;
1004 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001005 struct kobject *kobj;
1006 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001007 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001009 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001011 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 data = per_cpu(cpufreq_cpu_data, cpu);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001014 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001016 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001019 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 if (cpufreq_driver->target)
1024 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001025
Jacob Shin27ecddc2011-04-27 13:32:11 -05001026#ifdef CONFIG_HOTPLUG_CPU
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001027 if (!cpufreq_driver->setpolicy)
1028 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
1029 data->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001030#endif
1031
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301032 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001033 cpus = cpumask_weight(data->cpus);
1034 cpumask_clear_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301035 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001037 if (cpu != data->cpu) {
1038 sysfs_remove_link(&dev->kobj, "cpufreq");
1039 } else if (cpus > 1) {
Venki Pallipadiec282972007-03-26 12:03:19 -07001040 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001041 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1042 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1043 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1044 if (ret) {
1045 pr_err("%s: Failed to move kobj: %d", __func__, ret);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301046
1047 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001048 cpumask_set_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301049
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001050 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301051 per_cpu(cpufreq_cpu_data, cpu) = data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001052 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301053
1054 unlock_policy_rwsem_write(cpu);
1055
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001056 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1057 "cpufreq");
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001058 return -EINVAL;
1059 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001060
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301061 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001062 update_policy_cpu(data, cpu_dev->id);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301063 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001064 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1065 __func__, cpu_dev->id, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001066 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001067
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001068 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1069 cpufreq_cpu_put(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001070
1071 /* If cpu is last user of policy, free policy */
1072 if (cpus == 1) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001073 __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
1074
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301075 lock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001076 kobj = &data->kobj;
1077 cmp = &data->kobj_unregister;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301078 unlock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001079 kobject_put(kobj);
1080
1081 /* we need to make sure that the underlying kobj is actually
1082 * not referenced anymore by anybody before we proceed with
1083 * unloading.
1084 */
1085 pr_debug("waiting for dropping of refcount\n");
1086 wait_for_completion(cmp);
1087 pr_debug("wait complete\n");
1088
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001089 if (cpufreq_driver->exit)
1090 cpufreq_driver->exit(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001091
1092 free_cpumask_var(data->related_cpus);
1093 free_cpumask_var(data->cpus);
1094 kfree(data);
1095 } else if (cpufreq_driver->target) {
1096 __cpufreq_governor(data, CPUFREQ_GOV_START);
1097 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1098 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301100 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101 return 0;
1102}
1103
1104
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001105static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001106{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001107 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001108 int retval;
1109
1110 if (cpu_is_offline(cpu))
1111 return 0;
1112
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001113 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001114 return retval;
1115}
1116
1117
David Howells65f27f32006-11-22 14:55:48 +00001118static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119{
David Howells65f27f32006-11-22 14:55:48 +00001120 struct cpufreq_policy *policy =
1121 container_of(work, struct cpufreq_policy, update);
1122 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001123 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 cpufreq_update_policy(cpu);
1125}
1126
1127/**
1128 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1129 * @cpu: cpu number
1130 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1131 * @new_freq: CPU frequency the CPU actually runs at
1132 *
Dave Jones29464f22009-01-18 01:37:11 -05001133 * We adjust to current frequency first, and need to clean up later.
1134 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301136static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1137 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138{
1139 struct cpufreq_freqs freqs;
1140
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001141 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1143
1144 freqs.cpu = cpu;
1145 freqs.old = old_freq;
1146 freqs.new = new_freq;
1147 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1148 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1149}
1150
1151
Dave Jones32ee8c32006-02-28 00:43:23 -05001152/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301153 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001154 * @cpu: CPU number
1155 *
1156 * This is the last known freq, without actually getting it from the driver.
1157 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1158 */
1159unsigned int cpufreq_quick_get(unsigned int cpu)
1160{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001161 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301162 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001163
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001164 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1165 return cpufreq_driver->get(cpu);
1166
1167 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001168 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301169 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001170 cpufreq_cpu_put(policy);
1171 }
1172
Dave Jones4d34a672008-02-07 16:33:49 -05001173 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001174}
1175EXPORT_SYMBOL(cpufreq_quick_get);
1176
Jesse Barnes3d737102011-06-28 10:59:12 -07001177/**
1178 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1179 * @cpu: CPU number
1180 *
1181 * Just return the max possible frequency for a given CPU.
1182 */
1183unsigned int cpufreq_quick_get_max(unsigned int cpu)
1184{
1185 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1186 unsigned int ret_freq = 0;
1187
1188 if (policy) {
1189 ret_freq = policy->max;
1190 cpufreq_cpu_put(policy);
1191 }
1192
1193 return ret_freq;
1194}
1195EXPORT_SYMBOL(cpufreq_quick_get_max);
1196
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001197
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001198static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001200 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301201 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001204 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301206 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301208 if (ret_freq && policy->cur &&
1209 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1210 /* verify no discrepancy between actual and
1211 saved value exists */
1212 if (unlikely(ret_freq != policy->cur)) {
1213 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 schedule_work(&policy->update);
1215 }
1216 }
1217
Dave Jones4d34a672008-02-07 16:33:49 -05001218 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001219}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001221/**
1222 * cpufreq_get - get the current CPU frequency (in kHz)
1223 * @cpu: CPU number
1224 *
1225 * Get the CPU current (static) CPU frequency
1226 */
1227unsigned int cpufreq_get(unsigned int cpu)
1228{
1229 unsigned int ret_freq = 0;
1230 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1231
1232 if (!policy)
1233 goto out;
1234
1235 if (unlikely(lock_policy_rwsem_read(cpu)))
1236 goto out_policy;
1237
1238 ret_freq = __cpufreq_get(cpu);
1239
1240 unlock_policy_rwsem_read(cpu);
1241
1242out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001244out:
Dave Jones4d34a672008-02-07 16:33:49 -05001245 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246}
1247EXPORT_SYMBOL(cpufreq_get);
1248
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001249static struct subsys_interface cpufreq_interface = {
1250 .name = "cpufreq",
1251 .subsys = &cpu_subsys,
1252 .add_dev = cpufreq_add_dev,
1253 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001254};
1255
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
1257/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001258 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1259 *
1260 * This function is only executed for the boot processor. The other CPUs
1261 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001262 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001263static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001264{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301265 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001266
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001267 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001268 struct cpufreq_policy *cpu_policy;
1269
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001270 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001271
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001272 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001273 cpu_policy = cpufreq_cpu_get(cpu);
1274 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001275 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001276
1277 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001278 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001279 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001280 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1281 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001282 }
1283
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001284 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001285 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001286}
1287
1288/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001289 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 *
1291 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001292 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1293 * restored. It will verify that the current freq is in sync with
1294 * what we believe it to be. This is a bit later than when it
1295 * should be, but nonethteless it's better than calling
1296 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001297 *
1298 * This function is only executed for the boot CPU. The other CPUs have not
1299 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001301static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301303 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001304
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001305 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 struct cpufreq_policy *cpu_policy;
1307
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001308 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001310 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 cpu_policy = cpufreq_cpu_get(cpu);
1312 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001313 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314
1315 if (cpufreq_driver->resume) {
1316 ret = cpufreq_driver->resume(cpu_policy);
1317 if (ret) {
1318 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1319 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001320 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 }
1322 }
1323
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001325
Dave Jonesc9060492008-02-07 16:32:18 -05001326fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328}
1329
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001330static struct syscore_ops cpufreq_syscore_ops = {
1331 .suspend = cpufreq_bp_suspend,
1332 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333};
1334
Borislav Petkov9d950462013-01-20 10:24:28 +00001335/**
1336 * cpufreq_get_current_driver - return current driver's name
1337 *
1338 * Return the name string of the currently loaded cpufreq driver
1339 * or NULL, if none.
1340 */
1341const char *cpufreq_get_current_driver(void)
1342{
1343 if (cpufreq_driver)
1344 return cpufreq_driver->name;
1345
1346 return NULL;
1347}
1348EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349
1350/*********************************************************************
1351 * NOTIFIER LISTS INTERFACE *
1352 *********************************************************************/
1353
1354/**
1355 * cpufreq_register_notifier - register a driver with cpufreq
1356 * @nb: notifier function to register
1357 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1358 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001359 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 * are notified about clock rate changes (once before and once after
1361 * the transition), or a list of drivers that are notified about
1362 * changes in cpufreq policy.
1363 *
1364 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001365 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 */
1367int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1368{
1369 int ret;
1370
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001371 if (cpufreq_disabled())
1372 return -EINVAL;
1373
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001374 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1375
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 switch (list) {
1377 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001378 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001379 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 break;
1381 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001382 ret = blocking_notifier_chain_register(
1383 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 break;
1385 default:
1386 ret = -EINVAL;
1387 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388
1389 return ret;
1390}
1391EXPORT_SYMBOL(cpufreq_register_notifier);
1392
1393
1394/**
1395 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1396 * @nb: notifier block to be unregistered
1397 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1398 *
1399 * Remove a driver from the CPU frequency notifier list.
1400 *
1401 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001402 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 */
1404int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1405{
1406 int ret;
1407
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001408 if (cpufreq_disabled())
1409 return -EINVAL;
1410
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 switch (list) {
1412 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001413 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001414 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 break;
1416 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001417 ret = blocking_notifier_chain_unregister(
1418 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 break;
1420 default:
1421 ret = -EINVAL;
1422 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423
1424 return ret;
1425}
1426EXPORT_SYMBOL(cpufreq_unregister_notifier);
1427
1428
1429/*********************************************************************
1430 * GOVERNORS *
1431 *********************************************************************/
1432
1433
1434int __cpufreq_driver_target(struct cpufreq_policy *policy,
1435 unsigned int target_freq,
1436 unsigned int relation)
1437{
1438 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001439 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001440
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001441 if (cpufreq_disabled())
1442 return -ENODEV;
1443
Viresh Kumar72499242012-10-31 01:28:21 +01001444 /* Make sure that target_freq is within supported range */
1445 if (target_freq > policy->max)
1446 target_freq = policy->max;
1447 if (target_freq < policy->min)
1448 target_freq = policy->min;
1449
1450 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1451 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001452
1453 if (target_freq == policy->cur)
1454 return 0;
1455
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001456 if (cpufreq_driver->target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001458
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 return retval;
1460}
1461EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1462
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463int cpufreq_driver_target(struct cpufreq_policy *policy,
1464 unsigned int target_freq,
1465 unsigned int relation)
1466{
Julia Lawallf1829e42008-07-25 22:44:53 +02001467 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
1469 policy = cpufreq_cpu_get(policy->cpu);
1470 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001471 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001473 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001474 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475
1476 ret = __cpufreq_driver_target(policy, target_freq, relation);
1477
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001478 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
Julia Lawallf1829e42008-07-25 22:44:53 +02001480fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001482no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 return ret;
1484}
1485EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1486
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001487int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001488{
1489 int ret = 0;
1490
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001491 if (cpufreq_disabled())
1492 return ret;
1493
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001494 if (!cpufreq_driver->getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001495 return 0;
1496
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001497 policy = cpufreq_cpu_get(policy->cpu);
1498 if (!policy)
1499 return -EINVAL;
1500
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001501 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001502
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001503 cpufreq_cpu_put(policy);
1504 return ret;
1505}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001506EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001507
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001508/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001509 * when "event" is CPUFREQ_GOV_LIMITS
1510 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301512static int __cpufreq_governor(struct cpufreq_policy *policy,
1513 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514{
Dave Jonescc993ca2005-07-28 09:43:56 -07001515 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001516
1517 /* Only must be defined when default governor is known to have latency
1518 restrictions, like e.g. conservative or ondemand.
1519 That this is the case is already ensured in Kconfig
1520 */
1521#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1522 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1523#else
1524 struct cpufreq_governor *gov = NULL;
1525#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001526
1527 if (policy->governor->max_transition_latency &&
1528 policy->cpuinfo.transition_latency >
1529 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001530 if (!gov)
1531 return -EINVAL;
1532 else {
1533 printk(KERN_WARNING "%s governor failed, too long"
1534 " transition latency of HW, fallback"
1535 " to %s governor\n",
1536 policy->governor->name,
1537 gov->name);
1538 policy->governor = gov;
1539 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001540 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
1542 if (!try_module_get(policy->governor->owner))
1543 return -EINVAL;
1544
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001545 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301546 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 ret = policy->governor->governor(policy, event);
1548
Viresh Kumar8e536952013-02-07 12:51:27 +05301549 if (event == CPUFREQ_GOV_START)
1550 policy->governor->initialized++;
1551 else if (event == CPUFREQ_GOV_STOP)
1552 policy->governor->initialized--;
Viresh Kumarb3940582013-02-01 05:42:58 +00001553
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301554 /* we keep one module reference alive for
1555 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 if ((event != CPUFREQ_GOV_START) || ret)
1557 module_put(policy->governor->owner);
1558 if ((event == CPUFREQ_GOV_STOP) && !ret)
1559 module_put(policy->governor->owner);
1560
1561 return ret;
1562}
1563
1564
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565int cpufreq_register_governor(struct cpufreq_governor *governor)
1566{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001567 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568
1569 if (!governor)
1570 return -EINVAL;
1571
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001572 if (cpufreq_disabled())
1573 return -ENODEV;
1574
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001575 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001576
Viresh Kumarb3940582013-02-01 05:42:58 +00001577 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001578 err = -EBUSY;
1579 if (__find_governor(governor->name) == NULL) {
1580 err = 0;
1581 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
Dave Jones32ee8c32006-02-28 00:43:23 -05001584 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001585 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586}
1587EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1588
1589
1590void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1591{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001592#ifdef CONFIG_HOTPLUG_CPU
1593 int cpu;
1594#endif
1595
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 if (!governor)
1597 return;
1598
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001599 if (cpufreq_disabled())
1600 return;
1601
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001602#ifdef CONFIG_HOTPLUG_CPU
1603 for_each_present_cpu(cpu) {
1604 if (cpu_online(cpu))
1605 continue;
1606 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1607 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1608 }
1609#endif
1610
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001611 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001613 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 return;
1615}
1616EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1617
1618
1619
1620/*********************************************************************
1621 * POLICY INTERFACE *
1622 *********************************************************************/
1623
1624/**
1625 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001626 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1627 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 *
1629 * Reads the current cpufreq policy.
1630 */
1631int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1632{
1633 struct cpufreq_policy *cpu_policy;
1634 if (!policy)
1635 return -EINVAL;
1636
1637 cpu_policy = cpufreq_cpu_get(cpu);
1638 if (!cpu_policy)
1639 return -EINVAL;
1640
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642
1643 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 return 0;
1645}
1646EXPORT_SYMBOL(cpufreq_get_policy);
1647
1648
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001649/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301650 * data : current policy.
1651 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001652 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301653static int __cpufreq_set_policy(struct cpufreq_policy *data,
1654 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001656 int ret = 0, failed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001658 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659 policy->min, policy->max);
1660
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301661 memcpy(&policy->cpuinfo, &data->cpuinfo,
1662 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663
Yi Yang53391fa2008-01-30 13:33:34 +01001664 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001665 ret = -EINVAL;
1666 goto error_out;
1667 }
1668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 /* verify the cpu speed can be set within this limit */
1670 ret = cpufreq_driver->verify(policy);
1671 if (ret)
1672 goto error_out;
1673
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001675 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1676 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001679 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1680 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
1682 /* verify the cpu speed can be set within this limit,
1683 which might be different to the first one */
1684 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001685 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
1688 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001689 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1690 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
Dave Jones7d5e3502006-02-02 17:03:42 -05001692 data->min = policy->min;
1693 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001695 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301696 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697
1698 if (cpufreq_driver->setpolicy) {
1699 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001700 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 ret = cpufreq_driver->setpolicy(policy);
1702 } else {
1703 if (policy->governor != data->governor) {
1704 /* save old, working values */
1705 struct cpufreq_governor *old_gov = data->governor;
1706
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001707 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708
1709 /* end old governor */
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001710 if (data->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001712 __cpufreq_governor(data,
1713 CPUFREQ_GOV_POLICY_EXIT);
1714 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
1716 /* start new governor */
1717 data->governor = policy->governor;
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001718 if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
1719 if (!__cpufreq_governor(data, CPUFREQ_GOV_START))
1720 failed = 0;
1721 else
1722 __cpufreq_governor(data,
1723 CPUFREQ_GOV_POLICY_EXIT);
1724 }
1725
1726 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001728 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301729 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 if (old_gov) {
1731 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301732 __cpufreq_governor(data,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001733 CPUFREQ_GOV_POLICY_INIT);
1734 __cpufreq_governor(data,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301735 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 }
1737 ret = -EINVAL;
1738 goto error_out;
1739 }
1740 /* might be a policy change, too, so fall through */
1741 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001742 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1744 }
1745
Dave Jones7d5e3502006-02-02 17:03:42 -05001746error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 return ret;
1748}
1749
1750/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1752 * @cpu: CPU which shall be re-evaluated
1753 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001754 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 * at different times.
1756 */
1757int cpufreq_update_policy(unsigned int cpu)
1758{
1759 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1760 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001761 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
Julia Lawallf1829e42008-07-25 22:44:53 +02001763 if (!data) {
1764 ret = -ENODEV;
1765 goto no_policy;
1766 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
Julia Lawallf1829e42008-07-25 22:44:53 +02001768 if (unlikely(lock_policy_rwsem_write(cpu))) {
1769 ret = -EINVAL;
1770 goto fail;
1771 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001773 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001774 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 policy.min = data->user_policy.min;
1776 policy.max = data->user_policy.max;
1777 policy.policy = data->user_policy.policy;
1778 policy.governor = data->user_policy.governor;
1779
Thomas Renninger0961dd02006-01-26 18:46:33 +01001780 /* BIOS might change freq behind our back
1781 -> ask driver for current freq and notify governors about a change */
1782 if (cpufreq_driver->get) {
1783 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001784 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001785 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001786 data->cur = policy.cur;
1787 } else {
Dirk Brandewief6b05152013-02-06 09:02:09 -08001788 if (data->cur != policy.cur && cpufreq_driver->target)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301789 cpufreq_out_of_sync(cpu, data->cur,
1790 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001791 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001792 }
1793
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 ret = __cpufreq_set_policy(data, &policy);
1795
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001796 unlock_policy_rwsem_write(cpu);
1797
Julia Lawallf1829e42008-07-25 22:44:53 +02001798fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001800no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 return ret;
1802}
1803EXPORT_SYMBOL(cpufreq_update_policy);
1804
Satyam Sharmadd184a02007-10-02 13:28:14 -07001805static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001806 unsigned long action, void *hcpu)
1807{
1808 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001809 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001810
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001811 dev = get_cpu_device(cpu);
1812 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001813 switch (action) {
1814 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001815 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001816 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001817 break;
1818 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001819 case CPU_DOWN_PREPARE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001820 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001821 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001822 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001823 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001824 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001825 break;
1826 }
1827 }
1828 return NOTIFY_OK;
1829}
1830
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001831static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001832 .notifier_call = cpufreq_cpu_callback,
1833};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835/*********************************************************************
1836 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1837 *********************************************************************/
1838
1839/**
1840 * cpufreq_register_driver - register a CPU Frequency driver
1841 * @driver_data: A struct cpufreq_driver containing the values#
1842 * submitted by the CPU Frequency driver.
1843 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001844 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001846 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 *
1848 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001849int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850{
1851 unsigned long flags;
1852 int ret;
1853
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001854 if (cpufreq_disabled())
1855 return -ENODEV;
1856
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 if (!driver_data || !driver_data->verify || !driver_data->init ||
1858 ((!driver_data->setpolicy) && (!driver_data->target)))
1859 return -EINVAL;
1860
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001861 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 if (driver_data->setpolicy)
1864 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1865
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001866 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 if (cpufreq_driver) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001868 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 return -EBUSY;
1870 }
1871 cpufreq_driver = driver_data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001872 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001874 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001875 if (ret)
1876 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001878 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 int i;
1880 ret = -ENODEV;
1881
1882 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001883 for (i = 0; i < nr_cpu_ids; i++)
1884 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001886 break;
1887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
1889 /* if all ->init() calls failed, unregister */
1890 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001891 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301892 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001893 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 }
1895 }
1896
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001897 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001898 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001900 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001901err_if_unreg:
1902 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001903err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001904 write_lock_irqsave(&cpufreq_driver_lock, flags);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001905 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001906 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001907 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908}
1909EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1910
1911
1912/**
1913 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1914 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001915 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 * the right to do so, i.e. if you have succeeded in initialising before!
1917 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1918 * currently not initialised.
1919 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001920int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921{
1922 unsigned long flags;
1923
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001924 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001927 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001929 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001930 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001932 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001934 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
1936 return 0;
1937}
1938EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001939
1940static int __init cpufreq_core_init(void)
1941{
1942 int cpu;
1943
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001944 if (cpufreq_disabled())
1945 return -ENODEV;
1946
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001947 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001948 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001949 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1950 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001951
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001952 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001953 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001954 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001955
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001956 return 0;
1957}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001958core_initcall(cpufreq_core_init);