blob: 75c5bd424d599a71f49856d931787aef27f163a7 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/cpufreq/cpufreq.c
3 *
4 * Copyright (C) 2001 Russell King
5 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
Viresh Kumarbb176f72013-06-19 14:19:33 +05306 * (C) 2013 Viresh Kumar <viresh.kumar@linaro.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08008 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05009 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -050010 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
11 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080012 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 */
17
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Viresh Kumar5ff0a262013-08-06 22:53:03 +053020#include <linux/cpu.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/cpufreq.h>
22#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/device.h>
Viresh Kumar5ff0a262013-08-06 22:53:03 +053024#include <linux/init.h>
25#include <linux/kernel_stat.h>
26#include <linux/module.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080027#include <linux/mutex.h>
Viresh Kumar5ff0a262013-08-06 22:53:03 +053028#include <linux/slab.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010029#include <linux/syscore_ops.h>
Viresh Kumar5ff0a262013-08-06 22:53:03 +053030#include <linux/tick.h>
Thomas Renninger6f4f2722010-04-20 13:17:36 +020031#include <trace/events/power.h>
32
Linus Torvalds1da177e2005-04-16 15:20:36 -070033/**
Dave Jonescd878472006-08-11 17:59:28 -040034 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 * level driver of CPUFreq support, and its spinlock. This lock
36 * also protects the cpufreq_cpu_data array.
37 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +020038static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070039static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Srivatsa S. Bhat84148092013-07-30 04:25:10 +053040static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback);
Viresh Kumarbb176f72013-06-19 14:19:33 +053041static DEFINE_RWLOCK(cpufreq_driver_lock);
42static DEFINE_MUTEX(cpufreq_governor_lock);
Lukasz Majewskic88a1f82013-08-06 22:53:08 +053043static LIST_HEAD(cpufreq_policy_list);
Viresh Kumarbb176f72013-06-19 14:19:33 +053044
Thomas Renninger084f3492007-07-09 11:35:28 -070045#ifdef CONFIG_HOTPLUG_CPU
46/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040047static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070048#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080050/*
51 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
52 * all cpufreq/hotplug/workqueue/etc related lock issues.
53 *
54 * The rules for this semaphore:
55 * - Any routine that wants to read from the policy structure will
56 * do a down_read on this semaphore.
57 * - Any routine that will write to the policy structure and/or may take away
58 * the policy altogether (eg. CPU hotplug), will hold this lock in write
59 * mode before doing so.
60 *
61 * Additional rules:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080062 * - Governor routines that can be called in cpufreq hotplug path should not
63 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040064 * - Lock should not be held across
65 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080066 */
Tejun Heof1625062009-10-29 22:34:13 +090067static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080068static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
69
70#define lock_policy_rwsem(mode, cpu) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053071static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080072{ \
Tejun Heof1625062009-10-29 22:34:13 +090073 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080074 BUG_ON(policy_cpu == -1); \
75 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080076 \
77 return 0; \
78}
79
80lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080081lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080082
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053083#define unlock_policy_rwsem(mode, cpu) \
84static void unlock_policy_rwsem_##mode(int cpu) \
85{ \
86 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
87 BUG_ON(policy_cpu == -1); \
88 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080089}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080090
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053091unlock_policy_rwsem(read, cpu);
92unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Linus Torvalds1da177e2005-04-16 15:20:36 -070094/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -050095static int __cpufreq_governor(struct cpufreq_policy *policy,
96 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080097static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +000098static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
100/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500101 * Two notifier lists: the "policy" list is involved in the
102 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 * "transition" list for kernel code that needs to handle
104 * changes to devices when the CPU clock speed changes.
105 * The mutex locks both lists.
106 */
Alan Sterne041c682006-03-27 01:16:30 -0800107static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700108static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200110static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700111static int __init init_cpufreq_transition_notifier_list(void)
112{
113 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200114 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700115 return 0;
116}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800117pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400119static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200120static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400121{
122 return off;
123}
124void disable_cpufreq(void)
125{
126 off = 1;
127}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500129static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000131bool have_governor_per_policy(void)
132{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200133 return cpufreq_driver->have_governor_per_policy;
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000134}
Viresh Kumar3f869d62013-05-16 05:09:56 +0000135EXPORT_SYMBOL_GPL(have_governor_per_policy);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000136
Viresh Kumar944e9a02013-05-16 05:09:57 +0000137struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
138{
139 if (have_governor_per_policy())
140 return &policy->kobj;
141 else
142 return cpufreq_global_kobject;
143}
144EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
145
Viresh Kumar72a4ce32013-05-17 11:26:32 +0000146static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
147{
148 u64 idle_time;
149 u64 cur_wall_time;
150 u64 busy_time;
151
152 cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
153
154 busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
155 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
156 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
157 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
158 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
159 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
160
161 idle_time = cur_wall_time - busy_time;
162 if (wall)
163 *wall = cputime_to_usecs(cur_wall_time);
164
165 return cputime_to_usecs(idle_time);
166}
167
168u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
169{
170 u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
171
172 if (idle_time == -1ULL)
173 return get_cpu_idle_time_jiffy(cpu, wall);
174 else if (!io_busy)
175 idle_time += get_cpu_iowait_time_us(cpu, wall);
176
177 return idle_time;
178}
179EXPORT_SYMBOL_GPL(get_cpu_idle_time);
180
Stephen Boyda9144432012-07-20 18:14:38 +0000181static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182{
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530183 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 unsigned long flags;
185
Mike Travis7a6aedf2008-03-25 15:06:53 -0700186 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 goto err_out;
188
189 /* get the cpufreq driver */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000190 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200192 if (!cpufreq_driver)
193 goto err_out_unlock;
194
195 if (!try_module_get(cpufreq_driver->owner))
196 goto err_out_unlock;
197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 /* get the CPU */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530199 policy = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530201 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 goto err_out_put_module;
203
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530204 if (!sysfs && !kobject_get(&policy->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 goto err_out_put_module;
206
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000207 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530208 return policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
Dave Jones7d5e3502006-02-02 17:03:42 -0500210err_out_put_module:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200211 module_put(cpufreq_driver->owner);
Nathan Zimmer58000432013-04-04 14:53:25 +0000212err_out_unlock:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200213 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500214err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 return NULL;
216}
Stephen Boyda9144432012-07-20 18:14:38 +0000217
218struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
219{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000220 if (cpufreq_disabled())
221 return NULL;
222
Stephen Boyda9144432012-07-20 18:14:38 +0000223 return __cpufreq_cpu_get(cpu, false);
224}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
226
Stephen Boyda9144432012-07-20 18:14:38 +0000227static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
228{
229 return __cpufreq_cpu_get(cpu, true);
230}
231
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530232static void __cpufreq_cpu_put(struct cpufreq_policy *policy, bool sysfs)
Stephen Boyda9144432012-07-20 18:14:38 +0000233{
234 if (!sysfs)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530235 kobject_put(&policy->kobj);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200236 module_put(cpufreq_driver->owner);
Stephen Boyda9144432012-07-20 18:14:38 +0000237}
Dave Jones7d5e3502006-02-02 17:03:42 -0500238
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530239void cpufreq_cpu_put(struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000241 if (cpufreq_disabled())
242 return;
243
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530244 __cpufreq_cpu_put(policy, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245}
246EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
247
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530248static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *policy)
Stephen Boyda9144432012-07-20 18:14:38 +0000249{
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530250 __cpufreq_cpu_put(policy, true);
Stephen Boyda9144432012-07-20 18:14:38 +0000251}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
253/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
255 *********************************************************************/
256
257/**
258 * adjust_jiffies - adjust the system "loops_per_jiffy"
259 *
260 * This function alters the system "loops_per_jiffy" for the clock
261 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500262 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 * per-CPU loops_per_jiffy value wherever possible.
264 */
265#ifndef CONFIG_SMP
266static unsigned long l_p_j_ref;
Viresh Kumarbb176f72013-06-19 14:19:33 +0530267static unsigned int l_p_j_ref_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
Arjan van de Ven858119e2006-01-14 13:20:43 -0800269static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270{
271 if (ci->flags & CPUFREQ_CONST_LOOPS)
272 return;
273
274 if (!l_p_j_ref_freq) {
275 l_p_j_ref = loops_per_jiffy;
276 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200277 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530278 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 }
Viresh Kumarbb176f72013-06-19 14:19:33 +0530280 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700281 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530282 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
283 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200284 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530285 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 }
287}
288#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530289static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
290{
291 return;
292}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293#endif
294
Viresh Kumar0956df9c2013-06-19 14:19:34 +0530295static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530296 struct cpufreq_freqs *freqs, unsigned int state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297{
298 BUG_ON(irqs_disabled());
299
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000300 if (cpufreq_disabled())
301 return;
302
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200303 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200304 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800305 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800308
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 case CPUFREQ_PRECHANGE:
Viresh Kumar266c13d2013-07-02 16:36:28 +0530310 if (WARN(policy->transition_ongoing ==
311 cpumask_weight(policy->cpus),
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530312 "In middle of another frequency transition\n"))
313 return;
314
Viresh Kumar266c13d2013-07-02 16:36:28 +0530315 policy->transition_ongoing++;
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530316
Dave Jones32ee8c32006-02-28 00:43:23 -0500317 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800318 * which is not equal to what the cpufreq core thinks is
319 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200321 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800322 if ((policy) && (policy->cpu == freqs->cpu) &&
323 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200324 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800325 " %u, cpufreq assumed %u kHz.\n",
326 freqs->old, policy->cur);
327 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 }
329 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700330 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800331 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
333 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800334
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 case CPUFREQ_POSTCHANGE:
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530336 if (WARN(!policy->transition_ongoing,
337 "No frequency transition in progress\n"))
338 return;
339
Viresh Kumar266c13d2013-07-02 16:36:28 +0530340 policy->transition_ongoing--;
Viresh Kumar7c30ed52013-06-19 10:16:55 +0530341
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200343 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200344 (unsigned long)freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100345 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700346 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800347 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800348 if (likely(policy) && likely(policy->cpu == freqs->cpu))
349 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 break;
351 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352}
Viresh Kumarbb176f72013-06-19 14:19:33 +0530353
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530354/**
355 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
356 * on frequency transition.
357 *
358 * This function calls the transition notifiers and the "adjust_jiffies"
359 * function. It is called twice on all CPU frequency changes that have
360 * external effects.
361 */
362void cpufreq_notify_transition(struct cpufreq_policy *policy,
363 struct cpufreq_freqs *freqs, unsigned int state)
364{
365 for_each_cpu(freqs->cpu, policy->cpus)
366 __cpufreq_notify_transition(policy, freqs, state);
367}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
369
370
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371/*********************************************************************
372 * SYSFS INTERFACE *
373 *********************************************************************/
374
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700375static struct cpufreq_governor *__find_governor(const char *str_governor)
376{
377 struct cpufreq_governor *t;
378
379 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500380 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700381 return t;
382
383 return NULL;
384}
385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386/**
387 * cpufreq_parse_governor - parse a governor string
388 */
Dave Jones905d77c2008-03-05 14:28:32 -0500389static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 struct cpufreq_governor **governor)
391{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700392 int err = -EINVAL;
393
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200394 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700395 goto out;
396
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200397 if (cpufreq_driver->setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
399 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700400 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530401 } else if (!strnicmp(str_governor, "powersave",
402 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700404 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200406 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700408
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800409 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700410
411 t = __find_governor(str_governor);
412
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700413 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700414 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700415
Kees Cook1a8e1462011-05-04 08:38:56 -0700416 mutex_unlock(&cpufreq_governor_mutex);
417 ret = request_module("cpufreq_%s", str_governor);
418 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700419
Kees Cook1a8e1462011-05-04 08:38:56 -0700420 if (ret == 0)
421 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700422 }
423
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700424 if (t != NULL) {
425 *governor = t;
426 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700428
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800429 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 }
Dave Jones29464f22009-01-18 01:37:11 -0500431out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700432 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530436 * cpufreq_per_cpu_attr_read() / show_##file_name() -
437 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 *
439 * Write out information from cpufreq_driver->policy[cpu]; object must be
440 * "unsigned int".
441 */
442
Dave Jones32ee8c32006-02-28 00:43:23 -0500443#define show_one(file_name, object) \
444static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500445(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500446{ \
Dave Jones29464f22009-01-18 01:37:11 -0500447 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448}
449
450show_one(cpuinfo_min_freq, cpuinfo.min_freq);
451show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100452show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453show_one(scaling_min_freq, min);
454show_one(scaling_max_freq, max);
455show_one(scaling_cur_freq, cur);
456
Viresh Kumar3a3e9e02013-08-06 22:53:05 +0530457static int __cpufreq_set_policy(struct cpufreq_policy *policy,
458 struct cpufreq_policy *new_policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200459
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460/**
461 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
462 */
463#define store_one(file_name, object) \
464static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500465(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000467 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 struct cpufreq_policy new_policy; \
469 \
470 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
471 if (ret) \
472 return -EINVAL; \
473 \
Dave Jones29464f22009-01-18 01:37:11 -0500474 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 if (ret != 1) \
476 return -EINVAL; \
477 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200478 ret = __cpufreq_set_policy(policy, &new_policy); \
479 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 \
481 return ret ? ret : count; \
482}
483
Dave Jones29464f22009-01-18 01:37:11 -0500484store_one(scaling_min_freq, min);
485store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487/**
488 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
489 */
Dave Jones905d77c2008-03-05 14:28:32 -0500490static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
491 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800493 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 if (!cur_freq)
495 return sprintf(buf, "<unknown>");
496 return sprintf(buf, "%u\n", cur_freq);
497}
498
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499/**
500 * show_scaling_governor - show the current policy for the specified CPU
501 */
Dave Jones905d77c2008-03-05 14:28:32 -0500502static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503{
Dave Jones29464f22009-01-18 01:37:11 -0500504 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 return sprintf(buf, "powersave\n");
506 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
507 return sprintf(buf, "performance\n");
508 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200509 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500510 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 return -EINVAL;
512}
513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514/**
515 * store_scaling_governor - store policy for the specified CPU
516 */
Dave Jones905d77c2008-03-05 14:28:32 -0500517static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
518 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000520 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 char str_governor[16];
522 struct cpufreq_policy new_policy;
523
524 ret = cpufreq_get_policy(&new_policy, policy->cpu);
525 if (ret)
526 return ret;
527
Dave Jones29464f22009-01-18 01:37:11 -0500528 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 if (ret != 1)
530 return -EINVAL;
531
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530532 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
533 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 return -EINVAL;
535
Viresh Kumarbb176f72013-06-19 14:19:33 +0530536 /*
537 * Do not use cpufreq_set_policy here or the user_policy.max
538 * will be wrongly overridden
539 */
Thomas Renninger7970e082006-04-13 15:14:04 +0200540 ret = __cpufreq_set_policy(policy, &new_policy);
541
542 policy->user_policy.policy = policy->policy;
543 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200544
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530545 if (ret)
546 return ret;
547 else
548 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549}
550
551/**
552 * show_scaling_driver - show the cpufreq driver currently loaded
553 */
Dave Jones905d77c2008-03-05 14:28:32 -0500554static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200556 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557}
558
559/**
560 * show_scaling_available_governors - show the available CPUfreq governors
561 */
Dave Jones905d77c2008-03-05 14:28:32 -0500562static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
563 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564{
565 ssize_t i = 0;
566 struct cpufreq_governor *t;
567
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200568 if (!cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 i += sprintf(buf, "performance powersave");
570 goto out;
571 }
572
573 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500574 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
575 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200577 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500579out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 i += sprintf(&buf[i], "\n");
581 return i;
582}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700583
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800584ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585{
586 ssize_t i = 0;
587 unsigned int cpu;
588
Rusty Russell835481d2009-01-04 05:18:06 -0800589 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 if (i)
591 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
592 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
593 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500594 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 }
596 i += sprintf(&buf[i], "\n");
597 return i;
598}
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800599EXPORT_SYMBOL_GPL(cpufreq_show_cpus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700601/**
602 * show_related_cpus - show the CPUs affected by each transition even if
603 * hw coordination is in use
604 */
605static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
606{
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800607 return cpufreq_show_cpus(policy->related_cpus, buf);
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700608}
609
610/**
611 * show_affected_cpus - show the CPUs affected by each transition
612 */
613static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
614{
Lan Tianyuf4fd3792013-06-27 15:08:54 +0800615 return cpufreq_show_cpus(policy->cpus, buf);
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700616}
617
Venki Pallipadi9e769882007-10-26 10:18:21 -0700618static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500619 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700620{
621 unsigned int freq = 0;
622 unsigned int ret;
623
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700624 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700625 return -EINVAL;
626
627 ret = sscanf(buf, "%u", &freq);
628 if (ret != 1)
629 return -EINVAL;
630
631 policy->governor->store_setspeed(policy, freq);
632
633 return count;
634}
635
636static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
637{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700638 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700639 return sprintf(buf, "<unsupported>\n");
640
641 return policy->governor->show_setspeed(policy, buf);
642}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643
Thomas Renningere2f74f32009-11-19 12:31:01 +0100644/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200645 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100646 */
647static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
648{
649 unsigned int limit;
650 int ret;
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200651 if (cpufreq_driver->bios_limit) {
652 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
Thomas Renningere2f74f32009-11-19 12:31:01 +0100653 if (!ret)
654 return sprintf(buf, "%u\n", limit);
655 }
656 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
657}
658
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200659cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
660cpufreq_freq_attr_ro(cpuinfo_min_freq);
661cpufreq_freq_attr_ro(cpuinfo_max_freq);
662cpufreq_freq_attr_ro(cpuinfo_transition_latency);
663cpufreq_freq_attr_ro(scaling_available_governors);
664cpufreq_freq_attr_ro(scaling_driver);
665cpufreq_freq_attr_ro(scaling_cur_freq);
666cpufreq_freq_attr_ro(bios_limit);
667cpufreq_freq_attr_ro(related_cpus);
668cpufreq_freq_attr_ro(affected_cpus);
669cpufreq_freq_attr_rw(scaling_min_freq);
670cpufreq_freq_attr_rw(scaling_max_freq);
671cpufreq_freq_attr_rw(scaling_governor);
672cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
Dave Jones905d77c2008-03-05 14:28:32 -0500674static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 &cpuinfo_min_freq.attr,
676 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100677 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 &scaling_min_freq.attr,
679 &scaling_max_freq.attr,
680 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700681 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 &scaling_governor.attr,
683 &scaling_driver.attr,
684 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700685 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 NULL
687};
688
Dave Jones29464f22009-01-18 01:37:11 -0500689#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
690#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691
Dave Jones29464f22009-01-18 01:37:11 -0500692static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693{
Dave Jones905d77c2008-03-05 14:28:32 -0500694 struct cpufreq_policy *policy = to_policy(kobj);
695 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500696 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000697 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500699 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800700
701 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500702 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800703
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530704 if (fattr->show)
705 ret = fattr->show(policy, buf);
706 else
707 ret = -EIO;
708
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800709 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500710fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000711 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500712no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 return ret;
714}
715
Dave Jones905d77c2008-03-05 14:28:32 -0500716static ssize_t store(struct kobject *kobj, struct attribute *attr,
717 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718{
Dave Jones905d77c2008-03-05 14:28:32 -0500719 struct cpufreq_policy *policy = to_policy(kobj);
720 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500721 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000722 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500724 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800725
726 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500727 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800728
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530729 if (fattr->store)
730 ret = fattr->store(policy, buf, count);
731 else
732 ret = -EIO;
733
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800734 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500735fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000736 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500737no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 return ret;
739}
740
Dave Jones905d77c2008-03-05 14:28:32 -0500741static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742{
Dave Jones905d77c2008-03-05 14:28:32 -0500743 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200744 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 complete(&policy->kobj_unregister);
746}
747
Emese Revfy52cf25d2010-01-19 02:58:23 +0100748static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 .show = show,
750 .store = store,
751};
752
753static struct kobj_type ktype_cpufreq = {
754 .sysfs_ops = &sysfs_ops,
755 .default_attrs = default_attrs,
756 .release = cpufreq_sysfs_release,
757};
758
Viresh Kumar2361be22013-05-17 16:09:09 +0530759struct kobject *cpufreq_global_kobject;
760EXPORT_SYMBOL(cpufreq_global_kobject);
761
762static int cpufreq_global_kobject_usage;
763
764int cpufreq_get_global_kobject(void)
765{
766 if (!cpufreq_global_kobject_usage++)
767 return kobject_add(cpufreq_global_kobject,
768 &cpu_subsys.dev_root->kobj, "%s", "cpufreq");
769
770 return 0;
771}
772EXPORT_SYMBOL(cpufreq_get_global_kobject);
773
774void cpufreq_put_global_kobject(void)
775{
776 if (!--cpufreq_global_kobject_usage)
777 kobject_del(cpufreq_global_kobject);
778}
779EXPORT_SYMBOL(cpufreq_put_global_kobject);
780
781int cpufreq_sysfs_create_file(const struct attribute *attr)
782{
783 int ret = cpufreq_get_global_kobject();
784
785 if (!ret) {
786 ret = sysfs_create_file(cpufreq_global_kobject, attr);
787 if (ret)
788 cpufreq_put_global_kobject();
789 }
790
791 return ret;
792}
793EXPORT_SYMBOL(cpufreq_sysfs_create_file);
794
795void cpufreq_sysfs_remove_file(const struct attribute *attr)
796{
797 sysfs_remove_file(cpufreq_global_kobject, attr);
798 cpufreq_put_global_kobject();
799}
800EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
801
Dave Jones19d6f7e2009-07-08 17:35:39 -0400802/* symlink affected CPUs */
Viresh Kumar308b60e2013-07-31 14:35:14 +0200803static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400804{
805 unsigned int j;
806 int ret = 0;
807
808 for_each_cpu(j, policy->cpus) {
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800809 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400810
Viresh Kumar308b60e2013-07-31 14:35:14 +0200811 if (j == policy->cpu)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400812 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400813
Viresh Kumare8fdde12013-07-31 14:31:33 +0200814 pr_debug("Adding link for CPU: %u\n", j);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800815 cpu_dev = get_cpu_device(j);
816 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400817 "cpufreq");
Rafael J. Wysocki71c34612013-08-04 01:19:34 +0200818 if (ret)
819 break;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400820 }
821 return ret;
822}
823
Viresh Kumar308b60e2013-07-31 14:35:14 +0200824static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800825 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400826{
827 struct freq_attr **drv_attr;
Dave Jones909a6942009-07-08 18:05:42 -0400828 int ret = 0;
Dave Jones909a6942009-07-08 18:05:42 -0400829
830 /* prepare interface data */
831 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800832 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400833 if (ret)
834 return ret;
835
836 /* set up files for this cpu device */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200837 drv_attr = cpufreq_driver->attr;
Dave Jones909a6942009-07-08 18:05:42 -0400838 while ((drv_attr) && (*drv_attr)) {
839 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
840 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200841 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400842 drv_attr++;
843 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200844 if (cpufreq_driver->get) {
Dave Jones909a6942009-07-08 18:05:42 -0400845 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
846 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200847 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400848 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200849 if (cpufreq_driver->target) {
Dave Jones909a6942009-07-08 18:05:42 -0400850 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
851 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200852 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400853 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200854 if (cpufreq_driver->bios_limit) {
Thomas Renningere2f74f32009-11-19 12:31:01 +0100855 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
856 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200857 goto err_out_kobj_put;
Thomas Renningere2f74f32009-11-19 12:31:01 +0100858 }
Dave Jones909a6942009-07-08 18:05:42 -0400859
Viresh Kumar308b60e2013-07-31 14:35:14 +0200860 ret = cpufreq_add_dev_symlink(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400861 if (ret)
862 goto err_out_kobj_put;
863
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +0530864 return ret;
865
866err_out_kobj_put:
867 kobject_put(&policy->kobj);
868 wait_for_completion(&policy->kobj_unregister);
869 return ret;
870}
871
872static void cpufreq_init_policy(struct cpufreq_policy *policy)
873{
874 struct cpufreq_policy new_policy;
875 int ret = 0;
876
Viresh Kumard5b73cd2013-08-06 22:53:06 +0530877 memcpy(&new_policy, policy, sizeof(*policy));
Dave Jonesecf7e462009-07-08 18:48:47 -0400878 /* assure that the starting sequence is run in __cpufreq_set_policy */
879 policy->governor = NULL;
880
881 /* set default policy */
882 ret = __cpufreq_set_policy(policy, &new_policy);
883 policy->user_policy.policy = policy->policy;
884 policy->user_policy.governor = policy->governor;
885
886 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200887 pr_debug("setting policy failed\n");
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200888 if (cpufreq_driver->exit)
889 cpufreq_driver->exit(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400890 }
Dave Jones909a6942009-07-08 18:05:42 -0400891}
892
Viresh Kumarfcf80582013-01-29 14:39:08 +0000893#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumard8d3b472013-08-04 01:20:07 +0200894static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
895 unsigned int cpu, struct device *dev,
896 bool frozen)
Viresh Kumarfcf80582013-01-29 14:39:08 +0000897{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200898 int ret = 0, has_target = !!cpufreq_driver->target;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000899 unsigned long flags;
900
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200901 if (has_target)
902 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000903
Viresh Kumard8d3b472013-08-04 01:20:07 +0200904 lock_policy_rwsem_write(policy->cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530905
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000906 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530907
Viresh Kumarfcf80582013-01-29 14:39:08 +0000908 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530909 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000910 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000911 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000912
Viresh Kumard8d3b472013-08-04 01:20:07 +0200913 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530914
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200915 if (has_target) {
916 __cpufreq_governor(policy, CPUFREQ_GOV_START);
917 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
918 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000919
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530920 /* Don't touch sysfs links during light-weight init */
Rafael J. Wysocki71c34612013-08-04 01:19:34 +0200921 if (!frozen)
922 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
Viresh Kumarfcf80582013-01-29 14:39:08 +0000923
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530924 return ret;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000925}
926#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Srivatsa S. Bhat84148092013-07-30 04:25:10 +0530928static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu)
929{
930 struct cpufreq_policy *policy;
931 unsigned long flags;
932
933 write_lock_irqsave(&cpufreq_driver_lock, flags);
934
935 policy = per_cpu(cpufreq_cpu_data_fallback, cpu);
936
937 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
938
939 return policy;
940}
941
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530942static struct cpufreq_policy *cpufreq_policy_alloc(void)
943{
944 struct cpufreq_policy *policy;
945
946 policy = kzalloc(sizeof(*policy), GFP_KERNEL);
947 if (!policy)
948 return NULL;
949
950 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
951 goto err_free_policy;
952
953 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
954 goto err_free_cpumask;
955
Lukasz Majewskic88a1f82013-08-06 22:53:08 +0530956 INIT_LIST_HEAD(&policy->policy_list);
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530957 return policy;
958
959err_free_cpumask:
960 free_cpumask_var(policy->cpus);
961err_free_policy:
962 kfree(policy);
963
964 return NULL;
965}
966
967static void cpufreq_policy_free(struct cpufreq_policy *policy)
968{
Lukasz Majewskic88a1f82013-08-06 22:53:08 +0530969 unsigned long flags;
970
971 write_lock_irqsave(&cpufreq_driver_lock, flags);
972 list_del(&policy->policy_list);
973 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
974
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +0530975 free_cpumask_var(policy->related_cpus);
976 free_cpumask_var(policy->cpus);
977 kfree(policy);
978}
979
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +0530980static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
981 bool frozen)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000983 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530984 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500987#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000988 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500989 int sibling;
990#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
Ashok Rajc32b6b82005-10-30 14:59:54 -0800992 if (cpu_is_offline(cpu))
993 return 0;
994
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200995 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
997#ifdef CONFIG_SMP
998 /* check whether a different CPU already registered this
999 * CPU because it is in the same boat. */
1000 policy = cpufreq_cpu_get(cpu);
1001 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -05001002 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 return 0;
1004 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001005
1006#ifdef CONFIG_HOTPLUG_CPU
1007 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001008 read_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +00001009 for_each_online_cpu(sibling) {
1010 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301011 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001012 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumard8d3b472013-08-04 01:20:07 +02001013 return cpufreq_add_policy_cpu(cp, cpu, dev, frozen);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301014 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001015 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001016 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +00001017#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018#endif
1019
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001020 if (!try_module_get(cpufreq_driver->owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 ret = -EINVAL;
1022 goto module_out;
1023 }
1024
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301025 if (frozen)
1026 /* Restore the saved policy when doing light-weight init */
1027 policy = cpufreq_policy_restore(cpu);
1028 else
1029 policy = cpufreq_policy_alloc();
1030
Dave Jones059019a2009-07-08 16:30:03 -04001031 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -04001033
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +05301035 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -08001036 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001038 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +09001039 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001040
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +00001042 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
1044 /* call driver. From then on the cpufreq must be able
1045 * to accept all calls to ->verify and ->setpolicy for this CPU
1046 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001047 ret = cpufreq_driver->init(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001049 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301050 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001052
Viresh Kumarfcf80582013-01-29 14:39:08 +00001053 /* related cpus should atleast have policy->cpus */
1054 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
1055
Viresh Kumar643ae6e2013-01-12 05:14:38 +00001056 /*
1057 * affected cpus must always be the one, which are online. We aren't
1058 * managing offline cpus here.
1059 */
1060 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
1061
Mike Chan187d9f42008-12-04 12:19:17 -08001062 policy->user_policy.min = policy->min;
1063 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
Thomas Renningera1531ac2008-07-29 22:32:58 -07001065 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1066 CPUFREQ_START, policy);
1067
Viresh Kumarfcf80582013-01-29 14:39:08 +00001068#ifdef CONFIG_HOTPLUG_CPU
1069 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
1070 if (gov) {
1071 policy->governor = gov;
1072 pr_debug("Restoring governor %s for cpu %d\n",
1073 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +02001074 }
Viresh Kumarfcf80582013-01-29 14:39:08 +00001075#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301077 write_lock_irqsave(&cpufreq_driver_lock, flags);
1078 for_each_cpu(j, policy->cpus) {
1079 per_cpu(cpufreq_cpu_data, j) = policy;
1080 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
1081 }
1082 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1083
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301084 if (!frozen) {
Viresh Kumar308b60e2013-07-31 14:35:14 +02001085 ret = cpufreq_add_dev_interface(policy, dev);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301086 if (ret)
1087 goto err_out_unregister;
Lukasz Majewskic88a1f82013-08-06 22:53:08 +05301088
1089 write_lock_irqsave(&cpufreq_driver_lock, flags);
1090 list_add(&policy->policy_list, &cpufreq_policy_list);
1091 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301092 }
Dave Jones8ff69732006-03-05 03:37:23 -05001093
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301094 cpufreq_init_policy(policy);
1095
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001096 kobject_uevent(&policy->kobj, KOBJ_ADD);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001097 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001098 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001099
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 return 0;
1101
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001103 write_lock_irqsave(&cpufreq_driver_lock, flags);
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301104 for_each_cpu(j, policy->cpus) {
Mike Travis7a6aedf2008-03-25 15:06:53 -07001105 per_cpu(cpufreq_cpu_data, j) = NULL;
Srivatsa S. Bhate18f1682013-07-30 04:24:23 +05301106 if (j != cpu)
1107 per_cpu(cpufreq_policy_cpu, j) = -1;
1108 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001109 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301111err_set_policy_cpu:
1112 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Srivatsa S. Bhate9698cc2013-07-30 04:24:11 +05301113 cpufreq_policy_free(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114nomem_out:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001115 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001116module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 return ret;
1118}
1119
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301120/**
1121 * cpufreq_add_dev - add a CPU device
1122 *
1123 * Adds the cpufreq interface for a CPU device.
1124 *
1125 * The Oracle says: try running cpufreq registration/unregistration concurrently
1126 * with with cpu hotplugging and all hell will break loose. Tried to clean this
1127 * mess up, but more thorough testing is needed. - Mathieu
1128 */
1129static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
1130{
1131 return __cpufreq_add_dev(dev, sif, false);
1132}
1133
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001134static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1135{
1136 int j;
1137
1138 policy->last_cpu = policy->cpu;
1139 policy->cpu = cpu;
1140
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001141 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001142 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001143
1144#ifdef CONFIG_CPU_FREQ_TABLE
1145 cpufreq_frequency_table_update_policy_cpu(policy);
1146#endif
1147 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1148 CPUFREQ_UPDATE_POLICY_CPU, policy);
1149}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301151static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301152 unsigned int old_cpu, bool frozen)
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301153{
1154 struct device *cpu_dev;
1155 unsigned long flags;
1156 int ret;
1157
1158 /* first sibling now owns the new sysfs dir */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301159 cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301160
1161 /* Don't touch sysfs files during light-weight tear-down */
1162 if (frozen)
1163 return cpu_dev->id;
1164
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301165 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301166 ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301167 if (ret) {
1168 pr_err("%s: Failed to move kobj: %d", __func__, ret);
1169
1170 WARN_ON(lock_policy_rwsem_write(old_cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301171 cpumask_set_cpu(old_cpu, policy->cpus);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301172
1173 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301174 per_cpu(cpufreq_cpu_data, old_cpu) = policy;
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301175 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
1176
1177 unlock_policy_rwsem_write(old_cpu);
1178
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301179 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301180 "cpufreq");
1181
1182 return -EINVAL;
1183 }
1184
1185 return cpu_dev->id;
1186}
1187
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001189 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 *
1191 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001192 * Caller should already have policy_rwsem in write mode for this CPU.
1193 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 */
Viresh Kumarbb176f72013-06-19 14:19:33 +05301195static int __cpufreq_remove_dev(struct device *dev,
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301196 struct subsys_interface *sif, bool frozen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197{
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301198 unsigned int cpu = dev->id, cpus;
1199 int new_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 unsigned long flags;
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301201 struct cpufreq_policy *policy;
Amerigo Wang499bca92010-03-04 03:23:46 -05001202 struct kobject *kobj;
1203 struct completion *cmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001205 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001207 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301209 policy = per_cpu(cpufreq_cpu_data, cpu);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001210 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301212 /* Save the policy somewhere when doing a light-weight tear-down */
1213 if (frozen)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301214 per_cpu(cpufreq_cpu_data_fallback, cpu) = policy;
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301215
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001216 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301218 if (!policy) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001219 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001223 if (cpufreq_driver->target)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301224 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001225
Jacob Shin27ecddc2011-04-27 13:32:11 -05001226#ifdef CONFIG_HOTPLUG_CPU
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001227 if (!cpufreq_driver->setpolicy)
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001228 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301229 policy->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001230#endif
1231
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301232 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301233 cpus = cpumask_weight(policy->cpus);
Viresh Kumare4969eb2013-04-11 08:04:53 +00001234
1235 if (cpus > 1)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301236 cpumask_clear_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301237 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301239 if (cpu != policy->cpu && !frozen) {
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001240 sysfs_remove_link(&dev->kobj, "cpufreq");
1241 } else if (cpus > 1) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301242
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301243 new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen);
Srivatsa S. Bhatf9ba6802013-07-30 04:24:36 +05301244 if (new_cpu >= 0) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301245 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301246 update_policy_cpu(policy, new_cpu);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301247 unlock_policy_rwsem_write(cpu);
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301248
1249 if (!frozen) {
1250 pr_debug("%s: policy Kobject moved to cpu: %d "
1251 "from: %d\n",__func__, new_cpu, cpu);
1252 }
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001253 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001254 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001255
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001256 /* If cpu is last user of policy, free policy */
1257 if (cpus == 1) {
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001258 if (cpufreq_driver->target)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301259 __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT);
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001260
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301261 if (!frozen) {
1262 lock_policy_rwsem_read(cpu);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301263 kobj = &policy->kobj;
1264 cmp = &policy->kobj_unregister;
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301265 unlock_policy_rwsem_read(cpu);
1266 kobject_put(kobj);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001267
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301268 /*
1269 * We need to make sure that the underlying kobj is
1270 * actually not referenced anymore by anybody before we
1271 * proceed with unloading.
1272 */
1273 pr_debug("waiting for dropping of refcount\n");
1274 wait_for_completion(cmp);
1275 pr_debug("wait complete\n");
1276 }
1277
1278 /*
1279 * Perform the ->exit() even during light-weight tear-down,
1280 * since this is a core component, and is essential for the
1281 * subsequent light-weight ->init() to succeed.
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001282 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001283 if (cpufreq_driver->exit)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301284 cpufreq_driver->exit(policy);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001285
Srivatsa S. Bhat84148092013-07-30 04:25:10 +05301286 if (!frozen)
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301287 cpufreq_policy_free(policy);
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001288 } else {
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001289 if (cpufreq_driver->target) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301290 __cpufreq_governor(policy, CPUFREQ_GOV_START);
1291 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
Rafael J. Wysocki2a998592013-07-30 00:32:00 +02001292 }
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001293 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301295 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 return 0;
1297}
1298
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001299static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001300{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001301 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001302 int retval;
Venki Pallipadiec282972007-03-26 12:03:19 -07001303
1304 if (cpu_is_offline(cpu))
1305 return 0;
1306
Srivatsa S. Bhata82fab22013-07-30 04:24:49 +05301307 retval = __cpufreq_remove_dev(dev, sif, false);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001308 return retval;
1309}
1310
David Howells65f27f32006-11-22 14:55:48 +00001311static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312{
David Howells65f27f32006-11-22 14:55:48 +00001313 struct cpufreq_policy *policy =
1314 container_of(work, struct cpufreq_policy, update);
1315 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001316 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 cpufreq_update_policy(cpu);
1318}
1319
1320/**
Viresh Kumarbb176f72013-06-19 14:19:33 +05301321 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're
1322 * in deep trouble.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 * @cpu: cpu number
1324 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1325 * @new_freq: CPU frequency the CPU actually runs at
1326 *
Dave Jones29464f22009-01-18 01:37:11 -05001327 * We adjust to current frequency first, and need to clean up later.
1328 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301330static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1331 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332{
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301333 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 struct cpufreq_freqs freqs;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301335 unsigned long flags;
1336
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001337 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1339
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 freqs.old = old_freq;
1341 freqs.new = new_freq;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301342
1343 read_lock_irqsave(&cpufreq_driver_lock, flags);
1344 policy = per_cpu(cpufreq_cpu_data, cpu);
1345 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1346
1347 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
1348 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349}
1350
Dave Jones32ee8c32006-02-28 00:43:23 -05001351/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301352 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001353 * @cpu: CPU number
1354 *
1355 * This is the last known freq, without actually getting it from the driver.
1356 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1357 */
1358unsigned int cpufreq_quick_get(unsigned int cpu)
1359{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001360 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301361 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001362
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001363 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1364 return cpufreq_driver->get(cpu);
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001365
1366 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001367 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301368 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001369 cpufreq_cpu_put(policy);
1370 }
1371
Dave Jones4d34a672008-02-07 16:33:49 -05001372 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001373}
1374EXPORT_SYMBOL(cpufreq_quick_get);
1375
Jesse Barnes3d737102011-06-28 10:59:12 -07001376/**
1377 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1378 * @cpu: CPU number
1379 *
1380 * Just return the max possible frequency for a given CPU.
1381 */
1382unsigned int cpufreq_quick_get_max(unsigned int cpu)
1383{
1384 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1385 unsigned int ret_freq = 0;
1386
1387 if (policy) {
1388 ret_freq = policy->max;
1389 cpufreq_cpu_put(policy);
1390 }
1391
1392 return ret_freq;
1393}
1394EXPORT_SYMBOL(cpufreq_quick_get_max);
1395
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001396static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001398 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301399 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001401 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001402 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001404 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301406 if (ret_freq && policy->cur &&
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001407 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301408 /* verify no discrepancy between actual and
1409 saved value exists */
1410 if (unlikely(ret_freq != policy->cur)) {
1411 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 schedule_work(&policy->update);
1413 }
1414 }
1415
Dave Jones4d34a672008-02-07 16:33:49 -05001416 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001417}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001419/**
1420 * cpufreq_get - get the current CPU frequency (in kHz)
1421 * @cpu: CPU number
1422 *
1423 * Get the CPU current (static) CPU frequency
1424 */
1425unsigned int cpufreq_get(unsigned int cpu)
1426{
1427 unsigned int ret_freq = 0;
1428 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1429
1430 if (!policy)
1431 goto out;
1432
1433 if (unlikely(lock_policy_rwsem_read(cpu)))
1434 goto out_policy;
1435
1436 ret_freq = __cpufreq_get(cpu);
1437
1438 unlock_policy_rwsem_read(cpu);
1439
1440out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001442out:
Dave Jones4d34a672008-02-07 16:33:49 -05001443 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444}
1445EXPORT_SYMBOL(cpufreq_get);
1446
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001447static struct subsys_interface cpufreq_interface = {
1448 .name = "cpufreq",
1449 .subsys = &cpu_subsys,
1450 .add_dev = cpufreq_add_dev,
1451 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001452};
1453
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001455 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1456 *
1457 * This function is only executed for the boot processor. The other CPUs
1458 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001459 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001460static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001461{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301462 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001463
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001464 int cpu = smp_processor_id();
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301465 struct cpufreq_policy *policy;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001466
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001467 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001468
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001469 /* If there's no policy for the boot CPU, we have nothing to do. */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301470 policy = cpufreq_cpu_get(cpu);
1471 if (!policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001472 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001473
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001474 if (cpufreq_driver->suspend) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301475 ret = cpufreq_driver->suspend(policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001476 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001477 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301478 "step on CPU %u\n", policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001479 }
1480
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301481 cpufreq_cpu_put(policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001482 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001483}
1484
1485/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001486 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 *
1488 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001489 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1490 * restored. It will verify that the current freq is in sync with
1491 * what we believe it to be. This is a bit later than when it
1492 * should be, but nonethteless it's better than calling
1493 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001494 *
1495 * This function is only executed for the boot CPU. The other CPUs have not
1496 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001498static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301500 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001501
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001502 int cpu = smp_processor_id();
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301503 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001505 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001507 /* If there's no policy for the boot CPU, we have nothing to do. */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301508 policy = cpufreq_cpu_get(cpu);
1509 if (!policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001510 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001512 if (cpufreq_driver->resume) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301513 ret = cpufreq_driver->resume(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 if (ret) {
1515 printk(KERN_ERR "cpufreq: resume failed in ->resume "
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301516 "step on CPU %u\n", policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001517 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 }
1519 }
1520
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301521 schedule_work(&policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001522
Dave Jonesc9060492008-02-07 16:32:18 -05001523fail:
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301524 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525}
1526
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001527static struct syscore_ops cpufreq_syscore_ops = {
1528 .suspend = cpufreq_bp_suspend,
1529 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530};
1531
Borislav Petkov9d950462013-01-20 10:24:28 +00001532/**
1533 * cpufreq_get_current_driver - return current driver's name
1534 *
1535 * Return the name string of the currently loaded cpufreq driver
1536 * or NULL, if none.
1537 */
1538const char *cpufreq_get_current_driver(void)
1539{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001540 if (cpufreq_driver)
1541 return cpufreq_driver->name;
1542
1543 return NULL;
Borislav Petkov9d950462013-01-20 10:24:28 +00001544}
1545EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547/*********************************************************************
1548 * NOTIFIER LISTS INTERFACE *
1549 *********************************************************************/
1550
1551/**
1552 * cpufreq_register_notifier - register a driver with cpufreq
1553 * @nb: notifier function to register
1554 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1555 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001556 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 * are notified about clock rate changes (once before and once after
1558 * the transition), or a list of drivers that are notified about
1559 * changes in cpufreq policy.
1560 *
1561 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001562 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 */
1564int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1565{
1566 int ret;
1567
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001568 if (cpufreq_disabled())
1569 return -EINVAL;
1570
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001571 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1572
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 switch (list) {
1574 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001575 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001576 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 break;
1578 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001579 ret = blocking_notifier_chain_register(
1580 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 break;
1582 default:
1583 ret = -EINVAL;
1584 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585
1586 return ret;
1587}
1588EXPORT_SYMBOL(cpufreq_register_notifier);
1589
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590/**
1591 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1592 * @nb: notifier block to be unregistered
Viresh Kumarbb176f72013-06-19 14:19:33 +05301593 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 *
1595 * Remove a driver from the CPU frequency notifier list.
1596 *
1597 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001598 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 */
1600int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1601{
1602 int ret;
1603
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001604 if (cpufreq_disabled())
1605 return -EINVAL;
1606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 switch (list) {
1608 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001609 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001610 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 break;
1612 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001613 ret = blocking_notifier_chain_unregister(
1614 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 break;
1616 default:
1617 ret = -EINVAL;
1618 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619
1620 return ret;
1621}
1622EXPORT_SYMBOL(cpufreq_unregister_notifier);
1623
1624
1625/*********************************************************************
1626 * GOVERNORS *
1627 *********************************************************************/
1628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629int __cpufreq_driver_target(struct cpufreq_policy *policy,
1630 unsigned int target_freq,
1631 unsigned int relation)
1632{
1633 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001634 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001635
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001636 if (cpufreq_disabled())
1637 return -ENODEV;
Viresh Kumar7c30ed52013-06-19 10:16:55 +05301638 if (policy->transition_ongoing)
1639 return -EBUSY;
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001640
Viresh Kumar72499242012-10-31 01:28:21 +01001641 /* Make sure that target_freq is within supported range */
1642 if (target_freq > policy->max)
1643 target_freq = policy->max;
1644 if (target_freq < policy->min)
1645 target_freq = policy->min;
1646
1647 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1648 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001649
1650 if (target_freq == policy->cur)
1651 return 0;
1652
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001653 if (cpufreq_driver->target)
1654 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001655
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 return retval;
1657}
1658EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1659
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660int cpufreq_driver_target(struct cpufreq_policy *policy,
1661 unsigned int target_freq,
1662 unsigned int relation)
1663{
Julia Lawallf1829e42008-07-25 22:44:53 +02001664 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001666 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001667 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
1669 ret = __cpufreq_driver_target(policy, target_freq, relation);
1670
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001671 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672
Julia Lawallf1829e42008-07-25 22:44:53 +02001673fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674 return ret;
1675}
1676EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1677
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001678/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001679 * when "event" is CPUFREQ_GOV_LIMITS
1680 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301682static int __cpufreq_governor(struct cpufreq_policy *policy,
1683 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684{
Dave Jonescc993ca2005-07-28 09:43:56 -07001685 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001686
1687 /* Only must be defined when default governor is known to have latency
1688 restrictions, like e.g. conservative or ondemand.
1689 That this is the case is already ensured in Kconfig
1690 */
1691#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1692 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1693#else
1694 struct cpufreq_governor *gov = NULL;
1695#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001696
1697 if (policy->governor->max_transition_latency &&
1698 policy->cpuinfo.transition_latency >
1699 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001700 if (!gov)
1701 return -EINVAL;
1702 else {
1703 printk(KERN_WARNING "%s governor failed, too long"
1704 " transition latency of HW, fallback"
1705 " to %s governor\n",
1706 policy->governor->name,
1707 gov->name);
1708 policy->governor = gov;
1709 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001710 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
1712 if (!try_module_get(policy->governor->owner))
1713 return -EINVAL;
1714
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001715 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301716 policy->cpu, event);
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001717
1718 mutex_lock(&cpufreq_governor_lock);
1719 if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ||
1720 (policy->governor_enabled && (event == CPUFREQ_GOV_START))) {
1721 mutex_unlock(&cpufreq_governor_lock);
1722 return -EBUSY;
1723 }
1724
1725 if (event == CPUFREQ_GOV_STOP)
1726 policy->governor_enabled = false;
1727 else if (event == CPUFREQ_GOV_START)
1728 policy->governor_enabled = true;
1729
1730 mutex_unlock(&cpufreq_governor_lock);
1731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 ret = policy->governor->governor(policy, event);
1733
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001734 if (!ret) {
1735 if (event == CPUFREQ_GOV_POLICY_INIT)
1736 policy->governor->initialized++;
1737 else if (event == CPUFREQ_GOV_POLICY_EXIT)
1738 policy->governor->initialized--;
Xiaoguang Chen95731eb2013-06-19 15:00:07 +08001739 } else {
1740 /* Restore original values */
1741 mutex_lock(&cpufreq_governor_lock);
1742 if (event == CPUFREQ_GOV_STOP)
1743 policy->governor_enabled = true;
1744 else if (event == CPUFREQ_GOV_START)
1745 policy->governor_enabled = false;
1746 mutex_unlock(&cpufreq_governor_lock);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001747 }
Viresh Kumarb3940582013-02-01 05:42:58 +00001748
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301749 /* we keep one module reference alive for
1750 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 if ((event != CPUFREQ_GOV_START) || ret)
1752 module_put(policy->governor->owner);
1753 if ((event == CPUFREQ_GOV_STOP) && !ret)
1754 module_put(policy->governor->owner);
1755
1756 return ret;
1757}
1758
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759int cpufreq_register_governor(struct cpufreq_governor *governor)
1760{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001761 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
1763 if (!governor)
1764 return -EINVAL;
1765
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001766 if (cpufreq_disabled())
1767 return -ENODEV;
1768
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001769 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001770
Viresh Kumarb3940582013-02-01 05:42:58 +00001771 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001772 err = -EBUSY;
1773 if (__find_governor(governor->name) == NULL) {
1774 err = 0;
1775 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001777
Dave Jones32ee8c32006-02-28 00:43:23 -05001778 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001779 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780}
1781EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1782
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1784{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001785#ifdef CONFIG_HOTPLUG_CPU
1786 int cpu;
1787#endif
1788
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 if (!governor)
1790 return;
1791
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001792 if (cpufreq_disabled())
1793 return;
1794
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001795#ifdef CONFIG_HOTPLUG_CPU
1796 for_each_present_cpu(cpu) {
1797 if (cpu_online(cpu))
1798 continue;
1799 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1800 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1801 }
1802#endif
1803
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001804 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001806 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 return;
1808}
1809EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1810
1811
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812/*********************************************************************
1813 * POLICY INTERFACE *
1814 *********************************************************************/
1815
1816/**
1817 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001818 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1819 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 *
1821 * Reads the current cpufreq policy.
1822 */
1823int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1824{
1825 struct cpufreq_policy *cpu_policy;
1826 if (!policy)
1827 return -EINVAL;
1828
1829 cpu_policy = cpufreq_cpu_get(cpu);
1830 if (!cpu_policy)
1831 return -EINVAL;
1832
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301833 memcpy(policy, cpu_policy, sizeof(*policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 return 0;
1837}
1838EXPORT_SYMBOL(cpufreq_get_policy);
1839
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001840/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301841 * data : current policy.
1842 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001843 */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301844static int __cpufreq_set_policy(struct cpufreq_policy *policy,
1845 struct cpufreq_policy *new_policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001847 int ret = 0, failed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301849 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu,
1850 new_policy->min, new_policy->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301852 memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301854 if (new_policy->min > policy->max || new_policy->max < policy->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001855 ret = -EINVAL;
1856 goto error_out;
1857 }
1858
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 /* verify the cpu speed can be set within this limit */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301860 ret = cpufreq_driver->verify(new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861 if (ret)
1862 goto error_out;
1863
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001865 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301866 CPUFREQ_ADJUST, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
1868 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001869 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301870 CPUFREQ_INCOMPATIBLE, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Viresh Kumarbb176f72013-06-19 14:19:33 +05301872 /*
1873 * verify the cpu speed can be set within this limit, which might be
1874 * different to the first one
1875 */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301876 ret = cpufreq_driver->verify(new_policy);
Alan Sterne041c682006-03-27 01:16:30 -08001877 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
1880 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001881 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301882 CPUFREQ_NOTIFY, new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301884 policy->min = new_policy->min;
1885 policy->max = new_policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001887 pr_debug("new min and max freqs are %u - %u kHz\n",
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301888 policy->min, policy->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001890 if (cpufreq_driver->setpolicy) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301891 policy->policy = new_policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001892 pr_debug("setting range\n");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301893 ret = cpufreq_driver->setpolicy(new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301895 if (new_policy->governor != policy->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 /* save old, working values */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301897 struct cpufreq_governor *old_gov = policy->governor;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001899 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
1901 /* end old governor */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301902 if (policy->governor) {
1903 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
1904 unlock_policy_rwsem_write(new_policy->cpu);
1905 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001906 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301907 lock_policy_rwsem_write(new_policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
1910 /* start new governor */
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301911 policy->governor = new_policy->governor;
1912 if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) {
1913 if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001914 failed = 0;
Viresh Kumar955ef482013-05-16 05:09:58 +00001915 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301916 unlock_policy_rwsem_write(new_policy->cpu);
1917 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001918 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301919 lock_policy_rwsem_write(new_policy->cpu);
Viresh Kumar955ef482013-05-16 05:09:58 +00001920 }
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001921 }
1922
1923 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001925 pr_debug("starting governor %s failed\n",
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301926 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 if (old_gov) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301928 policy->governor = old_gov;
1929 __cpufreq_governor(policy,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001930 CPUFREQ_GOV_POLICY_INIT);
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301931 __cpufreq_governor(policy,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301932 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933 }
1934 ret = -EINVAL;
1935 goto error_out;
1936 }
1937 /* might be a policy change, too, so fall through */
1938 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001939 pr_debug("governor: change or update limits\n");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301940 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 }
1942
Dave Jones7d5e3502006-02-02 17:03:42 -05001943error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 return ret;
1945}
1946
1947/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1949 * @cpu: CPU which shall be re-evaluated
1950 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001951 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 * at different times.
1953 */
1954int cpufreq_update_policy(unsigned int cpu)
1955{
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301956 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1957 struct cpufreq_policy new_policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001958 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301960 if (!policy) {
Julia Lawallf1829e42008-07-25 22:44:53 +02001961 ret = -ENODEV;
1962 goto no_policy;
1963 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964
Julia Lawallf1829e42008-07-25 22:44:53 +02001965 if (unlikely(lock_policy_rwsem_write(cpu))) {
1966 ret = -EINVAL;
1967 goto fail;
1968 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001970 pr_debug("updating policy for CPU %u\n", cpu);
Viresh Kumard5b73cd2013-08-06 22:53:06 +05301971 memcpy(&new_policy, policy, sizeof(*policy));
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301972 new_policy.min = policy->user_policy.min;
1973 new_policy.max = policy->user_policy.max;
1974 new_policy.policy = policy->user_policy.policy;
1975 new_policy.governor = policy->user_policy.governor;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976
Viresh Kumarbb176f72013-06-19 14:19:33 +05301977 /*
1978 * BIOS might change freq behind our back
1979 * -> ask driver for current freq and notify governors about a change
1980 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001981 if (cpufreq_driver->get) {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301982 new_policy.cur = cpufreq_driver->get(cpu);
1983 if (!policy->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001984 pr_debug("Driver did not initialize current freq");
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301985 policy->cur = new_policy.cur;
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001986 } else {
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301987 if (policy->cur != new_policy.cur && cpufreq_driver->target)
1988 cpufreq_out_of_sync(cpu, policy->cur,
1989 new_policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001990 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001991 }
1992
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301993 ret = __cpufreq_set_policy(policy, &new_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001995 unlock_policy_rwsem_write(cpu);
1996
Julia Lawallf1829e42008-07-25 22:44:53 +02001997fail:
Viresh Kumar3a3e9e02013-08-06 22:53:05 +05301998 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001999no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 return ret;
2001}
2002EXPORT_SYMBOL(cpufreq_update_policy);
2003
Paul Gortmaker27609842013-06-19 13:54:04 -04002004static int cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08002005 unsigned long action, void *hcpu)
2006{
2007 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002008 struct device *dev;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302009 bool frozen = false;
Ashok Rajc32b6b82005-10-30 14:59:54 -08002010
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002011 dev = get_cpu_device(cpu);
2012 if (dev) {
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302013
2014 if (action & CPU_TASKS_FROZEN)
2015 frozen = true;
2016
2017 switch (action & ~CPU_TASKS_FROZEN) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08002018 case CPU_ONLINE:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302019 __cpufreq_add_dev(dev, NULL, frozen);
Srivatsa S. Bhat23d328992013-07-30 04:23:56 +05302020 cpufreq_update_policy(cpu);
Ashok Rajc32b6b82005-10-30 14:59:54 -08002021 break;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302022
Ashok Rajc32b6b82005-10-30 14:59:54 -08002023 case CPU_DOWN_PREPARE:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302024 __cpufreq_remove_dev(dev, NULL, frozen);
Ashok Rajc32b6b82005-10-30 14:59:54 -08002025 break;
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302026
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002027 case CPU_DOWN_FAILED:
Srivatsa S. Bhat5302c3f2013-07-30 04:25:25 +05302028 __cpufreq_add_dev(dev, NULL, frozen);
Ashok Rajc32b6b82005-10-30 14:59:54 -08002029 break;
2030 }
2031 }
2032 return NOTIFY_OK;
2033}
2034
Neal Buckendahl9c36f742010-06-22 22:02:44 -05002035static struct notifier_block __refdata cpufreq_cpu_notifier = {
Viresh Kumarbb176f72013-06-19 14:19:33 +05302036 .notifier_call = cpufreq_cpu_callback,
Ashok Rajc32b6b82005-10-30 14:59:54 -08002037};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038
2039/*********************************************************************
2040 * REGISTER / UNREGISTER CPUFREQ DRIVER *
2041 *********************************************************************/
2042
2043/**
2044 * cpufreq_register_driver - register a CPU Frequency driver
2045 * @driver_data: A struct cpufreq_driver containing the values#
2046 * submitted by the CPU Frequency driver.
2047 *
Viresh Kumarbb176f72013-06-19 14:19:33 +05302048 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05002050 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 *
2052 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002053int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054{
2055 unsigned long flags;
2056 int ret;
2057
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002058 if (cpufreq_disabled())
2059 return -ENODEV;
2060
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 if (!driver_data || !driver_data->verify || !driver_data->init ||
2062 ((!driver_data->setpolicy) && (!driver_data->target)))
2063 return -EINVAL;
2064
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002065 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066
2067 if (driver_data->setpolicy)
2068 driver_data->flags |= CPUFREQ_CONST_LOOPS;
2069
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002070 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002071 if (cpufreq_driver) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002072 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 return -EBUSY;
2074 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002075 cpufreq_driver = driver_data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002076 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002078 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002079 if (ret)
2080 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002082 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 int i;
2084 ret = -ENODEV;
2085
2086 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07002087 for (i = 0; i < nr_cpu_ids; i++)
2088 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07002090 break;
2091 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092
2093 /* if all ->init() calls failed, unregister */
2094 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002095 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05302096 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002097 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 }
2099 }
2100
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002101 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002102 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002104 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002105err_if_unreg:
2106 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01002107err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002108 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002109 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002110 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05002111 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112}
2113EXPORT_SYMBOL_GPL(cpufreq_register_driver);
2114
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115/**
2116 * cpufreq_unregister_driver - unregister the current CPUFreq driver
2117 *
Viresh Kumarbb176f72013-06-19 14:19:33 +05302118 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 * the right to do so, i.e. if you have succeeded in initialising before!
2120 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
2121 * currently not initialised.
2122 */
Linus Torvalds221dee22007-02-26 14:55:48 -08002123int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124{
2125 unsigned long flags;
2126
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002127 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02002130 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002132 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07002133 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002135 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002136 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002137 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138
2139 return 0;
2140}
2141EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002142
2143static int __init cpufreq_core_init(void)
2144{
2145 int cpu;
2146
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002147 if (cpufreq_disabled())
2148 return -ENODEV;
2149
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002150 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09002151 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002152 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
2153 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002154
Viresh Kumar2361be22013-05-17 16:09:09 +05302155 cpufreq_global_kobject = kobject_create();
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002156 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002157 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002158
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002159 return 0;
2160}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002161core_initcall(cpufreq_core_init);