blob: 374170d01d3628c7f165ae6e2835c25ad785e41a [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
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/notifier.h>
22#include <linux/cpufreq.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <linux/spinlock.h>
26#include <linux/device.h>
27#include <linux/slab.h>
28#include <linux/cpu.h>
29#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080030#include <linux/mutex.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010031#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
Thomas Renninger6f4f2722010-04-20 13:17:36 +020033#include <trace/events/power.h>
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/**
Dave Jonescd878472006-08-11 17:59:28 -040036 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 * level driver of CPUFreq support, and its spinlock. This lock
38 * also protects the cpufreq_cpu_data array.
39 */
Dave Jones7d5e3502006-02-02 17:03:42 -050040static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070041static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070042#ifdef CONFIG_HOTPLUG_CPU
43/* This one keeps track of the previously set governor of a removed CPU */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070044struct cpufreq_cpu_save_data {
45 char gov[CPUFREQ_NAME_LEN];
46 unsigned int max, min;
47};
48static DEFINE_PER_CPU(struct cpufreq_cpu_save_data, cpufreq_policy_save);
Thomas Renninger084f3492007-07-09 11:35:28 -070049#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070050static DEFINE_SPINLOCK(cpufreq_driver_lock);
51
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080052/*
53 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
54 * all cpufreq/hotplug/workqueue/etc related lock issues.
55 *
56 * The rules for this semaphore:
57 * - Any routine that wants to read from the policy structure will
58 * do a down_read on this semaphore.
59 * - Any routine that will write to the policy structure and/or may take away
60 * the policy altogether (eg. CPU hotplug), will hold this lock in write
61 * mode before doing so.
62 *
63 * Additional rules:
64 * - All holders of the lock should check to make sure that the CPU they
65 * are concerned with are online after they get the lock.
66 * - Governor routines that can be called in cpufreq hotplug path should not
67 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040068 * - Lock should not be held across
69 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080070 */
Tejun Heof1625062009-10-29 22:34:13 +090071static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
73
74#define lock_policy_rwsem(mode, cpu) \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075int lock_policy_rwsem_##mode \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076(int cpu) \
77{ \
Tejun Heof1625062009-10-29 22:34:13 +090078 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080079 BUG_ON(policy_cpu == -1); \
80 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
81 if (unlikely(!cpu_online(cpu))) { \
82 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
83 return -1; \
84 } \
85 \
86 return 0; \
87}
88
89lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
91lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080092
Amerigo Wang226528c2010-03-04 03:23:36 -050093static void unlock_policy_rwsem_read(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080094{
Tejun Heof1625062009-10-29 22:34:13 +090095 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080096 BUG_ON(policy_cpu == -1);
97 up_read(&per_cpu(cpu_policy_rwsem, policy_cpu));
98}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080099
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100void unlock_policy_rwsem_write(int cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800101{
Tejun Heof1625062009-10-29 22:34:13 +0900102 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800103 BUG_ON(policy_cpu == -1);
104 up_write(&per_cpu(cpu_policy_rwsem, policy_cpu));
105}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800106
107
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500109static int __cpufreq_governor(struct cpufreq_policy *policy,
110 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800111static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000112static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500115 * Two notifier lists: the "policy" list is involved in the
116 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 * "transition" list for kernel code that needs to handle
118 * changes to devices when the CPU clock speed changes.
119 * The mutex locks both lists.
120 */
Alan Sterne041c682006-03-27 01:16:30 -0800121static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700122static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200124static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700125static int __init init_cpufreq_transition_notifier_list(void)
126{
127 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200128 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700129 return 0;
130}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800131pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400133static int off __read_mostly;
134int cpufreq_disabled(void)
135{
136 return off;
137}
138void disable_cpufreq(void)
139{
140 off = 1;
141}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500143static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144
Stephen Boydf82ef512012-07-17 14:33:57 -0700145static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, int sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146{
147 struct cpufreq_policy *data;
148 unsigned long flags;
149
Mike Travis7a6aedf2008-03-25 15:06:53 -0700150 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 goto err_out;
152
153 /* get the cpufreq driver */
154 spin_lock_irqsave(&cpufreq_driver_lock, flags);
155
156 if (!cpufreq_driver)
157 goto err_out_unlock;
158
159 if (!try_module_get(cpufreq_driver->owner))
160 goto err_out_unlock;
161
162
163 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700164 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165
166 if (!data)
167 goto err_out_put_module;
168
Stephen Boydf82ef512012-07-17 14:33:57 -0700169 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 goto err_out_put_module;
171
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 return data;
174
Dave Jones7d5e3502006-02-02 17:03:42 -0500175err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500177err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500179err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 return NULL;
181}
Stephen Boydf82ef512012-07-17 14:33:57 -0700182
183struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
184{
185 return __cpufreq_cpu_get(cpu, 0);
186}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
188
Stephen Boydf82ef512012-07-17 14:33:57 -0700189static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
190{
191 return __cpufreq_cpu_get(cpu, 1);
192}
193
194static void __cpufreq_cpu_put(struct cpufreq_policy *data, int sysfs)
195{
196 if (!sysfs)
197 kobject_put(&data->kobj);
198 module_put(cpufreq_driver->owner);
199}
Dave Jones7d5e3502006-02-02 17:03:42 -0500200
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201void cpufreq_cpu_put(struct cpufreq_policy *data)
202{
Stephen Boydf82ef512012-07-17 14:33:57 -0700203 __cpufreq_cpu_put(data, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204}
205EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
206
Stephen Boydf82ef512012-07-17 14:33:57 -0700207static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
208{
209 __cpufreq_cpu_put(data, 1);
210}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
212/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
214 *********************************************************************/
215
216/**
217 * adjust_jiffies - adjust the system "loops_per_jiffy"
218 *
219 * This function alters the system "loops_per_jiffy" for the clock
220 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500221 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 * per-CPU loops_per_jiffy value wherever possible.
223 */
224#ifndef CONFIG_SMP
225static unsigned long l_p_j_ref;
226static unsigned int l_p_j_ref_freq;
227
Arjan van de Ven858119e2006-01-14 13:20:43 -0800228static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229{
230 if (ci->flags & CPUFREQ_CONST_LOOPS)
231 return;
232
233 if (!l_p_j_ref_freq) {
234 l_p_j_ref = loops_per_jiffy;
235 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200236 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530237 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530239 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700240 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530241 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
242 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200243 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530244 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 }
246}
247#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530248static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
249{
250 return;
251}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252#endif
253
254
255/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800256 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
257 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800259 * This function calls the transition notifiers and the "adjust_jiffies"
260 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500261 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 */
263void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
264{
Dave Jonese4472cb2006-01-31 15:53:55 -0800265 struct cpufreq_policy *policy;
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 BUG_ON(irqs_disabled());
268
269 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200270 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800271 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272
Mike Travis7a6aedf2008-03-25 15:06:53 -0700273 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500277 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800278 * which is not equal to what the cpufreq core thinks is
279 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 */
281 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800282 if ((policy) && (policy->cpu == freqs->cpu) &&
283 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200284 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800285 " %u, cpufreq assumed %u kHz.\n",
286 freqs->old, policy->cur);
287 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 }
289 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700290 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800291 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
293 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800294
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 case CPUFREQ_POSTCHANGE:
296 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200297 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200298 (unsigned long)freqs->cpu);
299 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100300 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700301 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800302 CPUFREQ_POSTCHANGE, freqs);
Amar Singhal99055d52012-02-23 13:54:46 -0800303 if (likely(policy) && likely(policy->cpu == freqs->cpu)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800304 policy->cur = freqs->new;
Amar Singhal99055d52012-02-23 13:54:46 -0800305 sysfs_notify(&policy->kobj, NULL, "scaling_cur_freq");
306 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 break;
308 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309}
310EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800311/**
312 * cpufreq_notify_utilization - notify CPU userspace about CPU utilization
313 * change
314 *
315 * This function is called everytime the CPU load is evaluated by the
316 * ondemand governor. It notifies userspace of cpu load changes via sysfs.
317 */
318void cpufreq_notify_utilization(struct cpufreq_policy *policy,
319 unsigned int util)
320{
321 if (policy)
322 policy->util = util;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800324 if (policy->util >= MIN_CPU_UTIL_NOTIFY)
325 sysfs_notify(&policy->kobj, NULL, "cpu_utilization");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800327}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328
329/*********************************************************************
330 * SYSFS INTERFACE *
331 *********************************************************************/
332
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700333static struct cpufreq_governor *__find_governor(const char *str_governor)
334{
335 struct cpufreq_governor *t;
336
337 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500338 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700339 return t;
340
341 return NULL;
342}
343
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344/**
345 * cpufreq_parse_governor - parse a governor string
346 */
Dave Jones905d77c2008-03-05 14:28:32 -0500347static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 struct cpufreq_governor **governor)
349{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700350 int err = -EINVAL;
351
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700353 goto out;
354
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 if (cpufreq_driver->setpolicy) {
356 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
357 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700358 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530359 } else if (!strnicmp(str_governor, "powersave",
360 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700362 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700364 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700366
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800367 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700368
369 t = __find_governor(str_governor);
370
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700371 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700372 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700373
Kees Cook1a8e1462011-05-04 08:38:56 -0700374 mutex_unlock(&cpufreq_governor_mutex);
375 ret = request_module("cpufreq_%s", str_governor);
376 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700377
Kees Cook1a8e1462011-05-04 08:38:56 -0700378 if (ret == 0)
379 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700380 }
381
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700382 if (t != NULL) {
383 *governor = t;
384 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700386
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800387 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 }
Dave Jones29464f22009-01-18 01:37:11 -0500389out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700390 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
393
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530395 * cpufreq_per_cpu_attr_read() / show_##file_name() -
396 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 *
398 * Write out information from cpufreq_driver->policy[cpu]; object must be
399 * "unsigned int".
400 */
401
Dave Jones32ee8c32006-02-28 00:43:23 -0500402#define show_one(file_name, object) \
403static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500404(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500405{ \
Dave Jones29464f22009-01-18 01:37:11 -0500406 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407}
408
409show_one(cpuinfo_min_freq, cpuinfo.min_freq);
410show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100411show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412show_one(scaling_min_freq, min);
413show_one(scaling_max_freq, max);
414show_one(scaling_cur_freq, cur);
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800415show_one(cpu_utilization, util);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530417static int __cpufreq_set_policy(struct cpufreq_policy *data,
418 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200419
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420/**
421 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
422 */
423#define store_one(file_name, object) \
424static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500425(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426{ \
427 unsigned int ret = -EINVAL; \
428 struct cpufreq_policy new_policy; \
429 \
430 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
431 if (ret) \
432 return -EINVAL; \
433 \
Dave Jones29464f22009-01-18 01:37:11 -0500434 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 if (ret != 1) \
436 return -EINVAL; \
437 \
Deepak Katragadda50eb26a2013-07-09 10:13:03 -0700438 ret = cpufreq_driver->verify(&new_policy); \
439 if (ret) \
440 pr_err("cpufreq: Frequency verification failed\n"); \
441 \
442 policy->user_policy.object = new_policy.object; \
Thomas Renninger7970e082006-04-13 15:14:04 +0200443 ret = __cpufreq_set_policy(policy, &new_policy); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 \
445 return ret ? ret : count; \
446}
447
Dave Jones29464f22009-01-18 01:37:11 -0500448store_one(scaling_min_freq, min);
449store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450
451/**
452 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
453 */
Dave Jones905d77c2008-03-05 14:28:32 -0500454static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
455 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800457 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 if (!cur_freq)
459 return sprintf(buf, "<unknown>");
460 return sprintf(buf, "%u\n", cur_freq);
461}
462
463
464/**
465 * show_scaling_governor - show the current policy for the specified CPU
466 */
Dave Jones905d77c2008-03-05 14:28:32 -0500467static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468{
Dave Jones29464f22009-01-18 01:37:11 -0500469 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 return sprintf(buf, "powersave\n");
471 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
472 return sprintf(buf, "performance\n");
473 else if (policy->governor)
Dave Jones29464f22009-01-18 01:37:11 -0500474 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
475 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 return -EINVAL;
477}
478
479
480/**
481 * store_scaling_governor - store policy for the specified CPU
482 */
Dave Jones905d77c2008-03-05 14:28:32 -0500483static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
484 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485{
486 unsigned int ret = -EINVAL;
487 char str_governor[16];
488 struct cpufreq_policy new_policy;
489
490 ret = cpufreq_get_policy(&new_policy, policy->cpu);
491 if (ret)
492 return ret;
493
Dave Jones29464f22009-01-18 01:37:11 -0500494 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 if (ret != 1)
496 return -EINVAL;
497
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530498 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
499 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 return -EINVAL;
501
Thomas Renninger7970e082006-04-13 15:14:04 +0200502 /* Do not use cpufreq_set_policy here or the user_policy.max
503 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200504 ret = __cpufreq_set_policy(policy, &new_policy);
505
506 policy->user_policy.policy = policy->policy;
507 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200508
Amar Singhal37d0b022012-05-25 14:40:05 -0700509 sysfs_notify(&policy->kobj, NULL, "scaling_governor");
510
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530511 if (ret)
512 return ret;
513 else
514 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515}
516
517/**
518 * show_scaling_driver - show the cpufreq driver currently loaded
519 */
Dave Jones905d77c2008-03-05 14:28:32 -0500520static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521{
522 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
523}
524
525/**
526 * show_scaling_available_governors - show the available CPUfreq governors
527 */
Dave Jones905d77c2008-03-05 14:28:32 -0500528static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
529 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530{
531 ssize_t i = 0;
532 struct cpufreq_governor *t;
533
534 if (!cpufreq_driver->target) {
535 i += sprintf(buf, "performance powersave");
536 goto out;
537 }
538
539 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500540 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
541 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 goto out;
543 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
544 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500545out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 i += sprintf(&buf[i], "\n");
547 return i;
548}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700549
Rusty Russell835481d2009-01-04 05:18:06 -0800550static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551{
552 ssize_t i = 0;
553 unsigned int cpu;
554
Rusty Russell835481d2009-01-04 05:18:06 -0800555 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 if (i)
557 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
558 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
559 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500560 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 }
562 i += sprintf(&buf[i], "\n");
563 return i;
564}
565
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700566/**
567 * show_related_cpus - show the CPUs affected by each transition even if
568 * hw coordination is in use
569 */
570static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
571{
Rusty Russell835481d2009-01-04 05:18:06 -0800572 if (cpumask_empty(policy->related_cpus))
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700573 return show_cpus(policy->cpus, buf);
574 return show_cpus(policy->related_cpus, buf);
575}
576
577/**
578 * show_affected_cpus - show the CPUs affected by each transition
579 */
580static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
581{
582 return show_cpus(policy->cpus, buf);
583}
584
Venki Pallipadi9e769882007-10-26 10:18:21 -0700585static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500586 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700587{
588 unsigned int freq = 0;
589 unsigned int ret;
590
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700591 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700592 return -EINVAL;
593
594 ret = sscanf(buf, "%u", &freq);
595 if (ret != 1)
596 return -EINVAL;
597
598 policy->governor->store_setspeed(policy, freq);
599
600 return count;
601}
602
603static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
604{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700605 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700606 return sprintf(buf, "<unsupported>\n");
607
608 return policy->governor->show_setspeed(policy, buf);
609}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Thomas Renningere2f74f32009-11-19 12:31:01 +0100611/**
612 * show_scaling_driver - show the current cpufreq HW/BIOS limitation
613 */
614static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
615{
616 unsigned int limit;
617 int ret;
618 if (cpufreq_driver->bios_limit) {
619 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
620 if (!ret)
621 return sprintf(buf, "%u\n", limit);
622 }
623 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
624}
625
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200626cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
627cpufreq_freq_attr_ro(cpuinfo_min_freq);
628cpufreq_freq_attr_ro(cpuinfo_max_freq);
629cpufreq_freq_attr_ro(cpuinfo_transition_latency);
630cpufreq_freq_attr_ro(scaling_available_governors);
631cpufreq_freq_attr_ro(scaling_driver);
632cpufreq_freq_attr_ro(scaling_cur_freq);
633cpufreq_freq_attr_ro(bios_limit);
634cpufreq_freq_attr_ro(related_cpus);
635cpufreq_freq_attr_ro(affected_cpus);
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800636cpufreq_freq_attr_ro(cpu_utilization);
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200637cpufreq_freq_attr_rw(scaling_min_freq);
638cpufreq_freq_attr_rw(scaling_max_freq);
639cpufreq_freq_attr_rw(scaling_governor);
640cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
Dave Jones905d77c2008-03-05 14:28:32 -0500642static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 &cpuinfo_min_freq.attr,
644 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100645 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 &scaling_min_freq.attr,
647 &scaling_max_freq.attr,
648 &affected_cpus.attr,
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800649 &cpu_utilization.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700650 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 &scaling_governor.attr,
652 &scaling_driver.attr,
653 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700654 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 NULL
656};
657
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200658struct kobject *cpufreq_global_kobject;
659EXPORT_SYMBOL(cpufreq_global_kobject);
660
Dave Jones29464f22009-01-18 01:37:11 -0500661#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
662#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663
Dave Jones29464f22009-01-18 01:37:11 -0500664static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665{
Dave Jones905d77c2008-03-05 14:28:32 -0500666 struct cpufreq_policy *policy = to_policy(kobj);
667 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500668 ssize_t ret = -EINVAL;
Stephen Boydf82ef512012-07-17 14:33:57 -0700669 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500671 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800672
673 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500674 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800675
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530676 if (fattr->show)
677 ret = fattr->show(policy, buf);
678 else
679 ret = -EIO;
680
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800681 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500682fail:
Stephen Boydf82ef512012-07-17 14:33:57 -0700683 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500684no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 return ret;
686}
687
Dave Jones905d77c2008-03-05 14:28:32 -0500688static ssize_t store(struct kobject *kobj, struct attribute *attr,
689 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690{
Dave Jones905d77c2008-03-05 14:28:32 -0500691 struct cpufreq_policy *policy = to_policy(kobj);
692 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500693 ssize_t ret = -EINVAL;
Stephen Boydf82ef512012-07-17 14:33:57 -0700694 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500696 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800697
698 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500699 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800700
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530701 if (fattr->store)
702 ret = fattr->store(policy, buf, count);
703 else
704 ret = -EIO;
705
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800706 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500707fail:
Stephen Boydf82ef512012-07-17 14:33:57 -0700708 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500709no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 return ret;
711}
712
Dave Jones905d77c2008-03-05 14:28:32 -0500713static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714{
Dave Jones905d77c2008-03-05 14:28:32 -0500715 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200716 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 complete(&policy->kobj_unregister);
718}
719
Emese Revfy52cf25d2010-01-19 02:58:23 +0100720static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 .show = show,
722 .store = store,
723};
724
725static struct kobj_type ktype_cpufreq = {
726 .sysfs_ops = &sysfs_ops,
727 .default_attrs = default_attrs,
728 .release = cpufreq_sysfs_release,
729};
730
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200731/*
732 * Returns:
733 * Negative: Failure
734 * 0: Success
735 * Positive: When we have a managed CPU and the sysfs got symlinked
736 */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700737static int cpufreq_add_dev_policy(unsigned int cpu,
738 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800739 struct device *dev)
Dave Jonesecf7e462009-07-08 18:48:47 -0400740{
741 int ret = 0;
742#ifdef CONFIG_SMP
743 unsigned long flags;
744 unsigned int j;
Dave Jonesecf7e462009-07-08 18:48:47 -0400745#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400746 struct cpufreq_governor *gov;
747
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700748 gov = __find_governor(per_cpu(cpufreq_policy_save, cpu).gov);
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400749 if (gov) {
750 policy->governor = gov;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200751 pr_debug("Restoring governor %s for cpu %d\n",
Dave Jonesecf7e462009-07-08 18:48:47 -0400752 policy->governor->name, cpu);
753 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700754 if (per_cpu(cpufreq_policy_save, cpu).min) {
755 policy->min = per_cpu(cpufreq_policy_save, cpu).min;
756 policy->user_policy.min = policy->min;
757 }
758 if (per_cpu(cpufreq_policy_save, cpu).max) {
759 policy->max = per_cpu(cpufreq_policy_save, cpu).max;
760 policy->user_policy.max = policy->max;
761 }
762 pr_debug("Restoring CPU%d min %d and max %d\n",
763 cpu, policy->min, policy->max);
Dave Jonesecf7e462009-07-08 18:48:47 -0400764#endif
765
766 for_each_cpu(j, policy->cpus) {
767 struct cpufreq_policy *managed_policy;
768
769 if (cpu == j)
770 continue;
771
772 /* Check for existing affected CPUs.
773 * They may not be aware of it due to CPU Hotplug.
774 * cpufreq_cpu_put is called when the device is removed
775 * in __cpufreq_remove_dev()
776 */
777 managed_policy = cpufreq_cpu_get(j);
778 if (unlikely(managed_policy)) {
779
780 /* Set proper policy_cpu */
781 unlock_policy_rwsem_write(cpu);
Tejun Heof1625062009-10-29 22:34:13 +0900782 per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
Dave Jonesecf7e462009-07-08 18:48:47 -0400783
784 if (lock_policy_rwsem_write(cpu) < 0) {
785 /* Should not go through policy unlock path */
786 if (cpufreq_driver->exit)
787 cpufreq_driver->exit(policy);
788 cpufreq_cpu_put(managed_policy);
789 return -EBUSY;
790 }
791
792 spin_lock_irqsave(&cpufreq_driver_lock, flags);
793 cpumask_copy(managed_policy->cpus, policy->cpus);
Srivatsa Vaddagiride09f072013-03-01 16:16:27 -0800794 cpumask_and(managed_policy->cpus,
795 managed_policy->cpus, cpu_online_mask);
Dave Jonesecf7e462009-07-08 18:48:47 -0400796 per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
797 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
798
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200799 pr_debug("CPU already managed, adding link\n");
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800800 ret = sysfs_create_link(&dev->kobj,
Dave Jonesecf7e462009-07-08 18:48:47 -0400801 &managed_policy->kobj,
802 "cpufreq");
803 if (ret)
804 cpufreq_cpu_put(managed_policy);
805 /*
806 * Success. We only needed to be added to the mask.
807 * Call driver->exit() because only the cpu parent of
808 * the kobj needed to call init().
809 */
810 if (cpufreq_driver->exit)
811 cpufreq_driver->exit(policy);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200812
813 if (!ret)
814 return 1;
815 else
816 return ret;
Dave Jonesecf7e462009-07-08 18:48:47 -0400817 }
818 }
819#endif
820 return ret;
821}
822
823
Dave Jones19d6f7e2009-07-08 17:35:39 -0400824/* symlink affected CPUs */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700825static int cpufreq_add_dev_symlink(unsigned int cpu,
826 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400827{
828 unsigned int j;
829 int ret = 0;
830
831 for_each_cpu(j, policy->cpus) {
832 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800833 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400834
835 if (j == cpu)
836 continue;
837 if (!cpu_online(j))
838 continue;
839
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200840 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400841 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800842 cpu_dev = get_cpu_device(j);
843 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400844 "cpufreq");
845 if (ret) {
846 cpufreq_cpu_put(managed_policy);
847 return ret;
848 }
849 }
850 return ret;
851}
852
Alex Chiangcf3289d2009-11-17 20:27:08 -0700853static int cpufreq_add_dev_interface(unsigned int cpu,
854 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800855 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400856{
Dave Jonesecf7e462009-07-08 18:48:47 -0400857 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400858 struct freq_attr **drv_attr;
859 unsigned long flags;
860 int ret = 0;
861 unsigned int j;
862
863 /* prepare interface data */
864 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800865 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400866 if (ret)
867 return ret;
868
869 /* set up files for this cpu device */
870 drv_attr = cpufreq_driver->attr;
871 while ((drv_attr) && (*drv_attr)) {
872 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
873 if (ret)
874 goto err_out_kobj_put;
875 drv_attr++;
876 }
877 if (cpufreq_driver->get) {
878 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
879 if (ret)
880 goto err_out_kobj_put;
881 }
882 if (cpufreq_driver->target) {
883 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
884 if (ret)
885 goto err_out_kobj_put;
886 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100887 if (cpufreq_driver->bios_limit) {
888 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
889 if (ret)
890 goto err_out_kobj_put;
891 }
Dave Jones909a6942009-07-08 18:05:42 -0400892
893 spin_lock_irqsave(&cpufreq_driver_lock, flags);
894 for_each_cpu(j, policy->cpus) {
Julia Lawallbec037a2010-08-05 22:23:00 +0200895 if (!cpu_online(j))
896 continue;
Dave Jones909a6942009-07-08 18:05:42 -0400897 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900898 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400899 }
900 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
901
902 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400903 if (ret)
904 goto err_out_kobj_put;
905
906 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
907 /* assure that the starting sequence is run in __cpufreq_set_policy */
908 policy->governor = NULL;
909
910 /* set default policy */
911 ret = __cpufreq_set_policy(policy, &new_policy);
912 policy->user_policy.policy = policy->policy;
913 policy->user_policy.governor = policy->governor;
914
915 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200916 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400917 if (cpufreq_driver->exit)
918 cpufreq_driver->exit(policy);
919 }
Dave Jones909a6942009-07-08 18:05:42 -0400920 return ret;
921
922err_out_kobj_put:
923 kobject_put(&policy->kobj);
924 wait_for_completion(&policy->kobj_unregister);
925 return ret;
926}
927
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
929/**
930 * cpufreq_add_dev - add a CPU device
931 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500932 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400933 *
934 * The Oracle says: try running cpufreq registration/unregistration concurrently
935 * with with cpu hotplugging and all hell will break loose. Tried to clean this
936 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800938static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939{
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800940 unsigned int cpu = dev->id;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500941 int ret = 0, found = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 unsigned long flags;
944 unsigned int j;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500945#ifdef CONFIG_HOTPLUG_CPU
946 int sibling;
947#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
Ashok Rajc32b6b82005-10-30 14:59:54 -0800949 if (cpu_is_offline(cpu))
950 return 0;
951
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200952 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953
954#ifdef CONFIG_SMP
955 /* check whether a different CPU already registered this
956 * CPU because it is in the same boat. */
957 policy = cpufreq_cpu_get(cpu);
958 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500959 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 return 0;
961 }
962#endif
963
964 if (!try_module_get(cpufreq_driver->owner)) {
965 ret = -EINVAL;
966 goto module_out;
967 }
968
Dave Jones059019a2009-07-08 16:30:03 -0400969 ret = -ENOMEM;
Dave Jonese98df502005-10-20 15:17:43 -0700970 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400971 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400973
974 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400975 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400976
977 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400978 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979
980 policy->cpu = cpu;
Rusty Russell835481d2009-01-04 05:18:06 -0800981 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800983 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900984 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400985 ret = (lock_policy_rwsem_write(cpu) < 0);
986 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800987
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000989 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700991 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500992#ifdef CONFIG_HOTPLUG_CPU
993 for_each_online_cpu(sibling) {
994 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
995 if (cp && cp->governor &&
996 (cpumask_test_cpu(cpu, cp->related_cpus))) {
997 policy->governor = cp->governor;
998 found = 1;
999 break;
1000 }
1001 }
1002#endif
1003 if (!found)
1004 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 /* call driver. From then on the cpufreq must be able
1006 * to accept all calls to ->verify and ->setpolicy for this CPU
1007 */
1008 ret = cpufreq_driver->init(policy);
1009 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001010 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001011 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 }
Mike Chan187d9f42008-12-04 12:19:17 -08001013 policy->user_policy.min = policy->min;
1014 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
Thomas Renningera1531ac2008-07-29 22:32:58 -07001016 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1017 CPUFREQ_START, policy);
1018
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001019 ret = cpufreq_add_dev_policy(cpu, policy, dev);
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001020 if (ret) {
1021 if (ret > 0)
1022 /* This is a managed cpu, symlink created,
1023 exit with 0 */
1024 ret = 0;
Dave Jonesecf7e462009-07-08 18:48:47 -04001025 goto err_unlock_policy;
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001026 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001028 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -04001029 if (ret)
1030 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -05001031
Lothar Waßmanndca02612008-05-29 17:54:52 +02001032 unlock_policy_rwsem_write(cpu);
1033
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001034 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001036 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001037
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 return 0;
1039
1040
1041err_out_unregister:
1042 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001043 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001044 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1046
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001047 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 wait_for_completion(&policy->kobj_unregister);
1049
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001050err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -05001051 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001052 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001053err_free_cpumask:
1054 free_cpumask_var(policy->cpus);
1055err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057nomem_out:
1058 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001059module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 return ret;
1061}
1062
1063
1064/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001065 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 *
1067 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001068 * Caller should already have policy_rwsem in write mode for this CPU.
1069 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001071static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001073 unsigned int cpu = dev->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 unsigned long flags;
1075 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001076 struct kobject *kobj;
1077 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078#ifdef CONFIG_SMP
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001079 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 unsigned int j;
1081#endif
1082
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001083 pr_debug("unregistering CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
1085 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001086 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
1088 if (!data) {
1089 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001090 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 return -EINVAL;
1092 }
Mike Travis7a6aedf2008-03-25 15:06:53 -07001093 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
1095
1096#ifdef CONFIG_SMP
1097 /* if this isn't the CPU which is the parent of the kobj, we
Dave Jones32ee8c32006-02-28 00:43:23 -05001098 * only need to unlink, put and exit
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099 */
1100 if (unlikely(cpu != data->cpu)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001101 pr_debug("removing link\n");
Rusty Russell835481d2009-01-04 05:18:06 -08001102 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001104 kobj = &dev->kobj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 cpufreq_cpu_put(data);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001106 unlock_policy_rwsem_write(cpu);
Amerigo Wang499bca92010-03-04 03:23:46 -05001107 sysfs_remove_link(kobj, "cpufreq");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 return 0;
1109 }
1110#endif
1111
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112#ifdef CONFIG_SMP
Thomas Renninger084f3492007-07-09 11:35:28 -07001113
1114#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001115 strncpy(per_cpu(cpufreq_policy_save, cpu).gov, data->governor->name,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001116 CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001117 per_cpu(cpufreq_policy_save, cpu).min = data->min;
1118 per_cpu(cpufreq_policy_save, cpu).max = data->max;
1119 pr_debug("Saving CPU%d policy min %d and max %d\n",
1120 cpu, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001121#endif
1122
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 /* if we have other CPUs still registered, we need to unlink them,
1124 * or else wait_for_completion below will lock up. Clean the
Mike Travis7a6aedf2008-03-25 15:06:53 -07001125 * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
1126 * the sysfs links afterwards.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 */
Rusty Russell835481d2009-01-04 05:18:06 -08001128 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1129 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 if (j == cpu)
1131 continue;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001132 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 }
1134 }
1135
1136 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1137
Rusty Russell835481d2009-01-04 05:18:06 -08001138 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1139 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 if (j == cpu)
1141 continue;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001142 pr_debug("removing link for cpu %u\n", j);
Thomas Renninger084f3492007-07-09 11:35:28 -07001143#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001144 strncpy(per_cpu(cpufreq_policy_save, j).gov,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001145 data->governor->name, CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001146 per_cpu(cpufreq_policy_save, j).min = data->min;
1147 per_cpu(cpufreq_policy_save, j).max = data->max;
1148 pr_debug("Saving CPU%d policy min %d and max %d\n",
1149 j, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001150#endif
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001151 cpu_dev = get_cpu_device(j);
1152 kobj = &cpu_dev->kobj;
Amerigo Wang499bca92010-03-04 03:23:46 -05001153 unlock_policy_rwsem_write(cpu);
1154 sysfs_remove_link(kobj, "cpufreq");
1155 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 cpufreq_cpu_put(data);
1157 }
1158 }
1159#else
1160 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1161#endif
1162
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 if (cpufreq_driver->target)
1164 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001165
Amerigo Wang499bca92010-03-04 03:23:46 -05001166 kobj = &data->kobj;
1167 cmp = &data->kobj_unregister;
1168 unlock_policy_rwsem_write(cpu);
1169 kobject_put(kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170
1171 /* we need to make sure that the underlying kobj is actually
Dave Jones32ee8c32006-02-28 00:43:23 -05001172 * not referenced anymore by anybody before we proceed with
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 * unloading.
1174 */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001175 pr_debug("waiting for dropping of refcount\n");
Amerigo Wang499bca92010-03-04 03:23:46 -05001176 wait_for_completion(cmp);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001177 pr_debug("wait complete\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178
Amerigo Wang499bca92010-03-04 03:23:46 -05001179 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 if (cpufreq_driver->exit)
1181 cpufreq_driver->exit(data);
venkatesh.pallipadi@intel.com7d26e2d2009-07-02 17:08:30 -07001182 unlock_policy_rwsem_write(cpu);
1183
Jacob Shin27ecddc2011-04-27 13:32:11 -05001184#ifdef CONFIG_HOTPLUG_CPU
1185 /* when the CPU which is the parent of the kobj is hotplugged
1186 * offline, check for siblings, and create cpufreq sysfs interface
1187 * and symlinks
1188 */
1189 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1190 /* first sibling now owns the new sysfs dir */
1191 cpumask_clear_cpu(cpu, data->cpus);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001192 cpufreq_add_dev(get_cpu_device(cpumask_first(data->cpus)), NULL);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001193
1194 /* finally remove our own symlink */
1195 lock_policy_rwsem_write(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001196 __cpufreq_remove_dev(dev, sif);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001197 }
1198#endif
1199
Rusty Russell835481d2009-01-04 05:18:06 -08001200 free_cpumask_var(data->related_cpus);
1201 free_cpumask_var(data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 kfree(data);
1203
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 return 0;
1205}
1206
1207
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001208static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001209{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001210 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001211 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001212
1213 if (cpu_is_offline(cpu))
1214 return 0;
1215
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001216 if (unlikely(lock_policy_rwsem_write(cpu)))
1217 BUG();
1218
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001219 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001220 return retval;
1221}
1222
1223
David Howells65f27f32006-11-22 14:55:48 +00001224static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225{
David Howells65f27f32006-11-22 14:55:48 +00001226 struct cpufreq_policy *policy =
1227 container_of(work, struct cpufreq_policy, update);
1228 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001229 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 cpufreq_update_policy(cpu);
1231}
1232
1233/**
1234 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1235 * @cpu: cpu number
1236 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1237 * @new_freq: CPU frequency the CPU actually runs at
1238 *
Dave Jones29464f22009-01-18 01:37:11 -05001239 * We adjust to current frequency first, and need to clean up later.
1240 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301242static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1243 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244{
1245 struct cpufreq_freqs freqs;
1246
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001247 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1249
1250 freqs.cpu = cpu;
1251 freqs.old = old_freq;
1252 freqs.new = new_freq;
1253 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1254 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1255}
1256
1257
Dave Jones32ee8c32006-02-28 00:43:23 -05001258/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301259 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001260 * @cpu: CPU number
1261 *
1262 * This is the last known freq, without actually getting it from the driver.
1263 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1264 */
1265unsigned int cpufreq_quick_get(unsigned int cpu)
1266{
1267 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301268 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001269
1270 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301271 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001272 cpufreq_cpu_put(policy);
1273 }
1274
Dave Jones4d34a672008-02-07 16:33:49 -05001275 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001276}
1277EXPORT_SYMBOL(cpufreq_quick_get);
1278
Jesse Barnes3d737102011-06-28 10:59:12 -07001279/**
1280 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1281 * @cpu: CPU number
1282 *
1283 * Just return the max possible frequency for a given CPU.
1284 */
1285unsigned int cpufreq_quick_get_max(unsigned int cpu)
1286{
1287 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1288 unsigned int ret_freq = 0;
1289
1290 if (policy) {
1291 ret_freq = policy->max;
1292 cpufreq_cpu_put(policy);
1293 }
1294
1295 return ret_freq;
1296}
1297EXPORT_SYMBOL(cpufreq_quick_get_max);
1298
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001299
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001300static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001302 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301303 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001306 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301308 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301310 if (ret_freq && policy->cur &&
1311 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1312 /* verify no discrepancy between actual and
1313 saved value exists */
1314 if (unlikely(ret_freq != policy->cur)) {
1315 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 schedule_work(&policy->update);
1317 }
1318 }
1319
Dave Jones4d34a672008-02-07 16:33:49 -05001320 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001321}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001323/**
1324 * cpufreq_get - get the current CPU frequency (in kHz)
1325 * @cpu: CPU number
1326 *
1327 * Get the CPU current (static) CPU frequency
1328 */
1329unsigned int cpufreq_get(unsigned int cpu)
1330{
1331 unsigned int ret_freq = 0;
1332 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1333
1334 if (!policy)
1335 goto out;
1336
1337 if (unlikely(lock_policy_rwsem_read(cpu)))
1338 goto out_policy;
1339
1340 ret_freq = __cpufreq_get(cpu);
1341
1342 unlock_policy_rwsem_read(cpu);
1343
1344out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001346out:
Dave Jones4d34a672008-02-07 16:33:49 -05001347 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348}
1349EXPORT_SYMBOL(cpufreq_get);
1350
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001351static struct subsys_interface cpufreq_interface = {
1352 .name = "cpufreq",
1353 .subsys = &cpu_subsys,
1354 .add_dev = cpufreq_add_dev,
1355 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001356};
1357
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358
1359/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001360 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1361 *
1362 * This function is only executed for the boot processor. The other CPUs
1363 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001364 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001365static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001366{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301367 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001368
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001369 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001370 struct cpufreq_policy *cpu_policy;
1371
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001372 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001373
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001374 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001375 cpu_policy = cpufreq_cpu_get(cpu);
1376 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001377 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001378
1379 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001380 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001381 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001382 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1383 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001384 }
1385
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001386 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001387 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001388}
1389
1390/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001391 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 *
1393 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001394 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1395 * restored. It will verify that the current freq is in sync with
1396 * what we believe it to be. This is a bit later than when it
1397 * should be, but nonethteless it's better than calling
1398 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001399 *
1400 * This function is only executed for the boot CPU. The other CPUs have not
1401 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001403static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301405 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001406
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001407 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 struct cpufreq_policy *cpu_policy;
1409
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001410 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001412 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 cpu_policy = cpufreq_cpu_get(cpu);
1414 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001415 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 if (cpufreq_driver->resume) {
1418 ret = cpufreq_driver->resume(cpu_policy);
1419 if (ret) {
1420 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1421 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001422 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 }
1424 }
1425
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001427
Dave Jonesc9060492008-02-07 16:32:18 -05001428fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430}
1431
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001432static struct syscore_ops cpufreq_syscore_ops = {
1433 .suspend = cpufreq_bp_suspend,
1434 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435};
1436
1437
1438/*********************************************************************
1439 * NOTIFIER LISTS INTERFACE *
1440 *********************************************************************/
1441
1442/**
1443 * cpufreq_register_notifier - register a driver with cpufreq
1444 * @nb: notifier function to register
1445 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1446 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001447 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 * are notified about clock rate changes (once before and once after
1449 * the transition), or a list of drivers that are notified about
1450 * changes in cpufreq policy.
1451 *
1452 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001453 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 */
1455int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1456{
1457 int ret;
1458
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001459 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1460
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 switch (list) {
1462 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001463 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001464 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 break;
1466 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001467 ret = blocking_notifier_chain_register(
1468 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 break;
1470 default:
1471 ret = -EINVAL;
1472 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
1474 return ret;
1475}
1476EXPORT_SYMBOL(cpufreq_register_notifier);
1477
1478
1479/**
1480 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1481 * @nb: notifier block to be unregistered
1482 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1483 *
1484 * Remove a driver from the CPU frequency notifier list.
1485 *
1486 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001487 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 */
1489int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1490{
1491 int ret;
1492
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 switch (list) {
1494 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001495 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001496 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 break;
1498 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001499 ret = blocking_notifier_chain_unregister(
1500 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 break;
1502 default:
1503 ret = -EINVAL;
1504 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505
1506 return ret;
1507}
1508EXPORT_SYMBOL(cpufreq_unregister_notifier);
1509
1510
1511/*********************************************************************
1512 * GOVERNORS *
1513 *********************************************************************/
1514
1515
1516int __cpufreq_driver_target(struct cpufreq_policy *policy,
1517 unsigned int target_freq,
1518 unsigned int relation)
1519{
1520 int retval = -EINVAL;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001521
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001522 if (cpufreq_disabled())
1523 return -ENODEV;
1524
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001525 pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 target_freq, relation);
1527 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1528 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001529
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 return retval;
1531}
1532EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1533
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534int cpufreq_driver_target(struct cpufreq_policy *policy,
1535 unsigned int target_freq,
1536 unsigned int relation)
1537{
Julia Lawallf1829e42008-07-25 22:44:53 +02001538 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
1540 policy = cpufreq_cpu_get(policy->cpu);
1541 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001542 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001544 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001545 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547 ret = __cpufreq_driver_target(policy, target_freq, relation);
1548
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001549 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550
Julia Lawallf1829e42008-07-25 22:44:53 +02001551fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001553no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 return ret;
1555}
1556EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1557
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001558int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001559{
1560 int ret = 0;
1561
1562 policy = cpufreq_cpu_get(policy->cpu);
1563 if (!policy)
1564 return -EINVAL;
1565
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001566 if (cpu_online(cpu) && cpufreq_driver->getavg)
1567 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001568
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001569 cpufreq_cpu_put(policy);
1570 return ret;
1571}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001572EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001573
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001574/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001575 * when "event" is CPUFREQ_GOV_LIMITS
1576 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301578static int __cpufreq_governor(struct cpufreq_policy *policy,
1579 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580{
Dave Jonescc993ca2005-07-28 09:43:56 -07001581 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001582
1583 /* Only must be defined when default governor is known to have latency
1584 restrictions, like e.g. conservative or ondemand.
1585 That this is the case is already ensured in Kconfig
1586 */
1587#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1588 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1589#else
1590 struct cpufreq_governor *gov = NULL;
1591#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001592
1593 if (policy->governor->max_transition_latency &&
1594 policy->cpuinfo.transition_latency >
1595 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001596 if (!gov)
1597 return -EINVAL;
1598 else {
1599 printk(KERN_WARNING "%s governor failed, too long"
1600 " transition latency of HW, fallback"
1601 " to %s governor\n",
1602 policy->governor->name,
1603 gov->name);
1604 policy->governor = gov;
1605 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001606 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607
1608 if (!try_module_get(policy->governor->owner))
1609 return -EINVAL;
1610
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001611 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301612 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 ret = policy->governor->governor(policy, event);
1614
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301615 /* we keep one module reference alive for
1616 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 if ((event != CPUFREQ_GOV_START) || ret)
1618 module_put(policy->governor->owner);
1619 if ((event == CPUFREQ_GOV_STOP) && !ret)
1620 module_put(policy->governor->owner);
1621
1622 return ret;
1623}
1624
1625
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626int cpufreq_register_governor(struct cpufreq_governor *governor)
1627{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001628 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
1630 if (!governor)
1631 return -EINVAL;
1632
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001633 if (cpufreq_disabled())
1634 return -ENODEV;
1635
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001636 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001637
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001638 err = -EBUSY;
1639 if (__find_governor(governor->name) == NULL) {
1640 err = 0;
1641 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
Dave Jones32ee8c32006-02-28 00:43:23 -05001644 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001645 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646}
1647EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1648
1649
1650void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1651{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001652#ifdef CONFIG_HOTPLUG_CPU
1653 int cpu;
1654#endif
1655
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 if (!governor)
1657 return;
1658
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001659 if (cpufreq_disabled())
1660 return;
1661
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001662#ifdef CONFIG_HOTPLUG_CPU
1663 for_each_present_cpu(cpu) {
1664 if (cpu_online(cpu))
1665 continue;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001666 if (!strcmp(per_cpu(cpufreq_policy_save, cpu).gov,
1667 governor->name))
1668 strcpy(per_cpu(cpufreq_policy_save, cpu).gov, "\0");
1669 per_cpu(cpufreq_policy_save, cpu).min = 0;
1670 per_cpu(cpufreq_policy_save, cpu).max = 0;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001671 }
1672#endif
1673
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001674 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001676 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 return;
1678}
1679EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1680
1681
1682
1683/*********************************************************************
1684 * POLICY INTERFACE *
1685 *********************************************************************/
1686
1687/**
1688 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001689 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1690 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 *
1692 * Reads the current cpufreq policy.
1693 */
1694int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1695{
1696 struct cpufreq_policy *cpu_policy;
1697 if (!policy)
1698 return -EINVAL;
1699
1700 cpu_policy = cpufreq_cpu_get(cpu);
1701 if (!cpu_policy)
1702 return -EINVAL;
1703
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705
1706 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 return 0;
1708}
1709EXPORT_SYMBOL(cpufreq_get_policy);
1710
1711
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001712/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301713 * data : current policy.
1714 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001715 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301716static int __cpufreq_set_policy(struct cpufreq_policy *data,
1717 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718{
1719 int ret = 0;
1720
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001721 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 policy->min, policy->max);
1723
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301724 memcpy(&policy->cpuinfo, &data->cpuinfo,
1725 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726
Yi Yang53391fa2008-01-30 13:33:34 +01001727 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001728 ret = -EINVAL;
1729 goto error_out;
1730 }
1731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 /* verify the cpu speed can be set within this limit */
1733 ret = cpufreq_driver->verify(policy);
1734 if (ret)
1735 goto error_out;
1736
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001738 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1739 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
1741 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001742 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1743 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
1745 /* verify the cpu speed can be set within this limit,
1746 which might be different to the first one */
1747 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001748 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
1751 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001752 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1753 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754
Dave Jones7d5e3502006-02-02 17:03:42 -05001755 data->min = policy->min;
1756 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001758 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301759 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
1761 if (cpufreq_driver->setpolicy) {
1762 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001763 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 ret = cpufreq_driver->setpolicy(policy);
1765 } else {
1766 if (policy->governor != data->governor) {
1767 /* save old, working values */
1768 struct cpufreq_governor *old_gov = data->governor;
1769
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001770 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771
1772 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001773 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1775
1776 /* start new governor */
1777 data->governor = policy->governor;
1778 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1779 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001780 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301781 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 if (old_gov) {
1783 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301784 __cpufreq_governor(data,
1785 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 }
1787 ret = -EINVAL;
1788 goto error_out;
1789 }
1790 /* might be a policy change, too, so fall through */
1791 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001792 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1794 }
1795
Dave Jones7d5e3502006-02-02 17:03:42 -05001796error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 return ret;
1798}
1799
1800/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1802 * @cpu: CPU which shall be re-evaluated
1803 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001804 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 * at different times.
1806 */
1807int cpufreq_update_policy(unsigned int cpu)
1808{
1809 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1810 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001811 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
Julia Lawallf1829e42008-07-25 22:44:53 +02001813 if (!data) {
1814 ret = -ENODEV;
1815 goto no_policy;
1816 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
Julia Lawallf1829e42008-07-25 22:44:53 +02001818 if (unlikely(lock_policy_rwsem_write(cpu))) {
1819 ret = -EINVAL;
1820 goto fail;
1821 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001823 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001824 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 policy.min = data->user_policy.min;
1826 policy.max = data->user_policy.max;
1827 policy.policy = data->user_policy.policy;
1828 policy.governor = data->user_policy.governor;
1829
Thomas Renninger0961dd02006-01-26 18:46:33 +01001830 /* BIOS might change freq behind our back
1831 -> ask driver for current freq and notify governors about a change */
1832 if (cpufreq_driver->get) {
1833 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001834 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001835 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001836 data->cur = policy.cur;
1837 } else {
1838 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301839 cpufreq_out_of_sync(cpu, data->cur,
1840 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001841 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001842 }
1843
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 ret = __cpufreq_set_policy(data, &policy);
1845
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001846 unlock_policy_rwsem_write(cpu);
1847
Julia Lawallf1829e42008-07-25 22:44:53 +02001848fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001850no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 return ret;
1852}
1853EXPORT_SYMBOL(cpufreq_update_policy);
1854
Satyam Sharmadd184a02007-10-02 13:28:14 -07001855static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001856 unsigned long action, void *hcpu)
1857{
1858 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001859 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001860
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001861 dev = get_cpu_device(cpu);
1862 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001863 switch (action) {
1864 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001865 case CPU_ONLINE_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001866 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001867 break;
1868 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001869 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001870 if (unlikely(lock_policy_rwsem_write(cpu)))
1871 BUG();
1872
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001873 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001874 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001875 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001876 case CPU_DOWN_FAILED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001877 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001878 break;
1879 }
1880 }
1881 return NOTIFY_OK;
1882}
1883
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001884static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001885 .notifier_call = cpufreq_cpu_callback,
1886};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887
1888/*********************************************************************
1889 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1890 *********************************************************************/
1891
1892/**
1893 * cpufreq_register_driver - register a CPU Frequency driver
1894 * @driver_data: A struct cpufreq_driver containing the values#
1895 * submitted by the CPU Frequency driver.
1896 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001897 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001899 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 *
1901 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001902int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903{
1904 unsigned long flags;
1905 int ret;
1906
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001907 if (cpufreq_disabled())
1908 return -ENODEV;
1909
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 if (!driver_data || !driver_data->verify || !driver_data->init ||
1911 ((!driver_data->setpolicy) && (!driver_data->target)))
1912 return -EINVAL;
1913
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001914 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915
1916 if (driver_data->setpolicy)
1917 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1918
1919 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1920 if (cpufreq_driver) {
1921 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1922 return -EBUSY;
1923 }
1924 cpufreq_driver = driver_data;
1925 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1926
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001927 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001928 if (ret)
1929 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001931 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 int i;
1933 ret = -ENODEV;
1934
1935 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001936 for (i = 0; i < nr_cpu_ids; i++)
1937 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001939 break;
1940 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941
1942 /* if all ->init() calls failed, unregister */
1943 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001944 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301945 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001946 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 }
1948 }
1949
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001950 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001951 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001953 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001954err_if_unreg:
1955 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001956err_null_driver:
1957 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1958 cpufreq_driver = NULL;
1959 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001960 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961}
1962EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1963
1964
1965/**
1966 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1967 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001968 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 * the right to do so, i.e. if you have succeeded in initialising before!
1970 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1971 * currently not initialised.
1972 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001973int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974{
1975 unsigned long flags;
1976
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001977 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001980 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001982 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001983 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
1985 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1986 cpufreq_driver = NULL;
1987 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1988
1989 return 0;
1990}
1991EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001992
1993static int __init cpufreq_core_init(void)
1994{
1995 int cpu;
1996
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001997 if (cpufreq_disabled())
1998 return -ENODEV;
1999
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002000 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09002001 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002002 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
2003 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002004
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002005 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002006 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002007 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002008
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002009 return 0;
2010}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002011core_initcall(cpufreq_core_init);