blob: c0ef84d601b7ad99e9d1836718827f6c3f7186ee [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>
Viresh Kumarbb176f72013-06-19 14:19:33 +05306 * (C) 2013 Viresh Kumar <viresh.kumar@linaro.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08008 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05009 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -050010 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
11 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080012 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 */
17
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Viresh Kumar5ff0a262013-08-06 22:53:03 +053020#include <linux/cpu.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/cpufreq.h>
22#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/device.h>
Viresh Kumar5ff0a262013-08-06 22:53:03 +053024#include <linux/init.h>
25#include <linux/kernel_stat.h>
26#include <linux/module.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080027#include <linux/mutex.h>
Viresh Kumar5ff0a262013-08-06 22:53:03 +053028#include <linux/slab.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010029#include <linux/syscore_ops.h>
Viresh Kumar5ff0a262013-08-06 22:53:03 +053030#include <linux/tick.h>
Thomas Renninger6f4f2722010-04-20 13:17:36 +020031#include <trace/events/power.h>
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033/**
Dave Jonescd878472006-08-11 17:59:28 -040034 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 * level driver of CPUFreq support, and its spinlock. This lock
36 * also protects the cpufreq_cpu_data array.
37 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +020038static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070039static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Srivatsa S. Bhat84148092013-07-30 04:25:10 +053040static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback);
Viresh Kumarbb176f72013-06-19 14:19:33 +053041static DEFINE_RWLOCK(cpufreq_driver_lock);
42static DEFINE_MUTEX(cpufreq_governor_lock);
Lukasz Majewskic88a1f82013-08-06 22:53:08 +053043static LIST_HEAD(cpufreq_policy_list);
Viresh Kumarbb176f72013-06-19 14:19:33 +053044
Thomas Renninger084f3492007-07-09 11:35:28 -070045#ifdef CONFIG_HOTPLUG_CPU
46/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040047static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070048#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080050/*
51 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
52 * all cpufreq/hotplug/workqueue/etc related lock issues.
53 *
54 * The rules for this semaphore:
55 * - Any routine that wants to read from the policy structure will
56 * do a down_read on this semaphore.
57 * - Any routine that will write to the policy structure and/or may take away
58 * the policy altogether (eg. CPU hotplug), will hold this lock in write
59 * mode before doing so.
60 *
61 * Additional rules:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080062 * - Governor routines that can be called in cpufreq hotplug path should not
63 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040064 * - Lock should not be held across
65 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080066 */
Tejun Heof1625062009-10-29 22:34:13 +090067static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080068static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
69
70#define lock_policy_rwsem(mode, cpu) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053071static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072{ \
Tejun Heof1625062009-10-29 22:34:13 +090073 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080074 BUG_ON(policy_cpu == -1); \
75 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076 \
77 return 0; \
78}
79
80lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080081lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080082
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053083#define unlock_policy_rwsem(mode, cpu) \
84static void unlock_policy_rwsem_##mode(int cpu) \
85{ \
86 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
87 BUG_ON(policy_cpu == -1); \
88 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080089}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053091unlock_policy_rwsem(read, cpu);
92unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Viresh Kumar6eed9402013-08-06 22:53:11 +053094/*
95 * rwsem to guarantee that cpufreq driver module doesn't unload during critical
96 * sections
97 */
98static DECLARE_RWSEM(cpufreq_rwsem);
99
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500101static int __cpufreq_governor(struct cpufreq_policy *policy,
102 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800103static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000104static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500107 * Two notifier lists: the "policy" list is involved in the
108 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 * "transition" list for kernel code that needs to handle
110 * changes to devices when the CPU clock speed changes.
111 * The mutex locks both lists.
112 */
Alan Sterne041c682006-03-27 01:16:30 -0800113static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700114static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200116static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700117static int __init init_cpufreq_transition_notifier_list(void)
118{
119 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200120 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700121 return 0;
122}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800123pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400125static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200126static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400127{
128 return off;
129}
130void disable_cpufreq(void)
131{
132 off = 1;
133}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500135static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000137bool have_governor_per_policy(void)
138{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200139 return cpufreq_driver->have_governor_per_policy;
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000140}
Viresh Kumar3f869d62013-05-16 05:09:56 +0000141EXPORT_SYMBOL_GPL(have_governor_per_policy);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000142
Viresh Kumar944e9a02013-05-16 05:09:57 +0000143struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
144{
145 if (have_governor_per_policy())
146 return &policy->kobj;
147 else
148 return cpufreq_global_kobject;
149}
150EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
151
Viresh Kumar72a4ce32013-05-17 11:26:32 +0000152static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
153{
154 u64 idle_time;
155 u64 cur_wall_time;
156 u64 busy_time;
157
158 cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
159
160 busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
161 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
162 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
163 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
164 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
165 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
166
167 idle_time = cur_wall_time - busy_time;
168 if (wall)
169 *wall = cputime_to_usecs(cur_wall_time);
170
171 return cputime_to_usecs(idle_time);
172}
173
174u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
175{
176 u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
177
178 if (idle_time == -1ULL)
179 return get_cpu_idle_time_jiffy(cpu, wall);
180 else if (!io_busy)
181 idle_time += get_cpu_iowait_time_us(cpu, wall);
182
183 return idle_time;
184}
185EXPORT_SYMBOL_GPL(get_cpu_idle_time);
186
Viresh Kumar6eed9402013-08-06 22:53:11 +0530187struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188{
Viresh Kumar6eed9402013-08-06 22:53:11 +0530189 struct cpufreq_policy *policy = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 unsigned long flags;
191
Viresh Kumar6eed9402013-08-06 22:53:11 +0530192 if (cpufreq_disabled() || (cpu >= nr_cpu_ids))
193 return NULL;
194
195 if (!down_read_trylock(&cpufreq_rwsem))
196 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197
198 /* get the cpufreq driver */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000199 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
Viresh Kumar6eed9402013-08-06 22:53:11 +0530201 if (cpufreq_driver) {
202 /* get the CPU */
203 policy = per_cpu(cpufreq_cpu_data, cpu);
204 if (policy)
205 kobject_get(&policy->kobj);
206 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200207
Viresh Kumar6eed9402013-08-06 22:53:11 +0530208 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530210 if (!policy)
Viresh Kumar6eed9402013-08-06 22:53:11 +0530211 up_read(&cpufreq_rwsem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530213 return policy;
Stephen Boyda9144432012-07-20 18:14:38 +0000214}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
216
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530217void cpufreq_cpu_put(struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000219 if (cpufreq_disabled())
220 return;
221
Viresh Kumar6eed9402013-08-06 22:53:11 +0530222 kobject_put(&policy->kobj);
223 up_read(&cpufreq_rwsem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224}
225EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
229 *********************************************************************/
230
231/**
232 * adjust_jiffies - adjust the system "loops_per_jiffy"
233 *
234 * This function alters the system "loops_per_jiffy" for the clock
235 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500236 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 * per-CPU loops_per_jiffy value wherever possible.
238 */
239#ifndef CONFIG_SMP
240static unsigned long l_p_j_ref;
Viresh Kumarbb176f72013-06-19 14:19:33 +0530241static unsigned int l_p_j_ref_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
Arjan van de Ven858119e2006-01-14 13:20:43 -0800243static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244{
245 if (ci->flags & CPUFREQ_CONST_LOOPS)
246 return;
247
248 if (!l_p_j_ref_freq) {
249 l_p_j_ref = loops_per_jiffy;
250 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200251 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530252 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 }
Viresh Kumarbb176f72013-06-19 14:19:33 +0530254 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700255 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530256 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
257 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200258 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530259 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 }
261}
262#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530263static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
264{
265 return;
266}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267#endif
268
Viresh Kumar0956df9c2013-06-19 14:19:34 +0530269static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530270 struct cpufreq_freqs *freqs, unsigned int state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271{
272 BUG_ON(irqs_disabled());
273
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000274 if (cpufreq_disabled())
275 return;
276
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200277 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200278 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800279 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 case CPUFREQ_PRECHANGE:
Viresh Kumar266c13d2013-07-02 16:36:28 +0530284 if (WARN(policy->transition_ongoing ==
285 cpumask_weight(policy->cpus),
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530286 "In middle of another frequency transition\n"))
287 return;
288
Viresh Kumar266c13d2013-07-02 16:36:28 +0530289 policy->transition_ongoing++;
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530290
Dave Jones32ee8c32006-02-28 00:43:23 -0500291 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800292 * which is not equal to what the cpufreq core thinks is
293 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200295 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800296 if ((policy) && (policy->cpu == freqs->cpu) &&
297 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200298 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800299 " %u, cpufreq assumed %u kHz.\n",
300 freqs->old, policy->cur);
301 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 }
303 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700304 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800305 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
307 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800308
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 case CPUFREQ_POSTCHANGE:
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530310 if (WARN(!policy->transition_ongoing,
311 "No frequency transition in progress\n"))
312 return;
313
Viresh Kumar266c13d2013-07-02 16:36:28 +0530314 policy->transition_ongoing--;
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530315
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200317 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200318 (unsigned long)freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100319 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700320 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800321 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800322 if (likely(policy) && likely(policy->cpu == freqs->cpu))
323 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324 break;
325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326}
Viresh Kumarbb176f72013-06-19 14:19:33 +0530327
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530328/**
329 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
330 * on frequency transition.
331 *
332 * This function calls the transition notifiers and the "adjust_jiffies"
333 * function. It is called twice on all CPU frequency changes that have
334 * external effects.
335 */
336void cpufreq_notify_transition(struct cpufreq_policy *policy,
337 struct cpufreq_freqs *freqs, unsigned int state)
338{
339 for_each_cpu(freqs->cpu, policy->cpus)
340 __cpufreq_notify_transition(policy, freqs, state);
341}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
343
344
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345/*********************************************************************
346 * SYSFS INTERFACE *
347 *********************************************************************/
348
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700349static struct cpufreq_governor *__find_governor(const char *str_governor)
350{
351 struct cpufreq_governor *t;
352
353 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500354 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700355 return t;
356
357 return NULL;
358}
359
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360/**
361 * cpufreq_parse_governor - parse a governor string
362 */
Dave Jones905d77c2008-03-05 14:28:32 -0500363static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 struct cpufreq_governor **governor)
365{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700366 int err = -EINVAL;
367
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200368 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700369 goto out;
370
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200371 if (cpufreq_driver->setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
373 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700374 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530375 } else if (!strnicmp(str_governor, "powersave",
376 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700378 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200380 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700382
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800383 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700384
385 t = __find_governor(str_governor);
386
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700387 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700388 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700389
Kees Cook1a8e1462011-05-04 08:38:56 -0700390 mutex_unlock(&cpufreq_governor_mutex);
391 ret = request_module("cpufreq_%s", str_governor);
392 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700393
Kees Cook1a8e1462011-05-04 08:38:56 -0700394 if (ret == 0)
395 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700396 }
397
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700398 if (t != NULL) {
399 *governor = t;
400 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700402
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800403 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 }
Dave Jones29464f22009-01-18 01:37:11 -0500405out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700406 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530410 * cpufreq_per_cpu_attr_read() / show_##file_name() -
411 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 *
413 * Write out information from cpufreq_driver->policy[cpu]; object must be
414 * "unsigned int".
415 */
416
Dave Jones32ee8c32006-02-28 00:43:23 -0500417#define show_one(file_name, object) \
418static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500419(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500420{ \
Dave Jones29464f22009-01-18 01:37:11 -0500421 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422}
423
424show_one(cpuinfo_min_freq, cpuinfo.min_freq);
425show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100426show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427show_one(scaling_min_freq, min);
428show_one(scaling_max_freq, max);
429show_one(scaling_cur_freq, cur);
430
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530431static int __cpufreq_set_policy(struct cpufreq_policy *policy,
432 struct cpufreq_policy *new_policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200433
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434/**
435 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
436 */
437#define store_one(file_name, object) \
438static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500439(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000441 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 struct cpufreq_policy new_policy; \
443 \
444 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
445 if (ret) \
446 return -EINVAL; \
447 \
Dave Jones29464f22009-01-18 01:37:11 -0500448 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 if (ret != 1) \
450 return -EINVAL; \
451 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200452 ret = __cpufreq_set_policy(policy, &new_policy); \
453 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 \
455 return ret ? ret : count; \
456}
457
Dave Jones29464f22009-01-18 01:37:11 -0500458store_one(scaling_min_freq, min);
459store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460
461/**
462 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
463 */
Dave Jones905d77c2008-03-05 14:28:32 -0500464static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
465 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800467 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 if (!cur_freq)
469 return sprintf(buf, "<unknown>");
470 return sprintf(buf, "%u\n", cur_freq);
471}
472
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473/**
474 * show_scaling_governor - show the current policy for the specified CPU
475 */
Dave Jones905d77c2008-03-05 14:28:32 -0500476static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477{
Dave Jones29464f22009-01-18 01:37:11 -0500478 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 return sprintf(buf, "powersave\n");
480 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
481 return sprintf(buf, "performance\n");
482 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200483 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500484 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 return -EINVAL;
486}
487
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488/**
489 * store_scaling_governor - store policy for the specified CPU
490 */
Dave Jones905d77c2008-03-05 14:28:32 -0500491static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
492 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000494 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 char str_governor[16];
496 struct cpufreq_policy new_policy;
497
498 ret = cpufreq_get_policy(&new_policy, policy->cpu);
499 if (ret)
500 return ret;
501
Dave Jones29464f22009-01-18 01:37:11 -0500502 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 if (ret != 1)
504 return -EINVAL;
505
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530506 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
507 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 return -EINVAL;
509
Viresh Kumarbb176f72013-06-19 14:19:33 +0530510 /*
511 * Do not use cpufreq_set_policy here or the user_policy.max
512 * will be wrongly overridden
513 */
Thomas Renninger7970e082006-04-13 15:14:04 +0200514 ret = __cpufreq_set_policy(policy, &new_policy);
515
516 policy->user_policy.policy = policy->policy;
517 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200518
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530519 if (ret)
520 return ret;
521 else
522 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523}
524
525/**
526 * show_scaling_driver - show the cpufreq driver currently loaded
527 */
Dave Jones905d77c2008-03-05 14:28:32 -0500528static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200530 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531}
532
533/**
534 * show_scaling_available_governors - show the available CPUfreq governors
535 */
Dave Jones905d77c2008-03-05 14:28:32 -0500536static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
537 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538{
539 ssize_t i = 0;
540 struct cpufreq_governor *t;
541
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200542 if (!cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 i += sprintf(buf, "performance powersave");
544 goto out;
545 }
546
547 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500548 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
549 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200551 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500553out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 i += sprintf(&buf[i], "\n");
555 return i;
556}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700557
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800558ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559{
560 ssize_t i = 0;
561 unsigned int cpu;
562
Rusty Russell835481d2009-01-04 05:18:06 -0800563 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 if (i)
565 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
566 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
567 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500568 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 }
570 i += sprintf(&buf[i], "\n");
571 return i;
572}
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800573EXPORT_SYMBOL_GPL(cpufreq_show_cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700575/**
576 * show_related_cpus - show the CPUs affected by each transition even if
577 * hw coordination is in use
578 */
579static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
580{
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800581 return cpufreq_show_cpus(policy->related_cpus, buf);
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700582}
583
584/**
585 * show_affected_cpus - show the CPUs affected by each transition
586 */
587static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
588{
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800589 return cpufreq_show_cpus(policy->cpus, buf);
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700590}
591
Venki Pallipadi9e769882007-10-26 10:18:21 -0700592static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500593 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700594{
595 unsigned int freq = 0;
596 unsigned int ret;
597
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700598 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700599 return -EINVAL;
600
601 ret = sscanf(buf, "%u", &freq);
602 if (ret != 1)
603 return -EINVAL;
604
605 policy->governor->store_setspeed(policy, freq);
606
607 return count;
608}
609
610static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
611{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700612 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700613 return sprintf(buf, "<unsupported>\n");
614
615 return policy->governor->show_setspeed(policy, buf);
616}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617
Thomas Renningere2f74f32009-11-19 12:31:01 +0100618/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200619 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100620 */
621static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
622{
623 unsigned int limit;
624 int ret;
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200625 if (cpufreq_driver->bios_limit) {
626 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
Thomas Renningere2f74f32009-11-19 12:31:01 +0100627 if (!ret)
628 return sprintf(buf, "%u\n", limit);
629 }
630 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
631}
632
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200633cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
634cpufreq_freq_attr_ro(cpuinfo_min_freq);
635cpufreq_freq_attr_ro(cpuinfo_max_freq);
636cpufreq_freq_attr_ro(cpuinfo_transition_latency);
637cpufreq_freq_attr_ro(scaling_available_governors);
638cpufreq_freq_attr_ro(scaling_driver);
639cpufreq_freq_attr_ro(scaling_cur_freq);
640cpufreq_freq_attr_ro(bios_limit);
641cpufreq_freq_attr_ro(related_cpus);
642cpufreq_freq_attr_ro(affected_cpus);
643cpufreq_freq_attr_rw(scaling_min_freq);
644cpufreq_freq_attr_rw(scaling_max_freq);
645cpufreq_freq_attr_rw(scaling_governor);
646cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
Dave Jones905d77c2008-03-05 14:28:32 -0500648static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 &cpuinfo_min_freq.attr,
650 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100651 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 &scaling_min_freq.attr,
653 &scaling_max_freq.attr,
654 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700655 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 &scaling_governor.attr,
657 &scaling_driver.attr,
658 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700659 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 NULL
661};
662
Dave Jones29464f22009-01-18 01:37:11 -0500663#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
664#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
Dave Jones29464f22009-01-18 01:37:11 -0500666static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667{
Dave Jones905d77c2008-03-05 14:28:32 -0500668 struct cpufreq_policy *policy = to_policy(kobj);
669 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500670 ssize_t ret = -EINVAL;
Viresh Kumar6eed9402013-08-06 22:53:11 +0530671
672 if (!down_read_trylock(&cpufreq_rwsem))
673 goto exit;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800674
675 if (lock_policy_rwsem_read(policy->cpu) < 0)
Viresh Kumar6eed9402013-08-06 22:53:11 +0530676 goto up_read;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800677
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530678 if (fattr->show)
679 ret = fattr->show(policy, buf);
680 else
681 ret = -EIO;
682
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800683 unlock_policy_rwsem_read(policy->cpu);
Viresh Kumar6eed9402013-08-06 22:53:11 +0530684
685up_read:
686 up_read(&cpufreq_rwsem);
687exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 return ret;
689}
690
Dave Jones905d77c2008-03-05 14:28:32 -0500691static ssize_t store(struct kobject *kobj, struct attribute *attr,
692 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693{
Dave Jones905d77c2008-03-05 14:28:32 -0500694 struct cpufreq_policy *policy = to_policy(kobj);
695 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500696 ssize_t ret = -EINVAL;
Viresh Kumar6eed9402013-08-06 22:53:11 +0530697
698 if (!down_read_trylock(&cpufreq_rwsem))
699 goto exit;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800700
701 if (lock_policy_rwsem_write(policy->cpu) < 0)
Viresh Kumar6eed9402013-08-06 22:53:11 +0530702 goto up_read;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800703
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530704 if (fattr->store)
705 ret = fattr->store(policy, buf, count);
706 else
707 ret = -EIO;
708
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800709 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar6eed9402013-08-06 22:53:11 +0530710
711up_read:
712 up_read(&cpufreq_rwsem);
713exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 return ret;
715}
716
Dave Jones905d77c2008-03-05 14:28:32 -0500717static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718{
Dave Jones905d77c2008-03-05 14:28:32 -0500719 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200720 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 complete(&policy->kobj_unregister);
722}
723
Emese Revfy52cf25d2010-01-19 02:58:23 +0100724static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 .show = show,
726 .store = store,
727};
728
729static struct kobj_type ktype_cpufreq = {
730 .sysfs_ops = &sysfs_ops,
731 .default_attrs = default_attrs,
732 .release = cpufreq_sysfs_release,
733};
734
Viresh Kumar2361be22013-05-17 16:09:09 +0530735struct kobject *cpufreq_global_kobject;
736EXPORT_SYMBOL(cpufreq_global_kobject);
737
738static int cpufreq_global_kobject_usage;
739
740int cpufreq_get_global_kobject(void)
741{
742 if (!cpufreq_global_kobject_usage++)
743 return kobject_add(cpufreq_global_kobject,
744 &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
745
746 return 0;
747}
748EXPORT_SYMBOL(cpufreq_get_global_kobject);
749
750void cpufreq_put_global_kobject(void)
751{
752 if (!--cpufreq_global_kobject_usage)
753 kobject_del(cpufreq_global_kobject);
754}
755EXPORT_SYMBOL(cpufreq_put_global_kobject);
756
757int cpufreq_sysfs_create_file(const struct attribute *attr)
758{
759 int ret = cpufreq_get_global_kobject();
760
761 if (!ret) {
762 ret = sysfs_create_file(cpufreq_global_kobject, attr);
763 if (ret)
764 cpufreq_put_global_kobject();
765 }
766
767 return ret;
768}
769EXPORT_SYMBOL(cpufreq_sysfs_create_file);
770
771void cpufreq_sysfs_remove_file(const struct attribute *attr)
772{
773 sysfs_remove_file(cpufreq_global_kobject, attr);
774 cpufreq_put_global_kobject();
775}
776EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
777
Dave Jones19d6f7e2009-07-08 17:35:39 -0400778/* symlink affected CPUs */
Viresh Kumar308b60e2013-07-31 14:35:14 +0200779static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400780{
781 unsigned int j;
782 int ret = 0;
783
784 for_each_cpu(j, policy->cpus) {
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800785 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400786
Viresh Kumar308b60e2013-07-31 14:35:14 +0200787 if (j == policy->cpu)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400788 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400789
Viresh Kumare8fdde12013-07-31 14:31:33 +0200790 pr_debug("Adding link for CPU: %u\n", j);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800791 cpu_dev = get_cpu_device(j);
792 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400793 "cpufreq");
Rafael J. Wysocki71c34612013-08-04 01:19:34 +0200794 if (ret)
795 break;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400796 }
797 return ret;
798}
799
Viresh Kumar308b60e2013-07-31 14:35:14 +0200800static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800801 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400802{
803 struct freq_attr **drv_attr;
Dave Jones909a6942009-07-08 18:05:42 -0400804 int ret = 0;
Dave Jones909a6942009-07-08 18:05:42 -0400805
806 /* prepare interface data */
807 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800808 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400809 if (ret)
810 return ret;
811
812 /* set up files for this cpu device */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200813 drv_attr = cpufreq_driver->attr;
Dave Jones909a6942009-07-08 18:05:42 -0400814 while ((drv_attr) && (*drv_attr)) {
815 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
816 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200817 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400818 drv_attr++;
819 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200820 if (cpufreq_driver->get) {
Dave Jones909a6942009-07-08 18:05:42 -0400821 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
822 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200823 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400824 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200825 if (cpufreq_driver->target) {
Dave Jones909a6942009-07-08 18:05:42 -0400826 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
827 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200828 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400829 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200830 if (cpufreq_driver->bios_limit) {
Thomas Renningere2f74f32009-11-19 12:31:01 +0100831 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
832 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200833 goto err_out_kobj_put;
Thomas Renningere2f74f32009-11-19 12:31:01 +0100834 }
Dave Jones909a6942009-07-08 18:05:42 -0400835
Viresh Kumar308b60e2013-07-31 14:35:14 +0200836 ret = cpufreq_add_dev_symlink(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400837 if (ret)
838 goto err_out_kobj_put;
839
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +0530840 return ret;
841
842err_out_kobj_put:
843 kobject_put(&policy->kobj);
844 wait_for_completion(&policy->kobj_unregister);
845 return ret;
846}
847
848static void cpufreq_init_policy(struct cpufreq_policy *policy)
849{
850 struct cpufreq_policy new_policy;
851 int ret = 0;
852
Viresh Kumard5b73cd2013-08-06 22:53:06 +0530853 memcpy(&new_policy, policy, sizeof(*policy));
Dave Jonesecf7e462009-07-08 18:48:47 -0400854 /* assure that the starting sequence is run in __cpufreq_set_policy */
855 policy->governor = NULL;
856
857 /* set default policy */
858 ret = __cpufreq_set_policy(policy, &new_policy);
859 policy->user_policy.policy = policy->policy;
860 policy->user_policy.governor = policy->governor;
861
862 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200863 pr_debug("setting policy failed\n");
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200864 if (cpufreq_driver->exit)
865 cpufreq_driver->exit(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400866 }
Dave Jones909a6942009-07-08 18:05:42 -0400867}
868
Viresh Kumarfcf80582013-01-29 14:39:08 +0000869#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumard8d3b472013-08-04 01:20:07 +0200870static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
871 unsigned int cpu, struct device *dev,
872 bool frozen)
Viresh Kumarfcf80582013-01-29 14:39:08 +0000873{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200874 int ret = 0, has_target = !!cpufreq_driver->target;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000875 unsigned long flags;
876
Viresh Kumar3de9bde2013-08-06 22:53:13 +0530877 if (has_target) {
878 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
879 if (ret) {
880 pr_err("%s: Failed to stop governor\n", __func__);
881 return ret;
882 }
883 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000884
Viresh Kumard8d3b472013-08-04 01:20:07 +0200885 lock_policy_rwsem_write(policy->cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530886
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000887 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530888
Viresh Kumarfcf80582013-01-29 14:39:08 +0000889 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530890 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000891 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000892 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000893
Viresh Kumard8d3b472013-08-04 01:20:07 +0200894 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530895
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200896 if (has_target) {
Viresh Kumar3de9bde2013-08-06 22:53:13 +0530897 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
898 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
899 pr_err("%s: Failed to start governor\n", __func__);
900 return ret;
901 }
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200902 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000903
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530904 /* Don't touch sysfs links during light-weight init */
Rafael J. Wysocki71c34612013-08-04 01:19:34 +0200905 if (!frozen)
906 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
Viresh Kumarfcf80582013-01-29 14:39:08 +0000907
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530908 return ret;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000909}
910#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911
Srivatsa S. Bhat84148092013-07-30 04:25:10 +0530912static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
913{
914 struct cpufreq_policy *policy;
915 unsigned long flags;
916
917 write_lock_irqsave(&cpufreq_driver_lock, flags);
918
919 policy = per_cpu(cpufreq_cpu_data_fallback, cpu);
920
921 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
922
923 return policy;
924}
925
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530926static struct cpufreq_policy *cpufreq_policy_alloc(void)
927{
928 struct cpufreq_policy *policy;
929
930 policy = kzalloc(sizeof(*policy), GFP_KERNEL);
931 if (!policy)
932 return NULL;
933
934 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
935 goto err_free_policy;
936
937 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
938 goto err_free_cpumask;
939
Lukasz Majewskic88a1f82013-08-06 22:53:08 +0530940 INIT_LIST_HEAD(&policy->policy_list);
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530941 return policy;
942
943err_free_cpumask:
944 free_cpumask_var(policy->cpus);
945err_free_policy:
946 kfree(policy);
947
948 return NULL;
949}
950
951static void cpufreq_policy_free(struct cpufreq_policy *policy)
952{
Lukasz Majewskic88a1f82013-08-06 22:53:08 +0530953 unsigned long flags;
954
955 write_lock_irqsave(&cpufreq_driver_lock, flags);
956 list_del(&policy->policy_list);
957 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
958
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530959 free_cpumask_var(policy->related_cpus);
960 free_cpumask_var(policy->cpus);
961 kfree(policy);
962}
963
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530964static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
965 bool frozen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000967 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530968 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500971#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000972 struct cpufreq_governor *gov;
Rafael J. Wysocki878f6e02013-08-18 15:35:59 +0200973 int sibling;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500974#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
Ashok Rajc32b6b82005-10-30 14:59:54 -0800976 if (cpu_is_offline(cpu))
977 return 0;
978
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200979 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
981#ifdef CONFIG_SMP
982 /* check whether a different CPU already registered this
983 * CPU because it is in the same boat. */
984 policy = cpufreq_cpu_get(cpu);
985 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500986 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 return 0;
988 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000989
Viresh Kumar6eed9402013-08-06 22:53:11 +0530990 if (!down_read_trylock(&cpufreq_rwsem))
991 return 0;
992
Viresh Kumarfcf80582013-01-29 14:39:08 +0000993#ifdef CONFIG_HOTPLUG_CPU
994 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000995 read_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki878f6e02013-08-18 15:35:59 +0200996 for_each_online_cpu(sibling) {
997 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
998 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000999 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Rafael J. Wysocki878f6e02013-08-18 15:35:59 +02001000 ret = cpufreq_add_policy_cpu(cp, cpu, dev, frozen);
Viresh Kumar6eed9402013-08-06 22:53:11 +05301001 up_read(&cpufreq_rwsem);
1002 return ret;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301003 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001004 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001005 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +00001006#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007#endif
1008
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301009 if (frozen)
1010 /* Restore the saved policy when doing light-weight init */
1011 policy = cpufreq_policy_restore(cpu);
1012 else
1013 policy = cpufreq_policy_alloc();
1014
Dave Jones059019a2009-07-08 16:30:03 -04001015 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -04001017
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +05301019 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -08001020 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001022 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +09001023 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001024
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +00001026 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027
1028 /* call driver. From then on the cpufreq must be able
1029 * to accept all calls to ->verify and ->setpolicy for this CPU
1030 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001031 ret = cpufreq_driver->init(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001033 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301034 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001036
Viresh Kumarfcf80582013-01-29 14:39:08 +00001037 /* related cpus should atleast have policy->cpus */
1038 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1039
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001040 /*
1041 * affected cpus must always be the one, which are online. We aren't
1042 * managing offline cpus here.
1043 */
1044 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
1045
Mike Chan187d9f42008-12-04 12:19:17 -08001046 policy->user_policy.min = policy->min;
1047 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Thomas Renningera1531ac2008-07-29 22:32:58 -07001049 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1050 CPUFREQ_START, policy);
1051
Viresh Kumarfcf80582013-01-29 14:39:08 +00001052#ifdef CONFIG_HOTPLUG_CPU
1053 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
1054 if (gov) {
1055 policy->governor = gov;
1056 pr_debug("Restoring governor %s for cpu %d\n",
1057 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001058 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001059#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301061 write_lock_irqsave(&cpufreq_driver_lock, flags);
1062 for_each_cpu(j, policy->cpus) {
1063 per_cpu(cpufreq_cpu_data, j) = policy;
1064 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
1065 }
1066 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1067
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301068 if (!frozen) {
Viresh Kumar308b60e2013-07-31 14:35:14 +02001069 ret = cpufreq_add_dev_interface(policy, dev);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301070 if (ret)
1071 goto err_out_unregister;
Lukasz Majewskic88a1f82013-08-06 22:53:08 +05301072
1073 write_lock_irqsave(&cpufreq_driver_lock, flags);
1074 list_add(&policy->policy_list, &cpufreq_policy_list);
1075 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301076 }
Dave Jones8ff69732006-03-05 03:37:23 -05001077
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301078 cpufreq_init_policy(policy);
1079
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001080 kobject_uevent(&policy->kobj, KOBJ_ADD);
Viresh Kumar6eed9402013-08-06 22:53:11 +05301081 up_read(&cpufreq_rwsem);
1082
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001083 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001084
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 return 0;
1086
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001088 write_lock_irqsave(&cpufreq_driver_lock, flags);
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301089 for_each_cpu(j, policy->cpus) {
Mike Travis7a6aedf2008-03-25 15:06:53 -07001090 per_cpu(cpufreq_cpu_data, j) = NULL;
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301091 if (j != cpu)
1092 per_cpu(cpufreq_policy_cpu, j) = -1;
1093 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001094 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301096err_set_policy_cpu:
1097 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +05301098 cpufreq_policy_free(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001099nomem_out:
Viresh Kumar6eed9402013-08-06 22:53:11 +05301100 up_read(&cpufreq_rwsem);
1101
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102 return ret;
1103}
1104
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301105/**
1106 * cpufreq_add_dev - add a CPU device
1107 *
1108 * Adds the cpufreq interface for a CPU device.
1109 *
1110 * The Oracle says: try running cpufreq registration/unregistration concurrently
1111 * with with cpu hotplugging and all hell will break loose. Tried to clean this
1112 * mess up, but more thorough testing is needed. - Mathieu
1113 */
1114static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
1115{
1116 return __cpufreq_add_dev(dev, sif, false);
1117}
1118
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001119static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1120{
1121 int j;
1122
1123 policy->last_cpu = policy->cpu;
1124 policy->cpu = cpu;
1125
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001126 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001127 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001128
1129#ifdef CONFIG_CPU_FREQ_TABLE
1130 cpufreq_frequency_table_update_policy_cpu(policy);
1131#endif
1132 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1133 CPUFREQ_UPDATE_POLICY_CPU, policy);
1134}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301136static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301137 unsigned int old_cpu, bool frozen)
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301138{
1139 struct device *cpu_dev;
1140 unsigned long flags;
1141 int ret;
1142
1143 /* first sibling now owns the new sysfs dir */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301144 cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301145
1146 /* Don't touch sysfs files during light-weight tear-down */
1147 if (frozen)
1148 return cpu_dev->id;
1149
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301150 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301151 ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301152 if (ret) {
1153 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1154
1155 WARN_ON(lock_policy_rwsem_write(old_cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301156 cpumask_set_cpu(old_cpu, policy->cpus);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301157
1158 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301159 per_cpu(cpufreq_cpu_data, old_cpu) = policy;
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301160 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1161
1162 unlock_policy_rwsem_write(old_cpu);
1163
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301164 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301165 "cpufreq");
1166
1167 return -EINVAL;
1168 }
1169
1170 return cpu_dev->id;
1171}
1172
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001174 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 *
1176 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001177 * Caller should already have policy_rwsem in write mode for this CPU.
1178 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 */
Viresh Kumarbb176f72013-06-19 14:19:33 +05301180static int __cpufreq_remove_dev(struct device *dev,
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301181 struct subsys_interface *sif, bool frozen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182{
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301183 unsigned int cpu = dev->id, cpus;
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301184 int new_cpu, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185 unsigned long flags;
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301186 struct cpufreq_policy *policy;
Amerigo Wang499bca92010-03-04 03:23:46 -05001187 struct kobject *kobj;
1188 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001190 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001192 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301194 policy = per_cpu(cpufreq_cpu_data, cpu);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001195 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301197 /* Save the policy somewhere when doing a light-weight tear-down */
1198 if (frozen)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301199 per_cpu(cpufreq_cpu_data_fallback, cpu) = policy;
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301200
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001201 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301203 if (!policy) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001204 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301208 if (cpufreq_driver->target) {
1209 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1210 if (ret) {
1211 pr_err("%s: Failed to stop governor\n", __func__);
1212 return ret;
1213 }
1214 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001215
Jacob Shin27ecddc2011-04-27 13:32:11 -05001216#ifdef CONFIG_HOTPLUG_CPU
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001217 if (!cpufreq_driver->setpolicy)
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001218 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301219 policy->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001220#endif
1221
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301222 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301223 cpus = cpumask_weight(policy->cpus);
Viresh Kumare4969eb2013-04-11 08:04:53 +00001224
1225 if (cpus > 1)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301226 cpumask_clear_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301227 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301229 if (cpu != policy->cpu && !frozen) {
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001230 sysfs_remove_link(&dev->kobj, "cpufreq");
1231 } else if (cpus > 1) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301232
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301233 new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301234 if (new_cpu >= 0) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301235 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301236 update_policy_cpu(policy, new_cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301237 unlock_policy_rwsem_write(cpu);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301238
1239 if (!frozen) {
1240 pr_debug("%s: policy Kobject moved to cpu: %d "
1241 "from: %d\n",__func__, new_cpu, cpu);
1242 }
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001243 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001244 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001245
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001246 /* If cpu is last user of policy, free policy */
1247 if (cpus == 1) {
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301248 if (cpufreq_driver->target) {
1249 ret = __cpufreq_governor(policy,
1250 CPUFREQ_GOV_POLICY_EXIT);
1251 if (ret) {
1252 pr_err("%s: Failed to exit governor\n",
1253 __func__);
1254 return ret;
1255 }
1256 }
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001257
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301258 if (!frozen) {
1259 lock_policy_rwsem_read(cpu);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301260 kobj = &policy->kobj;
1261 cmp = &policy->kobj_unregister;
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301262 unlock_policy_rwsem_read(cpu);
1263 kobject_put(kobj);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001264
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301265 /*
1266 * We need to make sure that the underlying kobj is
1267 * actually not referenced anymore by anybody before we
1268 * proceed with unloading.
1269 */
1270 pr_debug("waiting for dropping of refcount\n");
1271 wait_for_completion(cmp);
1272 pr_debug("wait complete\n");
1273 }
1274
1275 /*
1276 * Perform the ->exit() even during light-weight tear-down,
1277 * since this is a core component, and is essential for the
1278 * subsequent light-weight ->init() to succeed.
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001279 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001280 if (cpufreq_driver->exit)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301281 cpufreq_driver->exit(policy);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001282
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301283 if (!frozen)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301284 cpufreq_policy_free(policy);
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001285 } else {
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001286 if (cpufreq_driver->target) {
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301287 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
1288 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
1289 pr_err("%s: Failed to start governor\n",
1290 __func__);
1291 return ret;
1292 }
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001293 }
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001294 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301296 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 return 0;
1298}
1299
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001300static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001301{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001302 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001303 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001304
1305 if (cpu_is_offline(cpu))
1306 return 0;
1307
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301308 retval = __cpufreq_remove_dev(dev, sif, false);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001309 return retval;
1310}
1311
David Howells65f27f32006-11-22 14:55:48 +00001312static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313{
David Howells65f27f32006-11-22 14:55:48 +00001314 struct cpufreq_policy *policy =
1315 container_of(work, struct cpufreq_policy, update);
1316 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001317 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 cpufreq_update_policy(cpu);
1319}
1320
1321/**
Viresh Kumarbb176f72013-06-19 14:19:33 +05301322 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're
1323 * in deep trouble.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 * @cpu: cpu number
1325 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1326 * @new_freq: CPU frequency the CPU actually runs at
1327 *
Dave Jones29464f22009-01-18 01:37:11 -05001328 * We adjust to current frequency first, and need to clean up later.
1329 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301331static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1332 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333{
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301334 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 struct cpufreq_freqs freqs;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301336 unsigned long flags;
1337
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001338 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1340
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 freqs.old = old_freq;
1342 freqs.new = new_freq;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301343
1344 read_lock_irqsave(&cpufreq_driver_lock, flags);
1345 policy = per_cpu(cpufreq_cpu_data, cpu);
1346 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1347
1348 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
1349 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350}
1351
Dave Jones32ee8c32006-02-28 00:43:23 -05001352/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301353 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001354 * @cpu: CPU number
1355 *
1356 * This is the last known freq, without actually getting it from the driver.
1357 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1358 */
1359unsigned int cpufreq_quick_get(unsigned int cpu)
1360{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001361 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301362 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001363
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001364 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1365 return cpufreq_driver->get(cpu);
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001366
1367 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001368 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301369 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001370 cpufreq_cpu_put(policy);
1371 }
1372
Dave Jones4d34a672008-02-07 16:33:49 -05001373 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001374}
1375EXPORT_SYMBOL(cpufreq_quick_get);
1376
Jesse Barnes3d737102011-06-28 10:59:12 -07001377/**
1378 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1379 * @cpu: CPU number
1380 *
1381 * Just return the max possible frequency for a given CPU.
1382 */
1383unsigned int cpufreq_quick_get_max(unsigned int cpu)
1384{
1385 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1386 unsigned int ret_freq = 0;
1387
1388 if (policy) {
1389 ret_freq = policy->max;
1390 cpufreq_cpu_put(policy);
1391 }
1392
1393 return ret_freq;
1394}
1395EXPORT_SYMBOL(cpufreq_quick_get_max);
1396
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001397static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001399 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301400 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001402 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001403 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001405 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301407 if (ret_freq && policy->cur &&
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001408 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301409 /* verify no discrepancy between actual and
1410 saved value exists */
1411 if (unlikely(ret_freq != policy->cur)) {
1412 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 schedule_work(&policy->update);
1414 }
1415 }
1416
Dave Jones4d34a672008-02-07 16:33:49 -05001417 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001418}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001420/**
1421 * cpufreq_get - get the current CPU frequency (in kHz)
1422 * @cpu: CPU number
1423 *
1424 * Get the CPU current (static) CPU frequency
1425 */
1426unsigned int cpufreq_get(unsigned int cpu)
1427{
1428 unsigned int ret_freq = 0;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001429
Viresh Kumar6eed9402013-08-06 22:53:11 +05301430 if (!down_read_trylock(&cpufreq_rwsem))
1431 return 0;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001432
1433 if (unlikely(lock_policy_rwsem_read(cpu)))
1434 goto out_policy;
1435
1436 ret_freq = __cpufreq_get(cpu);
1437
1438 unlock_policy_rwsem_read(cpu);
1439
1440out_policy:
Viresh Kumar6eed9402013-08-06 22:53:11 +05301441 up_read(&cpufreq_rwsem);
1442
Dave Jones4d34a672008-02-07 16:33:49 -05001443 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444}
1445EXPORT_SYMBOL(cpufreq_get);
1446
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001447static struct subsys_interface cpufreq_interface = {
1448 .name = "cpufreq",
1449 .subsys = &cpu_subsys,
1450 .add_dev = cpufreq_add_dev,
1451 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001452};
1453
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001455 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1456 *
1457 * This function is only executed for the boot processor. The other CPUs
1458 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001459 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001460static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001461{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301462 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001463
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001464 int cpu = smp_processor_id();
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301465 struct cpufreq_policy *policy;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001466
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001467 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001468
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001469 /* If there's no policy for the boot CPU, we have nothing to do. */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301470 policy = cpufreq_cpu_get(cpu);
1471 if (!policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001472 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001473
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001474 if (cpufreq_driver->suspend) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301475 ret = cpufreq_driver->suspend(policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001476 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001477 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301478 "step on CPU %u\n", policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001479 }
1480
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301481 cpufreq_cpu_put(policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001482 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001483}
1484
1485/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001486 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 *
1488 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001489 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1490 * restored. It will verify that the current freq is in sync with
1491 * what we believe it to be. This is a bit later than when it
1492 * should be, but nonethteless it's better than calling
1493 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001494 *
1495 * This function is only executed for the boot CPU. The other CPUs have not
1496 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001498static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301500 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001501
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001502 int cpu = smp_processor_id();
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301503 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001505 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001507 /* If there's no policy for the boot CPU, we have nothing to do. */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301508 policy = cpufreq_cpu_get(cpu);
1509 if (!policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001510 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001512 if (cpufreq_driver->resume) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301513 ret = cpufreq_driver->resume(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 if (ret) {
1515 printk(KERN_ERR "cpufreq: resume failed in ->resume "
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301516 "step on CPU %u\n", policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001517 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 }
1519 }
1520
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301521 schedule_work(&policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001522
Dave Jonesc9060492008-02-07 16:32:18 -05001523fail:
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301524 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525}
1526
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001527static struct syscore_ops cpufreq_syscore_ops = {
1528 .suspend = cpufreq_bp_suspend,
1529 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530};
1531
Borislav Petkov9d950462013-01-20 10:24:28 +00001532/**
1533 * cpufreq_get_current_driver - return current driver's name
1534 *
1535 * Return the name string of the currently loaded cpufreq driver
1536 * or NULL, if none.
1537 */
1538const char *cpufreq_get_current_driver(void)
1539{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001540 if (cpufreq_driver)
1541 return cpufreq_driver->name;
1542
1543 return NULL;
Borislav Petkov9d950462013-01-20 10:24:28 +00001544}
1545EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547/*********************************************************************
1548 * NOTIFIER LISTS INTERFACE *
1549 *********************************************************************/
1550
1551/**
1552 * cpufreq_register_notifier - register a driver with cpufreq
1553 * @nb: notifier function to register
1554 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1555 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001556 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 * are notified about clock rate changes (once before and once after
1558 * the transition), or a list of drivers that are notified about
1559 * changes in cpufreq policy.
1560 *
1561 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001562 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 */
1564int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1565{
1566 int ret;
1567
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001568 if (cpufreq_disabled())
1569 return -EINVAL;
1570
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001571 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1572
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 switch (list) {
1574 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001575 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001576 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 break;
1578 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001579 ret = blocking_notifier_chain_register(
1580 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 break;
1582 default:
1583 ret = -EINVAL;
1584 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585
1586 return ret;
1587}
1588EXPORT_SYMBOL(cpufreq_register_notifier);
1589
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590/**
1591 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1592 * @nb: notifier block to be unregistered
Viresh Kumarbb176f72013-06-19 14:19:33 +05301593 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 *
1595 * Remove a driver from the CPU frequency notifier list.
1596 *
1597 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001598 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 */
1600int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1601{
1602 int ret;
1603
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001604 if (cpufreq_disabled())
1605 return -EINVAL;
1606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 switch (list) {
1608 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001609 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001610 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 break;
1612 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001613 ret = blocking_notifier_chain_unregister(
1614 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 break;
1616 default:
1617 ret = -EINVAL;
1618 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619
1620 return ret;
1621}
1622EXPORT_SYMBOL(cpufreq_unregister_notifier);
1623
1624
1625/*********************************************************************
1626 * GOVERNORS *
1627 *********************************************************************/
1628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629int __cpufreq_driver_target(struct cpufreq_policy *policy,
1630 unsigned int target_freq,
1631 unsigned int relation)
1632{
1633 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001634 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001635
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001636 if (cpufreq_disabled())
1637 return -ENODEV;
Viresh Kumar7c30ed52013-06-19 10:16:55 +05301638 if (policy->transition_ongoing)
1639 return -EBUSY;
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001640
Viresh Kumar72499242012-10-31 01:28:21 +01001641 /* Make sure that target_freq is within supported range */
1642 if (target_freq > policy->max)
1643 target_freq = policy->max;
1644 if (target_freq < policy->min)
1645 target_freq = policy->min;
1646
1647 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1648 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001649
1650 if (target_freq == policy->cur)
1651 return 0;
1652
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001653 if (cpufreq_driver->target)
1654 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001655
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 return retval;
1657}
1658EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1659
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660int cpufreq_driver_target(struct cpufreq_policy *policy,
1661 unsigned int target_freq,
1662 unsigned int relation)
1663{
Julia Lawallf1829e42008-07-25 22:44:53 +02001664 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001666 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001667 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
1669 ret = __cpufreq_driver_target(policy, target_freq, relation);
1670
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001671 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672
Julia Lawallf1829e42008-07-25 22:44:53 +02001673fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 return ret;
1675}
1676EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1677
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001678/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001679 * when "event" is CPUFREQ_GOV_LIMITS
1680 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301682static int __cpufreq_governor(struct cpufreq_policy *policy,
1683 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684{
Dave Jonescc993ca2005-07-28 09:43:56 -07001685 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001686
1687 /* Only must be defined when default governor is known to have latency
1688 restrictions, like e.g. conservative or ondemand.
1689 That this is the case is already ensured in Kconfig
1690 */
1691#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1692 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1693#else
1694 struct cpufreq_governor *gov = NULL;
1695#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001696
1697 if (policy->governor->max_transition_latency &&
1698 policy->cpuinfo.transition_latency >
1699 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001700 if (!gov)
1701 return -EINVAL;
1702 else {
1703 printk(KERN_WARNING "%s governor failed, too long"
1704 " transition latency of HW, fallback"
1705 " to %s governor\n",
1706 policy->governor->name,
1707 gov->name);
1708 policy->governor = gov;
1709 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001710 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
Viresh Kumarfe492f32013-08-06 22:53:10 +05301712 if (event == CPUFREQ_GOV_POLICY_INIT)
1713 if (!try_module_get(policy->governor->owner))
1714 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001716 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301717 policy->cpu, event);
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001718
1719 mutex_lock(&cpufreq_governor_lock);
1720 if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
1721 (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
1722 mutex_unlock(&cpufreq_governor_lock);
Viresh Kumarfe492f32013-08-06 22:53:10 +05301723 if (event == CPUFREQ_GOV_POLICY_INIT)
1724 module_put(policy->governor->owner);
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001725 return -EBUSY;
1726 }
1727
1728 if (event == CPUFREQ_GOV_STOP)
1729 policy->governor_enabled = false;
1730 else if (event == CPUFREQ_GOV_START)
1731 policy->governor_enabled = true;
1732
1733 mutex_unlock(&cpufreq_governor_lock);
1734
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 ret = policy->governor->governor(policy, event);
1736
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001737 if (!ret) {
1738 if (event == CPUFREQ_GOV_POLICY_INIT)
1739 policy->governor->initialized++;
1740 else if (event == CPUFREQ_GOV_POLICY_EXIT)
1741 policy->governor->initialized--;
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001742 } else {
1743 /* Restore original values */
1744 mutex_lock(&cpufreq_governor_lock);
1745 if (event == CPUFREQ_GOV_STOP)
1746 policy->governor_enabled = true;
1747 else if (event == CPUFREQ_GOV_START)
1748 policy->governor_enabled = false;
1749 mutex_unlock(&cpufreq_governor_lock);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001750 }
Viresh Kumarb3940582013-02-01 05:42:58 +00001751
Viresh Kumarfe492f32013-08-06 22:53:10 +05301752 if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
1753 ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 module_put(policy->governor->owner);
1755
1756 return ret;
1757}
1758
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759int cpufreq_register_governor(struct cpufreq_governor *governor)
1760{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001761 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
1763 if (!governor)
1764 return -EINVAL;
1765
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001766 if (cpufreq_disabled())
1767 return -ENODEV;
1768
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001769 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001770
Viresh Kumarb3940582013-02-01 05:42:58 +00001771 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001772 err = -EBUSY;
1773 if (__find_governor(governor->name) == NULL) {
1774 err = 0;
1775 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777
Dave Jones32ee8c32006-02-28 00:43:23 -05001778 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001779 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780}
1781EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1782
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1784{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001785#ifdef CONFIG_HOTPLUG_CPU
1786 int cpu;
1787#endif
1788
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 if (!governor)
1790 return;
1791
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001792 if (cpufreq_disabled())
1793 return;
1794
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001795#ifdef CONFIG_HOTPLUG_CPU
1796 for_each_present_cpu(cpu) {
1797 if (cpu_online(cpu))
1798 continue;
1799 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1800 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1801 }
1802#endif
1803
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001804 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001806 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 return;
1808}
1809EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1810
1811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812/*********************************************************************
1813 * POLICY INTERFACE *
1814 *********************************************************************/
1815
1816/**
1817 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001818 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1819 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 *
1821 * Reads the current cpufreq policy.
1822 */
1823int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1824{
1825 struct cpufreq_policy *cpu_policy;
1826 if (!policy)
1827 return -EINVAL;
1828
1829 cpu_policy = cpufreq_cpu_get(cpu);
1830 if (!cpu_policy)
1831 return -EINVAL;
1832
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301833 memcpy(policy, cpu_policy, sizeof(*policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 return 0;
1837}
1838EXPORT_SYMBOL(cpufreq_get_policy);
1839
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001840/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301841 * data : current policy.
1842 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001843 */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301844static int __cpufreq_set_policy(struct cpufreq_policy *policy,
1845 struct cpufreq_policy *new_policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001847 int ret = 0, failed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301849 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu,
1850 new_policy->min, new_policy->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301852 memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301854 if (new_policy->min > policy->max || new_policy->max < policy->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001855 ret = -EINVAL;
1856 goto error_out;
1857 }
1858
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 /* verify the cpu speed can be set within this limit */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301860 ret = cpufreq_driver->verify(new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 if (ret)
1862 goto error_out;
1863
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001865 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301866 CPUFREQ_ADJUST, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
1868 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001869 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301870 CPUFREQ_INCOMPATIBLE, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Viresh Kumarbb176f72013-06-19 14:19:33 +05301872 /*
1873 * verify the cpu speed can be set within this limit, which might be
1874 * different to the first one
1875 */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301876 ret = cpufreq_driver->verify(new_policy);
Alan Sterne041c682006-03-27 01:16:30 -08001877 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
1880 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001881 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301882 CPUFREQ_NOTIFY, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301884 policy->min = new_policy->min;
1885 policy->max = new_policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001887 pr_debug("new min and max freqs are %u - %u kHz\n",
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301888 policy->min, policy->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001890 if (cpufreq_driver->setpolicy) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301891 policy->policy = new_policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001892 pr_debug("setting range\n");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301893 ret = cpufreq_driver->setpolicy(new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301895 if (new_policy->governor != policy->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 /* save old, working values */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301897 struct cpufreq_governor *old_gov = policy->governor;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001899 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
1901 /* end old governor */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301902 if (policy->governor) {
1903 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1904 unlock_policy_rwsem_write(new_policy->cpu);
1905 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001906 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301907 lock_policy_rwsem_write(new_policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
1910 /* start new governor */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301911 policy->governor = new_policy->governor;
1912 if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
1913 if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001914 failed = 0;
Viresh Kumar955ef482013-05-16 05:09:58 +00001915 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301916 unlock_policy_rwsem_write(new_policy->cpu);
1917 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001918 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301919 lock_policy_rwsem_write(new_policy->cpu);
Viresh Kumar955ef482013-05-16 05:09:58 +00001920 }
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001921 }
1922
1923 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001925 pr_debug("starting governor %s failed\n",
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301926 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 if (old_gov) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301928 policy->governor = old_gov;
1929 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001930 CPUFREQ_GOV_POLICY_INIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301931 __cpufreq_governor(policy,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301932 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 }
1934 ret = -EINVAL;
1935 goto error_out;
1936 }
1937 /* might be a policy change, too, so fall through */
1938 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001939 pr_debug("governor: change or update limits\n");
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301940 ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 }
1942
Dave Jones7d5e3502006-02-02 17:03:42 -05001943error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 return ret;
1945}
1946
1947/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1949 * @cpu: CPU which shall be re-evaluated
1950 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001951 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 * at different times.
1953 */
1954int cpufreq_update_policy(unsigned int cpu)
1955{
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301956 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1957 struct cpufreq_policy new_policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001958 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301960 if (!policy) {
Julia Lawallf1829e42008-07-25 22:44:53 +02001961 ret = -ENODEV;
1962 goto no_policy;
1963 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964
Julia Lawallf1829e42008-07-25 22:44:53 +02001965 if (unlikely(lock_policy_rwsem_write(cpu))) {
1966 ret = -EINVAL;
1967 goto fail;
1968 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001970 pr_debug("updating policy for CPU %u\n", cpu);
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301971 memcpy(&new_policy, policy, sizeof(*policy));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301972 new_policy.min = policy->user_policy.min;
1973 new_policy.max = policy->user_policy.max;
1974 new_policy.policy = policy->user_policy.policy;
1975 new_policy.governor = policy->user_policy.governor;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976
Viresh Kumarbb176f72013-06-19 14:19:33 +05301977 /*
1978 * BIOS might change freq behind our back
1979 * -> ask driver for current freq and notify governors about a change
1980 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001981 if (cpufreq_driver->get) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301982 new_policy.cur = cpufreq_driver->get(cpu);
1983 if (!policy->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001984 pr_debug("Driver did not initialize current freq");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301985 policy->cur = new_policy.cur;
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001986 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301987 if (policy->cur != new_policy.cur && cpufreq_driver->target)
1988 cpufreq_out_of_sync(cpu, policy->cur,
1989 new_policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001990 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001991 }
1992
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301993 ret = __cpufreq_set_policy(policy, &new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001995 unlock_policy_rwsem_write(cpu);
1996
Julia Lawallf1829e42008-07-25 22:44:53 +02001997fail:
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301998 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001999no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 return ret;
2001}
2002EXPORT_SYMBOL(cpufreq_update_policy);
2003
Paul Gortmaker27609842013-06-19 13:54:04 -04002004static int cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08002005 unsigned long action, void *hcpu)
2006{
2007 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002008 struct device *dev;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302009 bool frozen = false;
Ashok Rajc32b6b82005-10-30 14:59:54 -08002010
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002011 dev = get_cpu_device(cpu);
2012 if (dev) {
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302013
2014 if (action & CPU_TASKS_FROZEN)
2015 frozen = true;
2016
2017 switch (action & ~CPU_TASKS_FROZEN) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08002018 case CPU_ONLINE:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302019 __cpufreq_add_dev(dev, NULL, frozen);
Srivatsa S. Bhat23d328992013-07-30 04:23:56 +05302020 cpufreq_update_policy(cpu);
Ashok Rajc32b6b82005-10-30 14:59:54 -08002021 break;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302022
Ashok Rajc32b6b82005-10-30 14:59:54 -08002023 case CPU_DOWN_PREPARE:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302024 __cpufreq_remove_dev(dev, NULL, frozen);
Ashok Rajc32b6b82005-10-30 14:59:54 -08002025 break;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302026
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002027 case CPU_DOWN_FAILED:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302028 __cpufreq_add_dev(dev, NULL, frozen);
Ashok Rajc32b6b82005-10-30 14:59:54 -08002029 break;
2030 }
2031 }
2032 return NOTIFY_OK;
2033}
2034
Neal Buckendahl9c36f742010-06-22 22:02:44 -05002035static struct notifier_block __refdata cpufreq_cpu_notifier = {
Viresh Kumarbb176f72013-06-19 14:19:33 +05302036 .notifier_call = cpufreq_cpu_callback,
Ashok Rajc32b6b82005-10-30 14:59:54 -08002037};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038
2039/*********************************************************************
2040 * REGISTER / UNREGISTER CPUFREQ DRIVER *
2041 *********************************************************************/
2042
2043/**
2044 * cpufreq_register_driver - register a CPU Frequency driver
2045 * @driver_data: A struct cpufreq_driver containing the values#
2046 * submitted by the CPU Frequency driver.
2047 *
Viresh Kumarbb176f72013-06-19 14:19:33 +05302048 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05002050 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 *
2052 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002053int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054{
2055 unsigned long flags;
2056 int ret;
2057
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002058 if (cpufreq_disabled())
2059 return -ENODEV;
2060
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 if (!driver_data || !driver_data->verify || !driver_data->init ||
2062 ((!driver_data->setpolicy) && (!driver_data->target)))
2063 return -EINVAL;
2064
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002065 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066
2067 if (driver_data->setpolicy)
2068 driver_data->flags |= CPUFREQ_CONST_LOOPS;
2069
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002070 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002071 if (cpufreq_driver) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002072 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 return -EBUSY;
2074 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002075 cpufreq_driver = driver_data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002076 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002078 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002079 if (ret)
2080 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002082 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 int i;
2084 ret = -ENODEV;
2085
2086 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07002087 for (i = 0; i < nr_cpu_ids; i++)
2088 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07002090 break;
2091 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092
2093 /* if all ->init() calls failed, unregister */
2094 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002095 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05302096 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002097 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 }
2099 }
2100
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002101 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002102 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002104 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002105err_if_unreg:
2106 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002107err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002108 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002109 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002110 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05002111 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112}
2113EXPORT_SYMBOL_GPL(cpufreq_register_driver);
2114
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115/**
2116 * cpufreq_unregister_driver - unregister the current CPUFreq driver
2117 *
Viresh Kumarbb176f72013-06-19 14:19:33 +05302118 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 * the right to do so, i.e. if you have succeeded in initialising before!
2120 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
2121 * currently not initialised.
2122 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002123int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124{
2125 unsigned long flags;
2126
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002127 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002130 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002132 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07002133 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134
Viresh Kumar6eed9402013-08-06 22:53:11 +05302135 down_write(&cpufreq_rwsem);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002136 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar6eed9402013-08-06 22:53:11 +05302137
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002138 cpufreq_driver = NULL;
Viresh Kumar6eed9402013-08-06 22:53:11 +05302139
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002140 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar6eed9402013-08-06 22:53:11 +05302141 up_write(&cpufreq_rwsem);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142
2143 return 0;
2144}
2145EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002146
2147static int __init cpufreq_core_init(void)
2148{
2149 int cpu;
2150
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002151 if (cpufreq_disabled())
2152 return -ENODEV;
2153
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002154 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09002155 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002156 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
2157 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002158
Viresh Kumar2361be22013-05-17 16:09:09 +05302159 cpufreq_global_kobject = kobject_create();
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002160 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002161 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002162
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002163 return 0;
2164}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002165core_initcall(cpufreq_core_init);