blob: c6ab21880c078fe42d6fed2adb889041af422b6d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/cpufreq/cpufreq.c
3 *
4 * Copyright (C) 2001 Russell King
5 * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6 *
Ashok Rajc32b6b82005-10-30 14:59:54 -08007 * Oct 2005 - Ashok Raj <ashok.raj@intel.com>
Dave Jones32ee8c32006-02-28 00:43:23 -05008 * Added handling for CPU hotplug
Dave Jones8ff69732006-03-05 03:37:23 -05009 * Feb 2006 - Jacob Shin <jacob.shin@amd.com>
10 * Fix handling for CPU hotplug -- affected CPUs
Ashok Rajc32b6b82005-10-30 14:59:54 -080011 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
Viresh Kumardb701152012-10-23 01:29:03 +020018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Viresh Kumara5d035d2013-05-16 14:17:11 +053020#include <asm/cputime.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <linux/kernel.h>
Viresh Kumara5d035d2013-05-16 14:17:11 +053022#include <linux/kernel_stat.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/notifier.h>
26#include <linux/cpufreq.h>
27#include <linux/delay.h>
28#include <linux/interrupt.h>
29#include <linux/spinlock.h>
Viresh Kumara5d035d2013-05-16 14:17:11 +053030#include <linux/tick.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/device.h>
32#include <linux/slab.h>
33#include <linux/cpu.h>
34#include <linux/completion.h>
akpm@osdl.org3fc54d32006-01-13 15:54:22 -080035#include <linux/mutex.h>
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +010036#include <linux/syscore_ops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
Thomas Renninger6f4f2722010-04-20 13:17:36 +020038#include <trace/events/power.h>
39
Linus Torvalds1da177e2005-04-16 15:20:36 -070040/**
Dave Jonescd878472006-08-11 17:59:28 -040041 * The "cpufreq driver" - the arch- or hardware-dependent low
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 * level driver of CPUFreq support, and its spinlock. This lock
43 * also protects the cpufreq_cpu_data array.
44 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +020045static struct cpufreq_driver *cpufreq_driver;
Mike Travis7a6aedf2008-03-25 15:06:53 -070046static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
Thomas Renninger084f3492007-07-09 11:35:28 -070047#ifdef CONFIG_HOTPLUG_CPU
48/* This one keeps track of the previously set governor of a removed CPU */
Dmitry Monakhove77b89f2009-10-05 00:38:55 +040049static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
Thomas Renninger084f3492007-07-09 11:35:28 -070050#endif
Nathan Zimmer0d1857a2013-02-22 16:24:34 +000051static DEFINE_RWLOCK(cpufreq_driver_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080053/*
54 * cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
55 * all cpufreq/hotplug/workqueue/etc related lock issues.
56 *
57 * The rules for this semaphore:
58 * - Any routine that wants to read from the policy structure will
59 * do a down_read on this semaphore.
60 * - Any routine that will write to the policy structure and/or may take away
61 * the policy altogether (eg. CPU hotplug), will hold this lock in write
62 * mode before doing so.
63 *
64 * Additional rules:
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080065 * - Governor routines that can be called in cpufreq hotplug path should not
66 * take this sem as top level hotplug notifier handler takes this.
Mathieu Desnoyers395913d2009-06-08 13:17:31 -040067 * - Lock should not be held across
68 * __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080069 */
Tejun Heof1625062009-10-29 22:34:13 +090070static DEFINE_PER_CPU(int, cpufreq_policy_cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080071static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
72
73#define lock_policy_rwsem(mode, cpu) \
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053074static int lock_policy_rwsem_##mode(int cpu) \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080075{ \
Tejun Heof1625062009-10-29 22:34:13 +090076 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080077 BUG_ON(policy_cpu == -1); \
78 down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080079 \
80 return 0; \
81}
82
83lock_policy_rwsem(read, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080084lock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080085
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053086#define unlock_policy_rwsem(mode, cpu) \
87static void unlock_policy_rwsem_##mode(int cpu) \
88{ \
89 int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \
90 BUG_ON(policy_cpu == -1); \
91 up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080092}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080093
Viresh Kumarfa1d8af2013-02-07 15:38:42 +053094unlock_policy_rwsem(read, cpu);
95unlock_policy_rwsem(write, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -080096
Linus Torvalds1da177e2005-04-16 15:20:36 -070097/* internal prototypes */
Dave Jones29464f22009-01-18 01:37:11 -050098static int __cpufreq_governor(struct cpufreq_policy *policy,
99 unsigned int event);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800100static unsigned int __cpufreq_get(unsigned int cpu);
David Howells65f27f32006-11-22 14:55:48 +0000101static void handle_update(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
103/**
Dave Jones32ee8c32006-02-28 00:43:23 -0500104 * Two notifier lists: the "policy" list is involved in the
105 * validation process for a new CPU frequency policy; the
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 * "transition" list for kernel code that needs to handle
107 * changes to devices when the CPU clock speed changes.
108 * The mutex locks both lists.
109 */
Alan Sterne041c682006-03-27 01:16:30 -0800110static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700111static struct srcu_notifier_head cpufreq_transition_notifier_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200113static bool init_cpufreq_transition_notifier_list_called;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700114static int __init init_cpufreq_transition_notifier_list(void)
115{
116 srcu_init_notifier_head(&cpufreq_transition_notifier_list);
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -0200117 init_cpufreq_transition_notifier_list_called = true;
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700118 return 0;
119}
Linus Torvaldsb3438f82006-11-20 11:47:18 -0800120pure_initcall(init_cpufreq_transition_notifier_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400122static int off __read_mostly;
Viresh Kumarda584452012-10-26 00:51:32 +0200123static int cpufreq_disabled(void)
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -0400124{
125 return off;
126}
127void disable_cpufreq(void)
128{
129 off = 1;
130}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131static LIST_HEAD(cpufreq_governor_list);
Dave Jones29464f22009-01-18 01:37:11 -0500132static DEFINE_MUTEX(cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000134bool have_governor_per_policy(void)
135{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200136 return cpufreq_driver->have_governor_per_policy;
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000137}
Viresh Kumar79973322013-05-13 16:31:04 +0530138EXPORT_SYMBOL_GPL(have_governor_per_policy);
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000139
Viresh Kumar69bbfa92013-05-13 16:26:48 +0530140struct kobject *get_governor_parent_kobj(struct cpufreq_policy *policy)
141{
142 if (have_governor_per_policy())
143 return &policy->kobj;
144 else
145 return cpufreq_global_kobject;
146}
147EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
148
Viresh Kumara5d035d2013-05-16 14:17:11 +0530149static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
150{
151 u64 idle_time;
152 u64 cur_wall_time;
153 u64 busy_time;
154
155 cur_wall_time = jiffies64_to_cputime64(get_jiffies_64());
156
157 busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER];
158 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM];
159 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ];
160 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ];
161 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL];
162 busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE];
163
164 idle_time = cur_wall_time - busy_time;
165 if (wall)
166 *wall = cputime_to_usecs(cur_wall_time);
167
168 return cputime_to_usecs(idle_time);
169}
170
171u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy)
172{
173 u64 idle_time = get_cpu_idle_time_us(cpu, io_busy ? wall : NULL);
174
175 if (idle_time == -1ULL)
176 return get_cpu_idle_time_jiffy(cpu, wall);
177 else if (!io_busy)
178 idle_time += get_cpu_iowait_time_us(cpu, wall);
179
180 return idle_time;
181}
182EXPORT_SYMBOL_GPL(get_cpu_idle_time);
183
Stephen Boyda9144432012-07-20 18:14:38 +0000184static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185{
186 struct cpufreq_policy *data;
187 unsigned long flags;
188
Mike Travis7a6aedf2008-03-25 15:06:53 -0700189 if (cpu >= nr_cpu_ids)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 goto err_out;
191
192 /* get the cpufreq driver */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000193 read_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200195 if (!cpufreq_driver)
196 goto err_out_unlock;
197
198 if (!try_module_get(cpufreq_driver->owner))
199 goto err_out_unlock;
200
201
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 /* get the CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -0700203 data = per_cpu(cpufreq_cpu_data, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205 if (!data)
206 goto err_out_put_module;
207
Stephen Boyda9144432012-07-20 18:14:38 +0000208 if (!sysfs && !kobject_get(&data->kobj))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 goto err_out_put_module;
210
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000211 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 return data;
213
Dave Jones7d5e3502006-02-02 17:03:42 -0500214err_out_put_module:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200215 module_put(cpufreq_driver->owner);
Nathan Zimmer58000432013-04-04 14:53:25 +0000216err_out_unlock:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200217 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones7d5e3502006-02-02 17:03:42 -0500218err_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 return NULL;
220}
Stephen Boyda9144432012-07-20 18:14:38 +0000221
222struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
223{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000224 if (cpufreq_disabled())
225 return NULL;
226
Stephen Boyda9144432012-07-20 18:14:38 +0000227 return __cpufreq_cpu_get(cpu, false);
228}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
230
Stephen Boyda9144432012-07-20 18:14:38 +0000231static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu)
232{
233 return __cpufreq_cpu_get(cpu, true);
234}
235
236static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
237{
238 if (!sysfs)
239 kobject_put(&data->kobj);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200240 module_put(cpufreq_driver->owner);
Stephen Boyda9144432012-07-20 18:14:38 +0000241}
Dave Jones7d5e3502006-02-02 17:03:42 -0500242
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243void cpufreq_cpu_put(struct cpufreq_policy *data)
244{
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000245 if (cpufreq_disabled())
246 return;
247
Stephen Boyda9144432012-07-20 18:14:38 +0000248 __cpufreq_cpu_put(data, false);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249}
250EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
251
Stephen Boyda9144432012-07-20 18:14:38 +0000252static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data)
253{
254 __cpufreq_cpu_put(data, true);
255}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
257/*********************************************************************
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
259 *********************************************************************/
260
261/**
262 * adjust_jiffies - adjust the system "loops_per_jiffy"
263 *
264 * This function alters the system "loops_per_jiffy" for the clock
265 * speed change. Note that loops_per_jiffy cannot be updated on SMP
Dave Jones32ee8c32006-02-28 00:43:23 -0500266 * systems as each CPU might be scaled differently. So, use the arch
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 * per-CPU loops_per_jiffy value wherever possible.
268 */
269#ifndef CONFIG_SMP
270static unsigned long l_p_j_ref;
271static unsigned int l_p_j_ref_freq;
272
Arjan van de Ven858119e2006-01-14 13:20:43 -0800273static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274{
275 if (ci->flags & CPUFREQ_CONST_LOOPS)
276 return;
277
278 if (!l_p_j_ref_freq) {
279 l_p_j_ref = loops_per_jiffy;
280 l_p_j_ref_freq = ci->old;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200281 pr_debug("saving %lu as reference value for loops_per_jiffy; "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530282 "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 }
Afzal Mohammedd08de0c12012-01-04 10:52:46 +0530284 if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) ||
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -0700285 (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530286 loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
287 ci->new);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200288 pr_debug("scaling loops_per_jiffy to %lu "
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530289 "for frequency %u kHz\n", loops_per_jiffy, ci->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 }
291}
292#else
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530293static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
294{
295 return;
296}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297#endif
298
299
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530300void __cpufreq_notify_transition(struct cpufreq_policy *policy,
301 struct cpufreq_freqs *freqs, unsigned int state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302{
303 BUG_ON(irqs_disabled());
304
Dirk Brandewied5aaffa2013-01-17 16:22:21 +0000305 if (cpufreq_disabled())
306 return;
307
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200308 freqs->flags = cpufreq_driver->flags;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200309 pr_debug("notification %u of frequency transition to %u kHz\n",
Dave Jonese4472cb2006-01-31 15:53:55 -0800310 state, freqs->new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 switch (state) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800313
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 case CPUFREQ_PRECHANGE:
Dave Jones32ee8c32006-02-28 00:43:23 -0500315 /* detect if the driver reported a value as "old frequency"
Dave Jonese4472cb2006-01-31 15:53:55 -0800316 * which is not equal to what the cpufreq core thinks is
317 * "old frequency".
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200319 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Dave Jonese4472cb2006-01-31 15:53:55 -0800320 if ((policy) && (policy->cpu == freqs->cpu) &&
321 (policy->cur) && (policy->cur != freqs->old)) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200322 pr_debug("Warning: CPU frequency is"
Dave Jonese4472cb2006-01-31 15:53:55 -0800323 " %u, cpufreq assumed %u kHz.\n",
324 freqs->old, policy->cur);
325 freqs->old = policy->cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 }
327 }
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700328 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800329 CPUFREQ_PRECHANGE, freqs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
331 break;
Dave Jonese4472cb2006-01-31 15:53:55 -0800332
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333 case CPUFREQ_POSTCHANGE:
334 adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200335 pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
Thomas Renninger6f4f2722010-04-20 13:17:36 +0200336 (unsigned long)freqs->cpu);
Thomas Renninger25e41932011-01-03 17:50:44 +0100337 trace_cpu_frequency(freqs->new, freqs->cpu);
Alan Sternb4dfdbb2006-10-04 02:17:06 -0700338 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
Alan Sterne041c682006-03-27 01:16:30 -0800339 CPUFREQ_POSTCHANGE, freqs);
Dave Jonese4472cb2006-01-31 15:53:55 -0800340 if (likely(policy) && likely(policy->cpu == freqs->cpu))
341 policy->cur = freqs->new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 break;
343 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344}
Viresh Kumarb43a7ff2013-03-24 11:56:43 +0530345/**
346 * cpufreq_notify_transition - call notifier chain and adjust_jiffies
347 * on frequency transition.
348 *
349 * This function calls the transition notifiers and the "adjust_jiffies"
350 * function. It is called twice on all CPU frequency changes that have
351 * external effects.
352 */
353void cpufreq_notify_transition(struct cpufreq_policy *policy,
354 struct cpufreq_freqs *freqs, unsigned int state)
355{
356 for_each_cpu(freqs->cpu, policy->cpus)
357 __cpufreq_notify_transition(policy, freqs, state);
358}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
360
361
362
363/*********************************************************************
364 * SYSFS INTERFACE *
365 *********************************************************************/
366
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700367static struct cpufreq_governor *__find_governor(const char *str_governor)
368{
369 struct cpufreq_governor *t;
370
371 list_for_each_entry(t, &cpufreq_governor_list, governor_list)
Dave Jones29464f22009-01-18 01:37:11 -0500372 if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN))
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700373 return t;
374
375 return NULL;
376}
377
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378/**
379 * cpufreq_parse_governor - parse a governor string
380 */
Dave Jones905d77c2008-03-05 14:28:32 -0500381static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 struct cpufreq_governor **governor)
383{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700384 int err = -EINVAL;
385
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200386 if (!cpufreq_driver)
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700387 goto out;
388
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200389 if (cpufreq_driver->setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
391 *policy = CPUFREQ_POLICY_PERFORMANCE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700392 err = 0;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530393 } else if (!strnicmp(str_governor, "powersave",
394 CPUFREQ_NAME_LEN)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 *policy = CPUFREQ_POLICY_POWERSAVE;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700396 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200398 } else if (cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 struct cpufreq_governor *t;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700400
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800401 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700402
403 t = __find_governor(str_governor);
404
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700405 if (t == NULL) {
Kees Cook1a8e1462011-05-04 08:38:56 -0700406 int ret;
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700407
Kees Cook1a8e1462011-05-04 08:38:56 -0700408 mutex_unlock(&cpufreq_governor_mutex);
409 ret = request_module("cpufreq_%s", str_governor);
410 mutex_lock(&cpufreq_governor_mutex);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700411
Kees Cook1a8e1462011-05-04 08:38:56 -0700412 if (ret == 0)
413 t = __find_governor(str_governor);
Jeremy Fitzhardingeea714972006-07-06 12:32:01 -0700414 }
415
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700416 if (t != NULL) {
417 *governor = t;
418 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 }
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700420
akpm@osdl.org3fc54d32006-01-13 15:54:22 -0800421 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 }
Dave Jones29464f22009-01-18 01:37:11 -0500423out:
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -0700424 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
427
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428/**
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530429 * cpufreq_per_cpu_attr_read() / show_##file_name() -
430 * print out cpufreq information
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 *
432 * Write out information from cpufreq_driver->policy[cpu]; object must be
433 * "unsigned int".
434 */
435
Dave Jones32ee8c32006-02-28 00:43:23 -0500436#define show_one(file_name, object) \
437static ssize_t show_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500438(struct cpufreq_policy *policy, char *buf) \
Dave Jones32ee8c32006-02-28 00:43:23 -0500439{ \
Dave Jones29464f22009-01-18 01:37:11 -0500440 return sprintf(buf, "%u\n", policy->object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441}
442
443show_one(cpuinfo_min_freq, cpuinfo.min_freq);
444show_one(cpuinfo_max_freq, cpuinfo.max_freq);
Thomas Renningered129782009-02-04 01:17:41 +0100445show_one(cpuinfo_transition_latency, cpuinfo.transition_latency);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446show_one(scaling_min_freq, min);
447show_one(scaling_max_freq, max);
448show_one(scaling_cur_freq, cur);
449
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530450static int __cpufreq_set_policy(struct cpufreq_policy *data,
451 struct cpufreq_policy *policy);
Thomas Renninger7970e082006-04-13 15:14:04 +0200452
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453/**
454 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
455 */
456#define store_one(file_name, object) \
457static ssize_t store_##file_name \
Dave Jones905d77c2008-03-05 14:28:32 -0500458(struct cpufreq_policy *policy, const char *buf, size_t count) \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459{ \
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000460 unsigned int ret; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 struct cpufreq_policy new_policy; \
462 \
463 ret = cpufreq_get_policy(&new_policy, policy->cpu); \
464 if (ret) \
465 return -EINVAL; \
466 \
Dave Jones29464f22009-01-18 01:37:11 -0500467 ret = sscanf(buf, "%u", &new_policy.object); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 if (ret != 1) \
469 return -EINVAL; \
470 \
Thomas Renninger7970e082006-04-13 15:14:04 +0200471 ret = __cpufreq_set_policy(policy, &new_policy); \
472 policy->user_policy.object = policy->object; \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 \
474 return ret ? ret : count; \
475}
476
Dave Jones29464f22009-01-18 01:37:11 -0500477store_one(scaling_min_freq, min);
478store_one(scaling_max_freq, max);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
480/**
481 * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
482 */
Dave Jones905d77c2008-03-05 14:28:32 -0500483static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
484 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485{
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800486 unsigned int cur_freq = __cpufreq_get(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 if (!cur_freq)
488 return sprintf(buf, "<unknown>");
489 return sprintf(buf, "%u\n", cur_freq);
490}
491
492
493/**
494 * show_scaling_governor - show the current policy for the specified CPU
495 */
Dave Jones905d77c2008-03-05 14:28:32 -0500496static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497{
Dave Jones29464f22009-01-18 01:37:11 -0500498 if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 return sprintf(buf, "powersave\n");
500 else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
501 return sprintf(buf, "performance\n");
502 else if (policy->governor)
viresh kumar4b972f02012-10-23 01:23:43 +0200503 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n",
Dave Jones29464f22009-01-18 01:37:11 -0500504 policy->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 return -EINVAL;
506}
507
508
509/**
510 * store_scaling_governor - store policy for the specified CPU
511 */
Dave Jones905d77c2008-03-05 14:28:32 -0500512static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
513 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514{
Jingoo Hanf55c9c22012-10-31 05:49:13 +0000515 unsigned int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 char str_governor[16];
517 struct cpufreq_policy new_policy;
518
519 ret = cpufreq_get_policy(&new_policy, policy->cpu);
520 if (ret)
521 return ret;
522
Dave Jones29464f22009-01-18 01:37:11 -0500523 ret = sscanf(buf, "%15s", str_governor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 if (ret != 1)
525 return -EINVAL;
526
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530527 if (cpufreq_parse_governor(str_governor, &new_policy.policy,
528 &new_policy.governor))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 return -EINVAL;
530
Thomas Renninger7970e082006-04-13 15:14:04 +0200531 /* Do not use cpufreq_set_policy here or the user_policy.max
532 will be wrongly overridden */
Thomas Renninger7970e082006-04-13 15:14:04 +0200533 ret = __cpufreq_set_policy(policy, &new_policy);
534
535 policy->user_policy.policy = policy->policy;
536 policy->user_policy.governor = policy->governor;
Thomas Renninger7970e082006-04-13 15:14:04 +0200537
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530538 if (ret)
539 return ret;
540 else
541 return count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542}
543
544/**
545 * show_scaling_driver - show the cpufreq driver currently loaded
546 */
Dave Jones905d77c2008-03-05 14:28:32 -0500547static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200549 return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550}
551
552/**
553 * show_scaling_available_governors - show the available CPUfreq governors
554 */
Dave Jones905d77c2008-03-05 14:28:32 -0500555static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
556 char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557{
558 ssize_t i = 0;
559 struct cpufreq_governor *t;
560
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200561 if (!cpufreq_driver->target) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 i += sprintf(buf, "performance powersave");
563 goto out;
564 }
565
566 list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
Dave Jones29464f22009-01-18 01:37:11 -0500567 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char))
568 - (CPUFREQ_NAME_LEN + 2)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 goto out;
viresh kumar4b972f02012-10-23 01:23:43 +0200570 i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 }
Dave Jones7d5e3502006-02-02 17:03:42 -0500572out:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 i += sprintf(&buf[i], "\n");
574 return i;
575}
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700576
Rusty Russell835481d2009-01-04 05:18:06 -0800577static ssize_t show_cpus(const struct cpumask *mask, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578{
579 ssize_t i = 0;
580 unsigned int cpu;
581
Rusty Russell835481d2009-01-04 05:18:06 -0800582 for_each_cpu(cpu, mask) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 if (i)
584 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
585 i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
586 if (i >= (PAGE_SIZE - 5))
Dave Jones29464f22009-01-18 01:37:11 -0500587 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 }
589 i += sprintf(&buf[i], "\n");
590 return i;
591}
592
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700593/**
594 * show_related_cpus - show the CPUs affected by each transition even if
595 * hw coordination is in use
596 */
597static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf)
598{
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700599 return show_cpus(policy->related_cpus, buf);
600}
601
602/**
603 * show_affected_cpus - show the CPUs affected by each transition
604 */
605static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf)
606{
607 return show_cpus(policy->cpus, buf);
608}
609
Venki Pallipadi9e769882007-10-26 10:18:21 -0700610static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy,
Dave Jones905d77c2008-03-05 14:28:32 -0500611 const char *buf, size_t count)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700612{
613 unsigned int freq = 0;
614 unsigned int ret;
615
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700616 if (!policy->governor || !policy->governor->store_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700617 return -EINVAL;
618
619 ret = sscanf(buf, "%u", &freq);
620 if (ret != 1)
621 return -EINVAL;
622
623 policy->governor->store_setspeed(policy, freq);
624
625 return count;
626}
627
628static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
629{
CHIKAMA masaki879000f2008-06-05 22:46:33 -0700630 if (!policy->governor || !policy->governor->show_setspeed)
Venki Pallipadi9e769882007-10-26 10:18:21 -0700631 return sprintf(buf, "<unsupported>\n");
632
633 return policy->governor->show_setspeed(policy, buf);
634}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635
Thomas Renningere2f74f32009-11-19 12:31:01 +0100636/**
viresh kumar8bf1ac722012-10-23 01:23:33 +0200637 * show_bios_limit - show the current cpufreq HW/BIOS limitation
Thomas Renningere2f74f32009-11-19 12:31:01 +0100638 */
639static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
640{
641 unsigned int limit;
642 int ret;
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200643 if (cpufreq_driver->bios_limit) {
644 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
Thomas Renningere2f74f32009-11-19 12:31:01 +0100645 if (!ret)
646 return sprintf(buf, "%u\n", limit);
647 }
648 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
649}
650
Borislav Petkov6dad2a22010-03-31 21:56:46 +0200651cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400);
652cpufreq_freq_attr_ro(cpuinfo_min_freq);
653cpufreq_freq_attr_ro(cpuinfo_max_freq);
654cpufreq_freq_attr_ro(cpuinfo_transition_latency);
655cpufreq_freq_attr_ro(scaling_available_governors);
656cpufreq_freq_attr_ro(scaling_driver);
657cpufreq_freq_attr_ro(scaling_cur_freq);
658cpufreq_freq_attr_ro(bios_limit);
659cpufreq_freq_attr_ro(related_cpus);
660cpufreq_freq_attr_ro(affected_cpus);
661cpufreq_freq_attr_rw(scaling_min_freq);
662cpufreq_freq_attr_rw(scaling_max_freq);
663cpufreq_freq_attr_rw(scaling_governor);
664cpufreq_freq_attr_rw(scaling_setspeed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665
Dave Jones905d77c2008-03-05 14:28:32 -0500666static struct attribute *default_attrs[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 &cpuinfo_min_freq.attr,
668 &cpuinfo_max_freq.attr,
Thomas Renningered129782009-02-04 01:17:41 +0100669 &cpuinfo_transition_latency.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 &scaling_min_freq.attr,
671 &scaling_max_freq.attr,
672 &affected_cpus.attr,
Darrick J. Wonge8628dd2008-04-18 13:31:12 -0700673 &related_cpus.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 &scaling_governor.attr,
675 &scaling_driver.attr,
676 &scaling_available_governors.attr,
Venki Pallipadi9e769882007-10-26 10:18:21 -0700677 &scaling_setspeed.attr,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 NULL
679};
680
Thomas Renninger8aa84ad2009-07-24 15:25:05 +0200681struct kobject *cpufreq_global_kobject;
682EXPORT_SYMBOL(cpufreq_global_kobject);
683
Dave Jones29464f22009-01-18 01:37:11 -0500684#define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
685#define to_attr(a) container_of(a, struct freq_attr, attr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686
Dave Jones29464f22009-01-18 01:37:11 -0500687static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688{
Dave Jones905d77c2008-03-05 14:28:32 -0500689 struct cpufreq_policy *policy = to_policy(kobj);
690 struct freq_attr *fattr = to_attr(attr);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500691 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000692 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 if (!policy)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500694 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800695
696 if (lock_policy_rwsem_read(policy->cpu) < 0)
Dave Jones0db4a8a2008-03-05 14:20:57 -0500697 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800698
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530699 if (fattr->show)
700 ret = fattr->show(policy, buf);
701 else
702 ret = -EIO;
703
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800704 unlock_policy_rwsem_read(policy->cpu);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500705fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000706 cpufreq_cpu_put_sysfs(policy);
Dave Jones0db4a8a2008-03-05 14:20:57 -0500707no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 return ret;
709}
710
Dave Jones905d77c2008-03-05 14:28:32 -0500711static ssize_t store(struct kobject *kobj, struct attribute *attr,
712 const char *buf, size_t count)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713{
Dave Jones905d77c2008-03-05 14:28:32 -0500714 struct cpufreq_policy *policy = to_policy(kobj);
715 struct freq_attr *fattr = to_attr(attr);
Dave Jonesa07530b2008-03-05 14:22:25 -0500716 ssize_t ret = -EINVAL;
Stephen Boyda9144432012-07-20 18:14:38 +0000717 policy = cpufreq_cpu_get_sysfs(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 if (!policy)
Dave Jonesa07530b2008-03-05 14:22:25 -0500719 goto no_policy;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800720
721 if (lock_policy_rwsem_write(policy->cpu) < 0)
Dave Jonesa07530b2008-03-05 14:22:25 -0500722 goto fail;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800723
Gautham R Shenoye08f5f52006-10-26 16:20:58 +0530724 if (fattr->store)
725 ret = fattr->store(policy, buf, count);
726 else
727 ret = -EIO;
728
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800729 unlock_policy_rwsem_write(policy->cpu);
Dave Jonesa07530b2008-03-05 14:22:25 -0500730fail:
Stephen Boyda9144432012-07-20 18:14:38 +0000731 cpufreq_cpu_put_sysfs(policy);
Dave Jonesa07530b2008-03-05 14:22:25 -0500732no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 return ret;
734}
735
Dave Jones905d77c2008-03-05 14:28:32 -0500736static void cpufreq_sysfs_release(struct kobject *kobj)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737{
Dave Jones905d77c2008-03-05 14:28:32 -0500738 struct cpufreq_policy *policy = to_policy(kobj);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200739 pr_debug("last reference is dropped\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 complete(&policy->kobj_unregister);
741}
742
Emese Revfy52cf25d2010-01-19 02:58:23 +0100743static const struct sysfs_ops sysfs_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 .show = show,
745 .store = store,
746};
747
748static struct kobj_type ktype_cpufreq = {
749 .sysfs_ops = &sysfs_ops,
750 .default_attrs = default_attrs,
751 .release = cpufreq_sysfs_release,
752};
753
Dave Jones19d6f7e2009-07-08 17:35:39 -0400754/* symlink affected CPUs */
Alex Chiangcf3289d02009-11-17 20:27:08 -0700755static int cpufreq_add_dev_symlink(unsigned int cpu,
756 struct cpufreq_policy *policy)
Dave Jones19d6f7e2009-07-08 17:35:39 -0400757{
758 unsigned int j;
759 int ret = 0;
760
761 for_each_cpu(j, policy->cpus) {
762 struct cpufreq_policy *managed_policy;
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800763 struct device *cpu_dev;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400764
765 if (j == cpu)
766 continue;
Dave Jones19d6f7e2009-07-08 17:35:39 -0400767
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200768 pr_debug("CPU %u already managed, adding link\n", j);
Dave Jones19d6f7e2009-07-08 17:35:39 -0400769 managed_policy = cpufreq_cpu_get(cpu);
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800770 cpu_dev = get_cpu_device(j);
771 ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
Dave Jones19d6f7e2009-07-08 17:35:39 -0400772 "cpufreq");
773 if (ret) {
774 cpufreq_cpu_put(managed_policy);
775 return ret;
776 }
777 }
778 return ret;
779}
780
Alex Chiangcf3289d02009-11-17 20:27:08 -0700781static int cpufreq_add_dev_interface(unsigned int cpu,
782 struct cpufreq_policy *policy,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800783 struct device *dev)
Dave Jones909a6942009-07-08 18:05:42 -0400784{
Dave Jonesecf7e462009-07-08 18:48:47 -0400785 struct cpufreq_policy new_policy;
Dave Jones909a6942009-07-08 18:05:42 -0400786 struct freq_attr **drv_attr;
787 unsigned long flags;
788 int ret = 0;
789 unsigned int j;
790
791 /* prepare interface data */
792 ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800793 &dev->kobj, "cpufreq");
Dave Jones909a6942009-07-08 18:05:42 -0400794 if (ret)
795 return ret;
796
797 /* set up files for this cpu device */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200798 drv_attr = cpufreq_driver->attr;
Dave Jones909a6942009-07-08 18:05:42 -0400799 while ((drv_attr) && (*drv_attr)) {
800 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
801 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200802 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400803 drv_attr++;
804 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200805 if (cpufreq_driver->get) {
Dave Jones909a6942009-07-08 18:05:42 -0400806 ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
807 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200808 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400809 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200810 if (cpufreq_driver->target) {
Dave Jones909a6942009-07-08 18:05:42 -0400811 ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
812 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200813 goto err_out_kobj_put;
Dave Jones909a6942009-07-08 18:05:42 -0400814 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200815 if (cpufreq_driver->bios_limit) {
Thomas Renningere2f74f32009-11-19 12:31:01 +0100816 ret = sysfs_create_file(&policy->kobj, &bios_limit.attr);
817 if (ret)
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200818 goto err_out_kobj_put;
Thomas Renningere2f74f32009-11-19 12:31:01 +0100819 }
Dave Jones909a6942009-07-08 18:05:42 -0400820
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000821 write_lock_irqsave(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400822 for_each_cpu(j, policy->cpus) {
Dave Jones909a6942009-07-08 18:05:42 -0400823 per_cpu(cpufreq_cpu_data, j) = policy;
Tejun Heof1625062009-10-29 22:34:13 +0900824 per_cpu(cpufreq_policy_cpu, j) = policy->cpu;
Dave Jones909a6942009-07-08 18:05:42 -0400825 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000826 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones909a6942009-07-08 18:05:42 -0400827
828 ret = cpufreq_add_dev_symlink(cpu, policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400829 if (ret)
830 goto err_out_kobj_put;
831
832 memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
833 /* assure that the starting sequence is run in __cpufreq_set_policy */
834 policy->governor = NULL;
835
836 /* set default policy */
837 ret = __cpufreq_set_policy(policy, &new_policy);
838 policy->user_policy.policy = policy->policy;
839 policy->user_policy.governor = policy->governor;
840
841 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200842 pr_debug("setting policy failed\n");
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200843 if (cpufreq_driver->exit)
844 cpufreq_driver->exit(policy);
Dave Jonesecf7e462009-07-08 18:48:47 -0400845 }
Dave Jones909a6942009-07-08 18:05:42 -0400846 return ret;
847
848err_out_kobj_put:
849 kobject_put(&policy->kobj);
850 wait_for_completion(&policy->kobj_unregister);
851 return ret;
852}
853
Viresh Kumarfcf80582013-01-29 14:39:08 +0000854#ifdef CONFIG_HOTPLUG_CPU
855static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
856 struct device *dev)
857{
858 struct cpufreq_policy *policy;
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200859 int ret = 0, has_target = !!cpufreq_driver->target;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000860 unsigned long flags;
861
862 policy = cpufreq_cpu_get(sibling);
863 WARN_ON(!policy);
864
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200865 if (has_target)
866 __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000867
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530868 lock_policy_rwsem_write(sibling);
869
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000870 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530871
Viresh Kumarfcf80582013-01-29 14:39:08 +0000872 cpumask_set_cpu(cpu, policy->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530873 per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu;
Viresh Kumarfcf80582013-01-29 14:39:08 +0000874 per_cpu(cpufreq_cpu_data, cpu) = policy;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000875 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000876
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530877 unlock_policy_rwsem_write(sibling);
878
Viresh Kumar820c6ca2013-04-22 00:48:03 +0200879 if (has_target) {
880 __cpufreq_governor(policy, CPUFREQ_GOV_START);
881 __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS);
882 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000883
Viresh Kumarfcf80582013-01-29 14:39:08 +0000884 ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
885 if (ret) {
886 cpufreq_cpu_put(policy);
887 return ret;
888 }
889
890 return 0;
891}
892#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
894/**
895 * cpufreq_add_dev - add a CPU device
896 *
Dave Jones32ee8c32006-02-28 00:43:23 -0500897 * Adds the cpufreq interface for a CPU device.
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400898 *
899 * The Oracle says: try running cpufreq registration/unregistration concurrently
900 * with with cpu hotplugging and all hell will break loose. Tried to clean this
901 * mess up, but more thorough testing is needed. - Mathieu
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -0800903static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904{
Viresh Kumarfcf80582013-01-29 14:39:08 +0000905 unsigned int j, cpu = dev->id;
Viresh Kumar65922462013-02-07 10:56:03 +0530906 int ret = -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 unsigned long flags;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500909#ifdef CONFIG_HOTPLUG_CPU
Viresh Kumarfcf80582013-01-29 14:39:08 +0000910 struct cpufreq_governor *gov;
Prarit Bhargava90e41ba2009-11-12 09:18:46 -0500911 int sibling;
912#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913
Ashok Rajc32b6b82005-10-30 14:59:54 -0800914 if (cpu_is_offline(cpu))
915 return 0;
916
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200917 pr_debug("adding CPU %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
919#ifdef CONFIG_SMP
920 /* check whether a different CPU already registered this
921 * CPU because it is in the same boat. */
922 policy = cpufreq_cpu_get(cpu);
923 if (unlikely(policy)) {
Dave Jones8ff69732006-03-05 03:37:23 -0500924 cpufreq_cpu_put(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 return 0;
926 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000927
928#ifdef CONFIG_HOTPLUG_CPU
929 /* Check if this cpu was hot-unplugged earlier and has siblings */
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000930 read_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000931 for_each_online_cpu(sibling) {
932 struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530933 if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000934 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000935 return cpufreq_add_policy_cpu(cpu, sibling, dev);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530936 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000937 }
Nathan Zimmer0d1857a2013-02-22 16:24:34 +0000938 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumarfcf80582013-01-29 14:39:08 +0000939#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940#endif
941
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200942 if (!try_module_get(cpufreq_driver->owner)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 ret = -EINVAL;
944 goto module_out;
945 }
946
Dave Jonese98df502005-10-20 15:17:43 -0700947 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
Dave Jones059019a2009-07-08 16:30:03 -0400948 if (!policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 goto nomem_out;
Dave Jones059019a2009-07-08 16:30:03 -0400950
951 if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400952 goto err_free_policy;
Dave Jones059019a2009-07-08 16:30:03 -0400953
954 if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -0400955 goto err_free_cpumask;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
957 policy->cpu = cpu;
Viresh Kumar65922462013-02-07 10:56:03 +0530958 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
Rusty Russell835481d2009-01-04 05:18:06 -0800959 cpumask_copy(policy->cpus, cpumask_of(cpu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800961 /* Initially set CPU itself as the policy_cpu */
Tejun Heof1625062009-10-29 22:34:13 +0900962 per_cpu(cpufreq_policy_cpu, cpu) = cpu;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -0800963
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 init_completion(&policy->kobj_unregister);
David Howells65f27f32006-11-22 14:55:48 +0000965 INIT_WORK(&policy->update, handle_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966
967 /* call driver. From then on the cpufreq must be able
968 * to accept all calls to ->verify and ->setpolicy for this CPU
969 */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +0200970 ret = cpufreq_driver->init(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +0200972 pr_debug("initialization failed\n");
Viresh Kumar2eaa3e22013-02-07 10:55:00 +0530973 goto err_set_policy_cpu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 }
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000975
Viresh Kumarfcf80582013-01-29 14:39:08 +0000976 /* related cpus should atleast have policy->cpus */
977 cpumask_or(policy->related_cpus, policy->related_cpus, policy->cpus);
978
Viresh Kumar643ae6e2013-01-12 05:14:38 +0000979 /*
980 * affected cpus must always be the one, which are online. We aren't
981 * managing offline cpus here.
982 */
983 cpumask_and(policy->cpus, policy->cpus, cpu_online_mask);
984
Mike Chan187d9f42008-12-04 12:19:17 -0800985 policy->user_policy.min = policy->min;
986 policy->user_policy.max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987
Thomas Renningera1531ac2008-07-29 22:32:58 -0700988 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
989 CPUFREQ_START, policy);
990
Viresh Kumarfcf80582013-01-29 14:39:08 +0000991#ifdef CONFIG_HOTPLUG_CPU
992 gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
993 if (gov) {
994 policy->governor = gov;
995 pr_debug("Restoring governor %s for cpu %d\n",
996 policy->governor->name, cpu);
Thomas Renninger4bfa0422009-07-24 15:25:03 +0200997 }
Viresh Kumarfcf80582013-01-29 14:39:08 +0000998#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001000 ret = cpufreq_add_dev_interface(cpu, policy, dev);
Dave Jones19d6f7e2009-07-08 17:35:39 -04001001 if (ret)
1002 goto err_out_unregister;
Dave Jones8ff69732006-03-05 03:37:23 -05001003
Greg Kroah-Hartman038c5b32007-12-17 15:54:39 -04001004 kobject_uevent(&policy->kobj, KOBJ_ADD);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001005 module_put(cpufreq_driver->owner);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001006 pr_debug("initialization complete\n");
Dave Jones87c32272006-03-29 01:48:37 -05001007
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 return 0;
1009
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010err_out_unregister:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001011 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rusty Russell835481d2009-01-04 05:18:06 -08001012 for_each_cpu(j, policy->cpus)
Mike Travis7a6aedf2008-03-25 15:06:53 -07001013 per_cpu(cpufreq_cpu_data, j) = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001014 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
Greg Kroah-Hartmanc10997f2007-12-20 08:13:05 -08001016 kobject_put(&policy->kobj);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 wait_for_completion(&policy->kobj_unregister);
1018
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301019err_set_policy_cpu:
1020 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Xiaotian Fengcad70a62010-07-20 20:11:02 +08001021 free_cpumask_var(policy->related_cpus);
Mathieu Desnoyers3f4a7822009-07-03 11:25:16 -04001022err_free_cpumask:
1023 free_cpumask_var(policy->cpus);
1024err_free_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 kfree(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026nomem_out:
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001027 module_put(cpufreq_driver->owner);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001028module_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 return ret;
1030}
1031
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001032static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
1033{
1034 int j;
1035
1036 policy->last_cpu = policy->cpu;
1037 policy->cpu = cpu;
1038
Viresh Kumar3361b7b2013-02-04 11:38:51 +00001039 for_each_cpu(j, policy->cpus)
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001040 per_cpu(cpufreq_policy_cpu, j) = cpu;
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001041
1042#ifdef CONFIG_CPU_FREQ_TABLE
1043 cpufreq_frequency_table_update_policy_cpu(policy);
1044#endif
1045 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1046 CPUFREQ_UPDATE_POLICY_CPU, policy);
1047}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049/**
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001050 * __cpufreq_remove_dev - remove a CPU device
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051 *
1052 * Removes the cpufreq interface for a CPU device.
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001053 * Caller should already have policy_rwsem in write mode for this CPU.
1054 * This routine frees the rwsem before returning.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 */
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001056static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057{
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001058 unsigned int cpu = dev->id, ret, cpus;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 unsigned long flags;
1060 struct cpufreq_policy *data;
Amerigo Wang499bca92010-03-04 03:23:46 -05001061 struct kobject *kobj;
1062 struct completion *cmp;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001063 struct device *cpu_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001065 pr_debug("%s: unregistering CPU %u\n", __func__, cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001067 write_lock_irqsave(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 data = per_cpu(cpufreq_cpu_data, cpu);
Mike Travis7a6aedf2008-03-25 15:06:53 -07001070 per_cpu(cpufreq_cpu_data, cpu) = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001072 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 if (!data) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001075 pr_debug("%s: No cpu_data found\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001079 if (cpufreq_driver->target)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001081
Jacob Shin27ecddc2011-04-27 13:32:11 -05001082#ifdef CONFIG_HOTPLUG_CPU
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001083 if (!cpufreq_driver->setpolicy)
Dirk Brandewiefa69e332013-02-06 09:02:11 -08001084 strncpy(per_cpu(cpufreq_cpu_governor, cpu),
1085 data->governor->name, CPUFREQ_NAME_LEN);
Jacob Shin27ecddc2011-04-27 13:32:11 -05001086#endif
1087
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301088 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001089 cpus = cpumask_weight(data->cpus);
Viresh Kumare4969eb2013-04-11 08:04:53 +00001090
1091 if (cpus > 1)
1092 cpumask_clear_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301093 unlock_policy_rwsem_write(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Viresh Kumar73bf0fc2013-02-05 22:21:14 +01001095 if (cpu != data->cpu) {
1096 sysfs_remove_link(&dev->kobj, "cpufreq");
1097 } else if (cpus > 1) {
Venki Pallipadiec282972007-03-26 12:03:19 -07001098 /* first sibling now owns the new sysfs dir */
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001099 cpu_dev = get_cpu_device(cpumask_first(data->cpus));
1100 sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
1101 ret = kobject_move(&data->kobj, &cpu_dev->kobj);
1102 if (ret) {
1103 pr_err("%s: Failed to move kobj: %d", __func__, ret);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301104
1105 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001106 cpumask_set_cpu(cpu, data->cpus);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301107
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001108 write_lock_irqsave(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301109 per_cpu(cpufreq_cpu_data, cpu) = data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001110 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301111
1112 unlock_policy_rwsem_write(cpu);
1113
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001114 ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj,
1115 "cpufreq");
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001116 return -EINVAL;
1117 }
Venki Pallipadiec282972007-03-26 12:03:19 -07001118
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301119 WARN_ON(lock_policy_rwsem_write(cpu));
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001120 update_policy_cpu(data, cpu_dev->id);
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301121 unlock_policy_rwsem_write(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001122 pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
1123 __func__, cpu_dev->id, cpu);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001124 }
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001125
Viresh Kumard96038e2013-04-30 14:32:18 +00001126 if ((cpus == 1) && (cpufreq_driver->target))
1127 __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
1128
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001129 pr_debug("%s: removing link, cpu: %d\n", __func__, cpu);
1130 cpufreq_cpu_put(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001131
1132 /* If cpu is last user of policy, free policy */
1133 if (cpus == 1) {
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301134 lock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001135 kobj = &data->kobj;
1136 cmp = &data->kobj_unregister;
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301137 unlock_policy_rwsem_read(cpu);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001138 kobject_put(kobj);
1139
1140 /* we need to make sure that the underlying kobj is actually
1141 * not referenced anymore by anybody before we proceed with
1142 * unloading.
1143 */
1144 pr_debug("waiting for dropping of refcount\n");
1145 wait_for_completion(cmp);
1146 pr_debug("wait complete\n");
1147
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001148 if (cpufreq_driver->exit)
1149 cpufreq_driver->exit(data);
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001150
1151 free_cpumask_var(data->related_cpus);
1152 free_cpumask_var(data->cpus);
1153 kfree(data);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001154 } else if (cpufreq_driver->target) {
Viresh Kumarb8eed8a2013-01-14 13:23:03 +00001155 __cpufreq_governor(data, CPUFREQ_GOV_START);
1156 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1157 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158
Viresh Kumar2eaa3e22013-02-07 10:55:00 +05301159 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 return 0;
1161}
1162
1163
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001164static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001165{
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001166 unsigned int cpu = dev->id;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001167 int retval;
1168
1169 if (cpu_is_offline(cpu))
1170 return 0;
1171
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001172 retval = __cpufreq_remove_dev(dev, sif);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001173 return retval;
1174}
1175
1176
David Howells65f27f32006-11-22 14:55:48 +00001177static void handle_update(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178{
David Howells65f27f32006-11-22 14:55:48 +00001179 struct cpufreq_policy *policy =
1180 container_of(work, struct cpufreq_policy, update);
1181 unsigned int cpu = policy->cpu;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001182 pr_debug("handle_update for cpu %u called\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 cpufreq_update_policy(cpu);
1184}
1185
1186/**
1187 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
1188 * @cpu: cpu number
1189 * @old_freq: CPU frequency the kernel thinks the CPU runs at
1190 * @new_freq: CPU frequency the CPU actually runs at
1191 *
Dave Jones29464f22009-01-18 01:37:11 -05001192 * We adjust to current frequency first, and need to clean up later.
1193 * So either call to cpufreq_update_policy() or schedule handle_update()).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301195static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1196 unsigned int new_freq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197{
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301198 struct cpufreq_policy *policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 struct cpufreq_freqs freqs;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301200 unsigned long flags;
1201
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001203 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
1205
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 freqs.old = old_freq;
1207 freqs.new = new_freq;
Viresh Kumarb43a7ff2013-03-24 11:56:43 +05301208
1209 read_lock_irqsave(&cpufreq_driver_lock, flags);
1210 policy = per_cpu(cpufreq_cpu_data, cpu);
1211 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1212
1213 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
1214 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215}
1216
1217
Dave Jones32ee8c32006-02-28 00:43:23 -05001218/**
Dhaval Giani4ab70df2006-12-13 14:49:15 +05301219 * cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001220 * @cpu: CPU number
1221 *
1222 * This is the last known freq, without actually getting it from the driver.
1223 * Return value will be same as what is shown in scaling_cur_freq in sysfs.
1224 */
1225unsigned int cpufreq_quick_get(unsigned int cpu)
1226{
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001227 struct cpufreq_policy *policy;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301228 unsigned int ret_freq = 0;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001229
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001230 if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get)
1231 return cpufreq_driver->get(cpu);
Dirk Brandewie9e21ba82013-02-06 09:02:08 -08001232
1233 policy = cpufreq_cpu_get(cpu);
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001234 if (policy) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301235 ret_freq = policy->cur;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001236 cpufreq_cpu_put(policy);
1237 }
1238
Dave Jones4d34a672008-02-07 16:33:49 -05001239 return ret_freq;
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001240}
1241EXPORT_SYMBOL(cpufreq_quick_get);
1242
Jesse Barnes3d737102011-06-28 10:59:12 -07001243/**
1244 * cpufreq_quick_get_max - get the max reported CPU frequency for this CPU
1245 * @cpu: CPU number
1246 *
1247 * Just return the max possible frequency for a given CPU.
1248 */
1249unsigned int cpufreq_quick_get_max(unsigned int cpu)
1250{
1251 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1252 unsigned int ret_freq = 0;
1253
1254 if (policy) {
1255 ret_freq = policy->max;
1256 cpufreq_cpu_put(policy);
1257 }
1258
1259 return ret_freq;
1260}
1261EXPORT_SYMBOL(cpufreq_quick_get_max);
1262
Venkatesh Pallipadi95235ca2005-12-02 10:43:20 -08001263
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001264static unsigned int __cpufreq_get(unsigned int cpu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265{
Mike Travis7a6aedf2008-03-25 15:06:53 -07001266 struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301267 unsigned int ret_freq = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001269 if (!cpufreq_driver->get)
Dave Jones4d34a672008-02-07 16:33:49 -05001270 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001272 ret_freq = cpufreq_driver->get(cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301274 if (ret_freq && policy->cur &&
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001275 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301276 /* verify no discrepancy between actual and
1277 saved value exists */
1278 if (unlikely(ret_freq != policy->cur)) {
1279 cpufreq_out_of_sync(cpu, policy->cur, ret_freq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 schedule_work(&policy->update);
1281 }
1282 }
1283
Dave Jones4d34a672008-02-07 16:33:49 -05001284 return ret_freq;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001285}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001287/**
1288 * cpufreq_get - get the current CPU frequency (in kHz)
1289 * @cpu: CPU number
1290 *
1291 * Get the CPU current (static) CPU frequency
1292 */
1293unsigned int cpufreq_get(unsigned int cpu)
1294{
1295 unsigned int ret_freq = 0;
1296 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1297
1298 if (!policy)
1299 goto out;
1300
1301 if (unlikely(lock_policy_rwsem_read(cpu)))
1302 goto out_policy;
1303
1304 ret_freq = __cpufreq_get(cpu);
1305
1306 unlock_policy_rwsem_read(cpu);
1307
1308out_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309 cpufreq_cpu_put(policy);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001310out:
Dave Jones4d34a672008-02-07 16:33:49 -05001311 return ret_freq;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312}
1313EXPORT_SYMBOL(cpufreq_get);
1314
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001315static struct subsys_interface cpufreq_interface = {
1316 .name = "cpufreq",
1317 .subsys = &cpu_subsys,
1318 .add_dev = cpufreq_add_dev,
1319 .remove_dev = cpufreq_remove_dev,
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001320};
1321
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322
1323/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001324 * cpufreq_bp_suspend - Prepare the boot CPU for system suspend.
1325 *
1326 * This function is only executed for the boot processor. The other CPUs
1327 * have been put offline by means of CPU hotplug.
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001328 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001329static int cpufreq_bp_suspend(void)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001330{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301331 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001332
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001333 int cpu = smp_processor_id();
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001334 struct cpufreq_policy *cpu_policy;
1335
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001336 pr_debug("suspending cpu %u\n", cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001337
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001338 /* If there's no policy for the boot CPU, we have nothing to do. */
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001339 cpu_policy = cpufreq_cpu_get(cpu);
1340 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001341 return 0;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001342
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001343 if (cpufreq_driver->suspend) {
1344 ret = cpufreq_driver->suspend(cpu_policy);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001345 if (ret)
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001346 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1347 "step on CPU %u\n", cpu_policy->cpu);
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001348 }
1349
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001350 cpufreq_cpu_put(cpu_policy);
Dave Jonesc9060492008-02-07 16:32:18 -05001351 return ret;
Benjamin Herrenschmidt42d4dc32005-04-29 07:40:12 -07001352}
1353
1354/**
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001355 * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 *
1357 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001358 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1359 * restored. It will verify that the current freq is in sync with
1360 * what we believe it to be. This is a bit later than when it
1361 * should be, but nonethteless it's better than calling
1362 * cpufreq_driver->get() here which might re-enable interrupts...
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001363 *
1364 * This function is only executed for the boot CPU. The other CPUs have not
1365 * been turned on yet.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 */
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001367static void cpufreq_bp_resume(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368{
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301369 int ret = 0;
Dave Jones4bc5d342009-08-04 14:03:25 -04001370
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001371 int cpu = smp_processor_id();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 struct cpufreq_policy *cpu_policy;
1373
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001374 pr_debug("resuming cpu %u\n", cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001376 /* If there's no policy for the boot CPU, we have nothing to do. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 cpu_policy = cpufreq_cpu_get(cpu);
1378 if (!cpu_policy)
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001379 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001381 if (cpufreq_driver->resume) {
1382 ret = cpufreq_driver->resume(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 if (ret) {
1384 printk(KERN_ERR "cpufreq: resume failed in ->resume "
1385 "step on CPU %u\n", cpu_policy->cpu);
Dave Jonesc9060492008-02-07 16:32:18 -05001386 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 }
1388 }
1389
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 schedule_work(&cpu_policy->update);
Dominik Brodowskice6c3992009-08-07 22:58:51 +02001391
Dave Jonesc9060492008-02-07 16:32:18 -05001392fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394}
1395
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01001396static struct syscore_ops cpufreq_syscore_ops = {
1397 .suspend = cpufreq_bp_suspend,
1398 .resume = cpufreq_bp_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399};
1400
Borislav Petkov9d950462013-01-20 10:24:28 +00001401/**
1402 * cpufreq_get_current_driver - return current driver's name
1403 *
1404 * Return the name string of the currently loaded cpufreq driver
1405 * or NULL, if none.
1406 */
1407const char *cpufreq_get_current_driver(void)
1408{
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001409 if (cpufreq_driver)
1410 return cpufreq_driver->name;
1411
1412 return NULL;
Borislav Petkov9d950462013-01-20 10:24:28 +00001413}
1414EXPORT_SYMBOL_GPL(cpufreq_get_current_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
1416/*********************************************************************
1417 * NOTIFIER LISTS INTERFACE *
1418 *********************************************************************/
1419
1420/**
1421 * cpufreq_register_notifier - register a driver with cpufreq
1422 * @nb: notifier function to register
1423 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1424 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001425 * Add a driver to one of two lists: either a list of drivers that
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 * are notified about clock rate changes (once before and once after
1427 * the transition), or a list of drivers that are notified about
1428 * changes in cpufreq policy.
1429 *
1430 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001431 * blocking_notifier_chain_register.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 */
1433int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
1434{
1435 int ret;
1436
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001437 if (cpufreq_disabled())
1438 return -EINVAL;
1439
Cesar Eduardo Barros74212ca2008-02-16 08:41:24 -02001440 WARN_ON(!init_cpufreq_transition_notifier_list_called);
1441
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 switch (list) {
1443 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001444 ret = srcu_notifier_chain_register(
Alan Sterne041c682006-03-27 01:16:30 -08001445 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 break;
1447 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001448 ret = blocking_notifier_chain_register(
1449 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 break;
1451 default:
1452 ret = -EINVAL;
1453 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
1455 return ret;
1456}
1457EXPORT_SYMBOL(cpufreq_register_notifier);
1458
1459
1460/**
1461 * cpufreq_unregister_notifier - unregister a driver with cpufreq
1462 * @nb: notifier block to be unregistered
1463 * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
1464 *
1465 * Remove a driver from the CPU frequency notifier list.
1466 *
1467 * This function may sleep, and has the same return conditions as
Alan Sterne041c682006-03-27 01:16:30 -08001468 * blocking_notifier_chain_unregister.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 */
1470int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1471{
1472 int ret;
1473
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001474 if (cpufreq_disabled())
1475 return -EINVAL;
1476
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 switch (list) {
1478 case CPUFREQ_TRANSITION_NOTIFIER:
Alan Sternb4dfdbb2006-10-04 02:17:06 -07001479 ret = srcu_notifier_chain_unregister(
Alan Sterne041c682006-03-27 01:16:30 -08001480 &cpufreq_transition_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 break;
1482 case CPUFREQ_POLICY_NOTIFIER:
Alan Sterne041c682006-03-27 01:16:30 -08001483 ret = blocking_notifier_chain_unregister(
1484 &cpufreq_policy_notifier_list, nb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 break;
1486 default:
1487 ret = -EINVAL;
1488 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489
1490 return ret;
1491}
1492EXPORT_SYMBOL(cpufreq_unregister_notifier);
1493
1494
1495/*********************************************************************
1496 * GOVERNORS *
1497 *********************************************************************/
1498
1499
1500int __cpufreq_driver_target(struct cpufreq_policy *policy,
1501 unsigned int target_freq,
1502 unsigned int relation)
1503{
1504 int retval = -EINVAL;
Viresh Kumar72499242012-10-31 01:28:21 +01001505 unsigned int old_target_freq = target_freq;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001506
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001507 if (cpufreq_disabled())
1508 return -ENODEV;
1509
Viresh Kumar72499242012-10-31 01:28:21 +01001510 /* Make sure that target_freq is within supported range */
1511 if (target_freq > policy->max)
1512 target_freq = policy->max;
1513 if (target_freq < policy->min)
1514 target_freq = policy->min;
1515
1516 pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
1517 policy->cpu, target_freq, relation, old_target_freq);
Viresh Kumar5a1c0222012-10-31 01:28:15 +01001518
1519 if (target_freq == policy->cur)
1520 return 0;
1521
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001522 if (cpufreq_driver->target)
1523 retval = cpufreq_driver->target(policy, target_freq, relation);
Ashok Raj90d45d12005-11-08 21:34:24 -08001524
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 return retval;
1526}
1527EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1528
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529int cpufreq_driver_target(struct cpufreq_policy *policy,
1530 unsigned int target_freq,
1531 unsigned int relation)
1532{
Julia Lawallf1829e42008-07-25 22:44:53 +02001533 int ret = -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
1535 policy = cpufreq_cpu_get(policy->cpu);
1536 if (!policy)
Julia Lawallf1829e42008-07-25 22:44:53 +02001537 goto no_policy;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001539 if (unlikely(lock_policy_rwsem_write(policy->cpu)))
Julia Lawallf1829e42008-07-25 22:44:53 +02001540 goto fail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
1542 ret = __cpufreq_driver_target(policy, target_freq, relation);
1543
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001544 unlock_policy_rwsem_write(policy->cpu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545
Julia Lawallf1829e42008-07-25 22:44:53 +02001546fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 cpufreq_cpu_put(policy);
Julia Lawallf1829e42008-07-25 22:44:53 +02001548no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 return ret;
1550}
1551EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1552
venkatesh.pallipadi@intel.combf0b90e2008-08-04 11:59:07 -07001553int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu)
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001554{
1555 int ret = 0;
1556
Dirk Brandewied5aaffa2013-01-17 16:22:21 +00001557 if (cpufreq_disabled())
1558 return ret;
1559
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001560 if (!cpufreq_driver->getavg)
Viresh Kumar0676f7f2012-10-24 23:39:48 +02001561 return 0;
1562
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001563 policy = cpufreq_cpu_get(policy->cpu);
1564 if (!policy)
1565 return -EINVAL;
1566
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001567 ret = cpufreq_driver->getavg(policy, cpu);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001568
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001569 cpufreq_cpu_put(policy);
1570 return ret;
1571}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001572EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg);
Venkatesh Pallipadidfde5d62006-10-03 12:38:45 -07001573
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001574/*
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001575 * when "event" is CPUFREQ_GOV_LIMITS
1576 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301578static int __cpufreq_governor(struct cpufreq_policy *policy,
1579 unsigned int event)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580{
Dave Jonescc993ca2005-07-28 09:43:56 -07001581 int ret;
Thomas Renninger6afde102007-10-02 13:28:13 -07001582
1583 /* Only must be defined when default governor is known to have latency
1584 restrictions, like e.g. conservative or ondemand.
1585 That this is the case is already ensured in Kconfig
1586 */
1587#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE
1588 struct cpufreq_governor *gov = &cpufreq_gov_performance;
1589#else
1590 struct cpufreq_governor *gov = NULL;
1591#endif
Thomas Renninger1c256242007-10-02 13:28:12 -07001592
1593 if (policy->governor->max_transition_latency &&
1594 policy->cpuinfo.transition_latency >
1595 policy->governor->max_transition_latency) {
Thomas Renninger6afde102007-10-02 13:28:13 -07001596 if (!gov)
1597 return -EINVAL;
1598 else {
1599 printk(KERN_WARNING "%s governor failed, too long"
1600 " transition latency of HW, fallback"
1601 " to %s governor\n",
1602 policy->governor->name,
1603 gov->name);
1604 policy->governor = gov;
1605 }
Thomas Renninger1c256242007-10-02 13:28:12 -07001606 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607
1608 if (!try_module_get(policy->governor->owner))
1609 return -EINVAL;
1610
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001611 pr_debug("__cpufreq_governor for CPU %u, event %u\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301612 policy->cpu, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 ret = policy->governor->governor(policy, event);
1614
Viresh Kumar4d5dcc42013-03-27 15:58:58 +00001615 if (!ret) {
1616 if (event == CPUFREQ_GOV_POLICY_INIT)
1617 policy->governor->initialized++;
1618 else if (event == CPUFREQ_GOV_POLICY_EXIT)
1619 policy->governor->initialized--;
1620 }
Viresh Kumarb3940582013-02-01 05:42:58 +00001621
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301622 /* we keep one module reference alive for
1623 each CPU governed by this CPU */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 if ((event != CPUFREQ_GOV_START) || ret)
1625 module_put(policy->governor->owner);
1626 if ((event == CPUFREQ_GOV_STOP) && !ret)
1627 module_put(policy->governor->owner);
1628
1629 return ret;
1630}
1631
1632
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633int cpufreq_register_governor(struct cpufreq_governor *governor)
1634{
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001635 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636
1637 if (!governor)
1638 return -EINVAL;
1639
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001640 if (cpufreq_disabled())
1641 return -ENODEV;
1642
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001643 mutex_lock(&cpufreq_governor_mutex);
Dave Jones32ee8c32006-02-28 00:43:23 -05001644
Viresh Kumarb3940582013-02-01 05:42:58 +00001645 governor->initialized = 0;
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001646 err = -EBUSY;
1647 if (__find_governor(governor->name) == NULL) {
1648 err = 0;
1649 list_add(&governor->governor_list, &cpufreq_governor_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
Dave Jones32ee8c32006-02-28 00:43:23 -05001652 mutex_unlock(&cpufreq_governor_mutex);
Jeremy Fitzhardinge3bcb09a2006-07-06 12:30:26 -07001653 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654}
1655EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1656
1657
1658void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1659{
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001660#ifdef CONFIG_HOTPLUG_CPU
1661 int cpu;
1662#endif
1663
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 if (!governor)
1665 return;
1666
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001667 if (cpufreq_disabled())
1668 return;
1669
Prarit Bhargava90e41ba2009-11-12 09:18:46 -05001670#ifdef CONFIG_HOTPLUG_CPU
1671 for_each_present_cpu(cpu) {
1672 if (cpu_online(cpu))
1673 continue;
1674 if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
1675 strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
1676 }
1677#endif
1678
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001679 mutex_lock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680 list_del(&governor->governor_list);
akpm@osdl.org3fc54d32006-01-13 15:54:22 -08001681 mutex_unlock(&cpufreq_governor_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682 return;
1683}
1684EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1685
1686
1687
1688/*********************************************************************
1689 * POLICY INTERFACE *
1690 *********************************************************************/
1691
1692/**
1693 * cpufreq_get_policy - get the current cpufreq_policy
Dave Jones29464f22009-01-18 01:37:11 -05001694 * @policy: struct cpufreq_policy into which the current cpufreq_policy
1695 * is written
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 *
1697 * Reads the current cpufreq policy.
1698 */
1699int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1700{
1701 struct cpufreq_policy *cpu_policy;
1702 if (!policy)
1703 return -EINVAL;
1704
1705 cpu_policy = cpufreq_cpu_get(cpu);
1706 if (!cpu_policy)
1707 return -EINVAL;
1708
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710
1711 cpufreq_cpu_put(cpu_policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 return 0;
1713}
1714EXPORT_SYMBOL(cpufreq_get_policy);
1715
1716
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001717/*
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301718 * data : current policy.
1719 * policy : policy to be set.
Arjan van de Ven153d7f32006-07-26 15:40:07 +02001720 */
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301721static int __cpufreq_set_policy(struct cpufreq_policy *data,
1722 struct cpufreq_policy *policy)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723{
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001724 int ret = 0, failed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001726 pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 policy->min, policy->max);
1728
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301729 memcpy(&policy->cpuinfo, &data->cpuinfo,
1730 sizeof(struct cpufreq_cpuinfo));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
Yi Yang53391fa2008-01-30 13:33:34 +01001732 if (policy->min > data->max || policy->max < data->min) {
Mattia Dongili9c9a43e2006-07-05 23:12:20 +02001733 ret = -EINVAL;
1734 goto error_out;
1735 }
1736
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 /* verify the cpu speed can be set within this limit */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001738 ret = cpufreq_driver->verify(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 if (ret)
1740 goto error_out;
1741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 /* adjust if necessary - all reasons */
Alan Sterne041c682006-03-27 01:16:30 -08001743 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1744 CPUFREQ_ADJUST, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745
1746 /* adjust if necessary - hardware incompatibility*/
Alan Sterne041c682006-03-27 01:16:30 -08001747 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1748 CPUFREQ_INCOMPATIBLE, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
1750 /* verify the cpu speed can be set within this limit,
1751 which might be different to the first one */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001752 ret = cpufreq_driver->verify(policy);
Alan Sterne041c682006-03-27 01:16:30 -08001753 if (ret)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 goto error_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755
1756 /* notification of the new policy */
Alan Sterne041c682006-03-27 01:16:30 -08001757 blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
1758 CPUFREQ_NOTIFY, policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
Dave Jones7d5e3502006-02-02 17:03:42 -05001760 data->min = policy->min;
1761 data->max = policy->max;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001763 pr_debug("new min and max freqs are %u - %u kHz\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301764 data->min, data->max);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001766 if (cpufreq_driver->setpolicy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 data->policy = policy->policy;
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001768 pr_debug("setting range\n");
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001769 ret = cpufreq_driver->setpolicy(policy);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 } else {
1771 if (policy->governor != data->governor) {
1772 /* save old, working values */
1773 struct cpufreq_governor *old_gov = data->governor;
1774
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001775 pr_debug("governor switch\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776
1777 /* end old governor */
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001778 if (data->governor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 __cpufreq_governor(data, CPUFREQ_GOV_STOP);
Viresh Kumar955ef482013-05-16 05:09:58 +00001780 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001781 __cpufreq_governor(data,
1782 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar955ef482013-05-16 05:09:58 +00001783 lock_policy_rwsem_write(policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001784 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
1786 /* start new governor */
1787 data->governor = policy->governor;
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001788 if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) {
Viresh Kumar955ef482013-05-16 05:09:58 +00001789 if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) {
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001790 failed = 0;
Viresh Kumar955ef482013-05-16 05:09:58 +00001791 } else {
1792 unlock_policy_rwsem_write(policy->cpu);
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001793 __cpufreq_governor(data,
1794 CPUFREQ_GOV_POLICY_EXIT);
Viresh Kumar955ef482013-05-16 05:09:58 +00001795 lock_policy_rwsem_write(policy->cpu);
1796 }
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001797 }
1798
1799 if (failed) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 /* new governor failed, so re-start old one */
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001801 pr_debug("starting governor %s failed\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301802 data->governor->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 if (old_gov) {
1804 data->governor = old_gov;
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301805 __cpufreq_governor(data,
Viresh Kumar7bd353a2013-03-27 15:58:57 +00001806 CPUFREQ_GOV_POLICY_INIT);
1807 __cpufreq_governor(data,
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301808 CPUFREQ_GOV_START);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 }
1810 ret = -EINVAL;
1811 goto error_out;
1812 }
1813 /* might be a policy change, too, so fall through */
1814 }
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001815 pr_debug("governor: change or update limits\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1817 }
1818
Dave Jones7d5e3502006-02-02 17:03:42 -05001819error_out:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 return ret;
1821}
1822
1823/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 * cpufreq_update_policy - re-evaluate an existing cpufreq policy
1825 * @cpu: CPU which shall be re-evaluated
1826 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001827 * Useful for policy notifiers which have different necessities
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 * at different times.
1829 */
1830int cpufreq_update_policy(unsigned int cpu)
1831{
1832 struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1833 struct cpufreq_policy policy;
Julia Lawallf1829e42008-07-25 22:44:53 +02001834 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
Julia Lawallf1829e42008-07-25 22:44:53 +02001836 if (!data) {
1837 ret = -ENODEV;
1838 goto no_policy;
1839 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
Julia Lawallf1829e42008-07-25 22:44:53 +02001841 if (unlikely(lock_policy_rwsem_write(cpu))) {
1842 ret = -EINVAL;
1843 goto fail;
1844 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001846 pr_debug("updating policy for CPU %u\n", cpu);
Dave Jones7d5e3502006-02-02 17:03:42 -05001847 memcpy(&policy, data, sizeof(struct cpufreq_policy));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 policy.min = data->user_policy.min;
1849 policy.max = data->user_policy.max;
1850 policy.policy = data->user_policy.policy;
1851 policy.governor = data->user_policy.governor;
1852
Thomas Renninger0961dd02006-01-26 18:46:33 +01001853 /* BIOS might change freq behind our back
1854 -> ask driver for current freq and notify governors about a change */
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001855 if (cpufreq_driver->get) {
1856 policy.cur = cpufreq_driver->get(cpu);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001857 if (!data->cur) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001858 pr_debug("Driver did not initialize current freq");
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001859 data->cur = policy.cur;
1860 } else {
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001861 if (data->cur != policy.cur && cpufreq_driver->target)
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301862 cpufreq_out_of_sync(cpu, data->cur,
1863 policy.cur);
Thomas Renningera85f7bd2006-02-01 11:36:04 +01001864 }
Thomas Renninger0961dd02006-01-26 18:46:33 +01001865 }
1866
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 ret = __cpufreq_set_policy(data, &policy);
1868
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001869 unlock_policy_rwsem_write(cpu);
1870
Julia Lawallf1829e42008-07-25 22:44:53 +02001871fail:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872 cpufreq_cpu_put(data);
Julia Lawallf1829e42008-07-25 22:44:53 +02001873no_policy:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 return ret;
1875}
1876EXPORT_SYMBOL(cpufreq_update_policy);
1877
Satyam Sharmadd184a02007-10-02 13:28:14 -07001878static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb,
Ashok Rajc32b6b82005-10-30 14:59:54 -08001879 unsigned long action, void *hcpu)
1880{
1881 unsigned int cpu = (unsigned long)hcpu;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001882 struct device *dev;
Ashok Rajc32b6b82005-10-30 14:59:54 -08001883
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001884 dev = get_cpu_device(cpu);
1885 if (dev) {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001886 switch (action) {
1887 case CPU_ONLINE:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001888 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001889 break;
1890 case CPU_DOWN_PREPARE:
Srivatsa S. Bhata66b2e52013-05-15 21:47:17 +02001891 case CPU_UP_CANCELED_FROZEN:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001892 __cpufreq_remove_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001893 break;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08001894 case CPU_DOWN_FAILED:
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001895 cpufreq_add_dev(dev, NULL);
Ashok Rajc32b6b82005-10-30 14:59:54 -08001896 break;
1897 }
1898 }
1899 return NOTIFY_OK;
1900}
1901
Neal Buckendahl9c36f742010-06-22 22:02:44 -05001902static struct notifier_block __refdata cpufreq_cpu_notifier = {
Ashok Rajc32b6b82005-10-30 14:59:54 -08001903 .notifier_call = cpufreq_cpu_callback,
1904};
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905
1906/*********************************************************************
1907 * REGISTER / UNREGISTER CPUFREQ DRIVER *
1908 *********************************************************************/
1909
1910/**
1911 * cpufreq_register_driver - register a CPU Frequency driver
1912 * @driver_data: A struct cpufreq_driver containing the values#
1913 * submitted by the CPU Frequency driver.
1914 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001915 * Registers a CPU Frequency driver to this core code. This code
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 * returns zero on success, -EBUSY when another driver got here first
Dave Jones32ee8c32006-02-28 00:43:23 -05001917 * (and isn't unregistered in the meantime).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 *
1919 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001920int cpufreq_register_driver(struct cpufreq_driver *driver_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921{
1922 unsigned long flags;
1923 int ret;
1924
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04001925 if (cpufreq_disabled())
1926 return -ENODEV;
1927
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 if (!driver_data || !driver_data->verify || !driver_data->init ||
1929 ((!driver_data->setpolicy) && (!driver_data->target)))
1930 return -EINVAL;
1931
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001932 pr_debug("trying to register driver %s\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933
1934 if (driver_data->setpolicy)
1935 driver_data->flags |= CPUFREQ_CONST_LOOPS;
1936
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001937 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001938 if (cpufreq_driver) {
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001939 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 return -EBUSY;
1941 }
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001942 cpufreq_driver = driver_data;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001943 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001945 ret = subsys_interface_register(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001946 if (ret)
1947 goto err_null_driver;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001949 if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 int i;
1951 ret = -ENODEV;
1952
1953 /* check for at least one working CPU */
Mike Travis7a6aedf2008-03-25 15:06:53 -07001954 for (i = 0; i < nr_cpu_ids; i++)
1955 if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 ret = 0;
Mike Travis7a6aedf2008-03-25 15:06:53 -07001957 break;
1958 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959
1960 /* if all ->init() calls failed, unregister */
1961 if (ret) {
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001962 pr_debug("no CPU initialized for driver %s\n",
Gautham R Shenoye08f5f52006-10-26 16:20:58 +05301963 driver_data->name);
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001964 goto err_if_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 }
1966 }
1967
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001968 register_hotcpu_notifier(&cpufreq_cpu_notifier);
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001969 pr_debug("driver %s up and running\n", driver_data->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001971 return 0;
Kay Sievers8a25a2f2011-12-21 14:29:42 -08001972err_if_unreg:
1973 subsys_interface_unregister(&cpufreq_interface);
Jiri Slaby8f5bc2a2011-03-01 17:41:10 +01001974err_null_driver:
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001975 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001976 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00001977 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Dave Jones4d34a672008-02-07 16:33:49 -05001978 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001979}
1980EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1981
1982
1983/**
1984 * cpufreq_unregister_driver - unregister the current CPUFreq driver
1985 *
Dave Jones32ee8c32006-02-28 00:43:23 -05001986 * Unregister the current CPUFreq driver. Only call this if you have
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 * the right to do so, i.e. if you have succeeded in initialising before!
1988 * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1989 * currently not initialised.
1990 */
Linus Torvalds221dee22007-02-26 14:55:48 -08001991int cpufreq_unregister_driver(struct cpufreq_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992{
1993 unsigned long flags;
1994
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02001995 if (!cpufreq_driver || (driver != cpufreq_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997
Dominik Brodowski2d06d8c2011-03-27 15:04:46 +02001998 pr_debug("unregistering driver %s\n", driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002000 subsys_interface_unregister(&cpufreq_interface);
Chandra Seetharaman65edc682006-06-27 02:54:08 -07002001 unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002003 write_lock_irqsave(&cpufreq_driver_lock, flags);
Rafael J. Wysocki1c3d85d2013-04-29 00:08:16 +02002004 cpufreq_driver = NULL;
Nathan Zimmer0d1857a2013-02-22 16:24:34 +00002005 write_unlock_irqrestore(&cpufreq_driver_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006
2007 return 0;
2008}
2009EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002010
2011static int __init cpufreq_core_init(void)
2012{
2013 int cpu;
2014
Konrad Rzeszutek Wilka7b422c2012-03-13 19:18:39 -04002015 if (cpufreq_disabled())
2016 return -ENODEV;
2017
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002018 for_each_possible_cpu(cpu) {
Tejun Heof1625062009-10-29 22:34:13 +09002019 per_cpu(cpufreq_policy_cpu, cpu) = -1;
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002020 init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
2021 }
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002022
Kay Sievers8a25a2f2011-12-21 14:29:42 -08002023 cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002024 BUG_ON(!cpufreq_global_kobject);
Rafael J. Wysockie00e56d2011-03-23 22:16:32 +01002025 register_syscore_ops(&cpufreq_syscore_ops);
Thomas Renninger8aa84ad2009-07-24 15:25:05 +02002026
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002027 return 0;
2028}
Venkatesh Pallipadi5a01f2e2007-02-05 16:12:44 -08002029core_initcall(cpufreq_core_init);