blob: 473b0ef8d9e0e6234f312e84ecbfd7a4075c1037 [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
Amar Singhal37d0b022012-05-25 14:40:05 -0700478 sysfs_notify(&policy->kobj, NULL, "scaling_governor");
479
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530480 if (ret)
481 return ret;
482 else
483 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484}
485
486/**
487 * show_scaling_driver - show the cpufreq driver currently loaded
488 */
Dave Jones905d77c2008-03-05 14:28:32 -0500489static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490{
491 return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
492}
493
494/**
495 * show_scaling_available_governors - show the available CPUfreq governors
496 */
Dave Jones905d77c2008-03-05 14:28:32 -0500497static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
498 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499{
500 ssize_t i = 0;
501 struct cpufreq_governor *t;
502
503 if (!cpufreq_driver->target) {
504 i += sprintf(buf, "performance powersave");
505 goto out;
506 }
507
508 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500509 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
510 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 goto out;
512 i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
513 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500514out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 i += sprintf(&buf[i], "\n");
516 return i;
517}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700518
Rusty Russell835481d2009-01-04 05:18:06 -0800519static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520{
521 ssize_t i = 0;
522 unsigned int cpu;
523
Rusty Russell835481d2009-01-04 05:18:06 -0800524 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 if (i)
526 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
527 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
528 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500529 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 }
531 i += sprintf(&buf[i], "\n");
532 return i;
533}
534
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700535/**
536 * show_related_cpus - show the CPUs affected by each transition even if
537 * hw coordination is in use
538 */
539static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
540{
Rusty Russell835481d2009-01-04 05:18:06 -0800541 if (cpumask_empty(policy->related_cpus))
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700542 return show_cpus(policy->cpus, buf);
543 return show_cpus(policy->related_cpus, buf);
544}
545
546/**
547 * show_affected_cpus - show the CPUs affected by each transition
548 */
549static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
550{
551 return show_cpus(policy->cpus, buf);
552}
553
Venki Pallipadi9e769882007-10-26 10:18:21 -0700554static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500555 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700556{
557 unsigned int freq = 0;
558 unsigned int ret;
559
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700560 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700561 return -EINVAL;
562
563 ret = sscanf(buf, "%u", &freq);
564 if (ret != 1)
565 return -EINVAL;
566
567 policy->governor->store_setspeed(policy, freq);
568
569 return count;
570}
571
572static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
573{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700574 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700575 return sprintf(buf, "<unsupported>\n");
576
577 return policy->governor->show_setspeed(policy, buf);
578}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
Thomas Renningere2f74f32009-11-19 12:31:01 +0100580/**
581 * show_scaling_driver - show the current cpufreq HW/BIOS limitation
582 */
583static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
584{
585 unsigned int limit;
586 int ret;
587 if (cpufreq_driver->bios_limit) {
588 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
589 if (!ret)
590 return sprintf(buf, "%u\n", limit);
591 }
592 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
593}
594
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200595cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
596cpufreq_freq_attr_ro(cpuinfo_min_freq);
597cpufreq_freq_attr_ro(cpuinfo_max_freq);
598cpufreq_freq_attr_ro(cpuinfo_transition_latency);
599cpufreq_freq_attr_ro(scaling_available_governors);
600cpufreq_freq_attr_ro(scaling_driver);
601cpufreq_freq_attr_ro(scaling_cur_freq);
602cpufreq_freq_attr_ro(bios_limit);
603cpufreq_freq_attr_ro(related_cpus);
604cpufreq_freq_attr_ro(affected_cpus);
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800605cpufreq_freq_attr_ro(cpu_utilization);
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200606cpufreq_freq_attr_rw(scaling_min_freq);
607cpufreq_freq_attr_rw(scaling_max_freq);
608cpufreq_freq_attr_rw(scaling_governor);
609cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Dave Jones905d77c2008-03-05 14:28:32 -0500611static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 &cpuinfo_min_freq.attr,
613 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100614 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 &scaling_min_freq.attr,
616 &scaling_max_freq.attr,
617 &affected_cpus.attr,
Anitha Anandcbeef6a2012-03-05 18:10:52 -0800618 &cpu_utilization.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700619 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 &scaling_governor.attr,
621 &scaling_driver.attr,
622 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700623 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 NULL
625};
626
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200627struct kobject *cpufreq_global_kobject;
628EXPORT_SYMBOL(cpufreq_global_kobject);
629
Dave Jones29464f22009-01-18 01:37:11 -0500630#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
631#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632
Dave Jones29464f22009-01-18 01:37:11 -0500633static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
Dave Jones905d77c2008-03-05 14:28:32 -0500635 struct cpufreq_policy *policy = to_policy(kobj);
636 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500637 ssize_t ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 policy = cpufreq_cpu_get(policy->cpu);
639 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500640 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800641
642 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500643 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800644
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530645 if (fattr->show)
646 ret = fattr->show(policy, buf);
647 else
648 ret = -EIO;
649
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800650 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500651fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 cpufreq_cpu_put(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500653no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 return ret;
655}
656
Dave Jones905d77c2008-03-05 14:28:32 -0500657static ssize_t store(struct kobject *kobj, struct attribute *attr,
658 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659{
Dave Jones905d77c2008-03-05 14:28:32 -0500660 struct cpufreq_policy *policy = to_policy(kobj);
661 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500662 ssize_t ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 policy = cpufreq_cpu_get(policy->cpu);
664 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500665 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800666
667 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500668 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800669
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530670 if (fattr->store)
671 ret = fattr->store(policy, buf, count);
672 else
673 ret = -EIO;
674
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800675 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500676fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 cpufreq_cpu_put(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500678no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 return ret;
680}
681
Dave Jones905d77c2008-03-05 14:28:32 -0500682static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683{
Dave Jones905d77c2008-03-05 14:28:32 -0500684 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200685 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 complete(&policy->kobj_unregister);
687}
688
Emese Revfy52cf25d2010-01-19 02:58:23 +0100689static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 .show = show,
691 .store = store,
692};
693
694static struct kobj_type ktype_cpufreq = {
695 .sysfs_ops = &sysfs_ops,
696 .default_attrs = default_attrs,
697 .release = cpufreq_sysfs_release,
698};
699
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200700/*
701 * Returns:
702 * Negative: Failure
703 * 0: Success
704 * Positive: When we have a managed CPU and the sysfs got symlinked
705 */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700706static int cpufreq_add_dev_policy(unsigned int cpu,
707 struct cpufreq_policy *policy,
708 struct sys_device *sys_dev)
Dave Jonesecf7e462009-07-08 18:48:47 -0400709{
710 int ret = 0;
711#ifdef CONFIG_SMP
712 unsigned long flags;
713 unsigned int j;
Dave Jonesecf7e462009-07-08 18:48:47 -0400714#ifdef CONFIG_HOTPLUG_CPU
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400715 struct cpufreq_governor *gov;
716
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700717 gov = __find_governor(per_cpu(cpufreq_policy_save, cpu).gov);
Dmitry Monakhove77b89f2009-10-05 00:38:55 +0400718 if (gov) {
719 policy->governor = gov;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200720 pr_debug("Restoring governor %s for cpu %d\n",
Dave Jonesecf7e462009-07-08 18:48:47 -0400721 policy->governor->name, cpu);
722 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700723 if (per_cpu(cpufreq_policy_save, cpu).min) {
724 policy->min = per_cpu(cpufreq_policy_save, cpu).min;
725 policy->user_policy.min = policy->min;
726 }
727 if (per_cpu(cpufreq_policy_save, cpu).max) {
728 policy->max = per_cpu(cpufreq_policy_save, cpu).max;
729 policy->user_policy.max = policy->max;
730 }
731 pr_debug("Restoring CPU%d min %d and max %d\n",
732 cpu, policy->min, policy->max);
Dave Jonesecf7e462009-07-08 18:48:47 -0400733#endif
734
735 for_each_cpu(j, policy->cpus) {
736 struct cpufreq_policy *managed_policy;
737
738 if (cpu == j)
739 continue;
740
741 /* Check for existing affected CPUs.
742 * They may not be aware of it due to CPU Hotplug.
743 * cpufreq_cpu_put is called when the device is removed
744 * in __cpufreq_remove_dev()
745 */
746 managed_policy = cpufreq_cpu_get(j);
747 if (unlikely(managed_policy)) {
748
749 /* Set proper policy_cpu */
750 unlock_policy_rwsem_write(cpu);
Tejun Heof1625062009-10-29 22:34:13 +0900751 per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu;
Dave Jonesecf7e462009-07-08 18:48:47 -0400752
753 if (lock_policy_rwsem_write(cpu) < 0) {
754 /* Should not go through policy unlock path */
755 if (cpufreq_driver->exit)
756 cpufreq_driver->exit(policy);
757 cpufreq_cpu_put(managed_policy);
758 return -EBUSY;
759 }
760
761 spin_lock_irqsave(&cpufreq_driver_lock, flags);
762 cpumask_copy(managed_policy->cpus, policy->cpus);
763 per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
764 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
765
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200766 pr_debug("CPU already managed, adding link\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400767 ret = sysfs_create_link(&sys_dev->kobj,
768 &managed_policy->kobj,
769 "cpufreq");
770 if (ret)
771 cpufreq_cpu_put(managed_policy);
772 /*
773 * Success. We only needed to be added to the mask.
774 * Call driver->exit() because only the cpu parent of
775 * the kobj needed to call init().
776 */
777 if (cpufreq_driver->exit)
778 cpufreq_driver->exit(policy);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200779
780 if (!ret)
781 return 1;
782 else
783 return ret;
Dave Jonesecf7e462009-07-08 18:48:47 -0400784 }
785 }
786#endif
787 return ret;
788}
789
790
Dave Jones19d6f7e2009-07-08 17:35:39 -0400791/* symlink affected CPUs */
Alex Chiangcf3289d2009-11-17 20:27:08 -0700792static int cpufreq_add_dev_symlink(unsigned int cpu,
793 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400794{
795 unsigned int j;
796 int ret = 0;
797
798 for_each_cpu(j, policy->cpus) {
799 struct cpufreq_policy *managed_policy;
800 struct sys_device *cpu_sys_dev;
801
802 if (j == cpu)
803 continue;
804 if (!cpu_online(j))
805 continue;
806
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200807 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400808 managed_policy = cpufreq_cpu_get(cpu);
809 cpu_sys_dev = get_cpu_sysdev(j);
810 ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
811 "cpufreq");
812 if (ret) {
813 cpufreq_cpu_put(managed_policy);
814 return ret;
815 }
816 }
817 return ret;
818}
819
Alex Chiangcf3289d2009-11-17 20:27:08 -0700820static int cpufreq_add_dev_interface(unsigned int cpu,
821 struct cpufreq_policy *policy,
822 struct sys_device *sys_dev)
Dave Jones909a6942009-07-08 18:05:42 -0400823{
Dave Jonesecf7e462009-07-08 18:48:47 -0400824 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400825 struct freq_attr **drv_attr;
826 unsigned long flags;
827 int ret = 0;
828 unsigned int j;
829
830 /* prepare interface data */
831 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
832 &sys_dev->kobj, "cpufreq");
833 if (ret)
834 return ret;
835
836 /* set up files for this cpu device */
837 drv_attr = cpufreq_driver->attr;
838 while ((drv_attr) && (*drv_attr)) {
839 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
840 if (ret)
841 goto err_out_kobj_put;
842 drv_attr++;
843 }
844 if (cpufreq_driver->get) {
845 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
846 if (ret)
847 goto err_out_kobj_put;
848 }
849 if (cpufreq_driver->target) {
850 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
851 if (ret)
852 goto err_out_kobj_put;
853 }
Thomas Renningere2f74f32009-11-19 12:31:01 +0100854 if (cpufreq_driver->bios_limit) {
855 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
856 if (ret)
857 goto err_out_kobj_put;
858 }
Dave Jones909a6942009-07-08 18:05:42 -0400859
860 spin_lock_irqsave(&cpufreq_driver_lock, flags);
861 for_each_cpu(j, policy->cpus) {
Julia Lawallbec037a2010-08-05 22:23:00 +0200862 if (!cpu_online(j))
863 continue;
Dave Jones909a6942009-07-08 18:05:42 -0400864 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900865 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400866 }
867 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
868
869 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400870 if (ret)
871 goto err_out_kobj_put;
872
873 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
874 /* assure that the starting sequence is run in __cpufreq_set_policy */
875 policy->governor = NULL;
876
877 /* set default policy */
878 ret = __cpufreq_set_policy(policy, &new_policy);
879 policy->user_policy.policy = policy->policy;
880 policy->user_policy.governor = policy->governor;
881
882 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200883 pr_debug("setting policy failed\n");
Dave Jonesecf7e462009-07-08 18:48:47 -0400884 if (cpufreq_driver->exit)
885 cpufreq_driver->exit(policy);
886 }
Dave Jones909a6942009-07-08 18:05:42 -0400887 return ret;
888
889err_out_kobj_put:
890 kobject_put(&policy->kobj);
891 wait_for_completion(&policy->kobj_unregister);
892 return ret;
893}
894
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
896/**
897 * cpufreq_add_dev - add a CPU device
898 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500899 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400900 *
901 * The Oracle says: try running cpufreq registration/unregistration concurrently
902 * with with cpu hotplugging and all hell will break loose. Tried to clean this
903 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 */
Dave Jones905d77c2008-03-05 14:28:32 -0500905static int cpufreq_add_dev(struct sys_device *sys_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906{
907 unsigned int cpu = sys_dev->id;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500908 int ret = 0, found = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 unsigned long flags;
911 unsigned int j;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500912#ifdef CONFIG_HOTPLUG_CPU
913 int sibling;
914#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915
Ashok Rajc32b6b82005-10-30 14:59:54 -0800916 if (cpu_is_offline(cpu))
917 return 0;
918
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200919 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920
921#ifdef CONFIG_SMP
922 /* check whether a different CPU already registered this
923 * CPU because it is in the same boat. */
924 policy = cpufreq_cpu_get(cpu);
925 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500926 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 return 0;
928 }
929#endif
930
931 if (!try_module_get(cpufreq_driver->owner)) {
932 ret = -EINVAL;
933 goto module_out;
934 }
935
Dave Jones059019a2009-07-08 16:30:03 -0400936 ret = -ENOMEM;
Dave Jonese98df502005-10-20 15:17:43 -0700937 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400938 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400940
941 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400942 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400943
944 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400945 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946
947 policy->cpu = cpu;
Rusty Russell835481d2009-01-04 05:18:06 -0800948 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800950 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900951 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400952 ret = (lock_policy_rwsem_write(cpu) < 0);
953 WARN_ON(ret);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800954
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000956 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957
Thomas Renninger8122c6c2007-10-02 13:28:09 -0700958 /* Set governor before ->init, so that driver could check it */
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500959#ifdef CONFIG_HOTPLUG_CPU
960 for_each_online_cpu(sibling) {
961 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
962 if (cp && cp->governor &&
963 (cpumask_test_cpu(cpu, cp->related_cpus))) {
964 policy->governor = cp->governor;
965 found = 1;
966 break;
967 }
968 }
969#endif
970 if (!found)
971 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 /* call driver. From then on the cpufreq must be able
973 * to accept all calls to ->verify and ->setpolicy for this CPU
974 */
975 ret = cpufreq_driver->init(policy);
976 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200977 pr_debug("initialization failed\n");
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400978 goto err_unlock_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 }
Mike Chan187d9f42008-12-04 12:19:17 -0800980 policy->user_policy.min = policy->min;
981 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982
Thomas Renningera1531ac2008-07-29 22:32:58 -0700983 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
984 CPUFREQ_START, policy);
985
Dave Jonesecf7e462009-07-08 18:48:47 -0400986 ret = cpufreq_add_dev_policy(cpu, policy, sys_dev);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200987 if (ret) {
988 if (ret > 0)
989 /* This is a managed cpu, symlink created,
990 exit with 0 */
991 ret = 0;
Dave Jonesecf7e462009-07-08 18:48:47 -0400992 goto err_unlock_policy;
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200993 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994
Dave Jones909a6942009-07-08 18:05:42 -0400995 ret = cpufreq_add_dev_interface(cpu, policy, sys_dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400996 if (ret)
997 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -0500998
Lothar Waßmanndca02612008-05-29 17:54:52 +0200999 unlock_policy_rwsem_write(cpu);
1000
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001001 kobject_uevent(&policy->kobj, KOBJ_ADD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001003 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001004
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 return 0;
1006
1007
1008err_out_unregister:
1009 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001010 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001011 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1013
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001014 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 wait_for_completion(&policy->kobj_unregister);
1016
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001017err_unlock_policy:
Dave Jones45709112008-03-05 14:07:34 -05001018 unlock_policy_rwsem_write(cpu);
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001019 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001020err_free_cpumask:
1021 free_cpumask_var(policy->cpus);
1022err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024nomem_out:
1025 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001026module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 return ret;
1028}
1029
1030
1031/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001032 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 *
1034 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001035 * Caller should already have policy_rwsem in write mode for this CPU.
1036 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 */
Dave Jones905d77c2008-03-05 14:28:32 -05001038static int __cpufreq_remove_dev(struct sys_device *sys_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039{
1040 unsigned int cpu = sys_dev->id;
1041 unsigned long flags;
1042 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001043 struct kobject *kobj;
1044 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045#ifdef CONFIG_SMP
Grant Coadye738cf62005-11-21 21:32:28 -08001046 struct sys_device *cpu_sys_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 unsigned int j;
1048#endif
1049
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001050 pr_debug("unregistering CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
1052 spin_lock_irqsave(&cpufreq_driver_lock, flags);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001053 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
1055 if (!data) {
1056 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001057 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 return -EINVAL;
1059 }
Mike Travis7a6aedf2008-03-25 15:06:53 -07001060 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061
1062
1063#ifdef CONFIG_SMP
1064 /* if this isn't the CPU which is the parent of the kobj, we
Dave Jones32ee8c32006-02-28 00:43:23 -05001065 * only need to unlink, put and exit
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 */
1067 if (unlikely(cpu != data->cpu)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001068 pr_debug("removing link\n");
Rusty Russell835481d2009-01-04 05:18:06 -08001069 cpumask_clear_cpu(cpu, data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Amerigo Wang499bca92010-03-04 03:23:46 -05001071 kobj = &sys_dev->kobj;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 cpufreq_cpu_put(data);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001073 unlock_policy_rwsem_write(cpu);
Amerigo Wang499bca92010-03-04 03:23:46 -05001074 sysfs_remove_link(kobj, "cpufreq");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 return 0;
1076 }
1077#endif
1078
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079#ifdef CONFIG_SMP
Thomas Renninger084f3492007-07-09 11:35:28 -07001080
1081#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001082 strncpy(per_cpu(cpufreq_policy_save, cpu).gov, data->governor->name,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001083 CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001084 per_cpu(cpufreq_policy_save, cpu).min = data->min;
1085 per_cpu(cpufreq_policy_save, cpu).max = data->max;
1086 pr_debug("Saving CPU%d policy min %d and max %d\n",
1087 cpu, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001088#endif
1089
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 /* if we have other CPUs still registered, we need to unlink them,
1091 * or else wait_for_completion below will lock up. Clean the
Mike Travis7a6aedf2008-03-25 15:06:53 -07001092 * per_cpu(cpufreq_cpu_data) while holding the lock, and remove
1093 * the sysfs links afterwards.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 */
Rusty Russell835481d2009-01-04 05:18:06 -08001095 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1096 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 if (j == cpu)
1098 continue;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001099 per_cpu(cpufreq_cpu_data, j) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 }
1101 }
1102
1103 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1104
Rusty Russell835481d2009-01-04 05:18:06 -08001105 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1106 for_each_cpu(j, data->cpus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 if (j == cpu)
1108 continue;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001109 pr_debug("removing link for cpu %u\n", j);
Thomas Renninger084f3492007-07-09 11:35:28 -07001110#ifdef CONFIG_HOTPLUG_CPU
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001111 strncpy(per_cpu(cpufreq_policy_save, j).gov,
Dmitry Monakhove77b89f2009-10-05 00:38:55 +04001112 data->governor->name, CPUFREQ_NAME_LEN);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001113 per_cpu(cpufreq_policy_save, j).min = data->min;
1114 per_cpu(cpufreq_policy_save, j).max = data->max;
1115 pr_debug("Saving CPU%d policy min %d and max %d\n",
1116 j, data->min, data->max);
Thomas Renninger084f3492007-07-09 11:35:28 -07001117#endif
Ashok Rajd434fca2005-10-30 14:59:52 -08001118 cpu_sys_dev = get_cpu_sysdev(j);
Amerigo Wang499bca92010-03-04 03:23:46 -05001119 kobj = &cpu_sys_dev->kobj;
1120 unlock_policy_rwsem_write(cpu);
1121 sysfs_remove_link(kobj, "cpufreq");
1122 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 cpufreq_cpu_put(data);
1124 }
1125 }
1126#else
1127 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1128#endif
1129
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130 if (cpufreq_driver->target)
1131 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001132
Amerigo Wang499bca92010-03-04 03:23:46 -05001133 kobj = &data->kobj;
1134 cmp = &data->kobj_unregister;
1135 unlock_policy_rwsem_write(cpu);
1136 kobject_put(kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
1138 /* we need to make sure that the underlying kobj is actually
Dave Jones32ee8c32006-02-28 00:43:23 -05001139 * not referenced anymore by anybody before we proceed with
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 * unloading.
1141 */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001142 pr_debug("waiting for dropping of refcount\n");
Amerigo Wang499bca92010-03-04 03:23:46 -05001143 wait_for_completion(cmp);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001144 pr_debug("wait complete\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145
Amerigo Wang499bca92010-03-04 03:23:46 -05001146 lock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147 if (cpufreq_driver->exit)
1148 cpufreq_driver->exit(data);
venkatesh.pallipadi@intel.com7d26e2d2009-07-02 17:08:30 -07001149 unlock_policy_rwsem_write(cpu);
1150
Jacob Shin27ecddc2011-04-27 13:32:11 -05001151#ifdef CONFIG_HOTPLUG_CPU
1152 /* when the CPU which is the parent of the kobj is hotplugged
1153 * offline, check for siblings, and create cpufreq sysfs interface
1154 * and symlinks
1155 */
1156 if (unlikely(cpumask_weight(data->cpus) > 1)) {
1157 /* first sibling now owns the new sysfs dir */
1158 cpumask_clear_cpu(cpu, data->cpus);
1159 cpufreq_add_dev(get_cpu_sysdev(cpumask_first(data->cpus)));
1160
1161 /* finally remove our own symlink */
1162 lock_policy_rwsem_write(cpu);
1163 __cpufreq_remove_dev(sys_dev);
1164 }
1165#endif
1166
Rusty Russell835481d2009-01-04 05:18:06 -08001167 free_cpumask_var(data->related_cpus);
1168 free_cpumask_var(data->cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 kfree(data);
1170
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 return 0;
1172}
1173
1174
Dave Jones905d77c2008-03-05 14:28:32 -05001175static int cpufreq_remove_dev(struct sys_device *sys_dev)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001176{
1177 unsigned int cpu = sys_dev->id;
1178 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001179
1180 if (cpu_is_offline(cpu))
1181 return 0;
1182
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001183 if (unlikely(lock_policy_rwsem_write(cpu)))
1184 BUG();
1185
1186 retval = __cpufreq_remove_dev(sys_dev);
1187 return retval;
1188}
1189
1190
David Howells65f27f32006-11-22 14:55:48 +00001191static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192{
David Howells65f27f32006-11-22 14:55:48 +00001193 struct cpufreq_policy *policy =
1194 container_of(work, struct cpufreq_policy, update);
1195 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001196 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 cpufreq_update_policy(cpu);
1198}
1199
1200/**
1201 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1202 * @cpu: cpu number
1203 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1204 * @new_freq: CPU frequency the CPU actually runs at
1205 *
Dave Jones29464f22009-01-18 01:37:11 -05001206 * We adjust to current frequency first, and need to clean up later.
1207 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301209static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1210 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211{
1212 struct cpufreq_freqs freqs;
1213
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001214 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1216
1217 freqs.cpu = cpu;
1218 freqs.old = old_freq;
1219 freqs.new = new_freq;
1220 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1221 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1222}
1223
1224
Dave Jones32ee8c32006-02-28 00:43:23 -05001225/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301226 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001227 * @cpu: CPU number
1228 *
1229 * This is the last known freq, without actually getting it from the driver.
1230 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1231 */
1232unsigned int cpufreq_quick_get(unsigned int cpu)
1233{
1234 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301235 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001236
1237 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301238 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001239 cpufreq_cpu_put(policy);
1240 }
1241
Dave Jones4d34a672008-02-07 16:33:49 -05001242 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001243}
1244EXPORT_SYMBOL(cpufreq_quick_get);
1245
1246
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001247static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001249 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301250 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001253 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301255 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301257 if (ret_freq && policy->cur &&
1258 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1259 /* verify no discrepancy between actual and
1260 saved value exists */
1261 if (unlikely(ret_freq != policy->cur)) {
1262 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 schedule_work(&policy->update);
1264 }
1265 }
1266
Dave Jones4d34a672008-02-07 16:33:49 -05001267 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001268}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001270/**
1271 * cpufreq_get - get the current CPU frequency (in kHz)
1272 * @cpu: CPU number
1273 *
1274 * Get the CPU current (static) CPU frequency
1275 */
1276unsigned int cpufreq_get(unsigned int cpu)
1277{
1278 unsigned int ret_freq = 0;
1279 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1280
1281 if (!policy)
1282 goto out;
1283
1284 if (unlikely(lock_policy_rwsem_read(cpu)))
1285 goto out_policy;
1286
1287 ret_freq = __cpufreq_get(cpu);
1288
1289 unlock_policy_rwsem_read(cpu);
1290
1291out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001293out:
Dave Jones4d34a672008-02-07 16:33:49 -05001294 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295}
1296EXPORT_SYMBOL(cpufreq_get);
1297
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001298static struct sysdev_driver cpufreq_sysdev_driver = {
1299 .add = cpufreq_add_dev,
1300 .remove = cpufreq_remove_dev,
1301};
1302
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303
1304/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001305 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1306 *
1307 * This function is only executed for the boot processor. The other CPUs
1308 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001309 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001310static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001311{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301312 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001313
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001314 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001315 struct cpufreq_policy *cpu_policy;
1316
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001317 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001318
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001319 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001320 cpu_policy = cpufreq_cpu_get(cpu);
1321 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001322 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001323
1324 if (cpufreq_driver->suspend) {
Rafael J. Wysocki7ca64e22011-03-10 21:13:05 +01001325 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001326 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001327 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1328 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001329 }
1330
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001331 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001332 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001333}
1334
1335/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001336 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 *
1338 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001339 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1340 * restored. It will verify that the current freq is in sync with
1341 * what we believe it to be. This is a bit later than when it
1342 * should be, but nonethteless it's better than calling
1343 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001344 *
1345 * This function is only executed for the boot CPU. The other CPUs have not
1346 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001348static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301350 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001351
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001352 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 struct cpufreq_policy *cpu_policy;
1354
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001355 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001357 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 cpu_policy = cpufreq_cpu_get(cpu);
1359 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001360 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
1362 if (cpufreq_driver->resume) {
1363 ret = cpufreq_driver->resume(cpu_policy);
1364 if (ret) {
1365 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1366 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001367 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 }
1369 }
1370
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001372
Dave Jonesc9060492008-02-07 16:32:18 -05001373fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375}
1376
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001377static struct syscore_ops cpufreq_syscore_ops = {
1378 .suspend = cpufreq_bp_suspend,
1379 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380};
1381
1382
1383/*********************************************************************
1384 * NOTIFIER LISTS INTERFACE *
1385 *********************************************************************/
1386
1387/**
1388 * cpufreq_register_notifier - register a driver with cpufreq
1389 * @nb: notifier function to register
1390 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1391 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001392 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 * are notified about clock rate changes (once before and once after
1394 * the transition), or a list of drivers that are notified about
1395 * changes in cpufreq policy.
1396 *
1397 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001398 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 */
1400int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1401{
1402 int ret;
1403
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001404 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1405
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 switch (list) {
1407 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001408 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001409 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 break;
1411 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001412 ret = blocking_notifier_chain_register(
1413 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 break;
1415 default:
1416 ret = -EINVAL;
1417 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
1419 return ret;
1420}
1421EXPORT_SYMBOL(cpufreq_register_notifier);
1422
1423
1424/**
1425 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1426 * @nb: notifier block to be unregistered
1427 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1428 *
1429 * Remove a driver from the CPU frequency notifier list.
1430 *
1431 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001432 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 */
1434int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1435{
1436 int ret;
1437
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 switch (list) {
1439 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001440 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001441 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 break;
1443 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001444 ret = blocking_notifier_chain_unregister(
1445 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 break;
1447 default:
1448 ret = -EINVAL;
1449 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450
1451 return ret;
1452}
1453EXPORT_SYMBOL(cpufreq_unregister_notifier);
1454
1455
1456/*********************************************************************
1457 * GOVERNORS *
1458 *********************************************************************/
1459
1460
1461int __cpufreq_driver_target(struct cpufreq_policy *policy,
1462 unsigned int target_freq,
1463 unsigned int relation)
1464{
1465 int retval = -EINVAL;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001466
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001467 pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 target_freq, relation);
1469 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1470 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001471
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 return retval;
1473}
1474EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1475
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476int cpufreq_driver_target(struct cpufreq_policy *policy,
1477 unsigned int target_freq,
1478 unsigned int relation)
1479{
Julia Lawallf1829e42008-07-25 22:44:53 +02001480 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
1482 policy = cpufreq_cpu_get(policy->cpu);
1483 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001484 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001486 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001487 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488
1489 ret = __cpufreq_driver_target(policy, target_freq, relation);
1490
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001491 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
Julia Lawallf1829e42008-07-25 22:44:53 +02001493fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001495no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 return ret;
1497}
1498EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1499
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001500int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001501{
1502 int ret = 0;
1503
1504 policy = cpufreq_cpu_get(policy->cpu);
1505 if (!policy)
1506 return -EINVAL;
1507
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001508 if (cpu_online(cpu) && cpufreq_driver->getavg)
1509 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001510
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001511 cpufreq_cpu_put(policy);
1512 return ret;
1513}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001514EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001515
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001516/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001517 * when "event" is CPUFREQ_GOV_LIMITS
1518 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301520static int __cpufreq_governor(struct cpufreq_policy *policy,
1521 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522{
Dave Jonescc993ca2005-07-28 09:43:56 -07001523 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001524
1525 /* Only must be defined when default governor is known to have latency
1526 restrictions, like e.g. conservative or ondemand.
1527 That this is the case is already ensured in Kconfig
1528 */
1529#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1530 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1531#else
1532 struct cpufreq_governor *gov = NULL;
1533#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001534
1535 if (policy->governor->max_transition_latency &&
1536 policy->cpuinfo.transition_latency >
1537 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001538 if (!gov)
1539 return -EINVAL;
1540 else {
1541 printk(KERN_WARNING "%s governor failed, too long"
1542 " transition latency of HW, fallback"
1543 " to %s governor\n",
1544 policy->governor->name,
1545 gov->name);
1546 policy->governor = gov;
1547 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001548 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
1550 if (!try_module_get(policy->governor->owner))
1551 return -EINVAL;
1552
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001553 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301554 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 ret = policy->governor->governor(policy, event);
1556
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301557 /* we keep one module reference alive for
1558 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 if ((event != CPUFREQ_GOV_START) || ret)
1560 module_put(policy->governor->owner);
1561 if ((event == CPUFREQ_GOV_STOP) && !ret)
1562 module_put(policy->governor->owner);
1563
1564 return ret;
1565}
1566
1567
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568int cpufreq_register_governor(struct cpufreq_governor *governor)
1569{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001570 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571
1572 if (!governor)
1573 return -EINVAL;
1574
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001575 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001576
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001577 err = -EBUSY;
1578 if (__find_governor(governor->name) == NULL) {
1579 err = 0;
1580 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582
Dave Jones32ee8c32006-02-28 00:43:23 -05001583 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001584 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585}
1586EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1587
1588
1589void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1590{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001591#ifdef CONFIG_HOTPLUG_CPU
1592 int cpu;
1593#endif
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595 if (!governor)
1596 return;
1597
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001598#ifdef CONFIG_HOTPLUG_CPU
1599 for_each_present_cpu(cpu) {
1600 if (cpu_online(cpu))
1601 continue;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001602 if (!strcmp(per_cpu(cpufreq_policy_save, cpu).gov,
1603 governor->name))
1604 strcpy(per_cpu(cpufreq_policy_save, cpu).gov, "\0");
1605 per_cpu(cpufreq_policy_save, cpu).min = 0;
1606 per_cpu(cpufreq_policy_save, cpu).max = 0;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001607 }
1608#endif
1609
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001610 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001612 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 return;
1614}
1615EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1616
1617
1618
1619/*********************************************************************
1620 * POLICY INTERFACE *
1621 *********************************************************************/
1622
1623/**
1624 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001625 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1626 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 *
1628 * Reads the current cpufreq policy.
1629 */
1630int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1631{
1632 struct cpufreq_policy *cpu_policy;
1633 if (!policy)
1634 return -EINVAL;
1635
1636 cpu_policy = cpufreq_cpu_get(cpu);
1637 if (!cpu_policy)
1638 return -EINVAL;
1639
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
1642 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 return 0;
1644}
1645EXPORT_SYMBOL(cpufreq_get_policy);
1646
1647
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001648/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301649 * data : current policy.
1650 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001651 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301652static int __cpufreq_set_policy(struct cpufreq_policy *data,
1653 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654{
1655 int ret = 0;
1656
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001657 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 policy->min, policy->max);
1659
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301660 memcpy(&policy->cpuinfo, &data->cpuinfo,
1661 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
Yi Yang53391fa2008-01-30 13:33:34 +01001663 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001664 ret = -EINVAL;
1665 goto error_out;
1666 }
1667
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 /* verify the cpu speed can be set within this limit */
1669 ret = cpufreq_driver->verify(policy);
1670 if (ret)
1671 goto error_out;
1672
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001674 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1675 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001678 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1679 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
1681 /* verify the cpu speed can be set within this limit,
1682 which might be different to the first one */
1683 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001684 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
1687 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001688 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1689 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
Dave Jones7d5e3502006-02-02 17:03:42 -05001691 data->min = policy->min;
1692 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001694 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301695 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696
1697 if (cpufreq_driver->setpolicy) {
1698 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001699 pr_debug("setting range\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 ret = cpufreq_driver->setpolicy(policy);
1701 } else {
1702 if (policy->governor != data->governor) {
1703 /* save old, working values */
1704 struct cpufreq_governor *old_gov = data->governor;
1705
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001706 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707
1708 /* end old governor */
Andrej Gelenbergffe62752010-05-14 15:15:58 -07001709 if (data->governor)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
1711
1712 /* start new governor */
1713 data->governor = policy->governor;
1714 if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1715 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001716 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301717 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 if (old_gov) {
1719 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301720 __cpufreq_governor(data,
1721 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 }
1723 ret = -EINVAL;
1724 goto error_out;
1725 }
1726 /* might be a policy change, too, so fall through */
1727 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001728 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1730 }
1731
Dave Jones7d5e3502006-02-02 17:03:42 -05001732error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 return ret;
1734}
1735
1736/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1738 * @cpu: CPU which shall be re-evaluated
1739 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001740 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 * at different times.
1742 */
1743int cpufreq_update_policy(unsigned int cpu)
1744{
1745 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1746 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001747 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748
Julia Lawallf1829e42008-07-25 22:44:53 +02001749 if (!data) {
1750 ret = -ENODEV;
1751 goto no_policy;
1752 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
Julia Lawallf1829e42008-07-25 22:44:53 +02001754 if (unlikely(lock_policy_rwsem_write(cpu))) {
1755 ret = -EINVAL;
1756 goto fail;
1757 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001759 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001760 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 policy.min = data->user_policy.min;
1762 policy.max = data->user_policy.max;
1763 policy.policy = data->user_policy.policy;
1764 policy.governor = data->user_policy.governor;
1765
Thomas Renninger0961dd02006-01-26 18:46:33 +01001766 /* BIOS might change freq behind our back
1767 -> ask driver for current freq and notify governors about a change */
1768 if (cpufreq_driver->get) {
1769 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001770 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001771 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001772 data->cur = policy.cur;
1773 } else {
1774 if (data->cur != policy.cur)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301775 cpufreq_out_of_sync(cpu, data->cur,
1776 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001777 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001778 }
1779
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 ret = __cpufreq_set_policy(data, &policy);
1781
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001782 unlock_policy_rwsem_write(cpu);
1783
Julia Lawallf1829e42008-07-25 22:44:53 +02001784fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001786no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 return ret;
1788}
1789EXPORT_SYMBOL(cpufreq_update_policy);
1790
Satyam Sharmadd184a02007-10-02 13:28:14 -07001791static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001792 unsigned long action, void *hcpu)
1793{
1794 unsigned int cpu = (unsigned long)hcpu;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001795 struct sys_device *sys_dev;
1796
1797 sys_dev = get_cpu_sysdev(cpu);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001798 if (sys_dev) {
1799 switch (action) {
1800 case CPU_ONLINE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001801 case CPU_ONLINE_FROZEN:
Ashok Rajc32b6b82005-10-30 14:59:54 -08001802 cpufreq_add_dev(sys_dev);
1803 break;
1804 case CPU_DOWN_PREPARE:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001805 case CPU_DOWN_PREPARE_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001806 if (unlikely(lock_policy_rwsem_write(cpu)))
1807 BUG();
1808
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001809 __cpufreq_remove_dev(sys_dev);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001810 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001811 case CPU_DOWN_FAILED:
Rafael J. Wysocki8bb78442007-05-09 02:35:10 -07001812 case CPU_DOWN_FAILED_FROZEN:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001813 cpufreq_add_dev(sys_dev);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001814 break;
1815 }
1816 }
1817 return NOTIFY_OK;
1818}
1819
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001820static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001821 .notifier_call = cpufreq_cpu_callback,
1822};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
1824/*********************************************************************
1825 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1826 *********************************************************************/
1827
1828/**
1829 * cpufreq_register_driver - register a CPU Frequency driver
1830 * @driver_data: A struct cpufreq_driver containing the values#
1831 * submitted by the CPU Frequency driver.
1832 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001833 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001835 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 *
1837 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001838int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839{
1840 unsigned long flags;
1841 int ret;
1842
1843 if (!driver_data || !driver_data->verify || !driver_data->init ||
1844 ((!driver_data->setpolicy) && (!driver_data->target)))
1845 return -EINVAL;
1846
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001847 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848
1849 if (driver_data->setpolicy)
1850 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1851
1852 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1853 if (cpufreq_driver) {
1854 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1855 return -EBUSY;
1856 }
1857 cpufreq_driver = driver_data;
1858 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1859
Mike Travis7a6aedf2008-03-25 15:06:53 -07001860 ret = sysdev_driver_register(&cpu_sysdev_class,
1861 &cpufreq_sysdev_driver);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001862 if (ret)
1863 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001865 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 int i;
1867 ret = -ENODEV;
1868
1869 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001870 for (i = 0; i < nr_cpu_ids; i++)
1871 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001873 break;
1874 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875
1876 /* if all ->init() calls failed, unregister */
1877 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001878 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301879 driver_data->name);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001880 goto err_sysdev_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 }
1882 }
1883
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001884 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001885 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001887 return 0;
1888err_sysdev_unreg:
1889 sysdev_driver_unregister(&cpu_sysdev_class,
1890 &cpufreq_sysdev_driver);
1891err_null_driver:
1892 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1893 cpufreq_driver = NULL;
1894 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001895 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896}
1897EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1898
1899
1900/**
1901 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1902 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001903 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 * the right to do so, i.e. if you have succeeded in initialising before!
1905 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1906 * currently not initialised.
1907 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001908int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909{
1910 unsigned long flags;
1911
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001912 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001915 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
1917 sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07001918 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919
1920 spin_lock_irqsave(&cpufreq_driver_lock, flags);
1921 cpufreq_driver = NULL;
1922 spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1923
1924 return 0;
1925}
1926EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001927
1928static int __init cpufreq_core_init(void)
1929{
1930 int cpu;
1931
1932 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09001933 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001934 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
1935 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001936
1937 cpufreq_global_kobject = kobject_create_and_add("cpufreq",
1938 &cpu_sysdev_class.kset.kobj);
1939 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001940 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02001941
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001942 return 0;
1943}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001944core_initcall(cpufreq_core_init);