blob: 81ceea6ed630af1836bc36b21cff6f50f1e6865a [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 */
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080067static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
68
69#define lock_policy_rwsem(mode, cpu) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053070static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080071{ \
Viresh Kumar474deff2013-08-20 12:08:25 +053072 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \
73 BUG_ON(!policy); \
74 down_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080075 \
76 return 0; \
77}
78
79lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080080lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080081
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053082#define unlock_policy_rwsem(mode, cpu) \
83static void unlock_policy_rwsem_##mode(int cpu) \
84{ \
Viresh Kumar474deff2013-08-20 12:08:25 +053085 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \
86 BUG_ON(!policy); \
87 up_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080088}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080089
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053090unlock_policy_rwsem(read, cpu);
91unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080092
Viresh Kumar6eed9402013-08-06 22:53:11 +053093/*
94 * rwsem to guarantee that cpufreq driver module doesn't unload during critical
95 * sections
96 */
97static DECLARE_RWSEM(cpufreq_rwsem);
98
Linus Torvalds1da177e2005-04-16 15:20:36 -070099/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -0500100static int __cpufreq_governor(struct cpufreq_policy *policy,
101 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800102static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000103static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
105/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500106 * Two notifier lists: the "policy" list is involved in the
107 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 * "transition" list for kernel code that needs to handle
109 * changes to devices when the CPU clock speed changes.
110 * The mutex locks both lists.
111 */
Alan Sterne041c682006-03-27 01:16:30 -0800112static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700113static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200115static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700116static int __init init_cpufreq_transition_notifier_list(void)
117{
118 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200119 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700120 return 0;
121}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800122pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400124static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200125static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400126{
127 return off;
128}
129void disable_cpufreq(void)
130{
131 off = 1;
132}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500134static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000136bool have_governor_per_policy(void)
137{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200138 return cpufreq_driver->have_governor_per_policy;
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000139}
Viresh Kumar3f869d62013-05-16 05:09:56 +0000140EXPORT_SYMBOL_GPL(have_governor_per_policy);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000141
Viresh Kumar944e9a02013-05-16 05:09:57 +0000142struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
143{
144 if (have_governor_per_policy())
145 return &policy->kobj;
146 else
147 return cpufreq_global_kobject;
148}
149EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
150
Viresh Kumar72a4ce32013-05-17 11:26:32 +0000151static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
152{
153 u64 idle_time;
154 u64 cur_wall_time;
155 u64 busy_time;
156
157 cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
158
159 busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
160 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
161 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
162 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
163 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
164 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
165
166 idle_time = cur_wall_time - busy_time;
167 if (wall)
168 *wall = cputime_to_usecs(cur_wall_time);
169
170 return cputime_to_usecs(idle_time);
171}
172
173u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
174{
175 u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
176
177 if (idle_time == -1ULL)
178 return get_cpu_idle_time_jiffy(cpu, wall);
179 else if (!io_busy)
180 idle_time += get_cpu_iowait_time_us(cpu, wall);
181
182 return idle_time;
183}
184EXPORT_SYMBOL_GPL(get_cpu_idle_time);
185
Viresh Kumar6eed9402013-08-06 22:53:11 +0530186struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187{
Viresh Kumar6eed9402013-08-06 22:53:11 +0530188 struct cpufreq_policy *policy = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 unsigned long flags;
190
Viresh Kumar6eed9402013-08-06 22:53:11 +0530191 if (cpufreq_disabled() || (cpu >= nr_cpu_ids))
192 return NULL;
193
194 if (!down_read_trylock(&cpufreq_rwsem))
195 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197 /* get the cpufreq driver */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000198 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
Viresh Kumar6eed9402013-08-06 22:53:11 +0530200 if (cpufreq_driver) {
201 /* get the CPU */
202 policy = per_cpu(cpufreq_cpu_data, cpu);
203 if (policy)
204 kobject_get(&policy->kobj);
205 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200206
Viresh Kumar6eed9402013-08-06 22:53:11 +0530207 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530209 if (!policy)
Viresh Kumar6eed9402013-08-06 22:53:11 +0530210 up_read(&cpufreq_rwsem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530212 return policy;
Stephen Boyda9144432012-07-20 18:14:38 +0000213}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
215
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530216void cpufreq_cpu_put(struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000218 if (cpufreq_disabled())
219 return;
220
Viresh Kumar6eed9402013-08-06 22:53:11 +0530221 kobject_put(&policy->kobj);
222 up_read(&cpufreq_rwsem);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223}
224EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
225
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
228 *********************************************************************/
229
230/**
231 * adjust_jiffies - adjust the system "loops_per_jiffy"
232 *
233 * This function alters the system "loops_per_jiffy" for the clock
234 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500235 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 * per-CPU loops_per_jiffy value wherever possible.
237 */
238#ifndef CONFIG_SMP
239static unsigned long l_p_j_ref;
Viresh Kumarbb176f72013-06-19 14:19:33 +0530240static unsigned int l_p_j_ref_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241
Arjan van de Ven858119e2006-01-14 13:20:43 -0800242static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243{
244 if (ci->flags & CPUFREQ_CONST_LOOPS)
245 return;
246
247 if (!l_p_j_ref_freq) {
248 l_p_j_ref = loops_per_jiffy;
249 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200250 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530251 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 }
Viresh Kumarbb176f72013-06-19 14:19:33 +0530253 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700254 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530255 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
256 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200257 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530258 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 }
260}
261#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530262static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
263{
264 return;
265}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266#endif
267
Viresh Kumar0956df9c2013-06-19 14:19:34 +0530268static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530269 struct cpufreq_freqs *freqs, unsigned int state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270{
271 BUG_ON(irqs_disabled());
272
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000273 if (cpufreq_disabled())
274 return;
275
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200276 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200277 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800278 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800281
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 case CPUFREQ_PRECHANGE:
Viresh Kumar266c13d2013-07-02 16:36:28 +0530283 if (WARN(policy->transition_ongoing ==
284 cpumask_weight(policy->cpus),
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530285 "In middle of another frequency transition\n"))
286 return;
287
Viresh Kumar266c13d2013-07-02 16:36:28 +0530288 policy->transition_ongoing++;
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530289
Dave Jones32ee8c32006-02-28 00:43:23 -0500290 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800291 * which is not equal to what the cpufreq core thinks is
292 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200294 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800295 if ((policy) && (policy->cpu == freqs->cpu) &&
296 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200297 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800298 " %u, cpufreq assumed %u kHz.\n",
299 freqs->old, policy->cur);
300 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 }
302 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700303 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800304 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
306 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800307
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 case CPUFREQ_POSTCHANGE:
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530309 if (WARN(!policy->transition_ongoing,
310 "No frequency transition in progress\n"))
311 return;
312
Viresh Kumar266c13d2013-07-02 16:36:28 +0530313 policy->transition_ongoing--;
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200316 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200317 (unsigned long)freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100318 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700319 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800320 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800321 if (likely(policy) && likely(policy->cpu == freqs->cpu))
322 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 break;
324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325}
Viresh Kumarbb176f72013-06-19 14:19:33 +0530326
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530327/**
328 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
329 * on frequency transition.
330 *
331 * This function calls the transition notifiers and the "adjust_jiffies"
332 * function. It is called twice on all CPU frequency changes that have
333 * external effects.
334 */
335void cpufreq_notify_transition(struct cpufreq_policy *policy,
336 struct cpufreq_freqs *freqs, unsigned int state)
337{
338 for_each_cpu(freqs->cpu, policy->cpus)
339 __cpufreq_notify_transition(policy, freqs, state);
340}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
342
343
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344/*********************************************************************
345 * SYSFS INTERFACE *
346 *********************************************************************/
347
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700348static struct cpufreq_governor *__find_governor(const char *str_governor)
349{
350 struct cpufreq_governor *t;
351
352 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500353 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700354 return t;
355
356 return NULL;
357}
358
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359/**
360 * cpufreq_parse_governor - parse a governor string
361 */
Dave Jones905d77c2008-03-05 14:28:32 -0500362static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 struct cpufreq_governor **governor)
364{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700365 int err = -EINVAL;
366
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200367 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700368 goto out;
369
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200370 if (cpufreq_driver->setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
372 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700373 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530374 } else if (!strnicmp(str_governor, "powersave",
375 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700377 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200379 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700381
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800382 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700383
384 t = __find_governor(str_governor);
385
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700386 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700387 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700388
Kees Cook1a8e1462011-05-04 08:38:56 -0700389 mutex_unlock(&cpufreq_governor_mutex);
390 ret = request_module("cpufreq_%s", str_governor);
391 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700392
Kees Cook1a8e1462011-05-04 08:38:56 -0700393 if (ret == 0)
394 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700395 }
396
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700397 if (t != NULL) {
398 *governor = t;
399 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700401
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800402 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 }
Dave Jones29464f22009-01-18 01:37:11 -0500404out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700405 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530409 * cpufreq_per_cpu_attr_read() / show_##file_name() -
410 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 *
412 * Write out information from cpufreq_driver->policy[cpu]; object must be
413 * "unsigned int".
414 */
415
Dave Jones32ee8c32006-02-28 00:43:23 -0500416#define show_one(file_name, object) \
417static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500418(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500419{ \
Dave Jones29464f22009-01-18 01:37:11 -0500420 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421}
422
423show_one(cpuinfo_min_freq, cpuinfo.min_freq);
424show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100425show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426show_one(scaling_min_freq, min);
427show_one(scaling_max_freq, max);
428show_one(scaling_cur_freq, cur);
429
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530430static int __cpufreq_set_policy(struct cpufreq_policy *policy,
431 struct cpufreq_policy *new_policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200432
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433/**
434 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
435 */
436#define store_one(file_name, object) \
437static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500438(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000440 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 struct cpufreq_policy new_policy; \
442 \
443 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
444 if (ret) \
445 return -EINVAL; \
446 \
Dave Jones29464f22009-01-18 01:37:11 -0500447 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 if (ret != 1) \
449 return -EINVAL; \
450 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200451 ret = __cpufreq_set_policy(policy, &new_policy); \
452 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 \
454 return ret ? ret : count; \
455}
456
Dave Jones29464f22009-01-18 01:37:11 -0500457store_one(scaling_min_freq, min);
458store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459
460/**
461 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
462 */
Dave Jones905d77c2008-03-05 14:28:32 -0500463static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
464 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800466 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 if (!cur_freq)
468 return sprintf(buf, "<unknown>");
469 return sprintf(buf, "%u\n", cur_freq);
470}
471
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472/**
473 * show_scaling_governor - show the current policy for the specified CPU
474 */
Dave Jones905d77c2008-03-05 14:28:32 -0500475static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476{
Dave Jones29464f22009-01-18 01:37:11 -0500477 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 return sprintf(buf, "powersave\n");
479 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
480 return sprintf(buf, "performance\n");
481 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200482 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500483 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 return -EINVAL;
485}
486
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487/**
488 * store_scaling_governor - store policy for the specified CPU
489 */
Dave Jones905d77c2008-03-05 14:28:32 -0500490static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
491 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000493 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 char str_governor[16];
495 struct cpufreq_policy new_policy;
496
497 ret = cpufreq_get_policy(&new_policy, policy->cpu);
498 if (ret)
499 return ret;
500
Dave Jones29464f22009-01-18 01:37:11 -0500501 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 if (ret != 1)
503 return -EINVAL;
504
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530505 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
506 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 return -EINVAL;
508
Viresh Kumarbb176f72013-06-19 14:19:33 +0530509 /*
510 * Do not use cpufreq_set_policy here or the user_policy.max
511 * will be wrongly overridden
512 */
Thomas Renninger7970e082006-04-13 15:14:04 +0200513 ret = __cpufreq_set_policy(policy, &new_policy);
514
515 policy->user_policy.policy = policy->policy;
516 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200517
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530518 if (ret)
519 return ret;
520 else
521 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522}
523
524/**
525 * show_scaling_driver - show the cpufreq driver currently loaded
526 */
Dave Jones905d77c2008-03-05 14:28:32 -0500527static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200529 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530}
531
532/**
533 * show_scaling_available_governors - show the available CPUfreq governors
534 */
Dave Jones905d77c2008-03-05 14:28:32 -0500535static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
536 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537{
538 ssize_t i = 0;
539 struct cpufreq_governor *t;
540
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200541 if (!cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 i += sprintf(buf, "performance powersave");
543 goto out;
544 }
545
546 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500547 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
548 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200550 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500552out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 i += sprintf(&buf[i], "\n");
554 return i;
555}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700556
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800557ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558{
559 ssize_t i = 0;
560 unsigned int cpu;
561
Rusty Russell835481d2009-01-04 05:18:06 -0800562 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 if (i)
564 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
565 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
566 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500567 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 }
569 i += sprintf(&buf[i], "\n");
570 return i;
571}
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800572EXPORT_SYMBOL_GPL(cpufreq_show_cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700574/**
575 * show_related_cpus - show the CPUs affected by each transition even if
576 * hw coordination is in use
577 */
578static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
579{
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800580 return cpufreq_show_cpus(policy->related_cpus, buf);
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700581}
582
583/**
584 * show_affected_cpus - show the CPUs affected by each transition
585 */
586static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
587{
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800588 return cpufreq_show_cpus(policy->cpus, buf);
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700589}
590
Venki Pallipadi9e769882007-10-26 10:18:21 -0700591static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500592 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700593{
594 unsigned int freq = 0;
595 unsigned int ret;
596
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700597 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700598 return -EINVAL;
599
600 ret = sscanf(buf, "%u", &freq);
601 if (ret != 1)
602 return -EINVAL;
603
604 policy->governor->store_setspeed(policy, freq);
605
606 return count;
607}
608
609static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
610{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700611 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700612 return sprintf(buf, "<unsupported>\n");
613
614 return policy->governor->show_setspeed(policy, buf);
615}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Thomas Renningere2f74f32009-11-19 12:31:01 +0100617/**
viresh kumar8bf1ac72012-10-23 01:23:33 +0200618 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100619 */
620static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
621{
622 unsigned int limit;
623 int ret;
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200624 if (cpufreq_driver->bios_limit) {
625 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
Thomas Renningere2f74f32009-11-19 12:31:01 +0100626 if (!ret)
627 return sprintf(buf, "%u\n", limit);
628 }
629 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
630}
631
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200632cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
633cpufreq_freq_attr_ro(cpuinfo_min_freq);
634cpufreq_freq_attr_ro(cpuinfo_max_freq);
635cpufreq_freq_attr_ro(cpuinfo_transition_latency);
636cpufreq_freq_attr_ro(scaling_available_governors);
637cpufreq_freq_attr_ro(scaling_driver);
638cpufreq_freq_attr_ro(scaling_cur_freq);
639cpufreq_freq_attr_ro(bios_limit);
640cpufreq_freq_attr_ro(related_cpus);
641cpufreq_freq_attr_ro(affected_cpus);
642cpufreq_freq_attr_rw(scaling_min_freq);
643cpufreq_freq_attr_rw(scaling_max_freq);
644cpufreq_freq_attr_rw(scaling_governor);
645cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646
Dave Jones905d77c2008-03-05 14:28:32 -0500647static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 &cpuinfo_min_freq.attr,
649 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100650 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 &scaling_min_freq.attr,
652 &scaling_max_freq.attr,
653 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700654 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 &scaling_governor.attr,
656 &scaling_driver.attr,
657 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700658 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 NULL
660};
661
Dave Jones29464f22009-01-18 01:37:11 -0500662#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
663#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
Dave Jones29464f22009-01-18 01:37:11 -0500665static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666{
Dave Jones905d77c2008-03-05 14:28:32 -0500667 struct cpufreq_policy *policy = to_policy(kobj);
668 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500669 ssize_t ret = -EINVAL;
Viresh Kumar6eed9402013-08-06 22:53:11 +0530670
671 if (!down_read_trylock(&cpufreq_rwsem))
672 goto exit;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800673
674 if (lock_policy_rwsem_read(policy->cpu) < 0)
Viresh Kumar6eed9402013-08-06 22:53:11 +0530675 goto up_read;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800676
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530677 if (fattr->show)
678 ret = fattr->show(policy, buf);
679 else
680 ret = -EIO;
681
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800682 unlock_policy_rwsem_read(policy->cpu);
Viresh Kumar6eed9402013-08-06 22:53:11 +0530683
684up_read:
685 up_read(&cpufreq_rwsem);
686exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 return ret;
688}
689
Dave Jones905d77c2008-03-05 14:28:32 -0500690static ssize_t store(struct kobject *kobj, struct attribute *attr,
691 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692{
Dave Jones905d77c2008-03-05 14:28:32 -0500693 struct cpufreq_policy *policy = to_policy(kobj);
694 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500695 ssize_t ret = -EINVAL;
Viresh Kumar6eed9402013-08-06 22:53:11 +0530696
697 if (!down_read_trylock(&cpufreq_rwsem))
698 goto exit;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800699
700 if (lock_policy_rwsem_write(policy->cpu) < 0)
Viresh Kumar6eed9402013-08-06 22:53:11 +0530701 goto up_read;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800702
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530703 if (fattr->store)
704 ret = fattr->store(policy, buf, count);
705 else
706 ret = -EIO;
707
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800708 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar6eed9402013-08-06 22:53:11 +0530709
710up_read:
711 up_read(&cpufreq_rwsem);
712exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 return ret;
714}
715
Dave Jones905d77c2008-03-05 14:28:32 -0500716static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717{
Dave Jones905d77c2008-03-05 14:28:32 -0500718 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200719 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 complete(&policy->kobj_unregister);
721}
722
Emese Revfy52cf25d2010-01-19 02:58:23 +0100723static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 .show = show,
725 .store = store,
726};
727
728static struct kobj_type ktype_cpufreq = {
729 .sysfs_ops = &sysfs_ops,
730 .default_attrs = default_attrs,
731 .release = cpufreq_sysfs_release,
732};
733
Viresh Kumar2361be22013-05-17 16:09:09 +0530734struct kobject *cpufreq_global_kobject;
735EXPORT_SYMBOL(cpufreq_global_kobject);
736
737static int cpufreq_global_kobject_usage;
738
739int cpufreq_get_global_kobject(void)
740{
741 if (!cpufreq_global_kobject_usage++)
742 return kobject_add(cpufreq_global_kobject,
743 &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
744
745 return 0;
746}
747EXPORT_SYMBOL(cpufreq_get_global_kobject);
748
749void cpufreq_put_global_kobject(void)
750{
751 if (!--cpufreq_global_kobject_usage)
752 kobject_del(cpufreq_global_kobject);
753}
754EXPORT_SYMBOL(cpufreq_put_global_kobject);
755
756int cpufreq_sysfs_create_file(const struct attribute *attr)
757{
758 int ret = cpufreq_get_global_kobject();
759
760 if (!ret) {
761 ret = sysfs_create_file(cpufreq_global_kobject, attr);
762 if (ret)
763 cpufreq_put_global_kobject();
764 }
765
766 return ret;
767}
768EXPORT_SYMBOL(cpufreq_sysfs_create_file);
769
770void cpufreq_sysfs_remove_file(const struct attribute *attr)
771{
772 sysfs_remove_file(cpufreq_global_kobject, attr);
773 cpufreq_put_global_kobject();
774}
775EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
776
Dave Jones19d6f7e2009-07-08 17:35:39 -0400777/* symlink affected CPUs */
Viresh Kumar308b60e2013-07-31 14:35:14 +0200778static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400779{
780 unsigned int j;
781 int ret = 0;
782
783 for_each_cpu(j, policy->cpus) {
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800784 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400785
Viresh Kumar308b60e2013-07-31 14:35:14 +0200786 if (j == policy->cpu)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400787 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400788
Viresh Kumare8fdde12013-07-31 14:31:33 +0200789 pr_debug("Adding link for CPU: %u\n", j);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800790 cpu_dev = get_cpu_device(j);
791 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400792 "cpufreq");
Rafael J. Wysocki71c34612013-08-04 01:19:34 +0200793 if (ret)
794 break;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400795 }
796 return ret;
797}
798
Viresh Kumar308b60e2013-07-31 14:35:14 +0200799static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800800 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400801{
802 struct freq_attr **drv_attr;
Dave Jones909a6942009-07-08 18:05:42 -0400803 int ret = 0;
Dave Jones909a6942009-07-08 18:05:42 -0400804
805 /* prepare interface data */
806 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800807 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400808 if (ret)
809 return ret;
810
811 /* set up files for this cpu device */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200812 drv_attr = cpufreq_driver->attr;
Dave Jones909a6942009-07-08 18:05:42 -0400813 while ((drv_attr) && (*drv_attr)) {
814 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
815 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200816 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400817 drv_attr++;
818 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200819 if (cpufreq_driver->get) {
Dave Jones909a6942009-07-08 18:05:42 -0400820 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
821 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200822 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400823 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200824 if (cpufreq_driver->target) {
Dave Jones909a6942009-07-08 18:05:42 -0400825 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
826 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200827 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400828 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200829 if (cpufreq_driver->bios_limit) {
Thomas Renningere2f74f32009-11-19 12:31:01 +0100830 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
831 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200832 goto err_out_kobj_put;
Thomas Renningere2f74f32009-11-19 12:31:01 +0100833 }
Dave Jones909a6942009-07-08 18:05:42 -0400834
Viresh Kumar308b60e2013-07-31 14:35:14 +0200835 ret = cpufreq_add_dev_symlink(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400836 if (ret)
837 goto err_out_kobj_put;
838
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +0530839 return ret;
840
841err_out_kobj_put:
842 kobject_put(&policy->kobj);
843 wait_for_completion(&policy->kobj_unregister);
844 return ret;
845}
846
847static void cpufreq_init_policy(struct cpufreq_policy *policy)
848{
849 struct cpufreq_policy new_policy;
850 int ret = 0;
851
Viresh Kumard5b73cd2013-08-06 22:53:06 +0530852 memcpy(&new_policy, policy, sizeof(*policy));
Dave Jonesecf7e462009-07-08 18:48:47 -0400853 /* assure that the starting sequence is run in __cpufreq_set_policy */
854 policy->governor = NULL;
855
856 /* set default policy */
857 ret = __cpufreq_set_policy(policy, &new_policy);
858 policy->user_policy.policy = policy->policy;
859 policy->user_policy.governor = policy->governor;
860
861 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200862 pr_debug("setting policy failed\n");
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200863 if (cpufreq_driver->exit)
864 cpufreq_driver->exit(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400865 }
Dave Jones909a6942009-07-08 18:05:42 -0400866}
867
Viresh Kumarfcf80582013-01-29 14:39:08 +0000868#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumard8d3b472013-08-04 01:20:07 +0200869static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
870 unsigned int cpu, struct device *dev,
871 bool frozen)
Viresh Kumarfcf80582013-01-29 14:39:08 +0000872{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200873 int ret = 0, has_target = !!cpufreq_driver->target;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000874 unsigned long flags;
875
Viresh Kumar3de9bde2013-08-06 22:53:13 +0530876 if (has_target) {
877 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
878 if (ret) {
879 pr_err("%s: Failed to stop governor\n", __func__);
880 return ret;
881 }
882 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000883
Viresh Kumard8d3b472013-08-04 01:20:07 +0200884 lock_policy_rwsem_write(policy->cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530885
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000886 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530887
Viresh Kumarfcf80582013-01-29 14:39:08 +0000888 cpumask_set_cpu(cpu, policy->cpus);
889 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000890 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000891
Viresh Kumard8d3b472013-08-04 01:20:07 +0200892 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530893
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200894 if (has_target) {
Viresh Kumar3de9bde2013-08-06 22:53:13 +0530895 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
896 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
897 pr_err("%s: Failed to start governor\n", __func__);
898 return ret;
899 }
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200900 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000901
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530902 /* Don't touch sysfs links during light-weight init */
Rafael J. Wysocki71c34612013-08-04 01:19:34 +0200903 if (!frozen)
904 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
Viresh Kumarfcf80582013-01-29 14:39:08 +0000905
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530906 return ret;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000907}
908#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909
Srivatsa S. Bhat84148092013-07-30 04:25:10 +0530910static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
911{
912 struct cpufreq_policy *policy;
913 unsigned long flags;
914
915 write_lock_irqsave(&cpufreq_driver_lock, flags);
916
917 policy = per_cpu(cpufreq_cpu_data_fallback, cpu);
918
919 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
920
921 return policy;
922}
923
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530924static struct cpufreq_policy *cpufreq_policy_alloc(void)
925{
926 struct cpufreq_policy *policy;
927
928 policy = kzalloc(sizeof(*policy), GFP_KERNEL);
929 if (!policy)
930 return NULL;
931
932 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
933 goto err_free_policy;
934
935 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
936 goto err_free_cpumask;
937
Lukasz Majewskic88a1f82013-08-06 22:53:08 +0530938 INIT_LIST_HEAD(&policy->policy_list);
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530939 return policy;
940
941err_free_cpumask:
942 free_cpumask_var(policy->cpus);
943err_free_policy:
944 kfree(policy);
945
946 return NULL;
947}
948
949static void cpufreq_policy_free(struct cpufreq_policy *policy)
950{
951 free_cpumask_var(policy->related_cpus);
952 free_cpumask_var(policy->cpus);
953 kfree(policy);
954}
955
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530956static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
957 bool frozen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000959 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530960 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500963#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumar1b274292013-08-20 12:08:26 +0530964 struct cpufreq_policy *tpolicy;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000965 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500966#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
Ashok Rajc32b6b82005-10-30 14:59:54 -0800968 if (cpu_is_offline(cpu))
969 return 0;
970
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200971 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
973#ifdef CONFIG_SMP
974 /* check whether a different CPU already registered this
975 * CPU because it is in the same boat. */
976 policy = cpufreq_cpu_get(cpu);
977 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500978 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 return 0;
980 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000981
Viresh Kumar6eed9402013-08-06 22:53:11 +0530982 if (!down_read_trylock(&cpufreq_rwsem))
983 return 0;
984
Viresh Kumarfcf80582013-01-29 14:39:08 +0000985#ifdef CONFIG_HOTPLUG_CPU
986 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000987 read_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar1b274292013-08-20 12:08:26 +0530988 list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) {
989 if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000990 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar1b274292013-08-20 12:08:26 +0530991 ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen);
Viresh Kumar6eed9402013-08-06 22:53:11 +0530992 up_read(&cpufreq_rwsem);
993 return ret;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530994 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000995 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000996 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000997#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998#endif
999
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301000 if (frozen)
1001 /* Restore the saved policy when doing light-weight init */
1002 policy = cpufreq_policy_restore(cpu);
1003 else
1004 policy = cpufreq_policy_alloc();
1005
Dave Jones059019a2009-07-08 16:30:03 -04001006 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -04001008
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +05301010 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -08001011 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +00001014 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
1016 /* call driver. From then on the cpufreq must be able
1017 * to accept all calls to ->verify and ->setpolicy for this CPU
1018 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001019 ret = cpufreq_driver->init(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001021 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301022 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001024
Viresh Kumarfcf80582013-01-29 14:39:08 +00001025 /* related cpus should atleast have policy->cpus */
1026 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1027
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001028 /*
1029 * affected cpus must always be the one, which are online. We aren't
1030 * managing offline cpus here.
1031 */
1032 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
1033
Mike Chan187d9f42008-12-04 12:19:17 -08001034 policy->user_policy.min = policy->min;
1035 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
Thomas Renningera1531ac2008-07-29 22:32:58 -07001037 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1038 CPUFREQ_START, policy);
1039
Viresh Kumarfcf80582013-01-29 14:39:08 +00001040#ifdef CONFIG_HOTPLUG_CPU
1041 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
1042 if (gov) {
1043 policy->governor = gov;
1044 pr_debug("Restoring governor %s for cpu %d\n",
1045 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001046 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001047#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301049 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar474deff2013-08-20 12:08:25 +05301050 for_each_cpu(j, policy->cpus)
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301051 per_cpu(cpufreq_cpu_data, j) = policy;
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301052 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1053
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301054 if (!frozen) {
Viresh Kumar308b60e2013-07-31 14:35:14 +02001055 ret = cpufreq_add_dev_interface(policy, dev);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301056 if (ret)
1057 goto err_out_unregister;
1058 }
Dave Jones8ff69732006-03-05 03:37:23 -05001059
Viresh Kumar9515f4d2013-08-20 12:08:23 +05301060 write_lock_irqsave(&cpufreq_driver_lock, flags);
1061 list_add(&policy->policy_list, &cpufreq_policy_list);
1062 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1063
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301064 cpufreq_init_policy(policy);
1065
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001066 kobject_uevent(&policy->kobj, KOBJ_ADD);
Viresh Kumar6eed9402013-08-06 22:53:11 +05301067 up_read(&cpufreq_rwsem);
1068
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001069 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001070
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 return 0;
1072
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001074 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar474deff2013-08-20 12:08:25 +05301075 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001076 per_cpu(cpufreq_cpu_data, j) = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001077 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301079err_set_policy_cpu:
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +05301080 cpufreq_policy_free(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081nomem_out:
Viresh Kumar6eed9402013-08-06 22:53:11 +05301082 up_read(&cpufreq_rwsem);
1083
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 return ret;
1085}
1086
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301087/**
1088 * cpufreq_add_dev - add a CPU device
1089 *
1090 * Adds the cpufreq interface for a CPU device.
1091 *
1092 * The Oracle says: try running cpufreq registration/unregistration concurrently
1093 * with with cpu hotplugging and all hell will break loose. Tried to clean this
1094 * mess up, but more thorough testing is needed. - Mathieu
1095 */
1096static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
1097{
1098 return __cpufreq_add_dev(dev, sif, false);
1099}
1100
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001101static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1102{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001103 policy->last_cpu = policy->cpu;
1104 policy->cpu = cpu;
1105
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001106#ifdef CONFIG_CPU_FREQ_TABLE
1107 cpufreq_frequency_table_update_policy_cpu(policy);
1108#endif
1109 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1110 CPUFREQ_UPDATE_POLICY_CPU, policy);
1111}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301113static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301114 unsigned int old_cpu, bool frozen)
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301115{
1116 struct device *cpu_dev;
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301117 int ret;
1118
1119 /* first sibling now owns the new sysfs dir */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301120 cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301121
1122 /* Don't touch sysfs files during light-weight tear-down */
1123 if (frozen)
1124 return cpu_dev->id;
1125
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301126 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301127 ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301128 if (ret) {
1129 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1130
1131 WARN_ON(lock_policy_rwsem_write(old_cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301132 cpumask_set_cpu(old_cpu, policy->cpus);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301133 unlock_policy_rwsem_write(old_cpu);
1134
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301135 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301136 "cpufreq");
1137
1138 return -EINVAL;
1139 }
1140
1141 return cpu_dev->id;
1142}
1143
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001145 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 *
1147 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001148 * Caller should already have policy_rwsem in write mode for this CPU.
1149 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 */
Viresh Kumarbb176f72013-06-19 14:19:33 +05301151static int __cpufreq_remove_dev(struct device *dev,
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301152 struct subsys_interface *sif, bool frozen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153{
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301154 unsigned int cpu = dev->id, cpus;
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301155 int new_cpu, ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 unsigned long flags;
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301157 struct cpufreq_policy *policy;
Amerigo Wang499bca92010-03-04 03:23:46 -05001158 struct kobject *kobj;
1159 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001161 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001163 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301165 policy = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301167 /* Save the policy somewhere when doing a light-weight tear-down */
1168 if (frozen)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301169 per_cpu(cpufreq_cpu_data_fallback, cpu) = policy;
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301170
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001171 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301173 if (!policy) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001174 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301178 if (cpufreq_driver->target) {
1179 ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1180 if (ret) {
1181 pr_err("%s: Failed to stop governor\n", __func__);
1182 return ret;
1183 }
1184 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001185
Jacob Shin27ecddc2011-04-27 13:32:11 -05001186#ifdef CONFIG_HOTPLUG_CPU
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001187 if (!cpufreq_driver->setpolicy)
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001188 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301189 policy->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001190#endif
1191
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301192 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301193 cpus = cpumask_weight(policy->cpus);
Viresh Kumare4969eb2013-04-11 08:04:53 +00001194
1195 if (cpus > 1)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301196 cpumask_clear_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301197 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301199 if (cpu != policy->cpu && !frozen) {
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001200 sysfs_remove_link(&dev->kobj, "cpufreq");
1201 } else if (cpus > 1) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301202
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301203 new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301204 if (new_cpu >= 0) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301205 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301206 update_policy_cpu(policy, new_cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301207 unlock_policy_rwsem_write(cpu);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301208
1209 if (!frozen) {
1210 pr_debug("%s: policy Kobject moved to cpu: %d "
1211 "from: %d\n",__func__, new_cpu, cpu);
1212 }
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001213 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001214 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001215
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001216 /* If cpu is last user of policy, free policy */
1217 if (cpus == 1) {
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301218 if (cpufreq_driver->target) {
1219 ret = __cpufreq_governor(policy,
1220 CPUFREQ_GOV_POLICY_EXIT);
1221 if (ret) {
1222 pr_err("%s: Failed to exit governor\n",
1223 __func__);
1224 return ret;
1225 }
Viresh Kumaredab2fb2013-08-20 12:08:22 +05301226 }
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001227
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301228 if (!frozen) {
1229 lock_policy_rwsem_read(cpu);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301230 kobj = &policy->kobj;
1231 cmp = &policy->kobj_unregister;
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301232 unlock_policy_rwsem_read(cpu);
1233 kobject_put(kobj);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001234
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301235 /*
1236 * We need to make sure that the underlying kobj is
1237 * actually not referenced anymore by anybody before we
1238 * proceed with unloading.
1239 */
1240 pr_debug("waiting for dropping of refcount\n");
1241 wait_for_completion(cmp);
1242 pr_debug("wait complete\n");
1243 }
1244
1245 /*
1246 * Perform the ->exit() even during light-weight tear-down,
1247 * since this is a core component, and is essential for the
1248 * subsequent light-weight ->init() to succeed.
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001249 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001250 if (cpufreq_driver->exit)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301251 cpufreq_driver->exit(policy);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001252
Viresh Kumar9515f4d2013-08-20 12:08:23 +05301253 /* Remove policy from list of active policies */
1254 write_lock_irqsave(&cpufreq_driver_lock, flags);
1255 list_del(&policy->policy_list);
1256 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1257
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301258 if (!frozen)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301259 cpufreq_policy_free(policy);
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001260 } else {
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001261 if (cpufreq_driver->target) {
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301262 if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
1263 (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
1264 pr_err("%s: Failed to start governor\n",
1265 __func__);
1266 return ret;
1267 }
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001268 }
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001269 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270
Viresh Kumar474deff2013-08-20 12:08:25 +05301271 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 return 0;
1273}
1274
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001275static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001276{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001277 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001278 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001279
1280 if (cpu_is_offline(cpu))
1281 return 0;
1282
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301283 retval = __cpufreq_remove_dev(dev, sif, false);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001284 return retval;
1285}
1286
David Howells65f27f32006-11-22 14:55:48 +00001287static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288{
David Howells65f27f32006-11-22 14:55:48 +00001289 struct cpufreq_policy *policy =
1290 container_of(work, struct cpufreq_policy, update);
1291 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001292 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293 cpufreq_update_policy(cpu);
1294}
1295
1296/**
Viresh Kumarbb176f72013-06-19 14:19:33 +05301297 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're
1298 * in deep trouble.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 * @cpu: cpu number
1300 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1301 * @new_freq: CPU frequency the CPU actually runs at
1302 *
Dave Jones29464f22009-01-18 01:37:11 -05001303 * We adjust to current frequency first, and need to clean up later.
1304 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301306static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1307 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308{
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301309 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310 struct cpufreq_freqs freqs;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301311 unsigned long flags;
1312
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001313 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1315
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 freqs.old = old_freq;
1317 freqs.new = new_freq;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301318
1319 read_lock_irqsave(&cpufreq_driver_lock, flags);
1320 policy = per_cpu(cpufreq_cpu_data, cpu);
1321 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1322
1323 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
1324 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325}
1326
Dave Jones32ee8c32006-02-28 00:43:23 -05001327/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301328 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001329 * @cpu: CPU number
1330 *
1331 * This is the last known freq, without actually getting it from the driver.
1332 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1333 */
1334unsigned int cpufreq_quick_get(unsigned int cpu)
1335{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001336 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301337 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001338
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001339 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1340 return cpufreq_driver->get(cpu);
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001341
1342 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001343 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301344 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001345 cpufreq_cpu_put(policy);
1346 }
1347
Dave Jones4d34a672008-02-07 16:33:49 -05001348 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001349}
1350EXPORT_SYMBOL(cpufreq_quick_get);
1351
Jesse Barnes3d737102011-06-28 10:59:12 -07001352/**
1353 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1354 * @cpu: CPU number
1355 *
1356 * Just return the max possible frequency for a given CPU.
1357 */
1358unsigned int cpufreq_quick_get_max(unsigned int cpu)
1359{
1360 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1361 unsigned int ret_freq = 0;
1362
1363 if (policy) {
1364 ret_freq = policy->max;
1365 cpufreq_cpu_put(policy);
1366 }
1367
1368 return ret_freq;
1369}
1370EXPORT_SYMBOL(cpufreq_quick_get_max);
1371
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001372static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001374 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301375 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001377 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001378 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001380 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301382 if (ret_freq && policy->cur &&
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001383 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301384 /* verify no discrepancy between actual and
1385 saved value exists */
1386 if (unlikely(ret_freq != policy->cur)) {
1387 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 schedule_work(&policy->update);
1389 }
1390 }
1391
Dave Jones4d34a672008-02-07 16:33:49 -05001392 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001393}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001395/**
1396 * cpufreq_get - get the current CPU frequency (in kHz)
1397 * @cpu: CPU number
1398 *
1399 * Get the CPU current (static) CPU frequency
1400 */
1401unsigned int cpufreq_get(unsigned int cpu)
1402{
1403 unsigned int ret_freq = 0;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001404
Viresh Kumar6eed9402013-08-06 22:53:11 +05301405 if (!down_read_trylock(&cpufreq_rwsem))
1406 return 0;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001407
1408 if (unlikely(lock_policy_rwsem_read(cpu)))
1409 goto out_policy;
1410
1411 ret_freq = __cpufreq_get(cpu);
1412
1413 unlock_policy_rwsem_read(cpu);
1414
1415out_policy:
Viresh Kumar6eed9402013-08-06 22:53:11 +05301416 up_read(&cpufreq_rwsem);
1417
Dave Jones4d34a672008-02-07 16:33:49 -05001418 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419}
1420EXPORT_SYMBOL(cpufreq_get);
1421
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001422static struct subsys_interface cpufreq_interface = {
1423 .name = "cpufreq",
1424 .subsys = &cpu_subsys,
1425 .add_dev = cpufreq_add_dev,
1426 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001427};
1428
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001430 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1431 *
1432 * This function is only executed for the boot processor. The other CPUs
1433 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001434 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001435static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001436{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301437 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001438
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001439 int cpu = smp_processor_id();
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301440 struct cpufreq_policy *policy;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001441
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001442 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001443
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001444 /* If there's no policy for the boot CPU, we have nothing to do. */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301445 policy = cpufreq_cpu_get(cpu);
1446 if (!policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001447 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001448
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001449 if (cpufreq_driver->suspend) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301450 ret = cpufreq_driver->suspend(policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001451 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001452 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301453 "step on CPU %u\n", policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001454 }
1455
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301456 cpufreq_cpu_put(policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001457 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001458}
1459
1460/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001461 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 *
1463 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001464 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1465 * restored. It will verify that the current freq is in sync with
1466 * what we believe it to be. This is a bit later than when it
1467 * should be, but nonethteless it's better than calling
1468 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001469 *
1470 * This function is only executed for the boot CPU. The other CPUs have not
1471 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001473static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301475 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001476
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001477 int cpu = smp_processor_id();
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301478 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001480 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001482 /* If there's no policy for the boot CPU, we have nothing to do. */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301483 policy = cpufreq_cpu_get(cpu);
1484 if (!policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001485 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001487 if (cpufreq_driver->resume) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301488 ret = cpufreq_driver->resume(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 if (ret) {
1490 printk(KERN_ERR "cpufreq: resume failed in ->resume "
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301491 "step on CPU %u\n", policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001492 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 }
1494 }
1495
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301496 schedule_work(&policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001497
Dave Jonesc9060492008-02-07 16:32:18 -05001498fail:
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301499 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500}
1501
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001502static struct syscore_ops cpufreq_syscore_ops = {
1503 .suspend = cpufreq_bp_suspend,
1504 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505};
1506
Borislav Petkov9d950462013-01-20 10:24:28 +00001507/**
1508 * cpufreq_get_current_driver - return current driver's name
1509 *
1510 * Return the name string of the currently loaded cpufreq driver
1511 * or NULL, if none.
1512 */
1513const char *cpufreq_get_current_driver(void)
1514{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001515 if (cpufreq_driver)
1516 return cpufreq_driver->name;
1517
1518 return NULL;
Borislav Petkov9d950462013-01-20 10:24:28 +00001519}
1520EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521
1522/*********************************************************************
1523 * NOTIFIER LISTS INTERFACE *
1524 *********************************************************************/
1525
1526/**
1527 * cpufreq_register_notifier - register a driver with cpufreq
1528 * @nb: notifier function to register
1529 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1530 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001531 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 * are notified about clock rate changes (once before and once after
1533 * the transition), or a list of drivers that are notified about
1534 * changes in cpufreq policy.
1535 *
1536 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001537 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 */
1539int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1540{
1541 int ret;
1542
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001543 if (cpufreq_disabled())
1544 return -EINVAL;
1545
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001546 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1547
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 switch (list) {
1549 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001550 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001551 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 break;
1553 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001554 ret = blocking_notifier_chain_register(
1555 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 break;
1557 default:
1558 ret = -EINVAL;
1559 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560
1561 return ret;
1562}
1563EXPORT_SYMBOL(cpufreq_register_notifier);
1564
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565/**
1566 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1567 * @nb: notifier block to be unregistered
Viresh Kumarbb176f72013-06-19 14:19:33 +05301568 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 *
1570 * Remove a driver from the CPU frequency notifier list.
1571 *
1572 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001573 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 */
1575int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1576{
1577 int ret;
1578
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001579 if (cpufreq_disabled())
1580 return -EINVAL;
1581
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 switch (list) {
1583 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001584 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001585 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 break;
1587 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001588 ret = blocking_notifier_chain_unregister(
1589 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 break;
1591 default:
1592 ret = -EINVAL;
1593 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
1595 return ret;
1596}
1597EXPORT_SYMBOL(cpufreq_unregister_notifier);
1598
1599
1600/*********************************************************************
1601 * GOVERNORS *
1602 *********************************************************************/
1603
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604int __cpufreq_driver_target(struct cpufreq_policy *policy,
1605 unsigned int target_freq,
1606 unsigned int relation)
1607{
1608 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001609 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001610
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001611 if (cpufreq_disabled())
1612 return -ENODEV;
Viresh Kumar7c30ed52013-06-19 10:16:55 +05301613 if (policy->transition_ongoing)
1614 return -EBUSY;
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001615
Viresh Kumar72499242012-10-31 01:28:21 +01001616 /* Make sure that target_freq is within supported range */
1617 if (target_freq > policy->max)
1618 target_freq = policy->max;
1619 if (target_freq < policy->min)
1620 target_freq = policy->min;
1621
1622 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1623 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001624
1625 if (target_freq == policy->cur)
1626 return 0;
1627
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001628 if (cpufreq_driver->target)
1629 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001630
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 return retval;
1632}
1633EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1634
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635int cpufreq_driver_target(struct cpufreq_policy *policy,
1636 unsigned int target_freq,
1637 unsigned int relation)
1638{
Julia Lawallf1829e42008-07-25 22:44:53 +02001639 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001641 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001642 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
1644 ret = __cpufreq_driver_target(policy, target_freq, relation);
1645
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001646 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647
Julia Lawallf1829e42008-07-25 22:44:53 +02001648fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649 return ret;
1650}
1651EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1652
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001653/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001654 * when "event" is CPUFREQ_GOV_LIMITS
1655 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301657static int __cpufreq_governor(struct cpufreq_policy *policy,
1658 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659{
Dave Jonescc993ca2005-07-28 09:43:56 -07001660 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001661
1662 /* Only must be defined when default governor is known to have latency
1663 restrictions, like e.g. conservative or ondemand.
1664 That this is the case is already ensured in Kconfig
1665 */
1666#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1667 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1668#else
1669 struct cpufreq_governor *gov = NULL;
1670#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001671
1672 if (policy->governor->max_transition_latency &&
1673 policy->cpuinfo.transition_latency >
1674 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001675 if (!gov)
1676 return -EINVAL;
1677 else {
1678 printk(KERN_WARNING "%s governor failed, too long"
1679 " transition latency of HW, fallback"
1680 " to %s governor\n",
1681 policy->governor->name,
1682 gov->name);
1683 policy->governor = gov;
1684 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001685 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Viresh Kumarfe492f32013-08-06 22:53:10 +05301687 if (event == CPUFREQ_GOV_POLICY_INIT)
1688 if (!try_module_get(policy->governor->owner))
1689 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001691 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301692 policy->cpu, event);
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001693
1694 mutex_lock(&cpufreq_governor_lock);
1695 if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
1696 (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
1697 mutex_unlock(&cpufreq_governor_lock);
1698 return -EBUSY;
1699 }
1700
1701 if (event == CPUFREQ_GOV_STOP)
1702 policy->governor_enabled = false;
1703 else if (event == CPUFREQ_GOV_START)
1704 policy->governor_enabled = true;
1705
1706 mutex_unlock(&cpufreq_governor_lock);
1707
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 ret = policy->governor->governor(policy, event);
1709
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001710 if (!ret) {
1711 if (event == CPUFREQ_GOV_POLICY_INIT)
1712 policy->governor->initialized++;
1713 else if (event == CPUFREQ_GOV_POLICY_EXIT)
1714 policy->governor->initialized--;
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001715 } else {
1716 /* Restore original values */
1717 mutex_lock(&cpufreq_governor_lock);
1718 if (event == CPUFREQ_GOV_STOP)
1719 policy->governor_enabled = true;
1720 else if (event == CPUFREQ_GOV_START)
1721 policy->governor_enabled = false;
1722 mutex_unlock(&cpufreq_governor_lock);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001723 }
Viresh Kumarb3940582013-02-01 05:42:58 +00001724
Viresh Kumarfe492f32013-08-06 22:53:10 +05301725 if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) ||
1726 ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 module_put(policy->governor->owner);
1728
1729 return ret;
1730}
1731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732int cpufreq_register_governor(struct cpufreq_governor *governor)
1733{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001734 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735
1736 if (!governor)
1737 return -EINVAL;
1738
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001739 if (cpufreq_disabled())
1740 return -ENODEV;
1741
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001742 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001743
Viresh Kumarb3940582013-02-01 05:42:58 +00001744 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001745 err = -EBUSY;
1746 if (__find_governor(governor->name) == NULL) {
1747 err = 0;
1748 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750
Dave Jones32ee8c32006-02-28 00:43:23 -05001751 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001752 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753}
1754EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1755
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1757{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001758#ifdef CONFIG_HOTPLUG_CPU
1759 int cpu;
1760#endif
1761
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 if (!governor)
1763 return;
1764
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001765 if (cpufreq_disabled())
1766 return;
1767
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001768#ifdef CONFIG_HOTPLUG_CPU
1769 for_each_present_cpu(cpu) {
1770 if (cpu_online(cpu))
1771 continue;
1772 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1773 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1774 }
1775#endif
1776
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001777 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001779 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 return;
1781}
1782EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1783
1784
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785/*********************************************************************
1786 * POLICY INTERFACE *
1787 *********************************************************************/
1788
1789/**
1790 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001791 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1792 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 *
1794 * Reads the current cpufreq policy.
1795 */
1796int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1797{
1798 struct cpufreq_policy *cpu_policy;
1799 if (!policy)
1800 return -EINVAL;
1801
1802 cpu_policy = cpufreq_cpu_get(cpu);
1803 if (!cpu_policy)
1804 return -EINVAL;
1805
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301806 memcpy(policy, cpu_policy, sizeof(*policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
1808 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 return 0;
1810}
1811EXPORT_SYMBOL(cpufreq_get_policy);
1812
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001813/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301814 * data : current policy.
1815 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001816 */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301817static int __cpufreq_set_policy(struct cpufreq_policy *policy,
1818 struct cpufreq_policy *new_policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001820 int ret = 0, failed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301822 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu,
1823 new_policy->min, new_policy->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301825 memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301827 if (new_policy->min > policy->max || new_policy->max < policy->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001828 ret = -EINVAL;
1829 goto error_out;
1830 }
1831
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 /* verify the cpu speed can be set within this limit */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301833 ret = cpufreq_driver->verify(new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 if (ret)
1835 goto error_out;
1836
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001838 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301839 CPUFREQ_ADJUST, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
1841 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001842 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301843 CPUFREQ_INCOMPATIBLE, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844
Viresh Kumarbb176f72013-06-19 14:19:33 +05301845 /*
1846 * verify the cpu speed can be set within this limit, which might be
1847 * different to the first one
1848 */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301849 ret = cpufreq_driver->verify(new_policy);
Alan Sterne041c682006-03-27 01:16:30 -08001850 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852
1853 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001854 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301855 CPUFREQ_NOTIFY, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301857 policy->min = new_policy->min;
1858 policy->max = new_policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001860 pr_debug("new min and max freqs are %u - %u kHz\n",
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301861 policy->min, policy->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001863 if (cpufreq_driver->setpolicy) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301864 policy->policy = new_policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001865 pr_debug("setting range\n");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301866 ret = cpufreq_driver->setpolicy(new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301868 if (new_policy->governor != policy->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 /* save old, working values */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301870 struct cpufreq_governor *old_gov = policy->governor;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001872 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 /* end old governor */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301875 if (policy->governor) {
1876 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1877 unlock_policy_rwsem_write(new_policy->cpu);
1878 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001879 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301880 lock_policy_rwsem_write(new_policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
1883 /* start new governor */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301884 policy->governor = new_policy->governor;
1885 if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
1886 if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001887 failed = 0;
Viresh Kumar955ef482013-05-16 05:09:58 +00001888 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301889 unlock_policy_rwsem_write(new_policy->cpu);
1890 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001891 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301892 lock_policy_rwsem_write(new_policy->cpu);
Viresh Kumar955ef482013-05-16 05:09:58 +00001893 }
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001894 }
1895
1896 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001898 pr_debug("starting governor %s failed\n",
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301899 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 if (old_gov) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301901 policy->governor = old_gov;
1902 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001903 CPUFREQ_GOV_POLICY_INIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301904 __cpufreq_governor(policy,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301905 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 }
1907 ret = -EINVAL;
1908 goto error_out;
1909 }
1910 /* might be a policy change, too, so fall through */
1911 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001912 pr_debug("governor: change or update limits\n");
Viresh Kumar3de9bde2013-08-06 22:53:13 +05301913 ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 }
1915
Dave Jones7d5e3502006-02-02 17:03:42 -05001916error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 return ret;
1918}
1919
1920/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1922 * @cpu: CPU which shall be re-evaluated
1923 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001924 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 * at different times.
1926 */
1927int cpufreq_update_policy(unsigned int cpu)
1928{
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301929 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1930 struct cpufreq_policy new_policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001931 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301933 if (!policy) {
Julia Lawallf1829e42008-07-25 22:44:53 +02001934 ret = -ENODEV;
1935 goto no_policy;
1936 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937
Julia Lawallf1829e42008-07-25 22:44:53 +02001938 if (unlikely(lock_policy_rwsem_write(cpu))) {
1939 ret = -EINVAL;
1940 goto fail;
1941 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001943 pr_debug("updating policy for CPU %u\n", cpu);
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301944 memcpy(&new_policy, policy, sizeof(*policy));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301945 new_policy.min = policy->user_policy.min;
1946 new_policy.max = policy->user_policy.max;
1947 new_policy.policy = policy->user_policy.policy;
1948 new_policy.governor = policy->user_policy.governor;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
Viresh Kumarbb176f72013-06-19 14:19:33 +05301950 /*
1951 * BIOS might change freq behind our back
1952 * -> ask driver for current freq and notify governors about a change
1953 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001954 if (cpufreq_driver->get) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301955 new_policy.cur = cpufreq_driver->get(cpu);
1956 if (!policy->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001957 pr_debug("Driver did not initialize current freq");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301958 policy->cur = new_policy.cur;
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001959 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301960 if (policy->cur != new_policy.cur && cpufreq_driver->target)
1961 cpufreq_out_of_sync(cpu, policy->cur,
1962 new_policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001963 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001964 }
1965
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301966 ret = __cpufreq_set_policy(policy, &new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001968 unlock_policy_rwsem_write(cpu);
1969
Julia Lawallf1829e42008-07-25 22:44:53 +02001970fail:
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301971 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001972no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 return ret;
1974}
1975EXPORT_SYMBOL(cpufreq_update_policy);
1976
Paul Gortmaker27609842013-06-19 13:54:04 -04001977static int cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001978 unsigned long action, void *hcpu)
1979{
1980 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001981 struct device *dev;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05301982 bool frozen = false;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001983
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001984 dev = get_cpu_device(cpu);
1985 if (dev) {
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05301986
1987 if (action & CPU_TASKS_FROZEN)
1988 frozen = true;
1989
1990 switch (action & ~CPU_TASKS_FROZEN) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001991 case CPU_ONLINE:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05301992 __cpufreq_add_dev(dev, NULL, frozen);
Srivatsa S. Bhat23d328992013-07-30 04:23:56 +05301993 cpufreq_update_policy(cpu);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001994 break;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05301995
Ashok Rajc32b6b82005-10-30 14:59:54 -08001996 case CPU_DOWN_PREPARE:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05301997 __cpufreq_remove_dev(dev, NULL, frozen);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001998 break;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05301999
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002000 case CPU_DOWN_FAILED:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302001 __cpufreq_add_dev(dev, NULL, frozen);
Ashok Rajc32b6b82005-10-30 14:59:54 -08002002 break;
2003 }
2004 }
2005 return NOTIFY_OK;
2006}
2007
Neal Buckendahl9c36f742010-06-22 22:02:44 -05002008static struct notifier_block __refdata cpufreq_cpu_notifier = {
Viresh Kumarbb176f72013-06-19 14:19:33 +05302009 .notifier_call = cpufreq_cpu_callback,
Ashok Rajc32b6b82005-10-30 14:59:54 -08002010};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011
2012/*********************************************************************
2013 * REGISTER / UNREGISTER CPUFREQ DRIVER *
2014 *********************************************************************/
2015
2016/**
2017 * cpufreq_register_driver - register a CPU Frequency driver
2018 * @driver_data: A struct cpufreq_driver containing the values#
2019 * submitted by the CPU Frequency driver.
2020 *
Viresh Kumarbb176f72013-06-19 14:19:33 +05302021 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05002023 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024 *
2025 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002026int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027{
2028 unsigned long flags;
2029 int ret;
2030
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002031 if (cpufreq_disabled())
2032 return -ENODEV;
2033
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 if (!driver_data || !driver_data->verify || !driver_data->init ||
2035 ((!driver_data->setpolicy) && (!driver_data->target)))
2036 return -EINVAL;
2037
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002038 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039
2040 if (driver_data->setpolicy)
2041 driver_data->flags |= CPUFREQ_CONST_LOOPS;
2042
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002043 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002044 if (cpufreq_driver) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002045 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 return -EBUSY;
2047 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002048 cpufreq_driver = driver_data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002049 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002051 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002052 if (ret)
2053 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002055 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 int i;
2057 ret = -ENODEV;
2058
2059 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07002060 for (i = 0; i < nr_cpu_ids; i++)
2061 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07002063 break;
2064 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065
2066 /* if all ->init() calls failed, unregister */
2067 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002068 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05302069 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002070 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 }
2072 }
2073
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002074 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002075 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002077 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002078err_if_unreg:
2079 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002080err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002081 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002082 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002083 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05002084 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085}
2086EXPORT_SYMBOL_GPL(cpufreq_register_driver);
2087
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088/**
2089 * cpufreq_unregister_driver - unregister the current CPUFreq driver
2090 *
Viresh Kumarbb176f72013-06-19 14:19:33 +05302091 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 * the right to do so, i.e. if you have succeeded in initialising before!
2093 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
2094 * currently not initialised.
2095 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002096int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097{
2098 unsigned long flags;
2099
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002100 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002102
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002103 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002105 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07002106 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002107
Viresh Kumar6eed9402013-08-06 22:53:11 +05302108 down_write(&cpufreq_rwsem);
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002109 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar6eed9402013-08-06 22:53:11 +05302110
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002111 cpufreq_driver = NULL;
Viresh Kumar6eed9402013-08-06 22:53:11 +05302112
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002113 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar6eed9402013-08-06 22:53:11 +05302114 up_write(&cpufreq_rwsem);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115
2116 return 0;
2117}
2118EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002119
2120static int __init cpufreq_core_init(void)
2121{
2122 int cpu;
2123
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002124 if (cpufreq_disabled())
2125 return -ENODEV;
2126
Viresh Kumar474deff2013-08-20 12:08:25 +05302127 for_each_possible_cpu(cpu)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002128 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002129
Viresh Kumar2361be22013-05-17 16:09:09 +05302130 cpufreq_global_kobject = kobject_create();
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002131 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002132 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002133
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002134 return 0;
2135}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002136core_initcall(cpufreq_core_init);