blob: 43cf6083246805f1150957d93be040d5ca83530a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/cpufreq/cpufreq.c
3 *
4 * Copyright (C) 2001 Russell King
5 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08007 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05008 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -05009 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
10 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080011 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Viresh Kumar72a4ce32013-05-17 11:26:32 +000020#include <asm/cputime.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/kernel.h>
Viresh Kumar72a4ce32013-05-17 11:26:32 +000022#include <linux/kernel_stat.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/notifier.h>
26#include <linux/cpufreq.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/spinlock.h>
Viresh Kumar72a4ce32013-05-17 11:26:32 +000030#include <linux/tick.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/device.h>
32#include <linux/slab.h>
33#include <linux/cpu.h>
34#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080035#include <linux/mutex.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010036#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
Thomas Renninger6f4f2722010-04-20 13:17:36 +020038#include <trace/events/power.h>
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040/**
Dave Jonescd878472006-08-11 17:59:28 -040041 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 * level driver of CPUFreq support, and its spinlock. This lock
43 * also protects the cpufreq_cpu_data array.
44 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +020045static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070046static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070047#ifdef CONFIG_HOTPLUG_CPU
48/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040049static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070050#endif
Nathan Zimmer0d1857a2013-02-22 16:24:34 +000051static DEFINE_RWLOCK(cpufreq_driver_lock);
Xiaoguang Chen95731eb2013-06-19 15:00:07 +080052static DEFINE_MUTEX(cpufreq_governor_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080054/*
55 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
56 * all cpufreq/hotplug/workqueue/etc related lock issues.
57 *
58 * The rules for this semaphore:
59 * - Any routine that wants to read from the policy structure will
60 * do a down_read on this semaphore.
61 * - Any routine that will write to the policy structure and/or may take away
62 * the policy altogether (eg. CPU hotplug), will hold this lock in write
63 * mode before doing so.
64 *
65 * Additional rules:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080066 * - 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) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053075static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076{ \
Tejun Heof1625062009-10-29 22:34:13 +090077 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080078 BUG_ON(policy_cpu == -1); \
79 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080080 \
81 return 0; \
82}
83
84lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080085lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080086
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053087#define unlock_policy_rwsem(mode, cpu) \
88static void unlock_policy_rwsem_##mode(int cpu) \
89{ \
90 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
91 BUG_ON(policy_cpu == -1); \
92 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080094
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053095unlock_policy_rwsem(read, cpu);
96unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097
Linus Torvalds1da177e2005-04-16 15:20:36 -070098/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -050099static int __cpufreq_governor(struct cpufreq_policy *policy,
100 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800101static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000102static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500105 * Two notifier lists: the "policy" list is involved in the
106 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 * "transition" list for kernel code that needs to handle
108 * changes to devices when the CPU clock speed changes.
109 * The mutex locks both lists.
110 */
Alan Sterne041c682006-03-27 01:16:30 -0800111static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700112static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200114static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700115static int __init init_cpufreq_transition_notifier_list(void)
116{
117 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200118 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700119 return 0;
120}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800121pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400123static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200124static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400125{
126 return off;
127}
128void disable_cpufreq(void)
129{
130 off = 1;
131}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500133static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000135bool have_governor_per_policy(void)
136{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200137 return cpufreq_driver->have_governor_per_policy;
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000138}
Viresh Kumar3f869d62013-05-16 05:09:56 +0000139EXPORT_SYMBOL_GPL(have_governor_per_policy);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000140
Viresh Kumar944e9a02013-05-16 05:09:57 +0000141struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
142{
143 if (have_governor_per_policy())
144 return &policy->kobj;
145 else
146 return cpufreq_global_kobject;
147}
148EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
149
Viresh Kumar72a4ce32013-05-17 11:26:32 +0000150static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
151{
152 u64 idle_time;
153 u64 cur_wall_time;
154 u64 busy_time;
155
156 cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
157
158 busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
159 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
160 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
161 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
162 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
163 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
164
165 idle_time = cur_wall_time - busy_time;
166 if (wall)
167 *wall = cputime_to_usecs(cur_wall_time);
168
169 return cputime_to_usecs(idle_time);
170}
171
172u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
173{
174 u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
175
176 if (idle_time == -1ULL)
177 return get_cpu_idle_time_jiffy(cpu, wall);
178 else if (!io_busy)
179 idle_time += get_cpu_iowait_time_us(cpu, wall);
180
181 return idle_time;
182}
183EXPORT_SYMBOL_GPL(get_cpu_idle_time);
184
Stephen Boyda9144432012-07-20 18:14:38 +0000185static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186{
187 struct cpufreq_policy *data;
188 unsigned long flags;
189
Mike Travis7a6aedf2008-03-25 15:06:53 -0700190 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 goto err_out;
192
193 /* get the cpufreq driver */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000194 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200196 if (!cpufreq_driver)
197 goto err_out_unlock;
198
199 if (!try_module_get(cpufreq_driver->owner))
200 goto err_out_unlock;
201
202
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700204 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205
206 if (!data)
207 goto err_out_put_module;
208
Stephen Boyda9144432012-07-20 18:14:38 +0000209 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 goto err_out_put_module;
211
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000212 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 return data;
214
Dave Jones7d5e3502006-02-02 17:03:42 -0500215err_out_put_module:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200216 module_put(cpufreq_driver->owner);
Nathan Zimmer58000432013-04-04 14:53:25 +0000217err_out_unlock:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200218 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500219err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 return NULL;
221}
Stephen Boyda9144432012-07-20 18:14:38 +0000222
223struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
224{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000225 if (cpufreq_disabled())
226 return NULL;
227
Stephen Boyda9144432012-07-20 18:14:38 +0000228 return __cpufreq_cpu_get(cpu, false);
229}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
231
Stephen Boyda9144432012-07-20 18:14:38 +0000232static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
233{
234 return __cpufreq_cpu_get(cpu, true);
235}
236
237static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
238{
239 if (!sysfs)
240 kobject_put(&data->kobj);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200241 module_put(cpufreq_driver->owner);
Stephen Boyda9144432012-07-20 18:14:38 +0000242}
Dave Jones7d5e3502006-02-02 17:03:42 -0500243
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244void cpufreq_cpu_put(struct cpufreq_policy *data)
245{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000246 if (cpufreq_disabled())
247 return;
248
Stephen Boyda9144432012-07-20 18:14:38 +0000249 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250}
251EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
252
Stephen Boyda9144432012-07-20 18:14:38 +0000253static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
254{
255 __cpufreq_cpu_put(data, true);
256}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257
258/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
260 *********************************************************************/
261
262/**
263 * adjust_jiffies - adjust the system "loops_per_jiffy"
264 *
265 * This function alters the system "loops_per_jiffy" for the clock
266 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500267 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 * per-CPU loops_per_jiffy value wherever possible.
269 */
270#ifndef CONFIG_SMP
271static unsigned long l_p_j_ref;
272static unsigned int l_p_j_ref_freq;
273
Arjan van de Ven858119e2006-01-14 13:20:43 -0800274static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275{
276 if (ci->flags & CPUFREQ_CONST_LOOPS)
277 return;
278
279 if (!l_p_j_ref_freq) {
280 l_p_j_ref = loops_per_jiffy;
281 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200282 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530283 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530285 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700286 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530287 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
288 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200289 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530290 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 }
292}
293#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530294static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
295{
296 return;
297}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298#endif
299
300
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530301void __cpufreq_notify_transition(struct cpufreq_policy *policy,
302 struct cpufreq_freqs *freqs, unsigned int state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303{
304 BUG_ON(irqs_disabled());
305
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000306 if (cpufreq_disabled())
307 return;
308
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200309 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200310 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800311 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500316 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800317 * which is not equal to what the cpufreq core thinks is
318 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200320 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800321 if ((policy) && (policy->cpu == freqs->cpu) &&
322 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200323 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800324 " %u, cpufreq assumed %u kHz.\n",
325 freqs->old, policy->cur);
326 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 }
328 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700329 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800330 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
332 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800333
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 case CPUFREQ_POSTCHANGE:
335 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200336 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200337 (unsigned long)freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100338 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700339 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800340 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800341 if (likely(policy) && likely(policy->cpu == freqs->cpu))
342 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 break;
344 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345}
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530346/**
347 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
348 * on frequency transition.
349 *
350 * This function calls the transition notifiers and the "adjust_jiffies"
351 * function. It is called twice on all CPU frequency changes that have
352 * external effects.
353 */
354void cpufreq_notify_transition(struct cpufreq_policy *policy,
355 struct cpufreq_freqs *freqs, unsigned int state)
356{
357 for_each_cpu(freqs->cpu, policy->cpus)
358 __cpufreq_notify_transition(policy, freqs, state);
359}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
361
362
363
364/*********************************************************************
365 * SYSFS INTERFACE *
366 *********************************************************************/
367
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700368static struct cpufreq_governor *__find_governor(const char *str_governor)
369{
370 struct cpufreq_governor *t;
371
372 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500373 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700374 return t;
375
376 return NULL;
377}
378
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379/**
380 * cpufreq_parse_governor - parse a governor string
381 */
Dave Jones905d77c2008-03-05 14:28:32 -0500382static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 struct cpufreq_governor **governor)
384{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700385 int err = -EINVAL;
386
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200387 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700388 goto out;
389
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200390 if (cpufreq_driver->setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
392 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700393 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530394 } else if (!strnicmp(str_governor, "powersave",
395 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700397 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200399 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700401
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800402 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700403
404 t = __find_governor(str_governor);
405
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700406 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700407 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700408
Kees Cook1a8e1462011-05-04 08:38:56 -0700409 mutex_unlock(&cpufreq_governor_mutex);
410 ret = request_module("cpufreq_%s", str_governor);
411 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700412
Kees Cook1a8e1462011-05-04 08:38:56 -0700413 if (ret == 0)
414 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700415 }
416
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700417 if (t != NULL) {
418 *governor = t;
419 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700421
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800422 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 }
Dave Jones29464f22009-01-18 01:37:11 -0500424out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700425 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
428
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530430 * cpufreq_per_cpu_attr_read() / show_##file_name() -
431 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 *
433 * Write out information from cpufreq_driver->policy[cpu]; object must be
434 * "unsigned int".
435 */
436
Dave Jones32ee8c32006-02-28 00:43:23 -0500437#define show_one(file_name, object) \
438static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500439(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500440{ \
Dave Jones29464f22009-01-18 01:37:11 -0500441 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442}
443
444show_one(cpuinfo_min_freq, cpuinfo.min_freq);
445show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100446show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447show_one(scaling_min_freq, min);
448show_one(scaling_max_freq, max);
449show_one(scaling_cur_freq, cur);
450
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530451static int __cpufreq_set_policy(struct cpufreq_policy *data,
452 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200453
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454/**
455 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
456 */
457#define store_one(file_name, object) \
458static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500459(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000461 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 struct cpufreq_policy new_policy; \
463 \
464 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
465 if (ret) \
466 return -EINVAL; \
467 \
Dave Jones29464f22009-01-18 01:37:11 -0500468 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 if (ret != 1) \
470 return -EINVAL; \
471 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200472 ret = __cpufreq_set_policy(policy, &new_policy); \
473 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 \
475 return ret ? ret : count; \
476}
477
Dave Jones29464f22009-01-18 01:37:11 -0500478store_one(scaling_min_freq, min);
479store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480
481/**
482 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
483 */
Dave Jones905d77c2008-03-05 14:28:32 -0500484static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
485 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800487 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 if (!cur_freq)
489 return sprintf(buf, "<unknown>");
490 return sprintf(buf, "%u\n", cur_freq);
491}
492
493
494/**
495 * show_scaling_governor - show the current policy for the specified CPU
496 */
Dave Jones905d77c2008-03-05 14:28:32 -0500497static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498{
Dave Jones29464f22009-01-18 01:37:11 -0500499 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 return sprintf(buf, "powersave\n");
501 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
502 return sprintf(buf, "performance\n");
503 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200504 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500505 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 return -EINVAL;
507}
508
509
510/**
511 * store_scaling_governor - store policy for the specified CPU
512 */
Dave Jones905d77c2008-03-05 14:28:32 -0500513static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
514 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000516 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 char str_governor[16];
518 struct cpufreq_policy new_policy;
519
520 ret = cpufreq_get_policy(&new_policy, policy->cpu);
521 if (ret)
522 return ret;
523
Dave Jones29464f22009-01-18 01:37:11 -0500524 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 if (ret != 1)
526 return -EINVAL;
527
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530528 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
529 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 return -EINVAL;
531
Thomas Renninger7970e082006-04-13 15:14:04 +0200532 /* Do not use cpufreq_set_policy here or the user_policy.max
533 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200534 ret = __cpufreq_set_policy(policy, &new_policy);
535
536 policy->user_policy.policy = policy->policy;
537 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200538
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530539 if (ret)
540 return ret;
541 else
542 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543}
544
545/**
546 * show_scaling_driver - show the cpufreq driver currently loaded
547 */
Dave Jones905d77c2008-03-05 14:28:32 -0500548static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200550 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551}
552
553/**
554 * show_scaling_available_governors - show the available CPUfreq governors
555 */
Dave Jones905d77c2008-03-05 14:28:32 -0500556static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
557 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558{
559 ssize_t i = 0;
560 struct cpufreq_governor *t;
561
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200562 if (!cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 i += sprintf(buf, "performance powersave");
564 goto out;
565 }
566
567 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500568 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
569 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200571 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500573out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 i += sprintf(&buf[i], "\n");
575 return i;
576}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700577
Rusty Russell835481d2009-01-04 05:18:06 -0800578static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579{
580 ssize_t i = 0;
581 unsigned int cpu;
582
Rusty Russell835481d2009-01-04 05:18:06 -0800583 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 if (i)
585 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
586 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
587 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500588 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 }
590 i += sprintf(&buf[i], "\n");
591 return i;
592}
593
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700594/**
595 * show_related_cpus - show the CPUs affected by each transition even if
596 * hw coordination is in use
597 */
598static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
599{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700600 return show_cpus(policy->related_cpus, buf);
601}
602
603/**
604 * show_affected_cpus - show the CPUs affected by each transition
605 */
606static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
607{
608 return show_cpus(policy->cpus, buf);
609}
610
Venki Pallipadi9e769882007-10-26 10:18:21 -0700611static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500612 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700613{
614 unsigned int freq = 0;
615 unsigned int ret;
616
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700617 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700618 return -EINVAL;
619
620 ret = sscanf(buf, "%u", &freq);
621 if (ret != 1)
622 return -EINVAL;
623
624 policy->governor->store_setspeed(policy, freq);
625
626 return count;
627}
628
629static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
630{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700631 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700632 return sprintf(buf, "<unsupported>\n");
633
634 return policy->governor->show_setspeed(policy, buf);
635}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636
Thomas Renningere2f74f32009-11-19 12:31:01 +0100637/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200638 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100639 */
640static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
641{
642 unsigned int limit;
643 int ret;
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200644 if (cpufreq_driver->bios_limit) {
645 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
Thomas Renningere2f74f32009-11-19 12:31:01 +0100646 if (!ret)
647 return sprintf(buf, "%u\n", limit);
648 }
649 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
650}
651
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200652cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
653cpufreq_freq_attr_ro(cpuinfo_min_freq);
654cpufreq_freq_attr_ro(cpuinfo_max_freq);
655cpufreq_freq_attr_ro(cpuinfo_transition_latency);
656cpufreq_freq_attr_ro(scaling_available_governors);
657cpufreq_freq_attr_ro(scaling_driver);
658cpufreq_freq_attr_ro(scaling_cur_freq);
659cpufreq_freq_attr_ro(bios_limit);
660cpufreq_freq_attr_ro(related_cpus);
661cpufreq_freq_attr_ro(affected_cpus);
662cpufreq_freq_attr_rw(scaling_min_freq);
663cpufreq_freq_attr_rw(scaling_max_freq);
664cpufreq_freq_attr_rw(scaling_governor);
665cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666
Dave Jones905d77c2008-03-05 14:28:32 -0500667static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 &cpuinfo_min_freq.attr,
669 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100670 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 &scaling_min_freq.attr,
672 &scaling_max_freq.attr,
673 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700674 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 &scaling_governor.attr,
676 &scaling_driver.attr,
677 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700678 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 NULL
680};
681
Dave Jones29464f22009-01-18 01:37:11 -0500682#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
683#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684
Dave Jones29464f22009-01-18 01:37:11 -0500685static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686{
Dave Jones905d77c2008-03-05 14:28:32 -0500687 struct cpufreq_policy *policy = to_policy(kobj);
688 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500689 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000690 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500692 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800693
694 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500695 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800696
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530697 if (fattr->show)
698 ret = fattr->show(policy, buf);
699 else
700 ret = -EIO;
701
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800702 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500703fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000704 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500705no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 return ret;
707}
708
Dave Jones905d77c2008-03-05 14:28:32 -0500709static ssize_t store(struct kobject *kobj, struct attribute *attr,
710 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711{
Dave Jones905d77c2008-03-05 14:28:32 -0500712 struct cpufreq_policy *policy = to_policy(kobj);
713 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500714 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000715 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500717 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800718
719 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500720 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800721
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530722 if (fattr->store)
723 ret = fattr->store(policy, buf, count);
724 else
725 ret = -EIO;
726
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800727 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500728fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000729 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500730no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 return ret;
732}
733
Dave Jones905d77c2008-03-05 14:28:32 -0500734static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735{
Dave Jones905d77c2008-03-05 14:28:32 -0500736 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200737 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 complete(&policy->kobj_unregister);
739}
740
Emese Revfy52cf25d2010-01-19 02:58:23 +0100741static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 .show = show,
743 .store = store,
744};
745
746static struct kobj_type ktype_cpufreq = {
747 .sysfs_ops = &sysfs_ops,
748 .default_attrs = default_attrs,
749 .release = cpufreq_sysfs_release,
750};
751
Viresh Kumar2361be22013-05-17 16:09:09 +0530752struct kobject *cpufreq_global_kobject;
753EXPORT_SYMBOL(cpufreq_global_kobject);
754
755static int cpufreq_global_kobject_usage;
756
757int cpufreq_get_global_kobject(void)
758{
759 if (!cpufreq_global_kobject_usage++)
760 return kobject_add(cpufreq_global_kobject,
761 &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
762
763 return 0;
764}
765EXPORT_SYMBOL(cpufreq_get_global_kobject);
766
767void cpufreq_put_global_kobject(void)
768{
769 if (!--cpufreq_global_kobject_usage)
770 kobject_del(cpufreq_global_kobject);
771}
772EXPORT_SYMBOL(cpufreq_put_global_kobject);
773
774int cpufreq_sysfs_create_file(const struct attribute *attr)
775{
776 int ret = cpufreq_get_global_kobject();
777
778 if (!ret) {
779 ret = sysfs_create_file(cpufreq_global_kobject, attr);
780 if (ret)
781 cpufreq_put_global_kobject();
782 }
783
784 return ret;
785}
786EXPORT_SYMBOL(cpufreq_sysfs_create_file);
787
788void cpufreq_sysfs_remove_file(const struct attribute *attr)
789{
790 sysfs_remove_file(cpufreq_global_kobject, attr);
791 cpufreq_put_global_kobject();
792}
793EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
794
Dave Jones19d6f7e2009-07-08 17:35:39 -0400795/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700796static int cpufreq_add_dev_symlink(unsigned int cpu,
797 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400798{
799 unsigned int j;
800 int ret = 0;
801
802 for_each_cpu(j, policy->cpus) {
803 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800804 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400805
806 if (j == cpu)
807 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400808
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200809 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400810 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800811 cpu_dev = get_cpu_device(j);
812 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400813 "cpufreq");
814 if (ret) {
815 cpufreq_cpu_put(managed_policy);
816 return ret;
817 }
818 }
819 return ret;
820}
821
Alex Chiangcf3289d02009-11-17 20:27:08 -0700822static int cpufreq_add_dev_interface(unsigned int cpu,
823 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800824 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400825{
Dave Jonesecf7e462009-07-08 18:48:47 -0400826 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400827 struct freq_attr **drv_attr;
828 unsigned long flags;
829 int ret = 0;
830 unsigned int j;
831
832 /* prepare interface data */
833 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800834 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400835 if (ret)
836 return ret;
837
838 /* set up files for this cpu device */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200839 drv_attr = cpufreq_driver->attr;
Dave Jones909a6942009-07-08 18:05:42 -0400840 while ((drv_attr) && (*drv_attr)) {
841 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
842 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200843 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400844 drv_attr++;
845 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200846 if (cpufreq_driver->get) {
Dave Jones909a6942009-07-08 18:05:42 -0400847 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
848 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200849 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400850 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200851 if (cpufreq_driver->target) {
Dave Jones909a6942009-07-08 18:05:42 -0400852 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
853 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200854 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400855 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200856 if (cpufreq_driver->bios_limit) {
Thomas Renningere2f74f32009-11-19 12:31:01 +0100857 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
858 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200859 goto err_out_kobj_put;
Thomas Renningere2f74f32009-11-19 12:31:01 +0100860 }
Dave Jones909a6942009-07-08 18:05:42 -0400861
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000862 write_lock_irqsave(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400863 for_each_cpu(j, policy->cpus) {
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 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000867 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400868
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");
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200884 if (cpufreq_driver->exit)
885 cpufreq_driver->exit(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400886 }
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
Viresh Kumarfcf80582013-01-29 14:39:08 +0000895#ifdef CONFIG_HOTPLUG_CPU
896static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
897 struct device *dev)
898{
899 struct cpufreq_policy *policy;
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200900 int ret = 0, has_target = !!cpufreq_driver->target;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000901 unsigned long flags;
902
903 policy = cpufreq_cpu_get(sibling);
904 WARN_ON(!policy);
905
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200906 if (has_target)
907 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000908
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530909 lock_policy_rwsem_write(sibling);
910
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000911 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530912
Viresh Kumarfcf80582013-01-29 14:39:08 +0000913 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530914 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000915 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000916 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000917
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530918 unlock_policy_rwsem_write(sibling);
919
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200920 if (has_target) {
921 __cpufreq_governor(policy, CPUFREQ_GOV_START);
922 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
923 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000924
Viresh Kumarfcf80582013-01-29 14:39:08 +0000925 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
926 if (ret) {
927 cpufreq_cpu_put(policy);
928 return ret;
929 }
930
931 return 0;
932}
933#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
935/**
936 * cpufreq_add_dev - add a CPU device
937 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500938 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400939 *
940 * The Oracle says: try running cpufreq registration/unregistration concurrently
941 * with with cpu hotplugging and all hell will break loose. Tried to clean this
942 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800944static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000946 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530947 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500950#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000951 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500952 int sibling;
953#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954
Ashok Rajc32b6b82005-10-30 14:59:54 -0800955 if (cpu_is_offline(cpu))
956 return 0;
957
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200958 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
960#ifdef CONFIG_SMP
961 /* check whether a different CPU already registered this
962 * CPU because it is in the same boat. */
963 policy = cpufreq_cpu_get(cpu);
964 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500965 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 return 0;
967 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000968
969#ifdef CONFIG_HOTPLUG_CPU
970 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000971 read_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000972 for_each_online_cpu(sibling) {
973 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530974 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000975 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000976 return cpufreq_add_policy_cpu(cpu, sibling, dev);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530977 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000978 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000979 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000980#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981#endif
982
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200983 if (!try_module_get(cpufreq_driver->owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 ret = -EINVAL;
985 goto module_out;
986 }
987
Dave Jonese98df502005-10-20 15:17:43 -0700988 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400989 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400991
992 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400993 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400994
995 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400996 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
998 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +0530999 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -08001000 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001002 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +09001003 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001004
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +00001006 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008 /* call driver. From then on the cpufreq must be able
1009 * to accept all calls to ->verify and ->setpolicy for this CPU
1010 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001011 ret = cpufreq_driver->init(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001013 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301014 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001016
Viresh Kumarfcf80582013-01-29 14:39:08 +00001017 /* related cpus should atleast have policy->cpus */
1018 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1019
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001020 /*
1021 * affected cpus must always be the one, which are online. We aren't
1022 * managing offline cpus here.
1023 */
1024 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
1025
Mike Chan187d9f42008-12-04 12:19:17 -08001026 policy->user_policy.min = policy->min;
1027 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028
Thomas Renningera1531ac2008-07-29 22:32:58 -07001029 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1030 CPUFREQ_START, policy);
1031
Viresh Kumarfcf80582013-01-29 14:39:08 +00001032#ifdef CONFIG_HOTPLUG_CPU
1033 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
1034 if (gov) {
1035 policy->governor = gov;
1036 pr_debug("Restoring governor %s for cpu %d\n",
1037 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001038 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001039#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001041 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -04001042 if (ret)
1043 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -05001044
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001045 kobject_uevent(&policy->kobj, KOBJ_ADD);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001046 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001047 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001048
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 return 0;
1050
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001052 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001053 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001054 per_cpu(cpufreq_cpu_data, j) = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001055 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001057 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 wait_for_completion(&policy->kobj_unregister);
1059
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301060err_set_policy_cpu:
1061 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001062 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001063err_free_cpumask:
1064 free_cpumask_var(policy->cpus);
1065err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067nomem_out:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001068 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001069module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 return ret;
1071}
1072
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001073static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1074{
1075 int j;
1076
1077 policy->last_cpu = policy->cpu;
1078 policy->cpu = cpu;
1079
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001080 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001081 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001082
1083#ifdef CONFIG_CPU_FREQ_TABLE
1084 cpufreq_frequency_table_update_policy_cpu(policy);
1085#endif
1086 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1087 CPUFREQ_UPDATE_POLICY_CPU, policy);
1088}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
1090/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001091 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 *
1093 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001094 * Caller should already have policy_rwsem in write mode for this CPU.
1095 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001097static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001099 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 unsigned long flags;
1101 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001102 struct kobject *kobj;
1103 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001104 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001106 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001108 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 data = per_cpu(cpufreq_cpu_data, cpu);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001111 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001113 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001116 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001120 if (cpufreq_driver->target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001122
Jacob Shin27ecddc2011-04-27 13:32:11 -05001123#ifdef CONFIG_HOTPLUG_CPU
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001124 if (!cpufreq_driver->setpolicy)
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001125 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
1126 data->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001127#endif
1128
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301129 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001130 cpus = cpumask_weight(data->cpus);
Viresh Kumare4969eb2013-04-11 08:04:53 +00001131
1132 if (cpus > 1)
1133 cpumask_clear_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301134 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001136 if (cpu != data->cpu) {
1137 sysfs_remove_link(&dev->kobj, "cpufreq");
1138 } else if (cpus > 1) {
Venki Pallipadiec282972007-03-26 12:03:19 -07001139 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001140 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1141 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1142 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1143 if (ret) {
1144 pr_err("%s: Failed to move kobj: %d", __func__, ret);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301145
1146 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001147 cpumask_set_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301148
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001149 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301150 per_cpu(cpufreq_cpu_data, cpu) = data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001151 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301152
1153 unlock_policy_rwsem_write(cpu);
1154
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001155 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1156 "cpufreq");
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001157 return -EINVAL;
1158 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001159
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301160 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001161 update_policy_cpu(data, cpu_dev->id);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301162 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001163 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1164 __func__, cpu_dev->id, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001165 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001166
Viresh Kumard96038e2013-04-30 14:32:18 +00001167 if ((cpus == 1) && (cpufreq_driver->target))
1168 __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
1169
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001170 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1171 cpufreq_cpu_put(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001172
1173 /* If cpu is last user of policy, free policy */
1174 if (cpus == 1) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301175 lock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001176 kobj = &data->kobj;
1177 cmp = &data->kobj_unregister;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301178 unlock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001179 kobject_put(kobj);
1180
1181 /* we need to make sure that the underlying kobj is actually
1182 * not referenced anymore by anybody before we proceed with
1183 * unloading.
1184 */
1185 pr_debug("waiting for dropping of refcount\n");
1186 wait_for_completion(cmp);
1187 pr_debug("wait complete\n");
1188
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001189 if (cpufreq_driver->exit)
1190 cpufreq_driver->exit(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001191
1192 free_cpumask_var(data->related_cpus);
1193 free_cpumask_var(data->cpus);
1194 kfree(data);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001195 } else if (cpufreq_driver->target) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001196 __cpufreq_governor(data, CPUFREQ_GOV_START);
1197 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1198 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301200 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 return 0;
1202}
1203
1204
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001205static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001206{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001207 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001208 int retval;
1209
1210 if (cpu_is_offline(cpu))
1211 return 0;
1212
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001213 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001214 return retval;
1215}
1216
1217
David Howells65f27f32006-11-22 14:55:48 +00001218static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219{
David Howells65f27f32006-11-22 14:55:48 +00001220 struct cpufreq_policy *policy =
1221 container_of(work, struct cpufreq_policy, update);
1222 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001223 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 cpufreq_update_policy(cpu);
1225}
1226
1227/**
1228 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1229 * @cpu: cpu number
1230 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1231 * @new_freq: CPU frequency the CPU actually runs at
1232 *
Dave Jones29464f22009-01-18 01:37:11 -05001233 * We adjust to current frequency first, and need to clean up later.
1234 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301236static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1237 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238{
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301239 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 struct cpufreq_freqs freqs;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301241 unsigned long flags;
1242
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001244 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1246
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 freqs.old = old_freq;
1248 freqs.new = new_freq;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301249
1250 read_lock_irqsave(&cpufreq_driver_lock, flags);
1251 policy = per_cpu(cpufreq_cpu_data, cpu);
1252 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1253
1254 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
1255 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256}
1257
1258
Dave Jones32ee8c32006-02-28 00:43:23 -05001259/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301260 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001261 * @cpu: CPU number
1262 *
1263 * This is the last known freq, without actually getting it from the driver.
1264 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1265 */
1266unsigned int cpufreq_quick_get(unsigned int cpu)
1267{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001268 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301269 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001270
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001271 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1272 return cpufreq_driver->get(cpu);
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001273
1274 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001275 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301276 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001277 cpufreq_cpu_put(policy);
1278 }
1279
Dave Jones4d34a672008-02-07 16:33:49 -05001280 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001281}
1282EXPORT_SYMBOL(cpufreq_quick_get);
1283
Jesse Barnes3d737102011-06-28 10:59:12 -07001284/**
1285 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1286 * @cpu: CPU number
1287 *
1288 * Just return the max possible frequency for a given CPU.
1289 */
1290unsigned int cpufreq_quick_get_max(unsigned int cpu)
1291{
1292 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1293 unsigned int ret_freq = 0;
1294
1295 if (policy) {
1296 ret_freq = policy->max;
1297 cpufreq_cpu_put(policy);
1298 }
1299
1300 return ret_freq;
1301}
1302EXPORT_SYMBOL(cpufreq_quick_get_max);
1303
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001304
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001305static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001307 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301308 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001310 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001311 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001313 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301315 if (ret_freq && policy->cur &&
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001316 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301317 /* verify no discrepancy between actual and
1318 saved value exists */
1319 if (unlikely(ret_freq != policy->cur)) {
1320 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 schedule_work(&policy->update);
1322 }
1323 }
1324
Dave Jones4d34a672008-02-07 16:33:49 -05001325 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001326}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001328/**
1329 * cpufreq_get - get the current CPU frequency (in kHz)
1330 * @cpu: CPU number
1331 *
1332 * Get the CPU current (static) CPU frequency
1333 */
1334unsigned int cpufreq_get(unsigned int cpu)
1335{
1336 unsigned int ret_freq = 0;
1337 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1338
1339 if (!policy)
1340 goto out;
1341
1342 if (unlikely(lock_policy_rwsem_read(cpu)))
1343 goto out_policy;
1344
1345 ret_freq = __cpufreq_get(cpu);
1346
1347 unlock_policy_rwsem_read(cpu);
1348
1349out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001351out:
Dave Jones4d34a672008-02-07 16:33:49 -05001352 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353}
1354EXPORT_SYMBOL(cpufreq_get);
1355
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001356static struct subsys_interface cpufreq_interface = {
1357 .name = "cpufreq",
1358 .subsys = &cpu_subsys,
1359 .add_dev = cpufreq_add_dev,
1360 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001361};
1362
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
1364/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001365 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1366 *
1367 * This function is only executed for the boot processor. The other CPUs
1368 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001369 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001370static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001371{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301372 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001373
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001374 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001375 struct cpufreq_policy *cpu_policy;
1376
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001377 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001378
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001379 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001380 cpu_policy = cpufreq_cpu_get(cpu);
1381 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001382 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001383
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001384 if (cpufreq_driver->suspend) {
1385 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001386 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001387 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1388 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001389 }
1390
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001391 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001392 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001393}
1394
1395/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001396 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 *
1398 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001399 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1400 * restored. It will verify that the current freq is in sync with
1401 * what we believe it to be. This is a bit later than when it
1402 * should be, but nonethteless it's better than calling
1403 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001404 *
1405 * This function is only executed for the boot CPU. The other CPUs have not
1406 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001408static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301410 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001411
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001412 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 struct cpufreq_policy *cpu_policy;
1414
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001415 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001417 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 cpu_policy = cpufreq_cpu_get(cpu);
1419 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001420 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001422 if (cpufreq_driver->resume) {
1423 ret = cpufreq_driver->resume(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 if (ret) {
1425 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1426 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001427 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 }
1429 }
1430
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001432
Dave Jonesc9060492008-02-07 16:32:18 -05001433fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435}
1436
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001437static struct syscore_ops cpufreq_syscore_ops = {
1438 .suspend = cpufreq_bp_suspend,
1439 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440};
1441
Borislav Petkov9d950462013-01-20 10:24:28 +00001442/**
1443 * cpufreq_get_current_driver - return current driver's name
1444 *
1445 * Return the name string of the currently loaded cpufreq driver
1446 * or NULL, if none.
1447 */
1448const char *cpufreq_get_current_driver(void)
1449{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001450 if (cpufreq_driver)
1451 return cpufreq_driver->name;
1452
1453 return NULL;
Borislav Petkov9d950462013-01-20 10:24:28 +00001454}
1455EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456
1457/*********************************************************************
1458 * NOTIFIER LISTS INTERFACE *
1459 *********************************************************************/
1460
1461/**
1462 * cpufreq_register_notifier - register a driver with cpufreq
1463 * @nb: notifier function to register
1464 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1465 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001466 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 * are notified about clock rate changes (once before and once after
1468 * the transition), or a list of drivers that are notified about
1469 * changes in cpufreq policy.
1470 *
1471 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001472 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 */
1474int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1475{
1476 int ret;
1477
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001478 if (cpufreq_disabled())
1479 return -EINVAL;
1480
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001481 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1482
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 switch (list) {
1484 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001485 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001486 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 break;
1488 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001489 ret = blocking_notifier_chain_register(
1490 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 break;
1492 default:
1493 ret = -EINVAL;
1494 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
1496 return ret;
1497}
1498EXPORT_SYMBOL(cpufreq_register_notifier);
1499
1500
1501/**
1502 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1503 * @nb: notifier block to be unregistered
1504 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1505 *
1506 * Remove a driver from the CPU frequency notifier list.
1507 *
1508 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001509 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 */
1511int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1512{
1513 int ret;
1514
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001515 if (cpufreq_disabled())
1516 return -EINVAL;
1517
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 switch (list) {
1519 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001520 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001521 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 break;
1523 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001524 ret = blocking_notifier_chain_unregister(
1525 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 break;
1527 default:
1528 ret = -EINVAL;
1529 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530
1531 return ret;
1532}
1533EXPORT_SYMBOL(cpufreq_unregister_notifier);
1534
1535
1536/*********************************************************************
1537 * GOVERNORS *
1538 *********************************************************************/
1539
1540
1541int __cpufreq_driver_target(struct cpufreq_policy *policy,
1542 unsigned int target_freq,
1543 unsigned int relation)
1544{
1545 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001546 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001547
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001548 if (cpufreq_disabled())
1549 return -ENODEV;
1550
Viresh Kumar72499242012-10-31 01:28:21 +01001551 /* Make sure that target_freq is within supported range */
1552 if (target_freq > policy->max)
1553 target_freq = policy->max;
1554 if (target_freq < policy->min)
1555 target_freq = policy->min;
1556
1557 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1558 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001559
1560 if (target_freq == policy->cur)
1561 return 0;
1562
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001563 if (cpufreq_driver->target)
1564 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001565
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 return retval;
1567}
1568EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1569
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570int cpufreq_driver_target(struct cpufreq_policy *policy,
1571 unsigned int target_freq,
1572 unsigned int relation)
1573{
Julia Lawallf1829e42008-07-25 22:44:53 +02001574 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001576 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001577 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578
1579 ret = __cpufreq_driver_target(policy, target_freq, relation);
1580
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001581 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582
Julia Lawallf1829e42008-07-25 22:44:53 +02001583fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 return ret;
1585}
1586EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1587
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001588int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001589{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001590 if (cpufreq_disabled())
Viresh Kumara262e942013-05-31 06:15:08 +00001591 return 0;
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001592
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001593 if (!cpufreq_driver->getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001594 return 0;
1595
Viresh Kumara262e942013-05-31 06:15:08 +00001596 return cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001597}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001598EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001599
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001600/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001601 * when "event" is CPUFREQ_GOV_LIMITS
1602 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301604static int __cpufreq_governor(struct cpufreq_policy *policy,
1605 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606{
Dave Jonescc993ca2005-07-28 09:43:56 -07001607 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001608
1609 /* Only must be defined when default governor is known to have latency
1610 restrictions, like e.g. conservative or ondemand.
1611 That this is the case is already ensured in Kconfig
1612 */
1613#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1614 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1615#else
1616 struct cpufreq_governor *gov = NULL;
1617#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001618
1619 if (policy->governor->max_transition_latency &&
1620 policy->cpuinfo.transition_latency >
1621 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001622 if (!gov)
1623 return -EINVAL;
1624 else {
1625 printk(KERN_WARNING "%s governor failed, too long"
1626 " transition latency of HW, fallback"
1627 " to %s governor\n",
1628 policy->governor->name,
1629 gov->name);
1630 policy->governor = gov;
1631 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001632 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633
1634 if (!try_module_get(policy->governor->owner))
1635 return -EINVAL;
1636
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001637 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301638 policy->cpu, event);
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001639
1640 mutex_lock(&cpufreq_governor_lock);
1641 if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
1642 (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
1643 mutex_unlock(&cpufreq_governor_lock);
1644 return -EBUSY;
1645 }
1646
1647 if (event == CPUFREQ_GOV_STOP)
1648 policy->governor_enabled = false;
1649 else if (event == CPUFREQ_GOV_START)
1650 policy->governor_enabled = true;
1651
1652 mutex_unlock(&cpufreq_governor_lock);
1653
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 ret = policy->governor->governor(policy, event);
1655
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001656 if (!ret) {
1657 if (event == CPUFREQ_GOV_POLICY_INIT)
1658 policy->governor->initialized++;
1659 else if (event == CPUFREQ_GOV_POLICY_EXIT)
1660 policy->governor->initialized--;
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001661 } else {
1662 /* Restore original values */
1663 mutex_lock(&cpufreq_governor_lock);
1664 if (event == CPUFREQ_GOV_STOP)
1665 policy->governor_enabled = true;
1666 else if (event == CPUFREQ_GOV_START)
1667 policy->governor_enabled = false;
1668 mutex_unlock(&cpufreq_governor_lock);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001669 }
Viresh Kumarb3940582013-02-01 05:42:58 +00001670
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301671 /* we keep one module reference alive for
1672 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 if ((event != CPUFREQ_GOV_START) || ret)
1674 module_put(policy->governor->owner);
1675 if ((event == CPUFREQ_GOV_STOP) && !ret)
1676 module_put(policy->governor->owner);
1677
1678 return ret;
1679}
1680
1681
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682int cpufreq_register_governor(struct cpufreq_governor *governor)
1683{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001684 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
1686 if (!governor)
1687 return -EINVAL;
1688
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001689 if (cpufreq_disabled())
1690 return -ENODEV;
1691
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001692 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001693
Viresh Kumarb3940582013-02-01 05:42:58 +00001694 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001695 err = -EBUSY;
1696 if (__find_governor(governor->name) == NULL) {
1697 err = 0;
1698 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700
Dave Jones32ee8c32006-02-28 00:43:23 -05001701 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001702 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703}
1704EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1705
1706
1707void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1708{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001709#ifdef CONFIG_HOTPLUG_CPU
1710 int cpu;
1711#endif
1712
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 if (!governor)
1714 return;
1715
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001716 if (cpufreq_disabled())
1717 return;
1718
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001719#ifdef CONFIG_HOTPLUG_CPU
1720 for_each_present_cpu(cpu) {
1721 if (cpu_online(cpu))
1722 continue;
1723 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1724 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1725 }
1726#endif
1727
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001728 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001730 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 return;
1732}
1733EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1734
1735
1736
1737/*********************************************************************
1738 * POLICY INTERFACE *
1739 *********************************************************************/
1740
1741/**
1742 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001743 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1744 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 *
1746 * Reads the current cpufreq policy.
1747 */
1748int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1749{
1750 struct cpufreq_policy *cpu_policy;
1751 if (!policy)
1752 return -EINVAL;
1753
1754 cpu_policy = cpufreq_cpu_get(cpu);
1755 if (!cpu_policy)
1756 return -EINVAL;
1757
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
1760 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761 return 0;
1762}
1763EXPORT_SYMBOL(cpufreq_get_policy);
1764
1765
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001766/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301767 * data : current policy.
1768 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001769 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301770static int __cpufreq_set_policy(struct cpufreq_policy *data,
1771 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001773 int ret = 0, failed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001775 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 policy->min, policy->max);
1777
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301778 memcpy(&policy->cpuinfo, &data->cpuinfo,
1779 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780
Yi Yang53391fa2008-01-30 13:33:34 +01001781 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001782 ret = -EINVAL;
1783 goto error_out;
1784 }
1785
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786 /* verify the cpu speed can be set within this limit */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001787 ret = cpufreq_driver->verify(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 if (ret)
1789 goto error_out;
1790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001792 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1793 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794
1795 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001796 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1797 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798
1799 /* verify the cpu speed can be set within this limit,
1800 which might be different to the first one */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001801 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001802 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804
1805 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001806 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1807 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
Dave Jones7d5e3502006-02-02 17:03:42 -05001809 data->min = policy->min;
1810 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001812 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301813 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001815 if (cpufreq_driver->setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001817 pr_debug("setting range\n");
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001818 ret = cpufreq_driver->setpolicy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 } else {
1820 if (policy->governor != data->governor) {
1821 /* save old, working values */
1822 struct cpufreq_governor *old_gov = data->governor;
1823
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001824 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
1826 /* end old governor */
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001827 if (data->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Viresh Kumar955ef482013-05-16 05:09:58 +00001829 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001830 __cpufreq_governor(data,
1831 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar955ef482013-05-16 05:09:58 +00001832 lock_policy_rwsem_write(policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001833 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835 /* start new governor */
1836 data->governor = policy->governor;
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001837 if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
Viresh Kumar955ef482013-05-16 05:09:58 +00001838 if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001839 failed = 0;
Viresh Kumar955ef482013-05-16 05:09:58 +00001840 } else {
1841 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001842 __cpufreq_governor(data,
1843 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar955ef482013-05-16 05:09:58 +00001844 lock_policy_rwsem_write(policy->cpu);
1845 }
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001846 }
1847
1848 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001850 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301851 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 if (old_gov) {
1853 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301854 __cpufreq_governor(data,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001855 CPUFREQ_GOV_POLICY_INIT);
1856 __cpufreq_governor(data,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301857 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 }
1859 ret = -EINVAL;
1860 goto error_out;
1861 }
1862 /* might be a policy change, too, so fall through */
1863 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001864 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1866 }
1867
Dave Jones7d5e3502006-02-02 17:03:42 -05001868error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 return ret;
1870}
1871
1872/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1874 * @cpu: CPU which shall be re-evaluated
1875 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001876 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 * at different times.
1878 */
1879int cpufreq_update_policy(unsigned int cpu)
1880{
1881 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1882 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001883 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884
Julia Lawallf1829e42008-07-25 22:44:53 +02001885 if (!data) {
1886 ret = -ENODEV;
1887 goto no_policy;
1888 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889
Julia Lawallf1829e42008-07-25 22:44:53 +02001890 if (unlikely(lock_policy_rwsem_write(cpu))) {
1891 ret = -EINVAL;
1892 goto fail;
1893 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001895 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001896 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 policy.min = data->user_policy.min;
1898 policy.max = data->user_policy.max;
1899 policy.policy = data->user_policy.policy;
1900 policy.governor = data->user_policy.governor;
1901
Thomas Renninger0961dd02006-01-26 18:46:33 +01001902 /* BIOS might change freq behind our back
1903 -> ask driver for current freq and notify governors about a change */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001904 if (cpufreq_driver->get) {
1905 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001906 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001907 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001908 data->cur = policy.cur;
1909 } else {
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001910 if (data->cur != policy.cur && cpufreq_driver->target)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301911 cpufreq_out_of_sync(cpu, data->cur,
1912 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001913 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001914 }
1915
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 ret = __cpufreq_set_policy(data, &policy);
1917
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001918 unlock_policy_rwsem_write(cpu);
1919
Julia Lawallf1829e42008-07-25 22:44:53 +02001920fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001922no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 return ret;
1924}
1925EXPORT_SYMBOL(cpufreq_update_policy);
1926
Satyam Sharmadd184a02007-10-02 13:28:14 -07001927static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001928 unsigned long action, void *hcpu)
1929{
1930 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001931 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001932
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001933 dev = get_cpu_device(cpu);
1934 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001935 switch (action) {
1936 case CPU_ONLINE:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001937 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001938 break;
1939 case CPU_DOWN_PREPARE:
Srivatsa S. Bhata66b2e52013-05-15 21:47:17 +02001940 case CPU_UP_CANCELED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001941 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001942 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001943 case CPU_DOWN_FAILED:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001944 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001945 break;
1946 }
1947 }
1948 return NOTIFY_OK;
1949}
1950
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001951static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001952 .notifier_call = cpufreq_cpu_callback,
1953};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954
1955/*********************************************************************
1956 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1957 *********************************************************************/
1958
1959/**
1960 * cpufreq_register_driver - register a CPU Frequency driver
1961 * @driver_data: A struct cpufreq_driver containing the values#
1962 * submitted by the CPU Frequency driver.
1963 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001964 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001966 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 *
1968 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001969int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970{
1971 unsigned long flags;
1972 int ret;
1973
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001974 if (cpufreq_disabled())
1975 return -ENODEV;
1976
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 if (!driver_data || !driver_data->verify || !driver_data->init ||
1978 ((!driver_data->setpolicy) && (!driver_data->target)))
1979 return -EINVAL;
1980
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001981 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982
1983 if (driver_data->setpolicy)
1984 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1985
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001986 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001987 if (cpufreq_driver) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001988 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 return -EBUSY;
1990 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001991 cpufreq_driver = driver_data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001992 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001994 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001995 if (ret)
1996 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001998 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 int i;
2000 ret = -ENODEV;
2001
2002 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07002003 for (i = 0; i < nr_cpu_ids; i++)
2004 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07002006 break;
2007 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008
2009 /* if all ->init() calls failed, unregister */
2010 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002011 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05302012 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002013 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 }
2015 }
2016
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002017 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002018 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002020 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002021err_if_unreg:
2022 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002023err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002024 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002025 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002026 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05002027 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028}
2029EXPORT_SYMBOL_GPL(cpufreq_register_driver);
2030
2031
2032/**
2033 * cpufreq_unregister_driver - unregister the current CPUFreq driver
2034 *
Dave Jones32ee8c32006-02-28 00:43:23 -05002035 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036 * the right to do so, i.e. if you have succeeded in initialising before!
2037 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
2038 * currently not initialised.
2039 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002040int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041{
2042 unsigned long flags;
2043
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002044 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002045 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002047 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002049 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07002050 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002052 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002053 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002054 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055
2056 return 0;
2057}
2058EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002059
2060static int __init cpufreq_core_init(void)
2061{
2062 int cpu;
2063
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002064 if (cpufreq_disabled())
2065 return -ENODEV;
2066
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002067 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09002068 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002069 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
2070 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002071
Viresh Kumar2361be22013-05-17 16:09:09 +05302072 cpufreq_global_kobject = kobject_create();
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002073 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002074 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002075
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002076 return 0;
2077}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002078core_initcall(cpufreq_core_init);