blob: 90311b2811ce7a9a6c5cbdf5b5c638defa2bc3bd [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
133static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500134static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Dave Jones7d5e3502006-02-02 17:03:42 -0500136struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137{
138 struct cpufreq_policy *data;
139 unsigned long flags;
140
Mike Travis7a6aedf2008-03-25 15:06:53 -0700141 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 goto err_out;
143
144 /* get the cpufreq driver */
145 spin_lock_irqsave(&cpufreq_driver_lock, flags);
146
147 if (!cpufreq_driver)
148 goto err_out_unlock;
149
150 if (!try_module_get(cpufreq_driver->owner))
151 goto err_out_unlock;
152
153
154 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700155 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
157 if (!data)
158 goto err_out_put_module;
159
160 if (!kobject_get(&data->kobj))
161 goto err_out_put_module;
162
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164 return data;
165
Dave Jones7d5e3502006-02-02 17:03:42 -0500166err_out_put_module:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 module_put(cpufreq_driver->owner);
Dave Jones7d5e3502006-02-02 17:03:42 -0500168err_out_unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500170err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 return NULL;
172}
173EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
174
Dave Jones7d5e3502006-02-02 17:03:42 -0500175
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176void cpufreq_cpu_put(struct cpufreq_policy *data)
177{
178 kobject_put(&data->kobj);
179 module_put(cpufreq_driver->owner);
180}
181EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
182
183
184/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
186 *********************************************************************/
187
188/**
189 * adjust_jiffies - adjust the system "loops_per_jiffy"
190 *
191 * This function alters the system "loops_per_jiffy" for the clock
192 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500193 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 * per-CPU loops_per_jiffy value wherever possible.
195 */
196#ifndef CONFIG_SMP
197static unsigned long l_p_j_ref;
198static unsigned int l_p_j_ref_freq;
199
Arjan van de Ven858119e2006-01-14 13:20:43 -0800200static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201{
202 if (ci->flags & CPUFREQ_CONST_LOOPS)
203 return;
204
205 if (!l_p_j_ref_freq) {
206 l_p_j_ref = loops_per_jiffy;
207 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200208 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530209 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 }
211 if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
212 (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700213 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530214 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
215 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200216 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530217 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 }
219}
220#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530221static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
222{
223 return;
224}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225#endif
226
227
228/**
Dave Jonese4472cb2006-01-31 15:53:55 -0800229 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
230 * on frequency transition.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 *
Dave Jonese4472cb2006-01-31 15:53:55 -0800232 * This function calls the transition notifiers and the "adjust_jiffies"
233 * function. It is called twice on all CPU frequency changes that have
Dave Jones32ee8c32006-02-28 00:43:23 -0500234 * external effects.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 */
236void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
237{
Dave Jonese4472cb2006-01-31 15:53:55 -0800238 struct cpufreq_policy *policy;
239
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 BUG_ON(irqs_disabled());
241
242 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200243 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800244 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
Mike Travis7a6aedf2008-03-25 15:06:53 -0700246 policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800248
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500250 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800251 * which is not equal to what the cpufreq core thinks is
252 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 */
254 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800255 if ((policy) && (policy->cpu == freqs->cpu) &&
256 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200257 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800258 " %u, cpufreq assumed %u kHz.\n",
259 freqs->old, policy->cur);
260 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 }
262 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700263 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800264 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
266 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800267
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 case CPUFREQ_POSTCHANGE:
269 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200270 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200271 (unsigned long)freqs->cpu);
272 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100273 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700274 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800275 CPUFREQ_POSTCHANGE, freqs);
Amar Singhal99055d52012-02-23 13:54:46 -0800276 if (likely(policy) && likely(policy->cpu == freqs->cpu)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800277 policy->cur = freqs->new;
Amar Singhal99055d52012-02-23 13:54:46 -0800278 sysfs_notify(&policy->kobj, NULL, "scaling_cur_freq");
279 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 break;
281 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282}
283EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800284/**
285 * cpufreq_notify_utilization - notify CPU userspace about CPU utilization
286 * change
287 *
288 * This function is called everytime the CPU load is evaluated by the
289 * ondemand governor. It notifies userspace of cpu load changes via sysfs.
290 */
291void cpufreq_notify_utilization(struct cpufreq_policy *policy,
292 unsigned int util)
293{
294 if (policy)
295 policy->util = util;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800297 if (policy->util >= MIN_CPU_UTIL_NOTIFY)
298 sysfs_notify(&policy->kobj, NULL, "cpu_utilization");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800300}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302/*********************************************************************
303 * SYSFS INTERFACE *
304 *********************************************************************/
305
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700306static struct cpufreq_governor *__find_governor(const char *str_governor)
307{
308 struct cpufreq_governor *t;
309
310 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500311 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700312 return t;
313
314 return NULL;
315}
316
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317/**
318 * cpufreq_parse_governor - parse a governor string
319 */
Dave Jones905d77c2008-03-05 14:28:32 -0500320static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 struct cpufreq_governor **governor)
322{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700323 int err = -EINVAL;
324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700326 goto out;
327
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 if (cpufreq_driver->setpolicy) {
329 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
330 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700331 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530332 } else if (!strnicmp(str_governor, "powersave",
333 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700335 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700337 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700339
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800340 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700341
342 t = __find_governor(str_governor);
343
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700344 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700345 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700346
Kees Cook1a8e1462011-05-04 08:38:56 -0700347 mutex_unlock(&cpufreq_governor_mutex);
348 ret = request_module("cpufreq_%s", str_governor);
349 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700350
Kees Cook1a8e1462011-05-04 08:38:56 -0700351 if (ret == 0)
352 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700353 }
354
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700355 if (t != NULL) {
356 *governor = t;
357 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700359
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800360 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 }
Dave Jones29464f22009-01-18 01:37:11 -0500362out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700363 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
366
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530368 * cpufreq_per_cpu_attr_read() / show_##file_name() -
369 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 *
371 * Write out information from cpufreq_driver->policy[cpu]; object must be
372 * "unsigned int".
373 */
374
Dave Jones32ee8c32006-02-28 00:43:23 -0500375#define show_one(file_name, object) \
376static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500377(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500378{ \
Dave Jones29464f22009-01-18 01:37:11 -0500379 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380}
381
382show_one(cpuinfo_min_freq, cpuinfo.min_freq);
383show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100384show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385show_one(scaling_min_freq, min);
386show_one(scaling_max_freq, max);
387show_one(scaling_cur_freq, cur);
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800388show_one(cpu_utilization, util);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530390static int __cpufreq_set_policy(struct cpufreq_policy *data,
391 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200392
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393/**
394 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
395 */
396#define store_one(file_name, object) \
397static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500398(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399{ \
400 unsigned int ret = -EINVAL; \
401 struct cpufreq_policy new_policy; \
402 \
403 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
404 if (ret) \
405 return -EINVAL; \
406 \
Dave Jones29464f22009-01-18 01:37:11 -0500407 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 if (ret != 1) \
409 return -EINVAL; \
410 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200411 ret = __cpufreq_set_policy(policy, &new_policy); \
412 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 \
414 return ret ? ret : count; \
415}
416
Dave Jones29464f22009-01-18 01:37:11 -0500417store_one(scaling_min_freq, min);
418store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
420/**
421 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
422 */
Dave Jones905d77c2008-03-05 14:28:32 -0500423static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
424 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800426 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 if (!cur_freq)
428 return sprintf(buf, "<unknown>");
429 return sprintf(buf, "%u\n", cur_freq);
430}
431
432
433/**
434 * show_scaling_governor - show the current policy for the specified CPU
435 */
Dave Jones905d77c2008-03-05 14:28:32 -0500436static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437{
Dave Jones29464f22009-01-18 01:37:11 -0500438 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 return sprintf(buf, "powersave\n");
440 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
441 return sprintf(buf, "performance\n");
442 else if (policy->governor)
Dave Jones29464f22009-01-18 01:37:11 -0500443 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n",
444 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 return -EINVAL;
446}
447
448
449/**
450 * store_scaling_governor - store policy for the specified CPU
451 */
Dave Jones905d77c2008-03-05 14:28:32 -0500452static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
453 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454{
455 unsigned int ret = -EINVAL;
456 char str_governor[16];
457 struct cpufreq_policy new_policy;
458
459 ret = cpufreq_get_policy(&new_policy, policy->cpu);
460 if (ret)
461 return ret;
462
Dave Jones29464f22009-01-18 01:37:11 -0500463 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464 if (ret != 1)
465 return -EINVAL;
466
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530467 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
468 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 return -EINVAL;
470
Thomas Renninger7970e082006-04-13 15:14:04 +0200471 /* Do not use cpufreq_set_policy here or the user_policy.max
472 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200473 ret = __cpufreq_set_policy(policy, &new_policy);
474
475 policy->user_policy.policy = policy->policy;
476 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200477
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530478 if (ret)
479 return ret;
480 else
481 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482}
483
484/**
485 * show_scaling_driver - show the cpufreq driver currently loaded
486 */
Dave Jones905d77c2008-03-05 14:28:32 -0500487static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488{
489 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
490}
491
492/**
493 * show_scaling_available_governors - show the available CPUfreq governors
494 */
Dave Jones905d77c2008-03-05 14:28:32 -0500495static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
496 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497{
498 ssize_t i = 0;
499 struct cpufreq_governor *t;
500
501 if (!cpufreq_driver->target) {
502 i += sprintf(buf, "performance powersave");
503 goto out;
504 }
505
506 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500507 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
508 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 goto out;
510 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
511 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500512out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 i += sprintf(&buf[i], "\n");
514 return i;
515}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700516
Rusty Russell835481d2009-01-04 05:18:06 -0800517static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518{
519 ssize_t i = 0;
520 unsigned int cpu;
521
Rusty Russell835481d2009-01-04 05:18:06 -0800522 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 if (i)
524 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
525 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
526 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500527 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 }
529 i += sprintf(&buf[i], "\n");
530 return i;
531}
532
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700533/**
534 * show_related_cpus - show the CPUs affected by each transition even if
535 * hw coordination is in use
536 */
537static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
538{
Rusty Russell835481d2009-01-04 05:18:06 -0800539 if (cpumask_empty(policy->related_cpus))
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700540 return show_cpus(policy->cpus, buf);
541 return show_cpus(policy->related_cpus, buf);
542}
543
544/**
545 * show_affected_cpus - show the CPUs affected by each transition
546 */
547static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
548{
549 return show_cpus(policy->cpus, buf);
550}
551
Venki Pallipadi9e769882007-10-26 10:18:21 -0700552static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500553 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700554{
555 unsigned int freq = 0;
556 unsigned int ret;
557
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700558 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700559 return -EINVAL;
560
561 ret = sscanf(buf, "%u", &freq);
562 if (ret != 1)
563 return -EINVAL;
564
565 policy->governor->store_setspeed(policy, freq);
566
567 return count;
568}
569
570static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
571{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700572 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700573 return sprintf(buf, "<unsupported>\n");
574
575 return policy->governor->show_setspeed(policy, buf);
576}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
Thomas Renningere2f74f32009-11-19 12:31:01 +0100578/**
579 * show_scaling_driver - show the current cpufreq HW/BIOS limitation
580 */
581static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
582{
583 unsigned int limit;
584 int ret;
585 if (cpufreq_driver->bios_limit) {
586 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
587 if (!ret)
588 return sprintf(buf, "%u\n", limit);
589 }
590 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
591}
592
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200593cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
594cpufreq_freq_attr_ro(cpuinfo_min_freq);
595cpufreq_freq_attr_ro(cpuinfo_max_freq);
596cpufreq_freq_attr_ro(cpuinfo_transition_latency);
597cpufreq_freq_attr_ro(scaling_available_governors);
598cpufreq_freq_attr_ro(scaling_driver);
599cpufreq_freq_attr_ro(scaling_cur_freq);
600cpufreq_freq_attr_ro(bios_limit);
601cpufreq_freq_attr_ro(related_cpus);
602cpufreq_freq_attr_ro(affected_cpus);
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800603cpufreq_freq_attr_ro(cpu_utilization);
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200604cpufreq_freq_attr_rw(scaling_min_freq);
605cpufreq_freq_attr_rw(scaling_max_freq);
606cpufreq_freq_attr_rw(scaling_governor);
607cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Dave Jones905d77c2008-03-05 14:28:32 -0500609static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 &cpuinfo_min_freq.attr,
611 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100612 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 &scaling_min_freq.attr,
614 &scaling_max_freq.attr,
615 &affected_cpus.attr,
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800616 &cpu_utilization.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700617 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 &scaling_governor.attr,
619 &scaling_driver.attr,
620 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700621 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 NULL
623};
624
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200625struct kobject *cpufreq_global_kobject;
626EXPORT_SYMBOL(cpufreq_global_kobject);
627
Dave Jones29464f22009-01-18 01:37:11 -0500628#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
629#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
Dave Jones29464f22009-01-18 01:37:11 -0500631static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632{
Dave Jones905d77c2008-03-05 14:28:32 -0500633 struct cpufreq_policy *policy = to_policy(kobj);
634 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500635 ssize_t ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 policy = cpufreq_cpu_get(policy->cpu);
637 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500638 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800639
640 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500641 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800642
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530643 if (fattr->show)
644 ret = fattr->show(policy, buf);
645 else
646 ret = -EIO;
647
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800648 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500649fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 cpufreq_cpu_put(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500651no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 return ret;
653}
654
Dave Jones905d77c2008-03-05 14:28:32 -0500655static ssize_t store(struct kobject *kobj, struct attribute *attr,
656 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657{
Dave Jones905d77c2008-03-05 14:28:32 -0500658 struct cpufreq_policy *policy = to_policy(kobj);
659 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500660 ssize_t ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 policy = cpufreq_cpu_get(policy->cpu);
662 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500663 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800664
665 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500666 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800667
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530668 if (fattr->store)
669 ret = fattr->store(policy, buf, count);
670 else
671 ret = -EIO;
672
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800673 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500674fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 cpufreq_cpu_put(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500676no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 return ret;
678}
679
Dave Jones905d77c2008-03-05 14:28:32 -0500680static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681{
Dave Jones905d77c2008-03-05 14:28:32 -0500682 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200683 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 complete(&policy->kobj_unregister);
685}
686
Emese Revfy52cf25d2010-01-19 02:58:23 +0100687static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 .show = show,
689 .store = store,
690};
691
692static struct kobj_type ktype_cpufreq = {
693 .sysfs_ops = &sysfs_ops,
694 .default_attrs = default_attrs,
695 .release = cpufreq_sysfs_release,
696};
697
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200698/*
699 * Returns:
700 * Negative: Failure
701 * 0: Success
702 * Positive: When we have a managed CPU and the sysfs got symlinked
703 */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700704static int cpufreq_add_dev_policy(unsigned int cpu,
705 struct cpufreq_policy *policy,
706 struct sys_device *sys_dev)
Dave Jonesecf7e462009-07-08 18:48:47 -0400707{
708 int ret = 0;
709#ifdef CONFIG_SMP
710 unsigned long flags;
711 unsigned int j;
Dave Jonesecf7e462009-07-08 18:48:47 -0400712#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400713 struct cpufreq_governor *gov;
714
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700715 gov = __find_governor(per_cpu(cpufreq_policy_save, cpu).gov);
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400716 if (gov) {
717 policy->governor = gov;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200718 pr_debug("Restoring governor %s for cpu %d\n",
Dave Jonesecf7e462009-07-08 18:48:47 -0400719 policy->governor->name, cpu);
720 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700721 if (per_cpu(cpufreq_policy_save, cpu).min) {
722 policy->min = per_cpu(cpufreq_policy_save, cpu).min;
723 policy->user_policy.min = policy->min;
724 }
725 if (per_cpu(cpufreq_policy_save, cpu).max) {
726 policy->max = per_cpu(cpufreq_policy_save, cpu).max;
727 policy->user_policy.max = policy->max;
728 }
729 pr_debug("Restoring CPU%d min %d and max %d\n",
730 cpu, policy->min, policy->max);
Dave Jonesecf7e462009-07-08 18:48:47 -0400731#endif
732
733 for_each_cpu(j, policy->cpus) {
734 struct cpufreq_policy *managed_policy;
735
736 if (cpu == j)
737 continue;
738
739 /* Check for existing affected CPUs.
740 * They may not be aware of it due to CPU Hotplug.
741 * cpufreq_cpu_put is called when the device is removed
742 * in __cpufreq_remove_dev()
743 */
744 managed_policy = cpufreq_cpu_get(j);
745 if (unlikely(managed_policy)) {
746
747 /* Set proper policy_cpu */
748 unlock_policy_rwsem_write(cpu);
Tejun Heof1625062009-10-29 22:34:13 +0900749 per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
Dave Jonesecf7e462009-07-08 18:48:47 -0400750
751 if (lock_policy_rwsem_write(cpu) < 0) {
752 /* Should not go through policy unlock path */
753 if (cpufreq_driver->exit)
754 cpufreq_driver->exit(policy);
755 cpufreq_cpu_put(managed_policy);
756 return -EBUSY;
757 }
758
759 spin_lock_irqsave(&cpufreq_driver_lock, flags);
760 cpumask_copy(managed_policy->cpus, policy->cpus);
761 per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
762 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
763
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200764 pr_debug("CPU already managed, adding link\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400765 ret = sysfs_create_link(&sys_dev->kobj,
766 &managed_policy->kobj,
767 "cpufreq");
768 if (ret)
769 cpufreq_cpu_put(managed_policy);
770 /*
771 * Success. We only needed to be added to the mask.
772 * Call driver->exit() because only the cpu parent of
773 * the kobj needed to call init().
774 */
775 if (cpufreq_driver->exit)
776 cpufreq_driver->exit(policy);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200777
778 if (!ret)
779 return 1;
780 else
781 return ret;
Dave Jonesecf7e462009-07-08 18:48:47 -0400782 }
783 }
784#endif
785 return ret;
786}
787
788
Dave Jones19d6f7e2009-07-08 17:35:39 -0400789/* symlink affected CPUs */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700790static int cpufreq_add_dev_symlink(unsigned int cpu,
791 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400792{
793 unsigned int j;
794 int ret = 0;
795
796 for_each_cpu(j, policy->cpus) {
797 struct cpufreq_policy *managed_policy;
798 struct sys_device *cpu_sys_dev;
799
800 if (j == cpu)
801 continue;
802 if (!cpu_online(j))
803 continue;
804
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200805 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400806 managed_policy = cpufreq_cpu_get(cpu);
807 cpu_sys_dev = get_cpu_sysdev(j);
808 ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
809 "cpufreq");
810 if (ret) {
811 cpufreq_cpu_put(managed_policy);
812 return ret;
813 }
814 }
815 return ret;
816}
817
Alex Chiangcf3289d2009-11-17 20:27:08 -0700818static int cpufreq_add_dev_interface(unsigned int cpu,
819 struct cpufreq_policy *policy,
820 struct sys_device *sys_dev)
Dave Jones909a6942009-07-08 18:05:42 -0400821{
Dave Jonesecf7e462009-07-08 18:48:47 -0400822 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400823 struct freq_attr **drv_attr;
824 unsigned long flags;
825 int ret = 0;
826 unsigned int j;
827
828 /* prepare interface data */
829 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
830 &sys_dev->kobj, "cpufreq");
831 if (ret)
832 return ret;
833
834 /* set up files for this cpu device */
835 drv_attr = cpufreq_driver->attr;
836 while ((drv_attr) && (*drv_attr)) {
837 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
838 if (ret)
839 goto err_out_kobj_put;
840 drv_attr++;
841 }
842 if (cpufreq_driver->get) {
843 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
844 if (ret)
845 goto err_out_kobj_put;
846 }
847 if (cpufreq_driver->target) {
848 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
849 if (ret)
850 goto err_out_kobj_put;
851 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100852 if (cpufreq_driver->bios_limit) {
853 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
854 if (ret)
855 goto err_out_kobj_put;
856 }
Dave Jones909a6942009-07-08 18:05:42 -0400857
858 spin_lock_irqsave(&cpufreq_driver_lock, flags);
859 for_each_cpu(j, policy->cpus) {
Julia Lawallbec037a2010-08-05 22:23:00 +0200860 if (!cpu_online(j))
861 continue;
Dave Jones909a6942009-07-08 18:05:42 -0400862 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900863 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400864 }
865 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
866
867 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400868 if (ret)
869 goto err_out_kobj_put;
870
871 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
872 /* assure that the starting sequence is run in __cpufreq_set_policy */
873 policy->governor = NULL;
874
875 /* set default policy */
876 ret = __cpufreq_set_policy(policy, &new_policy);
877 policy->user_policy.policy = policy->policy;
878 policy->user_policy.governor = policy->governor;
879
880 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200881 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400882 if (cpufreq_driver->exit)
883 cpufreq_driver->exit(policy);
884 }
Dave Jones909a6942009-07-08 18:05:42 -0400885 return ret;
886
887err_out_kobj_put:
888 kobject_put(&policy->kobj);
889 wait_for_completion(&policy->kobj_unregister);
890 return ret;
891}
892
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
894/**
895 * cpufreq_add_dev - add a CPU device
896 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500897 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400898 *
899 * The Oracle says: try running cpufreq registration/unregistration concurrently
900 * with with cpu hotplugging and all hell will break loose. Tried to clean this
901 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 */
Dave Jones905d77c2008-03-05 14:28:32 -0500903static int cpufreq_add_dev(struct sys_device *sys_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904{
905 unsigned int cpu = sys_dev->id;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500906 int ret = 0, found = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 unsigned long flags;
909 unsigned int j;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500910#ifdef CONFIG_HOTPLUG_CPU
911 int sibling;
912#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913
Ashok Rajc32b6b82005-10-30 14:59:54 -0800914 if (cpu_is_offline(cpu))
915 return 0;
916
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200917 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
919#ifdef CONFIG_SMP
920 /* check whether a different CPU already registered this
921 * CPU because it is in the same boat. */
922 policy = cpufreq_cpu_get(cpu);
923 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500924 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 return 0;
926 }
927#endif
928
929 if (!try_module_get(cpufreq_driver->owner)) {
930 ret = -EINVAL;
931 goto module_out;
932 }
933
Dave Jones059019a2009-07-08 16:30:03 -0400934 ret = -ENOMEM;
Dave Jonese98df502005-10-20 15:17:43 -0700935 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400936 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400938
939 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400940 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400941
942 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400943 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944
945 policy->cpu = cpu;
Rusty Russell835481d2009-01-04 05:18:06 -0800946 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800948 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900949 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400950 ret = (lock_policy_rwsem_write(cpu) < 0);
951 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800952
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000954 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700956 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500957#ifdef CONFIG_HOTPLUG_CPU
958 for_each_online_cpu(sibling) {
959 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
960 if (cp && cp->governor &&
961 (cpumask_test_cpu(cpu, cp->related_cpus))) {
962 policy->governor = cp->governor;
963 found = 1;
964 break;
965 }
966 }
967#endif
968 if (!found)
969 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 /* call driver. From then on the cpufreq must be able
971 * to accept all calls to ->verify and ->setpolicy for this CPU
972 */
973 ret = cpufreq_driver->init(policy);
974 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200975 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400976 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 }
Mike Chan187d9f42008-12-04 12:19:17 -0800978 policy->user_policy.min = policy->min;
979 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
Thomas Renningera1531ac2008-07-29 22:32:58 -0700981 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
982 CPUFREQ_START, policy);
983
Dave Jonesecf7e462009-07-08 18:48:47 -0400984 ret = cpufreq_add_dev_policy(cpu, policy, sys_dev);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200985 if (ret) {
986 if (ret > 0)
987 /* This is a managed cpu, symlink created,
988 exit with 0 */
989 ret = 0;
Dave Jonesecf7e462009-07-08 18:48:47 -0400990 goto err_unlock_policy;
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200991 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
Dave Jones909a6942009-07-08 18:05:42 -0400993 ret = cpufreq_add_dev_interface(cpu, policy, sys_dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400994 if (ret)
995 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500996
Lothar Waßmanndca02612008-05-29 17:54:52 +0200997 unlock_policy_rwsem_write(cpu);
998
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -0400999 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001001 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001002
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 return 0;
1004
1005
1006err_out_unregister:
1007 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001008 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001009 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1011
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001012 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 wait_for_completion(&policy->kobj_unregister);
1014
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001015err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -05001016 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001017 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001018err_free_cpumask:
1019 free_cpumask_var(policy->cpus);
1020err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022nomem_out:
1023 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001024module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 return ret;
1026}
1027
1028
1029/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001030 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 *
1032 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001033 * Caller should already have policy_rwsem in write mode for this CPU.
1034 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 */
Dave Jones905d77c2008-03-05 14:28:32 -05001036static int __cpufreq_remove_dev(struct sys_device *sys_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037{
1038 unsigned int cpu = sys_dev->id;
1039 unsigned long flags;
1040 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001041 struct kobject *kobj;
1042 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043#ifdef CONFIG_SMP
Grant Coadye738cf62005-11-21 21:32:28 -08001044 struct sys_device *cpu_sys_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 unsigned int j;
1046#endif
1047
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001048 pr_debug("unregistering CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049
1050 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001051 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052
1053 if (!data) {
1054 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001055 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 return -EINVAL;
1057 }
Mike Travis7a6aedf2008-03-25 15:06:53 -07001058 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060
1061#ifdef CONFIG_SMP
1062 /* if this isn't the CPU which is the parent of the kobj, we
Dave Jones32ee8c32006-02-28 00:43:23 -05001063 * only need to unlink, put and exit
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064 */
1065 if (unlikely(cpu != data->cpu)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001066 pr_debug("removing link\n");
Rusty Russell835481d2009-01-04 05:18:06 -08001067 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Amerigo Wang499bca92010-03-04 03:23:46 -05001069 kobj = &sys_dev->kobj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 cpufreq_cpu_put(data);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001071 unlock_policy_rwsem_write(cpu);
Amerigo Wang499bca92010-03-04 03:23:46 -05001072 sysfs_remove_link(kobj, "cpufreq");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 return 0;
1074 }
1075#endif
1076
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077#ifdef CONFIG_SMP
Thomas Renninger084f3492007-07-09 11:35:28 -07001078
1079#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001080 strncpy(per_cpu(cpufreq_policy_save, cpu).gov, data->governor->name,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001081 CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001082 per_cpu(cpufreq_policy_save, cpu).min = data->min;
1083 per_cpu(cpufreq_policy_save, cpu).max = data->max;
1084 pr_debug("Saving CPU%d policy min %d and max %d\n",
1085 cpu, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001086#endif
1087
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 /* if we have other CPUs still registered, we need to unlink them,
1089 * or else wait_for_completion below will lock up. Clean the
Mike Travis7a6aedf2008-03-25 15:06:53 -07001090 * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
1091 * the sysfs links afterwards.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 */
Rusty Russell835481d2009-01-04 05:18:06 -08001093 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1094 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 if (j == cpu)
1096 continue;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001097 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 }
1099 }
1100
1101 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1102
Rusty Russell835481d2009-01-04 05:18:06 -08001103 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1104 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 if (j == cpu)
1106 continue;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001107 pr_debug("removing link for cpu %u\n", j);
Thomas Renninger084f3492007-07-09 11:35:28 -07001108#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001109 strncpy(per_cpu(cpufreq_policy_save, j).gov,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001110 data->governor->name, CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001111 per_cpu(cpufreq_policy_save, j).min = data->min;
1112 per_cpu(cpufreq_policy_save, j).max = data->max;
1113 pr_debug("Saving CPU%d policy min %d and max %d\n",
1114 j, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001115#endif
Ashok Rajd434fca2005-10-30 14:59:52 -08001116 cpu_sys_dev = get_cpu_sysdev(j);
Amerigo Wang499bca92010-03-04 03:23:46 -05001117 kobj = &cpu_sys_dev->kobj;
1118 unlock_policy_rwsem_write(cpu);
1119 sysfs_remove_link(kobj, "cpufreq");
1120 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 cpufreq_cpu_put(data);
1122 }
1123 }
1124#else
1125 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1126#endif
1127
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 if (cpufreq_driver->target)
1129 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001130
Amerigo Wang499bca92010-03-04 03:23:46 -05001131 kobj = &data->kobj;
1132 cmp = &data->kobj_unregister;
1133 unlock_policy_rwsem_write(cpu);
1134 kobject_put(kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
1136 /* we need to make sure that the underlying kobj is actually
Dave Jones32ee8c32006-02-28 00:43:23 -05001137 * not referenced anymore by anybody before we proceed with
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 * unloading.
1139 */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001140 pr_debug("waiting for dropping of refcount\n");
Amerigo Wang499bca92010-03-04 03:23:46 -05001141 wait_for_completion(cmp);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001142 pr_debug("wait complete\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143
Amerigo Wang499bca92010-03-04 03:23:46 -05001144 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145 if (cpufreq_driver->exit)
1146 cpufreq_driver->exit(data);
venkatesh.pallipadi@intel.com7d26e2d2009-07-02 17:08:30 -07001147 unlock_policy_rwsem_write(cpu);
1148
Jacob Shin27ecddc2011-04-27 13:32:11 -05001149#ifdef CONFIG_HOTPLUG_CPU
1150 /* when the CPU which is the parent of the kobj is hotplugged
1151 * offline, check for siblings, and create cpufreq sysfs interface
1152 * and symlinks
1153 */
1154 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1155 /* first sibling now owns the new sysfs dir */
1156 cpumask_clear_cpu(cpu, data->cpus);
1157 cpufreq_add_dev(get_cpu_sysdev(cpumask_first(data->cpus)));
1158
1159 /* finally remove our own symlink */
1160 lock_policy_rwsem_write(cpu);
1161 __cpufreq_remove_dev(sys_dev);
1162 }
1163#endif
1164
Rusty Russell835481d2009-01-04 05:18:06 -08001165 free_cpumask_var(data->related_cpus);
1166 free_cpumask_var(data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 kfree(data);
1168
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 return 0;
1170}
1171
1172
Dave Jones905d77c2008-03-05 14:28:32 -05001173static int cpufreq_remove_dev(struct sys_device *sys_dev)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001174{
1175 unsigned int cpu = sys_dev->id;
1176 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001177
1178 if (cpu_is_offline(cpu))
1179 return 0;
1180
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001181 if (unlikely(lock_policy_rwsem_write(cpu)))
1182 BUG();
1183
1184 retval = __cpufreq_remove_dev(sys_dev);
1185 return retval;
1186}
1187
1188
David Howells65f27f32006-11-22 14:55:48 +00001189static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190{
David Howells65f27f32006-11-22 14:55:48 +00001191 struct cpufreq_policy *policy =
1192 container_of(work, struct cpufreq_policy, update);
1193 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001194 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 cpufreq_update_policy(cpu);
1196}
1197
1198/**
1199 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1200 * @cpu: cpu number
1201 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1202 * @new_freq: CPU frequency the CPU actually runs at
1203 *
Dave Jones29464f22009-01-18 01:37:11 -05001204 * We adjust to current frequency first, and need to clean up later.
1205 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301207static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1208 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209{
1210 struct cpufreq_freqs freqs;
1211
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001212 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1214
1215 freqs.cpu = cpu;
1216 freqs.old = old_freq;
1217 freqs.new = new_freq;
1218 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1219 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1220}
1221
1222
Dave Jones32ee8c32006-02-28 00:43:23 -05001223/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301224 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001225 * @cpu: CPU number
1226 *
1227 * This is the last known freq, without actually getting it from the driver.
1228 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1229 */
1230unsigned int cpufreq_quick_get(unsigned int cpu)
1231{
1232 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301233 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001234
1235 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301236 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001237 cpufreq_cpu_put(policy);
1238 }
1239
Dave Jones4d34a672008-02-07 16:33:49 -05001240 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001241}
1242EXPORT_SYMBOL(cpufreq_quick_get);
1243
1244
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001245static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001247 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301248 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001251 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301253 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301255 if (ret_freq && policy->cur &&
1256 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1257 /* verify no discrepancy between actual and
1258 saved value exists */
1259 if (unlikely(ret_freq != policy->cur)) {
1260 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 schedule_work(&policy->update);
1262 }
1263 }
1264
Dave Jones4d34a672008-02-07 16:33:49 -05001265 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001266}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001268/**
1269 * cpufreq_get - get the current CPU frequency (in kHz)
1270 * @cpu: CPU number
1271 *
1272 * Get the CPU current (static) CPU frequency
1273 */
1274unsigned int cpufreq_get(unsigned int cpu)
1275{
1276 unsigned int ret_freq = 0;
1277 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1278
1279 if (!policy)
1280 goto out;
1281
1282 if (unlikely(lock_policy_rwsem_read(cpu)))
1283 goto out_policy;
1284
1285 ret_freq = __cpufreq_get(cpu);
1286
1287 unlock_policy_rwsem_read(cpu);
1288
1289out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001291out:
Dave Jones4d34a672008-02-07 16:33:49 -05001292 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293}
1294EXPORT_SYMBOL(cpufreq_get);
1295
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001296static struct sysdev_driver cpufreq_sysdev_driver = {
1297 .add = cpufreq_add_dev,
1298 .remove = cpufreq_remove_dev,
1299};
1300
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301
1302/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001303 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1304 *
1305 * This function is only executed for the boot processor. The other CPUs
1306 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001307 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001308static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001309{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301310 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001311
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001312 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001313 struct cpufreq_policy *cpu_policy;
1314
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001315 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001316
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001317 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001318 cpu_policy = cpufreq_cpu_get(cpu);
1319 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001320 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001321
1322 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001323 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001324 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001325 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1326 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001327 }
1328
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001329 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001330 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001331}
1332
1333/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001334 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 *
1336 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001337 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1338 * restored. It will verify that the current freq is in sync with
1339 * what we believe it to be. This is a bit later than when it
1340 * should be, but nonethteless it's better than calling
1341 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001342 *
1343 * This function is only executed for the boot CPU. The other CPUs have not
1344 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001346static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301348 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001349
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001350 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 struct cpufreq_policy *cpu_policy;
1352
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001353 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001355 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 cpu_policy = cpufreq_cpu_get(cpu);
1357 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001358 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359
1360 if (cpufreq_driver->resume) {
1361 ret = cpufreq_driver->resume(cpu_policy);
1362 if (ret) {
1363 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1364 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001365 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 }
1367 }
1368
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001370
Dave Jonesc9060492008-02-07 16:32:18 -05001371fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373}
1374
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001375static struct syscore_ops cpufreq_syscore_ops = {
1376 .suspend = cpufreq_bp_suspend,
1377 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378};
1379
1380
1381/*********************************************************************
1382 * NOTIFIER LISTS INTERFACE *
1383 *********************************************************************/
1384
1385/**
1386 * cpufreq_register_notifier - register a driver with cpufreq
1387 * @nb: notifier function to register
1388 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1389 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001390 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 * are notified about clock rate changes (once before and once after
1392 * the transition), or a list of drivers that are notified about
1393 * changes in cpufreq policy.
1394 *
1395 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001396 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 */
1398int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1399{
1400 int ret;
1401
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001402 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1403
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 switch (list) {
1405 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001406 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001407 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 break;
1409 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001410 ret = blocking_notifier_chain_register(
1411 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 break;
1413 default:
1414 ret = -EINVAL;
1415 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 return ret;
1418}
1419EXPORT_SYMBOL(cpufreq_register_notifier);
1420
1421
1422/**
1423 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1424 * @nb: notifier block to be unregistered
1425 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1426 *
1427 * Remove a driver from the CPU frequency notifier list.
1428 *
1429 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001430 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 */
1432int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1433{
1434 int ret;
1435
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 switch (list) {
1437 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001438 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001439 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440 break;
1441 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001442 ret = blocking_notifier_chain_unregister(
1443 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 break;
1445 default:
1446 ret = -EINVAL;
1447 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448
1449 return ret;
1450}
1451EXPORT_SYMBOL(cpufreq_unregister_notifier);
1452
1453
1454/*********************************************************************
1455 * GOVERNORS *
1456 *********************************************************************/
1457
1458
1459int __cpufreq_driver_target(struct cpufreq_policy *policy,
1460 unsigned int target_freq,
1461 unsigned int relation)
1462{
1463 int retval = -EINVAL;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001464
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001465 pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 target_freq, relation);
1467 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1468 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001469
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 return retval;
1471}
1472EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1473
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474int cpufreq_driver_target(struct cpufreq_policy *policy,
1475 unsigned int target_freq,
1476 unsigned int relation)
1477{
Julia Lawallf1829e42008-07-25 22:44:53 +02001478 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
1480 policy = cpufreq_cpu_get(policy->cpu);
1481 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001482 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001484 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001485 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486
1487 ret = __cpufreq_driver_target(policy, target_freq, relation);
1488
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001489 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490
Julia Lawallf1829e42008-07-25 22:44:53 +02001491fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001493no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 return ret;
1495}
1496EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1497
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001498int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001499{
1500 int ret = 0;
1501
1502 policy = cpufreq_cpu_get(policy->cpu);
1503 if (!policy)
1504 return -EINVAL;
1505
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001506 if (cpu_online(cpu) && cpufreq_driver->getavg)
1507 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001508
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001509 cpufreq_cpu_put(policy);
1510 return ret;
1511}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001512EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001513
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001514/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001515 * when "event" is CPUFREQ_GOV_LIMITS
1516 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301518static int __cpufreq_governor(struct cpufreq_policy *policy,
1519 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520{
Dave Jonescc993ca2005-07-28 09:43:56 -07001521 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001522
1523 /* Only must be defined when default governor is known to have latency
1524 restrictions, like e.g. conservative or ondemand.
1525 That this is the case is already ensured in Kconfig
1526 */
1527#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1528 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1529#else
1530 struct cpufreq_governor *gov = NULL;
1531#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001532
1533 if (policy->governor->max_transition_latency &&
1534 policy->cpuinfo.transition_latency >
1535 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001536 if (!gov)
1537 return -EINVAL;
1538 else {
1539 printk(KERN_WARNING "%s governor failed, too long"
1540 " transition latency of HW, fallback"
1541 " to %s governor\n",
1542 policy->governor->name,
1543 gov->name);
1544 policy->governor = gov;
1545 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001546 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547
1548 if (!try_module_get(policy->governor->owner))
1549 return -EINVAL;
1550
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001551 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301552 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 ret = policy->governor->governor(policy, event);
1554
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301555 /* we keep one module reference alive for
1556 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 if ((event != CPUFREQ_GOV_START) || ret)
1558 module_put(policy->governor->owner);
1559 if ((event == CPUFREQ_GOV_STOP) && !ret)
1560 module_put(policy->governor->owner);
1561
1562 return ret;
1563}
1564
1565
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566int cpufreq_register_governor(struct cpufreq_governor *governor)
1567{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001568 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
1570 if (!governor)
1571 return -EINVAL;
1572
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001573 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001574
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001575 err = -EBUSY;
1576 if (__find_governor(governor->name) == NULL) {
1577 err = 0;
1578 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580
Dave Jones32ee8c32006-02-28 00:43:23 -05001581 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001582 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583}
1584EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1585
1586
1587void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1588{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001589#ifdef CONFIG_HOTPLUG_CPU
1590 int cpu;
1591#endif
1592
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 if (!governor)
1594 return;
1595
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001596#ifdef CONFIG_HOTPLUG_CPU
1597 for_each_present_cpu(cpu) {
1598 if (cpu_online(cpu))
1599 continue;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001600 if (!strcmp(per_cpu(cpufreq_policy_save, cpu).gov,
1601 governor->name))
1602 strcpy(per_cpu(cpufreq_policy_save, cpu).gov, "\0");
1603 per_cpu(cpufreq_policy_save, cpu).min = 0;
1604 per_cpu(cpufreq_policy_save, cpu).max = 0;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001605 }
1606#endif
1607
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001608 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001610 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 return;
1612}
1613EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1614
1615
1616
1617/*********************************************************************
1618 * POLICY INTERFACE *
1619 *********************************************************************/
1620
1621/**
1622 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001623 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1624 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 *
1626 * Reads the current cpufreq policy.
1627 */
1628int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1629{
1630 struct cpufreq_policy *cpu_policy;
1631 if (!policy)
1632 return -EINVAL;
1633
1634 cpu_policy = cpufreq_cpu_get(cpu);
1635 if (!cpu_policy)
1636 return -EINVAL;
1637
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
1640 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 return 0;
1642}
1643EXPORT_SYMBOL(cpufreq_get_policy);
1644
1645
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001646/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301647 * data : current policy.
1648 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001649 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301650static int __cpufreq_set_policy(struct cpufreq_policy *data,
1651 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652{
1653 int ret = 0;
1654
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001655 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 policy->min, policy->max);
1657
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301658 memcpy(&policy->cpuinfo, &data->cpuinfo,
1659 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
Yi Yang53391fa2008-01-30 13:33:34 +01001661 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001662 ret = -EINVAL;
1663 goto error_out;
1664 }
1665
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 /* verify the cpu speed can be set within this limit */
1667 ret = cpufreq_driver->verify(policy);
1668 if (ret)
1669 goto error_out;
1670
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001672 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1673 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
1675 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001676 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1677 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678
1679 /* verify the cpu speed can be set within this limit,
1680 which might be different to the first one */
1681 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001682 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
1685 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001686 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1687 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
Dave Jones7d5e3502006-02-02 17:03:42 -05001689 data->min = policy->min;
1690 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001692 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301693 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694
1695 if (cpufreq_driver->setpolicy) {
1696 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001697 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 ret = cpufreq_driver->setpolicy(policy);
1699 } else {
1700 if (policy->governor != data->governor) {
1701 /* save old, working values */
1702 struct cpufreq_governor *old_gov = data->governor;
1703
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001704 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705
1706 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001707 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1709
1710 /* start new governor */
1711 data->governor = policy->governor;
1712 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1713 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001714 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301715 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 if (old_gov) {
1717 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301718 __cpufreq_governor(data,
1719 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 }
1721 ret = -EINVAL;
1722 goto error_out;
1723 }
1724 /* might be a policy change, too, so fall through */
1725 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001726 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1728 }
1729
Dave Jones7d5e3502006-02-02 17:03:42 -05001730error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 return ret;
1732}
1733
1734/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1736 * @cpu: CPU which shall be re-evaluated
1737 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001738 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 * at different times.
1740 */
1741int cpufreq_update_policy(unsigned int cpu)
1742{
1743 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1744 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001745 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746
Julia Lawallf1829e42008-07-25 22:44:53 +02001747 if (!data) {
1748 ret = -ENODEV;
1749 goto no_policy;
1750 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751
Julia Lawallf1829e42008-07-25 22:44:53 +02001752 if (unlikely(lock_policy_rwsem_write(cpu))) {
1753 ret = -EINVAL;
1754 goto fail;
1755 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001757 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001758 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759 policy.min = data->user_policy.min;
1760 policy.max = data->user_policy.max;
1761 policy.policy = data->user_policy.policy;
1762 policy.governor = data->user_policy.governor;
1763
Thomas Renninger0961dd02006-01-26 18:46:33 +01001764 /* BIOS might change freq behind our back
1765 -> ask driver for current freq and notify governors about a change */
1766 if (cpufreq_driver->get) {
1767 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001768 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001769 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001770 data->cur = policy.cur;
1771 } else {
1772 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301773 cpufreq_out_of_sync(cpu, data->cur,
1774 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001775 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001776 }
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 ret = __cpufreq_set_policy(data, &policy);
1779
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001780 unlock_policy_rwsem_write(cpu);
1781
Julia Lawallf1829e42008-07-25 22:44:53 +02001782fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001784no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 return ret;
1786}
1787EXPORT_SYMBOL(cpufreq_update_policy);
1788
Satyam Sharmadd184a02007-10-02 13:28:14 -07001789static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001790 unsigned long action, void *hcpu)
1791{
1792 unsigned int cpu = (unsigned long)hcpu;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001793 struct sys_device *sys_dev;
1794
1795 sys_dev = get_cpu_sysdev(cpu);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001796 if (sys_dev) {
1797 switch (action) {
1798 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001799 case CPU_ONLINE_FROZEN:
Ashok Rajc32b6b82005-10-30 14:59:54 -08001800 cpufreq_add_dev(sys_dev);
1801 break;
1802 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001803 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001804 if (unlikely(lock_policy_rwsem_write(cpu)))
1805 BUG();
1806
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001807 __cpufreq_remove_dev(sys_dev);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001808 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001809 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001810 case CPU_DOWN_FAILED_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001811 cpufreq_add_dev(sys_dev);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001812 break;
1813 }
1814 }
1815 return NOTIFY_OK;
1816}
1817
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001818static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001819 .notifier_call = cpufreq_cpu_callback,
1820};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
1822/*********************************************************************
1823 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1824 *********************************************************************/
1825
1826/**
1827 * cpufreq_register_driver - register a CPU Frequency driver
1828 * @driver_data: A struct cpufreq_driver containing the values#
1829 * submitted by the CPU Frequency driver.
1830 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001831 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001833 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 *
1835 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001836int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837{
1838 unsigned long flags;
1839 int ret;
1840
1841 if (!driver_data || !driver_data->verify || !driver_data->init ||
1842 ((!driver_data->setpolicy) && (!driver_data->target)))
1843 return -EINVAL;
1844
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001845 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
1847 if (driver_data->setpolicy)
1848 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1849
1850 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1851 if (cpufreq_driver) {
1852 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1853 return -EBUSY;
1854 }
1855 cpufreq_driver = driver_data;
1856 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1857
Mike Travis7a6aedf2008-03-25 15:06:53 -07001858 ret = sysdev_driver_register(&cpu_sysdev_class,
1859 &cpufreq_sysdev_driver);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001860 if (ret)
1861 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001863 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 int i;
1865 ret = -ENODEV;
1866
1867 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001868 for (i = 0; i < nr_cpu_ids; i++)
1869 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001871 break;
1872 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 /* if all ->init() calls failed, unregister */
1875 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001876 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301877 driver_data->name);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001878 goto err_sysdev_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879 }
1880 }
1881
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001882 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001883 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001885 return 0;
1886err_sysdev_unreg:
1887 sysdev_driver_unregister(&cpu_sysdev_class,
1888 &cpufreq_sysdev_driver);
1889err_null_driver:
1890 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1891 cpufreq_driver = NULL;
1892 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001893 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894}
1895EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1896
1897
1898/**
1899 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1900 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001901 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 * the right to do so, i.e. if you have succeeded in initialising before!
1903 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1904 * currently not initialised.
1905 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001906int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907{
1908 unsigned long flags;
1909
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001910 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001913 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
1915 sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001916 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917
1918 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1919 cpufreq_driver = NULL;
1920 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1921
1922 return 0;
1923}
1924EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001925
1926static int __init cpufreq_core_init(void)
1927{
1928 int cpu;
1929
1930 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001931 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001932 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1933 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001934
1935 cpufreq_global_kobject = kobject_create_and_add("cpufreq",
1936 &cpu_sysdev_class.kset.kobj);
1937 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001938 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001939
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001940 return 0;
1941}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001942core_initcall(cpufreq_core_init);