xref: /openbmc/linux/drivers/cpufreq/cpufreq.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus Torvalds /*
2*1da177e4SLinus Torvalds  *  linux/drivers/cpufreq/cpufreq.c
3*1da177e4SLinus Torvalds  *
4*1da177e4SLinus Torvalds  *  Copyright (C) 2001 Russell King
5*1da177e4SLinus Torvalds  *            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
6*1da177e4SLinus Torvalds  *
7*1da177e4SLinus Torvalds  * This program is free software; you can redistribute it and/or modify
8*1da177e4SLinus Torvalds  * it under the terms of the GNU General Public License version 2 as
9*1da177e4SLinus Torvalds  * published by the Free Software Foundation.
10*1da177e4SLinus Torvalds  *
11*1da177e4SLinus Torvalds  */
12*1da177e4SLinus Torvalds 
13*1da177e4SLinus Torvalds #include <linux/config.h>
14*1da177e4SLinus Torvalds #include <linux/kernel.h>
15*1da177e4SLinus Torvalds #include <linux/module.h>
16*1da177e4SLinus Torvalds #include <linux/init.h>
17*1da177e4SLinus Torvalds #include <linux/notifier.h>
18*1da177e4SLinus Torvalds #include <linux/cpufreq.h>
19*1da177e4SLinus Torvalds #include <linux/delay.h>
20*1da177e4SLinus Torvalds #include <linux/interrupt.h>
21*1da177e4SLinus Torvalds #include <linux/spinlock.h>
22*1da177e4SLinus Torvalds #include <linux/device.h>
23*1da177e4SLinus Torvalds #include <linux/slab.h>
24*1da177e4SLinus Torvalds #include <linux/cpu.h>
25*1da177e4SLinus Torvalds #include <linux/completion.h>
26*1da177e4SLinus Torvalds 
27*1da177e4SLinus Torvalds #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "cpufreq-core", msg)
28*1da177e4SLinus Torvalds 
29*1da177e4SLinus Torvalds /**
30*1da177e4SLinus Torvalds  * The "cpufreq driver" - the arch- or hardware-dependend low
31*1da177e4SLinus Torvalds  * level driver of CPUFreq support, and its spinlock. This lock
32*1da177e4SLinus Torvalds  * also protects the cpufreq_cpu_data array.
33*1da177e4SLinus Torvalds  */
34*1da177e4SLinus Torvalds static struct cpufreq_driver   	*cpufreq_driver;
35*1da177e4SLinus Torvalds static struct cpufreq_policy	*cpufreq_cpu_data[NR_CPUS];
36*1da177e4SLinus Torvalds static DEFINE_SPINLOCK(cpufreq_driver_lock);
37*1da177e4SLinus Torvalds 
38*1da177e4SLinus Torvalds 
39*1da177e4SLinus Torvalds /* we keep a copy of all ->add'ed CPU's struct sys_device here;
40*1da177e4SLinus Torvalds  * as it is only accessed in ->add and ->remove, no lock or reference
41*1da177e4SLinus Torvalds  * count is necessary.
42*1da177e4SLinus Torvalds  */
43*1da177e4SLinus Torvalds static struct sys_device	*cpu_sys_devices[NR_CPUS];
44*1da177e4SLinus Torvalds 
45*1da177e4SLinus Torvalds 
46*1da177e4SLinus Torvalds /* internal prototypes */
47*1da177e4SLinus Torvalds static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
48*1da177e4SLinus Torvalds static void handle_update(void *data);
49*1da177e4SLinus Torvalds static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci);
50*1da177e4SLinus Torvalds 
51*1da177e4SLinus Torvalds /**
52*1da177e4SLinus Torvalds  * Two notifier lists: the "policy" list is involved in the
53*1da177e4SLinus Torvalds  * validation process for a new CPU frequency policy; the
54*1da177e4SLinus Torvalds  * "transition" list for kernel code that needs to handle
55*1da177e4SLinus Torvalds  * changes to devices when the CPU clock speed changes.
56*1da177e4SLinus Torvalds  * The mutex locks both lists.
57*1da177e4SLinus Torvalds  */
58*1da177e4SLinus Torvalds static struct notifier_block    *cpufreq_policy_notifier_list;
59*1da177e4SLinus Torvalds static struct notifier_block    *cpufreq_transition_notifier_list;
60*1da177e4SLinus Torvalds static DECLARE_RWSEM		(cpufreq_notifier_rwsem);
61*1da177e4SLinus Torvalds 
62*1da177e4SLinus Torvalds 
63*1da177e4SLinus Torvalds static LIST_HEAD(cpufreq_governor_list);
64*1da177e4SLinus Torvalds static DECLARE_MUTEX		(cpufreq_governor_sem);
65*1da177e4SLinus Torvalds 
66*1da177e4SLinus Torvalds struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
67*1da177e4SLinus Torvalds {
68*1da177e4SLinus Torvalds 	struct cpufreq_policy *data;
69*1da177e4SLinus Torvalds 	unsigned long flags;
70*1da177e4SLinus Torvalds 
71*1da177e4SLinus Torvalds 	if (cpu >= NR_CPUS)
72*1da177e4SLinus Torvalds 		goto err_out;
73*1da177e4SLinus Torvalds 
74*1da177e4SLinus Torvalds 	/* get the cpufreq driver */
75*1da177e4SLinus Torvalds 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
76*1da177e4SLinus Torvalds 
77*1da177e4SLinus Torvalds 	if (!cpufreq_driver)
78*1da177e4SLinus Torvalds 		goto err_out_unlock;
79*1da177e4SLinus Torvalds 
80*1da177e4SLinus Torvalds 	if (!try_module_get(cpufreq_driver->owner))
81*1da177e4SLinus Torvalds 		goto err_out_unlock;
82*1da177e4SLinus Torvalds 
83*1da177e4SLinus Torvalds 
84*1da177e4SLinus Torvalds 	/* get the CPU */
85*1da177e4SLinus Torvalds 	data = cpufreq_cpu_data[cpu];
86*1da177e4SLinus Torvalds 
87*1da177e4SLinus Torvalds 	if (!data)
88*1da177e4SLinus Torvalds 		goto err_out_put_module;
89*1da177e4SLinus Torvalds 
90*1da177e4SLinus Torvalds 	if (!kobject_get(&data->kobj))
91*1da177e4SLinus Torvalds 		goto err_out_put_module;
92*1da177e4SLinus Torvalds 
93*1da177e4SLinus Torvalds 
94*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
95*1da177e4SLinus Torvalds 
96*1da177e4SLinus Torvalds 	return data;
97*1da177e4SLinus Torvalds 
98*1da177e4SLinus Torvalds  err_out_put_module:
99*1da177e4SLinus Torvalds 	module_put(cpufreq_driver->owner);
100*1da177e4SLinus Torvalds  err_out_unlock:
101*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
102*1da177e4SLinus Torvalds  err_out:
103*1da177e4SLinus Torvalds 	return NULL;
104*1da177e4SLinus Torvalds }
105*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_cpu_get);
106*1da177e4SLinus Torvalds 
107*1da177e4SLinus Torvalds void cpufreq_cpu_put(struct cpufreq_policy *data)
108*1da177e4SLinus Torvalds {
109*1da177e4SLinus Torvalds 	kobject_put(&data->kobj);
110*1da177e4SLinus Torvalds 	module_put(cpufreq_driver->owner);
111*1da177e4SLinus Torvalds }
112*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
113*1da177e4SLinus Torvalds 
114*1da177e4SLinus Torvalds 
115*1da177e4SLinus Torvalds /*********************************************************************
116*1da177e4SLinus Torvalds  *                     UNIFIED DEBUG HELPERS                         *
117*1da177e4SLinus Torvalds  *********************************************************************/
118*1da177e4SLinus Torvalds #ifdef CONFIG_CPU_FREQ_DEBUG
119*1da177e4SLinus Torvalds 
120*1da177e4SLinus Torvalds /* what part(s) of the CPUfreq subsystem are debugged? */
121*1da177e4SLinus Torvalds static unsigned int debug;
122*1da177e4SLinus Torvalds 
123*1da177e4SLinus Torvalds /* is the debug output ratelimit'ed using printk_ratelimit? User can
124*1da177e4SLinus Torvalds  * set or modify this value.
125*1da177e4SLinus Torvalds  */
126*1da177e4SLinus Torvalds static unsigned int debug_ratelimit = 1;
127*1da177e4SLinus Torvalds 
128*1da177e4SLinus Torvalds /* is the printk_ratelimit'ing enabled? It's enabled after a successful
129*1da177e4SLinus Torvalds  * loading of a cpufreq driver, temporarily disabled when a new policy
130*1da177e4SLinus Torvalds  * is set, and disabled upon cpufreq driver removal
131*1da177e4SLinus Torvalds  */
132*1da177e4SLinus Torvalds static unsigned int disable_ratelimit = 1;
133*1da177e4SLinus Torvalds static DEFINE_SPINLOCK(disable_ratelimit_lock);
134*1da177e4SLinus Torvalds 
135*1da177e4SLinus Torvalds static inline void cpufreq_debug_enable_ratelimit(void)
136*1da177e4SLinus Torvalds {
137*1da177e4SLinus Torvalds 	unsigned long flags;
138*1da177e4SLinus Torvalds 
139*1da177e4SLinus Torvalds 	spin_lock_irqsave(&disable_ratelimit_lock, flags);
140*1da177e4SLinus Torvalds 	if (disable_ratelimit)
141*1da177e4SLinus Torvalds 		disable_ratelimit--;
142*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
143*1da177e4SLinus Torvalds }
144*1da177e4SLinus Torvalds 
145*1da177e4SLinus Torvalds static inline void cpufreq_debug_disable_ratelimit(void)
146*1da177e4SLinus Torvalds {
147*1da177e4SLinus Torvalds 	unsigned long flags;
148*1da177e4SLinus Torvalds 
149*1da177e4SLinus Torvalds 	spin_lock_irqsave(&disable_ratelimit_lock, flags);
150*1da177e4SLinus Torvalds 	disable_ratelimit++;
151*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
152*1da177e4SLinus Torvalds }
153*1da177e4SLinus Torvalds 
154*1da177e4SLinus Torvalds void cpufreq_debug_printk(unsigned int type, const char *prefix, const char *fmt, ...)
155*1da177e4SLinus Torvalds {
156*1da177e4SLinus Torvalds 	char s[256];
157*1da177e4SLinus Torvalds 	va_list args;
158*1da177e4SLinus Torvalds 	unsigned int len;
159*1da177e4SLinus Torvalds 	unsigned long flags;
160*1da177e4SLinus Torvalds 
161*1da177e4SLinus Torvalds 	WARN_ON(!prefix);
162*1da177e4SLinus Torvalds 	if (type & debug) {
163*1da177e4SLinus Torvalds 		spin_lock_irqsave(&disable_ratelimit_lock, flags);
164*1da177e4SLinus Torvalds 		if (!disable_ratelimit && debug_ratelimit && !printk_ratelimit()) {
165*1da177e4SLinus Torvalds 			spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
166*1da177e4SLinus Torvalds 			return;
167*1da177e4SLinus Torvalds 		}
168*1da177e4SLinus Torvalds 		spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
169*1da177e4SLinus Torvalds 
170*1da177e4SLinus Torvalds 		len = snprintf(s, 256, KERN_DEBUG "%s: ", prefix);
171*1da177e4SLinus Torvalds 
172*1da177e4SLinus Torvalds 		va_start(args, fmt);
173*1da177e4SLinus Torvalds 		len += vsnprintf(&s[len], (256 - len), fmt, args);
174*1da177e4SLinus Torvalds 		va_end(args);
175*1da177e4SLinus Torvalds 
176*1da177e4SLinus Torvalds 		printk(s);
177*1da177e4SLinus Torvalds 
178*1da177e4SLinus Torvalds 		WARN_ON(len < 5);
179*1da177e4SLinus Torvalds 	}
180*1da177e4SLinus Torvalds }
181*1da177e4SLinus Torvalds EXPORT_SYMBOL(cpufreq_debug_printk);
182*1da177e4SLinus Torvalds 
183*1da177e4SLinus Torvalds 
184*1da177e4SLinus Torvalds module_param(debug, uint, 0644);
185*1da177e4SLinus Torvalds MODULE_PARM_DESC(debug, "CPUfreq debugging: add 1 to debug core, 2 to debug drivers, and 4 to debug governors.");
186*1da177e4SLinus Torvalds 
187*1da177e4SLinus Torvalds module_param(debug_ratelimit, uint, 0644);
188*1da177e4SLinus Torvalds MODULE_PARM_DESC(debug_ratelimit, "CPUfreq debugging: set to 0 to disable ratelimiting.");
189*1da177e4SLinus Torvalds 
190*1da177e4SLinus Torvalds #else /* !CONFIG_CPU_FREQ_DEBUG */
191*1da177e4SLinus Torvalds 
192*1da177e4SLinus Torvalds static inline void cpufreq_debug_enable_ratelimit(void) { return; }
193*1da177e4SLinus Torvalds static inline void cpufreq_debug_disable_ratelimit(void) { return; }
194*1da177e4SLinus Torvalds 
195*1da177e4SLinus Torvalds #endif /* CONFIG_CPU_FREQ_DEBUG */
196*1da177e4SLinus Torvalds 
197*1da177e4SLinus Torvalds 
198*1da177e4SLinus Torvalds /*********************************************************************
199*1da177e4SLinus Torvalds  *            EXTERNALLY AFFECTING FREQUENCY CHANGES                 *
200*1da177e4SLinus Torvalds  *********************************************************************/
201*1da177e4SLinus Torvalds 
202*1da177e4SLinus Torvalds /**
203*1da177e4SLinus Torvalds  * adjust_jiffies - adjust the system "loops_per_jiffy"
204*1da177e4SLinus Torvalds  *
205*1da177e4SLinus Torvalds  * This function alters the system "loops_per_jiffy" for the clock
206*1da177e4SLinus Torvalds  * speed change. Note that loops_per_jiffy cannot be updated on SMP
207*1da177e4SLinus Torvalds  * systems as each CPU might be scaled differently. So, use the arch
208*1da177e4SLinus Torvalds  * per-CPU loops_per_jiffy value wherever possible.
209*1da177e4SLinus Torvalds  */
210*1da177e4SLinus Torvalds #ifndef CONFIG_SMP
211*1da177e4SLinus Torvalds static unsigned long l_p_j_ref;
212*1da177e4SLinus Torvalds static unsigned int  l_p_j_ref_freq;
213*1da177e4SLinus Torvalds 
214*1da177e4SLinus Torvalds static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
215*1da177e4SLinus Torvalds {
216*1da177e4SLinus Torvalds 	if (ci->flags & CPUFREQ_CONST_LOOPS)
217*1da177e4SLinus Torvalds 		return;
218*1da177e4SLinus Torvalds 
219*1da177e4SLinus Torvalds 	if (!l_p_j_ref_freq) {
220*1da177e4SLinus Torvalds 		l_p_j_ref = loops_per_jiffy;
221*1da177e4SLinus Torvalds 		l_p_j_ref_freq = ci->old;
222*1da177e4SLinus Torvalds 		dprintk("saving %lu as reference value for loops_per_jiffy; freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
223*1da177e4SLinus Torvalds 	}
224*1da177e4SLinus Torvalds 	if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) ||
225*1da177e4SLinus Torvalds 	    (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) ||
226*1da177e4SLinus Torvalds 	    (val == CPUFREQ_RESUMECHANGE)) {
227*1da177e4SLinus Torvalds 		loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
228*1da177e4SLinus Torvalds 		dprintk("scaling loops_per_jiffy to %lu for frequency %u kHz\n", loops_per_jiffy, ci->new);
229*1da177e4SLinus Torvalds 	}
230*1da177e4SLinus Torvalds }
231*1da177e4SLinus Torvalds #else
232*1da177e4SLinus Torvalds static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) { return; }
233*1da177e4SLinus Torvalds #endif
234*1da177e4SLinus Torvalds 
235*1da177e4SLinus Torvalds 
236*1da177e4SLinus Torvalds /**
237*1da177e4SLinus Torvalds  * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
238*1da177e4SLinus Torvalds  *
239*1da177e4SLinus Torvalds  * This function calls the transition notifiers and the "adjust_jiffies" function. It is called
240*1da177e4SLinus Torvalds  * twice on all CPU frequency changes that have external effects.
241*1da177e4SLinus Torvalds  */
242*1da177e4SLinus Torvalds void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
243*1da177e4SLinus Torvalds {
244*1da177e4SLinus Torvalds 	BUG_ON(irqs_disabled());
245*1da177e4SLinus Torvalds 
246*1da177e4SLinus Torvalds 	freqs->flags = cpufreq_driver->flags;
247*1da177e4SLinus Torvalds 	dprintk("notification %u of frequency transition to %u kHz\n", state, freqs->new);
248*1da177e4SLinus Torvalds 
249*1da177e4SLinus Torvalds 	down_read(&cpufreq_notifier_rwsem);
250*1da177e4SLinus Torvalds 	switch (state) {
251*1da177e4SLinus Torvalds 	case CPUFREQ_PRECHANGE:
252*1da177e4SLinus Torvalds 		/* detect if the driver reported a value as "old frequency" which
253*1da177e4SLinus Torvalds 		 * is not equal to what the cpufreq core thinks is "old frequency".
254*1da177e4SLinus Torvalds 		 */
255*1da177e4SLinus Torvalds 		if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
256*1da177e4SLinus Torvalds 			if ((likely(cpufreq_cpu_data[freqs->cpu])) &&
257*1da177e4SLinus Torvalds 			    (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)) &&
258*1da177e4SLinus Torvalds 			    (likely(cpufreq_cpu_data[freqs->cpu]->cur)) &&
259*1da177e4SLinus Torvalds 			    (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur)))
260*1da177e4SLinus Torvalds 			{
261*1da177e4SLinus Torvalds 				printk(KERN_WARNING "Warning: CPU frequency is %u, "
262*1da177e4SLinus Torvalds 				       "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur);
263*1da177e4SLinus Torvalds 				freqs->old = cpufreq_cpu_data[freqs->cpu]->cur;
264*1da177e4SLinus Torvalds 			}
265*1da177e4SLinus Torvalds 		}
266*1da177e4SLinus Torvalds 		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs);
267*1da177e4SLinus Torvalds 		adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
268*1da177e4SLinus Torvalds 		break;
269*1da177e4SLinus Torvalds 	case CPUFREQ_POSTCHANGE:
270*1da177e4SLinus Torvalds 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
271*1da177e4SLinus Torvalds 		notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
272*1da177e4SLinus Torvalds 		if ((likely(cpufreq_cpu_data[freqs->cpu])) &&
273*1da177e4SLinus Torvalds 		    (likely(cpufreq_cpu_data[freqs->cpu]->cpu == freqs->cpu)))
274*1da177e4SLinus Torvalds 			cpufreq_cpu_data[freqs->cpu]->cur = freqs->new;
275*1da177e4SLinus Torvalds 		break;
276*1da177e4SLinus Torvalds 	}
277*1da177e4SLinus Torvalds 	up_read(&cpufreq_notifier_rwsem);
278*1da177e4SLinus Torvalds }
279*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
280*1da177e4SLinus Torvalds 
281*1da177e4SLinus Torvalds 
282*1da177e4SLinus Torvalds 
283*1da177e4SLinus Torvalds /*********************************************************************
284*1da177e4SLinus Torvalds  *                          SYSFS INTERFACE                          *
285*1da177e4SLinus Torvalds  *********************************************************************/
286*1da177e4SLinus Torvalds 
287*1da177e4SLinus Torvalds /**
288*1da177e4SLinus Torvalds  * cpufreq_parse_governor - parse a governor string
289*1da177e4SLinus Torvalds  */
290*1da177e4SLinus Torvalds static int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
291*1da177e4SLinus Torvalds 				struct cpufreq_governor **governor)
292*1da177e4SLinus Torvalds {
293*1da177e4SLinus Torvalds 	if (!cpufreq_driver)
294*1da177e4SLinus Torvalds 		return -EINVAL;
295*1da177e4SLinus Torvalds 	if (cpufreq_driver->setpolicy) {
296*1da177e4SLinus Torvalds 		if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
297*1da177e4SLinus Torvalds 			*policy = CPUFREQ_POLICY_PERFORMANCE;
298*1da177e4SLinus Torvalds 			return 0;
299*1da177e4SLinus Torvalds 		} else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
300*1da177e4SLinus Torvalds 			*policy = CPUFREQ_POLICY_POWERSAVE;
301*1da177e4SLinus Torvalds 			return 0;
302*1da177e4SLinus Torvalds 		}
303*1da177e4SLinus Torvalds 		return -EINVAL;
304*1da177e4SLinus Torvalds 	} else {
305*1da177e4SLinus Torvalds 		struct cpufreq_governor *t;
306*1da177e4SLinus Torvalds 		down(&cpufreq_governor_sem);
307*1da177e4SLinus Torvalds 		if (!cpufreq_driver || !cpufreq_driver->target)
308*1da177e4SLinus Torvalds 			goto out;
309*1da177e4SLinus Torvalds 		list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
310*1da177e4SLinus Torvalds 			if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
311*1da177e4SLinus Torvalds 				*governor = t;
312*1da177e4SLinus Torvalds 				up(&cpufreq_governor_sem);
313*1da177e4SLinus Torvalds 				return 0;
314*1da177e4SLinus Torvalds 			}
315*1da177e4SLinus Torvalds 		}
316*1da177e4SLinus Torvalds 	out:
317*1da177e4SLinus Torvalds 		up(&cpufreq_governor_sem);
318*1da177e4SLinus Torvalds 	}
319*1da177e4SLinus Torvalds 	return -EINVAL;
320*1da177e4SLinus Torvalds }
321*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_parse_governor);
322*1da177e4SLinus Torvalds 
323*1da177e4SLinus Torvalds 
324*1da177e4SLinus Torvalds /* drivers/base/cpu.c */
325*1da177e4SLinus Torvalds extern struct sysdev_class cpu_sysdev_class;
326*1da177e4SLinus Torvalds 
327*1da177e4SLinus Torvalds 
328*1da177e4SLinus Torvalds /**
329*1da177e4SLinus Torvalds  * cpufreq_per_cpu_attr_read() / show_##file_name() - print out cpufreq information
330*1da177e4SLinus Torvalds  *
331*1da177e4SLinus Torvalds  * Write out information from cpufreq_driver->policy[cpu]; object must be
332*1da177e4SLinus Torvalds  * "unsigned int".
333*1da177e4SLinus Torvalds  */
334*1da177e4SLinus Torvalds 
335*1da177e4SLinus Torvalds #define show_one(file_name, object)		 			\
336*1da177e4SLinus Torvalds static ssize_t show_##file_name 					\
337*1da177e4SLinus Torvalds (struct cpufreq_policy * policy, char *buf)				\
338*1da177e4SLinus Torvalds {									\
339*1da177e4SLinus Torvalds 	return sprintf (buf, "%u\n", policy->object);			\
340*1da177e4SLinus Torvalds }
341*1da177e4SLinus Torvalds 
342*1da177e4SLinus Torvalds show_one(cpuinfo_min_freq, cpuinfo.min_freq);
343*1da177e4SLinus Torvalds show_one(cpuinfo_max_freq, cpuinfo.max_freq);
344*1da177e4SLinus Torvalds show_one(scaling_min_freq, min);
345*1da177e4SLinus Torvalds show_one(scaling_max_freq, max);
346*1da177e4SLinus Torvalds show_one(scaling_cur_freq, cur);
347*1da177e4SLinus Torvalds 
348*1da177e4SLinus Torvalds /**
349*1da177e4SLinus Torvalds  * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
350*1da177e4SLinus Torvalds  */
351*1da177e4SLinus Torvalds #define store_one(file_name, object)			\
352*1da177e4SLinus Torvalds static ssize_t store_##file_name					\
353*1da177e4SLinus Torvalds (struct cpufreq_policy * policy, const char *buf, size_t count)		\
354*1da177e4SLinus Torvalds {									\
355*1da177e4SLinus Torvalds 	unsigned int ret = -EINVAL;					\
356*1da177e4SLinus Torvalds 	struct cpufreq_policy new_policy;				\
357*1da177e4SLinus Torvalds 									\
358*1da177e4SLinus Torvalds 	ret = cpufreq_get_policy(&new_policy, policy->cpu);		\
359*1da177e4SLinus Torvalds 	if (ret)							\
360*1da177e4SLinus Torvalds 		return -EINVAL;						\
361*1da177e4SLinus Torvalds 									\
362*1da177e4SLinus Torvalds 	ret = sscanf (buf, "%u", &new_policy.object);			\
363*1da177e4SLinus Torvalds 	if (ret != 1)							\
364*1da177e4SLinus Torvalds 		return -EINVAL;						\
365*1da177e4SLinus Torvalds 									\
366*1da177e4SLinus Torvalds 	ret = cpufreq_set_policy(&new_policy);				\
367*1da177e4SLinus Torvalds 									\
368*1da177e4SLinus Torvalds 	return ret ? ret : count;					\
369*1da177e4SLinus Torvalds }
370*1da177e4SLinus Torvalds 
371*1da177e4SLinus Torvalds store_one(scaling_min_freq,min);
372*1da177e4SLinus Torvalds store_one(scaling_max_freq,max);
373*1da177e4SLinus Torvalds 
374*1da177e4SLinus Torvalds /**
375*1da177e4SLinus Torvalds  * show_cpuinfo_cur_freq - current CPU frequency as detected by hardware
376*1da177e4SLinus Torvalds  */
377*1da177e4SLinus Torvalds static ssize_t show_cpuinfo_cur_freq (struct cpufreq_policy * policy, char *buf)
378*1da177e4SLinus Torvalds {
379*1da177e4SLinus Torvalds 	unsigned int cur_freq = cpufreq_get(policy->cpu);
380*1da177e4SLinus Torvalds 	if (!cur_freq)
381*1da177e4SLinus Torvalds 		return sprintf(buf, "<unknown>");
382*1da177e4SLinus Torvalds 	return sprintf(buf, "%u\n", cur_freq);
383*1da177e4SLinus Torvalds }
384*1da177e4SLinus Torvalds 
385*1da177e4SLinus Torvalds 
386*1da177e4SLinus Torvalds /**
387*1da177e4SLinus Torvalds  * show_scaling_governor - show the current policy for the specified CPU
388*1da177e4SLinus Torvalds  */
389*1da177e4SLinus Torvalds static ssize_t show_scaling_governor (struct cpufreq_policy * policy, char *buf)
390*1da177e4SLinus Torvalds {
391*1da177e4SLinus Torvalds 	if(policy->policy == CPUFREQ_POLICY_POWERSAVE)
392*1da177e4SLinus Torvalds 		return sprintf(buf, "powersave\n");
393*1da177e4SLinus Torvalds 	else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE)
394*1da177e4SLinus Torvalds 		return sprintf(buf, "performance\n");
395*1da177e4SLinus Torvalds 	else if (policy->governor)
396*1da177e4SLinus Torvalds 		return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", policy->governor->name);
397*1da177e4SLinus Torvalds 	return -EINVAL;
398*1da177e4SLinus Torvalds }
399*1da177e4SLinus Torvalds 
400*1da177e4SLinus Torvalds 
401*1da177e4SLinus Torvalds /**
402*1da177e4SLinus Torvalds  * store_scaling_governor - store policy for the specified CPU
403*1da177e4SLinus Torvalds  */
404*1da177e4SLinus Torvalds static ssize_t store_scaling_governor (struct cpufreq_policy * policy,
405*1da177e4SLinus Torvalds 				       const char *buf, size_t count)
406*1da177e4SLinus Torvalds {
407*1da177e4SLinus Torvalds 	unsigned int ret = -EINVAL;
408*1da177e4SLinus Torvalds 	char	str_governor[16];
409*1da177e4SLinus Torvalds 	struct cpufreq_policy new_policy;
410*1da177e4SLinus Torvalds 
411*1da177e4SLinus Torvalds 	ret = cpufreq_get_policy(&new_policy, policy->cpu);
412*1da177e4SLinus Torvalds 	if (ret)
413*1da177e4SLinus Torvalds 		return ret;
414*1da177e4SLinus Torvalds 
415*1da177e4SLinus Torvalds 	ret = sscanf (buf, "%15s", str_governor);
416*1da177e4SLinus Torvalds 	if (ret != 1)
417*1da177e4SLinus Torvalds 		return -EINVAL;
418*1da177e4SLinus Torvalds 
419*1da177e4SLinus Torvalds 	if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor))
420*1da177e4SLinus Torvalds 		return -EINVAL;
421*1da177e4SLinus Torvalds 
422*1da177e4SLinus Torvalds 	ret = cpufreq_set_policy(&new_policy);
423*1da177e4SLinus Torvalds 
424*1da177e4SLinus Torvalds 	return ret ? ret : count;
425*1da177e4SLinus Torvalds }
426*1da177e4SLinus Torvalds 
427*1da177e4SLinus Torvalds /**
428*1da177e4SLinus Torvalds  * show_scaling_driver - show the cpufreq driver currently loaded
429*1da177e4SLinus Torvalds  */
430*1da177e4SLinus Torvalds static ssize_t show_scaling_driver (struct cpufreq_policy * policy, char *buf)
431*1da177e4SLinus Torvalds {
432*1da177e4SLinus Torvalds 	return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name);
433*1da177e4SLinus Torvalds }
434*1da177e4SLinus Torvalds 
435*1da177e4SLinus Torvalds /**
436*1da177e4SLinus Torvalds  * show_scaling_available_governors - show the available CPUfreq governors
437*1da177e4SLinus Torvalds  */
438*1da177e4SLinus Torvalds static ssize_t show_scaling_available_governors (struct cpufreq_policy * policy,
439*1da177e4SLinus Torvalds 				char *buf)
440*1da177e4SLinus Torvalds {
441*1da177e4SLinus Torvalds 	ssize_t i = 0;
442*1da177e4SLinus Torvalds 	struct cpufreq_governor *t;
443*1da177e4SLinus Torvalds 
444*1da177e4SLinus Torvalds 	if (!cpufreq_driver->target) {
445*1da177e4SLinus Torvalds 		i += sprintf(buf, "performance powersave");
446*1da177e4SLinus Torvalds 		goto out;
447*1da177e4SLinus Torvalds 	}
448*1da177e4SLinus Torvalds 
449*1da177e4SLinus Torvalds 	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
450*1da177e4SLinus Torvalds 		if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2)))
451*1da177e4SLinus Torvalds 			goto out;
452*1da177e4SLinus Torvalds 		i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name);
453*1da177e4SLinus Torvalds 	}
454*1da177e4SLinus Torvalds  out:
455*1da177e4SLinus Torvalds 	i += sprintf(&buf[i], "\n");
456*1da177e4SLinus Torvalds 	return i;
457*1da177e4SLinus Torvalds }
458*1da177e4SLinus Torvalds /**
459*1da177e4SLinus Torvalds  * show_affected_cpus - show the CPUs affected by each transition
460*1da177e4SLinus Torvalds  */
461*1da177e4SLinus Torvalds static ssize_t show_affected_cpus (struct cpufreq_policy * policy, char *buf)
462*1da177e4SLinus Torvalds {
463*1da177e4SLinus Torvalds 	ssize_t i = 0;
464*1da177e4SLinus Torvalds 	unsigned int cpu;
465*1da177e4SLinus Torvalds 
466*1da177e4SLinus Torvalds 	for_each_cpu_mask(cpu, policy->cpus) {
467*1da177e4SLinus Torvalds 		if (i)
468*1da177e4SLinus Torvalds 			i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), " ");
469*1da177e4SLinus Torvalds 		i += scnprintf(&buf[i], (PAGE_SIZE - i - 2), "%u", cpu);
470*1da177e4SLinus Torvalds 		if (i >= (PAGE_SIZE - 5))
471*1da177e4SLinus Torvalds 		    break;
472*1da177e4SLinus Torvalds 	}
473*1da177e4SLinus Torvalds 	i += sprintf(&buf[i], "\n");
474*1da177e4SLinus Torvalds 	return i;
475*1da177e4SLinus Torvalds }
476*1da177e4SLinus Torvalds 
477*1da177e4SLinus Torvalds 
478*1da177e4SLinus Torvalds #define define_one_ro(_name) \
479*1da177e4SLinus Torvalds static struct freq_attr _name = \
480*1da177e4SLinus Torvalds __ATTR(_name, 0444, show_##_name, NULL)
481*1da177e4SLinus Torvalds 
482*1da177e4SLinus Torvalds #define define_one_ro0400(_name) \
483*1da177e4SLinus Torvalds static struct freq_attr _name = \
484*1da177e4SLinus Torvalds __ATTR(_name, 0400, show_##_name, NULL)
485*1da177e4SLinus Torvalds 
486*1da177e4SLinus Torvalds #define define_one_rw(_name) \
487*1da177e4SLinus Torvalds static struct freq_attr _name = \
488*1da177e4SLinus Torvalds __ATTR(_name, 0644, show_##_name, store_##_name)
489*1da177e4SLinus Torvalds 
490*1da177e4SLinus Torvalds define_one_ro0400(cpuinfo_cur_freq);
491*1da177e4SLinus Torvalds define_one_ro(cpuinfo_min_freq);
492*1da177e4SLinus Torvalds define_one_ro(cpuinfo_max_freq);
493*1da177e4SLinus Torvalds define_one_ro(scaling_available_governors);
494*1da177e4SLinus Torvalds define_one_ro(scaling_driver);
495*1da177e4SLinus Torvalds define_one_ro(scaling_cur_freq);
496*1da177e4SLinus Torvalds define_one_ro(affected_cpus);
497*1da177e4SLinus Torvalds define_one_rw(scaling_min_freq);
498*1da177e4SLinus Torvalds define_one_rw(scaling_max_freq);
499*1da177e4SLinus Torvalds define_one_rw(scaling_governor);
500*1da177e4SLinus Torvalds 
501*1da177e4SLinus Torvalds static struct attribute * default_attrs[] = {
502*1da177e4SLinus Torvalds 	&cpuinfo_min_freq.attr,
503*1da177e4SLinus Torvalds 	&cpuinfo_max_freq.attr,
504*1da177e4SLinus Torvalds 	&scaling_min_freq.attr,
505*1da177e4SLinus Torvalds 	&scaling_max_freq.attr,
506*1da177e4SLinus Torvalds 	&affected_cpus.attr,
507*1da177e4SLinus Torvalds 	&scaling_governor.attr,
508*1da177e4SLinus Torvalds 	&scaling_driver.attr,
509*1da177e4SLinus Torvalds 	&scaling_available_governors.attr,
510*1da177e4SLinus Torvalds 	NULL
511*1da177e4SLinus Torvalds };
512*1da177e4SLinus Torvalds 
513*1da177e4SLinus Torvalds #define to_policy(k) container_of(k,struct cpufreq_policy,kobj)
514*1da177e4SLinus Torvalds #define to_attr(a) container_of(a,struct freq_attr,attr)
515*1da177e4SLinus Torvalds 
516*1da177e4SLinus Torvalds static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
517*1da177e4SLinus Torvalds {
518*1da177e4SLinus Torvalds 	struct cpufreq_policy * policy = to_policy(kobj);
519*1da177e4SLinus Torvalds 	struct freq_attr * fattr = to_attr(attr);
520*1da177e4SLinus Torvalds 	ssize_t ret;
521*1da177e4SLinus Torvalds 	policy = cpufreq_cpu_get(policy->cpu);
522*1da177e4SLinus Torvalds 	if (!policy)
523*1da177e4SLinus Torvalds 		return -EINVAL;
524*1da177e4SLinus Torvalds 	ret = fattr->show ? fattr->show(policy,buf) : 0;
525*1da177e4SLinus Torvalds 	cpufreq_cpu_put(policy);
526*1da177e4SLinus Torvalds 	return ret;
527*1da177e4SLinus Torvalds }
528*1da177e4SLinus Torvalds 
529*1da177e4SLinus Torvalds static ssize_t store(struct kobject * kobj, struct attribute * attr,
530*1da177e4SLinus Torvalds 		     const char * buf, size_t count)
531*1da177e4SLinus Torvalds {
532*1da177e4SLinus Torvalds 	struct cpufreq_policy * policy = to_policy(kobj);
533*1da177e4SLinus Torvalds 	struct freq_attr * fattr = to_attr(attr);
534*1da177e4SLinus Torvalds 	ssize_t ret;
535*1da177e4SLinus Torvalds 	policy = cpufreq_cpu_get(policy->cpu);
536*1da177e4SLinus Torvalds 	if (!policy)
537*1da177e4SLinus Torvalds 		return -EINVAL;
538*1da177e4SLinus Torvalds 	ret = fattr->store ? fattr->store(policy,buf,count) : 0;
539*1da177e4SLinus Torvalds 	cpufreq_cpu_put(policy);
540*1da177e4SLinus Torvalds 	return ret;
541*1da177e4SLinus Torvalds }
542*1da177e4SLinus Torvalds 
543*1da177e4SLinus Torvalds static void cpufreq_sysfs_release(struct kobject * kobj)
544*1da177e4SLinus Torvalds {
545*1da177e4SLinus Torvalds 	struct cpufreq_policy * policy = to_policy(kobj);
546*1da177e4SLinus Torvalds 	dprintk("last reference is dropped\n");
547*1da177e4SLinus Torvalds 	complete(&policy->kobj_unregister);
548*1da177e4SLinus Torvalds }
549*1da177e4SLinus Torvalds 
550*1da177e4SLinus Torvalds static struct sysfs_ops sysfs_ops = {
551*1da177e4SLinus Torvalds 	.show	= show,
552*1da177e4SLinus Torvalds 	.store	= store,
553*1da177e4SLinus Torvalds };
554*1da177e4SLinus Torvalds 
555*1da177e4SLinus Torvalds static struct kobj_type ktype_cpufreq = {
556*1da177e4SLinus Torvalds 	.sysfs_ops	= &sysfs_ops,
557*1da177e4SLinus Torvalds 	.default_attrs	= default_attrs,
558*1da177e4SLinus Torvalds 	.release	= cpufreq_sysfs_release,
559*1da177e4SLinus Torvalds };
560*1da177e4SLinus Torvalds 
561*1da177e4SLinus Torvalds 
562*1da177e4SLinus Torvalds /**
563*1da177e4SLinus Torvalds  * cpufreq_add_dev - add a CPU device
564*1da177e4SLinus Torvalds  *
565*1da177e4SLinus Torvalds  * Adds the cpufreq interface for a CPU device.
566*1da177e4SLinus Torvalds  */
567*1da177e4SLinus Torvalds static int cpufreq_add_dev (struct sys_device * sys_dev)
568*1da177e4SLinus Torvalds {
569*1da177e4SLinus Torvalds 	unsigned int cpu = sys_dev->id;
570*1da177e4SLinus Torvalds 	int ret = 0;
571*1da177e4SLinus Torvalds 	struct cpufreq_policy new_policy;
572*1da177e4SLinus Torvalds 	struct cpufreq_policy *policy;
573*1da177e4SLinus Torvalds 	struct freq_attr **drv_attr;
574*1da177e4SLinus Torvalds 	unsigned long flags;
575*1da177e4SLinus Torvalds 	unsigned int j;
576*1da177e4SLinus Torvalds 
577*1da177e4SLinus Torvalds 	cpufreq_debug_disable_ratelimit();
578*1da177e4SLinus Torvalds 	dprintk("adding CPU %u\n", cpu);
579*1da177e4SLinus Torvalds 
580*1da177e4SLinus Torvalds #ifdef CONFIG_SMP
581*1da177e4SLinus Torvalds 	/* check whether a different CPU already registered this
582*1da177e4SLinus Torvalds 	 * CPU because it is in the same boat. */
583*1da177e4SLinus Torvalds 	policy = cpufreq_cpu_get(cpu);
584*1da177e4SLinus Torvalds 	if (unlikely(policy)) {
585*1da177e4SLinus Torvalds 		cpu_sys_devices[cpu] = sys_dev;
586*1da177e4SLinus Torvalds 		dprintk("CPU already managed, adding link\n");
587*1da177e4SLinus Torvalds 		sysfs_create_link(&sys_dev->kobj, &policy->kobj, "cpufreq");
588*1da177e4SLinus Torvalds 		cpufreq_debug_enable_ratelimit();
589*1da177e4SLinus Torvalds 		return 0;
590*1da177e4SLinus Torvalds 	}
591*1da177e4SLinus Torvalds #endif
592*1da177e4SLinus Torvalds 
593*1da177e4SLinus Torvalds 	if (!try_module_get(cpufreq_driver->owner)) {
594*1da177e4SLinus Torvalds 		ret = -EINVAL;
595*1da177e4SLinus Torvalds 		goto module_out;
596*1da177e4SLinus Torvalds 	}
597*1da177e4SLinus Torvalds 
598*1da177e4SLinus Torvalds 	policy = kmalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
599*1da177e4SLinus Torvalds 	if (!policy) {
600*1da177e4SLinus Torvalds 		ret = -ENOMEM;
601*1da177e4SLinus Torvalds 		goto nomem_out;
602*1da177e4SLinus Torvalds 	}
603*1da177e4SLinus Torvalds 	memset(policy, 0, sizeof(struct cpufreq_policy));
604*1da177e4SLinus Torvalds 
605*1da177e4SLinus Torvalds 	policy->cpu = cpu;
606*1da177e4SLinus Torvalds 	policy->cpus = cpumask_of_cpu(cpu);
607*1da177e4SLinus Torvalds 
608*1da177e4SLinus Torvalds 	init_MUTEX_LOCKED(&policy->lock);
609*1da177e4SLinus Torvalds 	init_completion(&policy->kobj_unregister);
610*1da177e4SLinus Torvalds 	INIT_WORK(&policy->update, handle_update, (void *)(long)cpu);
611*1da177e4SLinus Torvalds 
612*1da177e4SLinus Torvalds 	/* call driver. From then on the cpufreq must be able
613*1da177e4SLinus Torvalds 	 * to accept all calls to ->verify and ->setpolicy for this CPU
614*1da177e4SLinus Torvalds 	 */
615*1da177e4SLinus Torvalds 	ret = cpufreq_driver->init(policy);
616*1da177e4SLinus Torvalds 	if (ret) {
617*1da177e4SLinus Torvalds 		dprintk("initialization failed\n");
618*1da177e4SLinus Torvalds 		goto err_out;
619*1da177e4SLinus Torvalds 	}
620*1da177e4SLinus Torvalds 
621*1da177e4SLinus Torvalds 	memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
622*1da177e4SLinus Torvalds 
623*1da177e4SLinus Torvalds 	/* prepare interface data */
624*1da177e4SLinus Torvalds 	policy->kobj.parent = &sys_dev->kobj;
625*1da177e4SLinus Torvalds 	policy->kobj.ktype = &ktype_cpufreq;
626*1da177e4SLinus Torvalds 	strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
627*1da177e4SLinus Torvalds 
628*1da177e4SLinus Torvalds 	ret = kobject_register(&policy->kobj);
629*1da177e4SLinus Torvalds 	if (ret)
630*1da177e4SLinus Torvalds 		goto err_out;
631*1da177e4SLinus Torvalds 
632*1da177e4SLinus Torvalds 	/* set up files for this cpu device */
633*1da177e4SLinus Torvalds 	drv_attr = cpufreq_driver->attr;
634*1da177e4SLinus Torvalds 	while ((drv_attr) && (*drv_attr)) {
635*1da177e4SLinus Torvalds 		sysfs_create_file(&policy->kobj, &((*drv_attr)->attr));
636*1da177e4SLinus Torvalds 		drv_attr++;
637*1da177e4SLinus Torvalds 	}
638*1da177e4SLinus Torvalds 	if (cpufreq_driver->get)
639*1da177e4SLinus Torvalds 		sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr);
640*1da177e4SLinus Torvalds 	if (cpufreq_driver->target)
641*1da177e4SLinus Torvalds 		sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
642*1da177e4SLinus Torvalds 
643*1da177e4SLinus Torvalds 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
644*1da177e4SLinus Torvalds 	for_each_cpu_mask(j, policy->cpus)
645*1da177e4SLinus Torvalds 		cpufreq_cpu_data[j] = policy;
646*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
647*1da177e4SLinus Torvalds 	policy->governor = NULL; /* to assure that the starting sequence is
648*1da177e4SLinus Torvalds 				  * run in cpufreq_set_policy */
649*1da177e4SLinus Torvalds 	up(&policy->lock);
650*1da177e4SLinus Torvalds 
651*1da177e4SLinus Torvalds 	/* set default policy */
652*1da177e4SLinus Torvalds 
653*1da177e4SLinus Torvalds 	ret = cpufreq_set_policy(&new_policy);
654*1da177e4SLinus Torvalds 	if (ret) {
655*1da177e4SLinus Torvalds 		dprintk("setting policy failed\n");
656*1da177e4SLinus Torvalds 		goto err_out_unregister;
657*1da177e4SLinus Torvalds 	}
658*1da177e4SLinus Torvalds 
659*1da177e4SLinus Torvalds 	module_put(cpufreq_driver->owner);
660*1da177e4SLinus Torvalds 	cpu_sys_devices[cpu] = sys_dev;
661*1da177e4SLinus Torvalds 	dprintk("initialization complete\n");
662*1da177e4SLinus Torvalds 	cpufreq_debug_enable_ratelimit();
663*1da177e4SLinus Torvalds 
664*1da177e4SLinus Torvalds 	return 0;
665*1da177e4SLinus Torvalds 
666*1da177e4SLinus Torvalds 
667*1da177e4SLinus Torvalds err_out_unregister:
668*1da177e4SLinus Torvalds 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
669*1da177e4SLinus Torvalds 	for_each_cpu_mask(j, policy->cpus)
670*1da177e4SLinus Torvalds 		cpufreq_cpu_data[j] = NULL;
671*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
672*1da177e4SLinus Torvalds 
673*1da177e4SLinus Torvalds 	kobject_unregister(&policy->kobj);
674*1da177e4SLinus Torvalds 	wait_for_completion(&policy->kobj_unregister);
675*1da177e4SLinus Torvalds 
676*1da177e4SLinus Torvalds err_out:
677*1da177e4SLinus Torvalds 	kfree(policy);
678*1da177e4SLinus Torvalds 
679*1da177e4SLinus Torvalds nomem_out:
680*1da177e4SLinus Torvalds 	module_put(cpufreq_driver->owner);
681*1da177e4SLinus Torvalds  module_out:
682*1da177e4SLinus Torvalds 	cpufreq_debug_enable_ratelimit();
683*1da177e4SLinus Torvalds 	return ret;
684*1da177e4SLinus Torvalds }
685*1da177e4SLinus Torvalds 
686*1da177e4SLinus Torvalds 
687*1da177e4SLinus Torvalds /**
688*1da177e4SLinus Torvalds  * cpufreq_remove_dev - remove a CPU device
689*1da177e4SLinus Torvalds  *
690*1da177e4SLinus Torvalds  * Removes the cpufreq interface for a CPU device.
691*1da177e4SLinus Torvalds  */
692*1da177e4SLinus Torvalds static int cpufreq_remove_dev (struct sys_device * sys_dev)
693*1da177e4SLinus Torvalds {
694*1da177e4SLinus Torvalds 	unsigned int cpu = sys_dev->id;
695*1da177e4SLinus Torvalds 	unsigned long flags;
696*1da177e4SLinus Torvalds 	struct cpufreq_policy *data;
697*1da177e4SLinus Torvalds #ifdef CONFIG_SMP
698*1da177e4SLinus Torvalds 	unsigned int j;
699*1da177e4SLinus Torvalds #endif
700*1da177e4SLinus Torvalds 
701*1da177e4SLinus Torvalds 	cpufreq_debug_disable_ratelimit();
702*1da177e4SLinus Torvalds 	dprintk("unregistering CPU %u\n", cpu);
703*1da177e4SLinus Torvalds 
704*1da177e4SLinus Torvalds 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
705*1da177e4SLinus Torvalds 	data = cpufreq_cpu_data[cpu];
706*1da177e4SLinus Torvalds 
707*1da177e4SLinus Torvalds 	if (!data) {
708*1da177e4SLinus Torvalds 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
709*1da177e4SLinus Torvalds 		cpu_sys_devices[cpu] = NULL;
710*1da177e4SLinus Torvalds 		cpufreq_debug_enable_ratelimit();
711*1da177e4SLinus Torvalds 		return -EINVAL;
712*1da177e4SLinus Torvalds 	}
713*1da177e4SLinus Torvalds 	cpufreq_cpu_data[cpu] = NULL;
714*1da177e4SLinus Torvalds 
715*1da177e4SLinus Torvalds 
716*1da177e4SLinus Torvalds #ifdef CONFIG_SMP
717*1da177e4SLinus Torvalds 	/* if this isn't the CPU which is the parent of the kobj, we
718*1da177e4SLinus Torvalds 	 * only need to unlink, put and exit
719*1da177e4SLinus Torvalds 	 */
720*1da177e4SLinus Torvalds 	if (unlikely(cpu != data->cpu)) {
721*1da177e4SLinus Torvalds 		dprintk("removing link\n");
722*1da177e4SLinus Torvalds 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
723*1da177e4SLinus Torvalds 		sysfs_remove_link(&sys_dev->kobj, "cpufreq");
724*1da177e4SLinus Torvalds 		cpu_sys_devices[cpu] = NULL;
725*1da177e4SLinus Torvalds 		cpufreq_cpu_put(data);
726*1da177e4SLinus Torvalds 		cpufreq_debug_enable_ratelimit();
727*1da177e4SLinus Torvalds 		return 0;
728*1da177e4SLinus Torvalds 	}
729*1da177e4SLinus Torvalds #endif
730*1da177e4SLinus Torvalds 
731*1da177e4SLinus Torvalds 	cpu_sys_devices[cpu] = NULL;
732*1da177e4SLinus Torvalds 
733*1da177e4SLinus Torvalds 	if (!kobject_get(&data->kobj)) {
734*1da177e4SLinus Torvalds 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
735*1da177e4SLinus Torvalds 		cpufreq_debug_enable_ratelimit();
736*1da177e4SLinus Torvalds  		return -EFAULT;
737*1da177e4SLinus Torvalds 	}
738*1da177e4SLinus Torvalds 
739*1da177e4SLinus Torvalds #ifdef CONFIG_SMP
740*1da177e4SLinus Torvalds 	/* if we have other CPUs still registered, we need to unlink them,
741*1da177e4SLinus Torvalds 	 * or else wait_for_completion below will lock up. Clean the
742*1da177e4SLinus Torvalds 	 * cpufreq_cpu_data[] while holding the lock, and remove the sysfs
743*1da177e4SLinus Torvalds 	 * links afterwards.
744*1da177e4SLinus Torvalds 	 */
745*1da177e4SLinus Torvalds 	if (unlikely(cpus_weight(data->cpus) > 1)) {
746*1da177e4SLinus Torvalds 		for_each_cpu_mask(j, data->cpus) {
747*1da177e4SLinus Torvalds 			if (j == cpu)
748*1da177e4SLinus Torvalds 				continue;
749*1da177e4SLinus Torvalds 			cpufreq_cpu_data[j] = NULL;
750*1da177e4SLinus Torvalds 		}
751*1da177e4SLinus Torvalds 	}
752*1da177e4SLinus Torvalds 
753*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
754*1da177e4SLinus Torvalds 
755*1da177e4SLinus Torvalds 	if (unlikely(cpus_weight(data->cpus) > 1)) {
756*1da177e4SLinus Torvalds 		for_each_cpu_mask(j, data->cpus) {
757*1da177e4SLinus Torvalds 			if (j == cpu)
758*1da177e4SLinus Torvalds 				continue;
759*1da177e4SLinus Torvalds 			dprintk("removing link for cpu %u\n", j);
760*1da177e4SLinus Torvalds 			sysfs_remove_link(&cpu_sys_devices[j]->kobj, "cpufreq");
761*1da177e4SLinus Torvalds 			cpufreq_cpu_put(data);
762*1da177e4SLinus Torvalds 		}
763*1da177e4SLinus Torvalds 	}
764*1da177e4SLinus Torvalds #else
765*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
766*1da177e4SLinus Torvalds #endif
767*1da177e4SLinus Torvalds 
768*1da177e4SLinus Torvalds 	down(&data->lock);
769*1da177e4SLinus Torvalds 	if (cpufreq_driver->target)
770*1da177e4SLinus Torvalds 		__cpufreq_governor(data, CPUFREQ_GOV_STOP);
771*1da177e4SLinus Torvalds 	cpufreq_driver->target = NULL;
772*1da177e4SLinus Torvalds 	up(&data->lock);
773*1da177e4SLinus Torvalds 
774*1da177e4SLinus Torvalds 	kobject_unregister(&data->kobj);
775*1da177e4SLinus Torvalds 
776*1da177e4SLinus Torvalds 	kobject_put(&data->kobj);
777*1da177e4SLinus Torvalds 
778*1da177e4SLinus Torvalds 	/* we need to make sure that the underlying kobj is actually
779*1da177e4SLinus Torvalds 	 * not referenced anymore by anybody before we proceed with
780*1da177e4SLinus Torvalds 	 * unloading.
781*1da177e4SLinus Torvalds 	 */
782*1da177e4SLinus Torvalds 	dprintk("waiting for dropping of refcount\n");
783*1da177e4SLinus Torvalds 	wait_for_completion(&data->kobj_unregister);
784*1da177e4SLinus Torvalds 	dprintk("wait complete\n");
785*1da177e4SLinus Torvalds 
786*1da177e4SLinus Torvalds 	if (cpufreq_driver->exit)
787*1da177e4SLinus Torvalds 		cpufreq_driver->exit(data);
788*1da177e4SLinus Torvalds 
789*1da177e4SLinus Torvalds 	kfree(data);
790*1da177e4SLinus Torvalds 
791*1da177e4SLinus Torvalds 	cpufreq_debug_enable_ratelimit();
792*1da177e4SLinus Torvalds 
793*1da177e4SLinus Torvalds 	return 0;
794*1da177e4SLinus Torvalds }
795*1da177e4SLinus Torvalds 
796*1da177e4SLinus Torvalds 
797*1da177e4SLinus Torvalds static void handle_update(void *data)
798*1da177e4SLinus Torvalds {
799*1da177e4SLinus Torvalds 	unsigned int cpu = (unsigned int)(long)data;
800*1da177e4SLinus Torvalds 	dprintk("handle_update for cpu %u called\n", cpu);
801*1da177e4SLinus Torvalds 	cpufreq_update_policy(cpu);
802*1da177e4SLinus Torvalds }
803*1da177e4SLinus Torvalds 
804*1da177e4SLinus Torvalds /**
805*1da177e4SLinus Torvalds  *	cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble.
806*1da177e4SLinus Torvalds  *	@cpu: cpu number
807*1da177e4SLinus Torvalds  *	@old_freq: CPU frequency the kernel thinks the CPU runs at
808*1da177e4SLinus Torvalds  *	@new_freq: CPU frequency the CPU actually runs at
809*1da177e4SLinus Torvalds  *
810*1da177e4SLinus Torvalds  *	We adjust to current frequency first, and need to clean up later. So either call
811*1da177e4SLinus Torvalds  *	to cpufreq_update_policy() or schedule handle_update()).
812*1da177e4SLinus Torvalds  */
813*1da177e4SLinus Torvalds static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigned int new_freq)
814*1da177e4SLinus Torvalds {
815*1da177e4SLinus Torvalds 	struct cpufreq_freqs freqs;
816*1da177e4SLinus Torvalds 
817*1da177e4SLinus Torvalds 	printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing "
818*1da177e4SLinus Torvalds 	       "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
819*1da177e4SLinus Torvalds 
820*1da177e4SLinus Torvalds 	freqs.cpu = cpu;
821*1da177e4SLinus Torvalds 	freqs.old = old_freq;
822*1da177e4SLinus Torvalds 	freqs.new = new_freq;
823*1da177e4SLinus Torvalds 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
824*1da177e4SLinus Torvalds 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
825*1da177e4SLinus Torvalds }
826*1da177e4SLinus Torvalds 
827*1da177e4SLinus Torvalds 
828*1da177e4SLinus Torvalds /**
829*1da177e4SLinus Torvalds  * cpufreq_get - get the current CPU frequency (in kHz)
830*1da177e4SLinus Torvalds  * @cpu: CPU number
831*1da177e4SLinus Torvalds  *
832*1da177e4SLinus Torvalds  * Get the CPU current (static) CPU frequency
833*1da177e4SLinus Torvalds  */
834*1da177e4SLinus Torvalds unsigned int cpufreq_get(unsigned int cpu)
835*1da177e4SLinus Torvalds {
836*1da177e4SLinus Torvalds 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
837*1da177e4SLinus Torvalds 	unsigned int ret = 0;
838*1da177e4SLinus Torvalds 
839*1da177e4SLinus Torvalds 	if (!policy)
840*1da177e4SLinus Torvalds 		return 0;
841*1da177e4SLinus Torvalds 
842*1da177e4SLinus Torvalds 	if (!cpufreq_driver->get)
843*1da177e4SLinus Torvalds 		goto out;
844*1da177e4SLinus Torvalds 
845*1da177e4SLinus Torvalds 	down(&policy->lock);
846*1da177e4SLinus Torvalds 
847*1da177e4SLinus Torvalds 	ret = cpufreq_driver->get(cpu);
848*1da177e4SLinus Torvalds 
849*1da177e4SLinus Torvalds 	if (ret && policy->cur && !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS))
850*1da177e4SLinus Torvalds 	{
851*1da177e4SLinus Torvalds 		/* verify no discrepancy between actual and saved value exists */
852*1da177e4SLinus Torvalds 		if (unlikely(ret != policy->cur)) {
853*1da177e4SLinus Torvalds 			cpufreq_out_of_sync(cpu, policy->cur, ret);
854*1da177e4SLinus Torvalds 			schedule_work(&policy->update);
855*1da177e4SLinus Torvalds 		}
856*1da177e4SLinus Torvalds 	}
857*1da177e4SLinus Torvalds 
858*1da177e4SLinus Torvalds 	up(&policy->lock);
859*1da177e4SLinus Torvalds 
860*1da177e4SLinus Torvalds  out:
861*1da177e4SLinus Torvalds 	cpufreq_cpu_put(policy);
862*1da177e4SLinus Torvalds 
863*1da177e4SLinus Torvalds 	return (ret);
864*1da177e4SLinus Torvalds }
865*1da177e4SLinus Torvalds EXPORT_SYMBOL(cpufreq_get);
866*1da177e4SLinus Torvalds 
867*1da177e4SLinus Torvalds 
868*1da177e4SLinus Torvalds /**
869*1da177e4SLinus Torvalds  *	cpufreq_resume -  restore proper CPU frequency handling after resume
870*1da177e4SLinus Torvalds  *
871*1da177e4SLinus Torvalds  *	1.) resume CPUfreq hardware support (cpufreq_driver->resume())
872*1da177e4SLinus Torvalds  *	2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync
873*1da177e4SLinus Torvalds  *	3.) schedule call cpufreq_update_policy() ASAP as interrupts are restored.
874*1da177e4SLinus Torvalds  */
875*1da177e4SLinus Torvalds static int cpufreq_resume(struct sys_device * sysdev)
876*1da177e4SLinus Torvalds {
877*1da177e4SLinus Torvalds 	int cpu = sysdev->id;
878*1da177e4SLinus Torvalds 	unsigned int ret = 0;
879*1da177e4SLinus Torvalds 	struct cpufreq_policy *cpu_policy;
880*1da177e4SLinus Torvalds 
881*1da177e4SLinus Torvalds 	dprintk("resuming cpu %u\n", cpu);
882*1da177e4SLinus Torvalds 
883*1da177e4SLinus Torvalds 	if (!cpu_online(cpu))
884*1da177e4SLinus Torvalds 		return 0;
885*1da177e4SLinus Torvalds 
886*1da177e4SLinus Torvalds 	/* we may be lax here as interrupts are off. Nonetheless
887*1da177e4SLinus Torvalds 	 * we need to grab the correct cpu policy, as to check
888*1da177e4SLinus Torvalds 	 * whether we really run on this CPU.
889*1da177e4SLinus Torvalds 	 */
890*1da177e4SLinus Torvalds 
891*1da177e4SLinus Torvalds 	cpu_policy = cpufreq_cpu_get(cpu);
892*1da177e4SLinus Torvalds 	if (!cpu_policy)
893*1da177e4SLinus Torvalds 		return -EINVAL;
894*1da177e4SLinus Torvalds 
895*1da177e4SLinus Torvalds 	/* only handle each CPU group once */
896*1da177e4SLinus Torvalds 	if (unlikely(cpu_policy->cpu != cpu)) {
897*1da177e4SLinus Torvalds 		cpufreq_cpu_put(cpu_policy);
898*1da177e4SLinus Torvalds 		return 0;
899*1da177e4SLinus Torvalds 	}
900*1da177e4SLinus Torvalds 
901*1da177e4SLinus Torvalds 	if (cpufreq_driver->resume) {
902*1da177e4SLinus Torvalds 		ret = cpufreq_driver->resume(cpu_policy);
903*1da177e4SLinus Torvalds 		if (ret) {
904*1da177e4SLinus Torvalds 			printk(KERN_ERR "cpufreq: resume failed in ->resume "
905*1da177e4SLinus Torvalds 					"step on CPU %u\n", cpu_policy->cpu);
906*1da177e4SLinus Torvalds 			cpufreq_cpu_put(cpu_policy);
907*1da177e4SLinus Torvalds 			return ret;
908*1da177e4SLinus Torvalds 		}
909*1da177e4SLinus Torvalds 	}
910*1da177e4SLinus Torvalds 
911*1da177e4SLinus Torvalds 	if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
912*1da177e4SLinus Torvalds 		unsigned int cur_freq = 0;
913*1da177e4SLinus Torvalds 
914*1da177e4SLinus Torvalds 		if (cpufreq_driver->get)
915*1da177e4SLinus Torvalds 			cur_freq = cpufreq_driver->get(cpu_policy->cpu);
916*1da177e4SLinus Torvalds 
917*1da177e4SLinus Torvalds 		if (!cur_freq || !cpu_policy->cur) {
918*1da177e4SLinus Torvalds 			printk(KERN_ERR "cpufreq: resume failed to assert current frequency is what timing core thinks it is.\n");
919*1da177e4SLinus Torvalds 			goto out;
920*1da177e4SLinus Torvalds 		}
921*1da177e4SLinus Torvalds 
922*1da177e4SLinus Torvalds 		if (unlikely(cur_freq != cpu_policy->cur)) {
923*1da177e4SLinus Torvalds 			struct cpufreq_freqs freqs;
924*1da177e4SLinus Torvalds 
925*1da177e4SLinus Torvalds 			printk(KERN_WARNING "Warning: CPU frequency is %u, "
926*1da177e4SLinus Torvalds 			       "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur);
927*1da177e4SLinus Torvalds 
928*1da177e4SLinus Torvalds 			freqs.cpu = cpu;
929*1da177e4SLinus Torvalds 			freqs.old = cpu_policy->cur;
930*1da177e4SLinus Torvalds 			freqs.new = cur_freq;
931*1da177e4SLinus Torvalds 
932*1da177e4SLinus Torvalds 			notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_RESUMECHANGE, &freqs);
933*1da177e4SLinus Torvalds 			adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
934*1da177e4SLinus Torvalds 
935*1da177e4SLinus Torvalds 			cpu_policy->cur = cur_freq;
936*1da177e4SLinus Torvalds 		}
937*1da177e4SLinus Torvalds 	}
938*1da177e4SLinus Torvalds 
939*1da177e4SLinus Torvalds out:
940*1da177e4SLinus Torvalds 	schedule_work(&cpu_policy->update);
941*1da177e4SLinus Torvalds 	cpufreq_cpu_put(cpu_policy);
942*1da177e4SLinus Torvalds 	return ret;
943*1da177e4SLinus Torvalds }
944*1da177e4SLinus Torvalds 
945*1da177e4SLinus Torvalds static struct sysdev_driver cpufreq_sysdev_driver = {
946*1da177e4SLinus Torvalds 	.add		= cpufreq_add_dev,
947*1da177e4SLinus Torvalds 	.remove		= cpufreq_remove_dev,
948*1da177e4SLinus Torvalds 	.resume		= cpufreq_resume,
949*1da177e4SLinus Torvalds };
950*1da177e4SLinus Torvalds 
951*1da177e4SLinus Torvalds 
952*1da177e4SLinus Torvalds /*********************************************************************
953*1da177e4SLinus Torvalds  *                     NOTIFIER LISTS INTERFACE                      *
954*1da177e4SLinus Torvalds  *********************************************************************/
955*1da177e4SLinus Torvalds 
956*1da177e4SLinus Torvalds /**
957*1da177e4SLinus Torvalds  *	cpufreq_register_notifier - register a driver with cpufreq
958*1da177e4SLinus Torvalds  *	@nb: notifier function to register
959*1da177e4SLinus Torvalds  *      @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
960*1da177e4SLinus Torvalds  *
961*1da177e4SLinus Torvalds  *	Add a driver to one of two lists: either a list of drivers that
962*1da177e4SLinus Torvalds  *      are notified about clock rate changes (once before and once after
963*1da177e4SLinus Torvalds  *      the transition), or a list of drivers that are notified about
964*1da177e4SLinus Torvalds  *      changes in cpufreq policy.
965*1da177e4SLinus Torvalds  *
966*1da177e4SLinus Torvalds  *	This function may sleep, and has the same return conditions as
967*1da177e4SLinus Torvalds  *	notifier_chain_register.
968*1da177e4SLinus Torvalds  */
969*1da177e4SLinus Torvalds int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
970*1da177e4SLinus Torvalds {
971*1da177e4SLinus Torvalds 	int ret;
972*1da177e4SLinus Torvalds 
973*1da177e4SLinus Torvalds 	down_write(&cpufreq_notifier_rwsem);
974*1da177e4SLinus Torvalds 	switch (list) {
975*1da177e4SLinus Torvalds 	case CPUFREQ_TRANSITION_NOTIFIER:
976*1da177e4SLinus Torvalds 		ret = notifier_chain_register(&cpufreq_transition_notifier_list, nb);
977*1da177e4SLinus Torvalds 		break;
978*1da177e4SLinus Torvalds 	case CPUFREQ_POLICY_NOTIFIER:
979*1da177e4SLinus Torvalds 		ret = notifier_chain_register(&cpufreq_policy_notifier_list, nb);
980*1da177e4SLinus Torvalds 		break;
981*1da177e4SLinus Torvalds 	default:
982*1da177e4SLinus Torvalds 		ret = -EINVAL;
983*1da177e4SLinus Torvalds 	}
984*1da177e4SLinus Torvalds 	up_write(&cpufreq_notifier_rwsem);
985*1da177e4SLinus Torvalds 
986*1da177e4SLinus Torvalds 	return ret;
987*1da177e4SLinus Torvalds }
988*1da177e4SLinus Torvalds EXPORT_SYMBOL(cpufreq_register_notifier);
989*1da177e4SLinus Torvalds 
990*1da177e4SLinus Torvalds 
991*1da177e4SLinus Torvalds /**
992*1da177e4SLinus Torvalds  *	cpufreq_unregister_notifier - unregister a driver with cpufreq
993*1da177e4SLinus Torvalds  *	@nb: notifier block to be unregistered
994*1da177e4SLinus Torvalds  *      @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
995*1da177e4SLinus Torvalds  *
996*1da177e4SLinus Torvalds  *	Remove a driver from the CPU frequency notifier list.
997*1da177e4SLinus Torvalds  *
998*1da177e4SLinus Torvalds  *	This function may sleep, and has the same return conditions as
999*1da177e4SLinus Torvalds  *	notifier_chain_unregister.
1000*1da177e4SLinus Torvalds  */
1001*1da177e4SLinus Torvalds int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
1002*1da177e4SLinus Torvalds {
1003*1da177e4SLinus Torvalds 	int ret;
1004*1da177e4SLinus Torvalds 
1005*1da177e4SLinus Torvalds 	down_write(&cpufreq_notifier_rwsem);
1006*1da177e4SLinus Torvalds 	switch (list) {
1007*1da177e4SLinus Torvalds 	case CPUFREQ_TRANSITION_NOTIFIER:
1008*1da177e4SLinus Torvalds 		ret = notifier_chain_unregister(&cpufreq_transition_notifier_list, nb);
1009*1da177e4SLinus Torvalds 		break;
1010*1da177e4SLinus Torvalds 	case CPUFREQ_POLICY_NOTIFIER:
1011*1da177e4SLinus Torvalds 		ret = notifier_chain_unregister(&cpufreq_policy_notifier_list, nb);
1012*1da177e4SLinus Torvalds 		break;
1013*1da177e4SLinus Torvalds 	default:
1014*1da177e4SLinus Torvalds 		ret = -EINVAL;
1015*1da177e4SLinus Torvalds 	}
1016*1da177e4SLinus Torvalds 	up_write(&cpufreq_notifier_rwsem);
1017*1da177e4SLinus Torvalds 
1018*1da177e4SLinus Torvalds 	return ret;
1019*1da177e4SLinus Torvalds }
1020*1da177e4SLinus Torvalds EXPORT_SYMBOL(cpufreq_unregister_notifier);
1021*1da177e4SLinus Torvalds 
1022*1da177e4SLinus Torvalds 
1023*1da177e4SLinus Torvalds /*********************************************************************
1024*1da177e4SLinus Torvalds  *                              GOVERNORS                            *
1025*1da177e4SLinus Torvalds  *********************************************************************/
1026*1da177e4SLinus Torvalds 
1027*1da177e4SLinus Torvalds 
1028*1da177e4SLinus Torvalds int __cpufreq_driver_target(struct cpufreq_policy *policy,
1029*1da177e4SLinus Torvalds 			    unsigned int target_freq,
1030*1da177e4SLinus Torvalds 			    unsigned int relation)
1031*1da177e4SLinus Torvalds {
1032*1da177e4SLinus Torvalds 	int retval = -EINVAL;
1033*1da177e4SLinus Torvalds 	lock_cpu_hotplug();
1034*1da177e4SLinus Torvalds 	dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
1035*1da177e4SLinus Torvalds 		target_freq, relation);
1036*1da177e4SLinus Torvalds 	if (cpu_online(policy->cpu) && cpufreq_driver->target)
1037*1da177e4SLinus Torvalds 		retval = cpufreq_driver->target(policy, target_freq, relation);
1038*1da177e4SLinus Torvalds 	unlock_cpu_hotplug();
1039*1da177e4SLinus Torvalds 	return retval;
1040*1da177e4SLinus Torvalds }
1041*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
1042*1da177e4SLinus Torvalds 
1043*1da177e4SLinus Torvalds 
1044*1da177e4SLinus Torvalds int cpufreq_driver_target(struct cpufreq_policy *policy,
1045*1da177e4SLinus Torvalds 			  unsigned int target_freq,
1046*1da177e4SLinus Torvalds 			  unsigned int relation)
1047*1da177e4SLinus Torvalds {
1048*1da177e4SLinus Torvalds 	unsigned int ret;
1049*1da177e4SLinus Torvalds 
1050*1da177e4SLinus Torvalds 	policy = cpufreq_cpu_get(policy->cpu);
1051*1da177e4SLinus Torvalds 	if (!policy)
1052*1da177e4SLinus Torvalds 		return -EINVAL;
1053*1da177e4SLinus Torvalds 
1054*1da177e4SLinus Torvalds 	down(&policy->lock);
1055*1da177e4SLinus Torvalds 
1056*1da177e4SLinus Torvalds 	ret = __cpufreq_driver_target(policy, target_freq, relation);
1057*1da177e4SLinus Torvalds 
1058*1da177e4SLinus Torvalds 	up(&policy->lock);
1059*1da177e4SLinus Torvalds 
1060*1da177e4SLinus Torvalds 	cpufreq_cpu_put(policy);
1061*1da177e4SLinus Torvalds 
1062*1da177e4SLinus Torvalds 	return ret;
1063*1da177e4SLinus Torvalds }
1064*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_driver_target);
1065*1da177e4SLinus Torvalds 
1066*1da177e4SLinus Torvalds 
1067*1da177e4SLinus Torvalds static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
1068*1da177e4SLinus Torvalds {
1069*1da177e4SLinus Torvalds 	int ret = -EINVAL;
1070*1da177e4SLinus Torvalds 
1071*1da177e4SLinus Torvalds 	if (!try_module_get(policy->governor->owner))
1072*1da177e4SLinus Torvalds 		return -EINVAL;
1073*1da177e4SLinus Torvalds 
1074*1da177e4SLinus Torvalds 	dprintk("__cpufreq_governor for CPU %u, event %u\n", policy->cpu, event);
1075*1da177e4SLinus Torvalds 	ret = policy->governor->governor(policy, event);
1076*1da177e4SLinus Torvalds 
1077*1da177e4SLinus Torvalds 	/* we keep one module reference alive for each CPU governed by this CPU */
1078*1da177e4SLinus Torvalds 	if ((event != CPUFREQ_GOV_START) || ret)
1079*1da177e4SLinus Torvalds 		module_put(policy->governor->owner);
1080*1da177e4SLinus Torvalds 	if ((event == CPUFREQ_GOV_STOP) && !ret)
1081*1da177e4SLinus Torvalds 		module_put(policy->governor->owner);
1082*1da177e4SLinus Torvalds 
1083*1da177e4SLinus Torvalds 	return ret;
1084*1da177e4SLinus Torvalds }
1085*1da177e4SLinus Torvalds 
1086*1da177e4SLinus Torvalds 
1087*1da177e4SLinus Torvalds int cpufreq_governor(unsigned int cpu, unsigned int event)
1088*1da177e4SLinus Torvalds {
1089*1da177e4SLinus Torvalds 	int ret = 0;
1090*1da177e4SLinus Torvalds 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
1091*1da177e4SLinus Torvalds 
1092*1da177e4SLinus Torvalds 	if (!policy)
1093*1da177e4SLinus Torvalds 		return -EINVAL;
1094*1da177e4SLinus Torvalds 
1095*1da177e4SLinus Torvalds 	down(&policy->lock);
1096*1da177e4SLinus Torvalds 	ret = __cpufreq_governor(policy, event);
1097*1da177e4SLinus Torvalds 	up(&policy->lock);
1098*1da177e4SLinus Torvalds 
1099*1da177e4SLinus Torvalds 	cpufreq_cpu_put(policy);
1100*1da177e4SLinus Torvalds 
1101*1da177e4SLinus Torvalds 	return ret;
1102*1da177e4SLinus Torvalds }
1103*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_governor);
1104*1da177e4SLinus Torvalds 
1105*1da177e4SLinus Torvalds 
1106*1da177e4SLinus Torvalds int cpufreq_register_governor(struct cpufreq_governor *governor)
1107*1da177e4SLinus Torvalds {
1108*1da177e4SLinus Torvalds 	struct cpufreq_governor *t;
1109*1da177e4SLinus Torvalds 
1110*1da177e4SLinus Torvalds 	if (!governor)
1111*1da177e4SLinus Torvalds 		return -EINVAL;
1112*1da177e4SLinus Torvalds 
1113*1da177e4SLinus Torvalds 	down(&cpufreq_governor_sem);
1114*1da177e4SLinus Torvalds 
1115*1da177e4SLinus Torvalds 	list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
1116*1da177e4SLinus Torvalds 		if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) {
1117*1da177e4SLinus Torvalds 			up(&cpufreq_governor_sem);
1118*1da177e4SLinus Torvalds 			return -EBUSY;
1119*1da177e4SLinus Torvalds 		}
1120*1da177e4SLinus Torvalds 	}
1121*1da177e4SLinus Torvalds 	list_add(&governor->governor_list, &cpufreq_governor_list);
1122*1da177e4SLinus Torvalds 
1123*1da177e4SLinus Torvalds  	up(&cpufreq_governor_sem);
1124*1da177e4SLinus Torvalds 
1125*1da177e4SLinus Torvalds 	return 0;
1126*1da177e4SLinus Torvalds }
1127*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_register_governor);
1128*1da177e4SLinus Torvalds 
1129*1da177e4SLinus Torvalds 
1130*1da177e4SLinus Torvalds void cpufreq_unregister_governor(struct cpufreq_governor *governor)
1131*1da177e4SLinus Torvalds {
1132*1da177e4SLinus Torvalds 	if (!governor)
1133*1da177e4SLinus Torvalds 		return;
1134*1da177e4SLinus Torvalds 
1135*1da177e4SLinus Torvalds 	down(&cpufreq_governor_sem);
1136*1da177e4SLinus Torvalds 	list_del(&governor->governor_list);
1137*1da177e4SLinus Torvalds 	up(&cpufreq_governor_sem);
1138*1da177e4SLinus Torvalds 	return;
1139*1da177e4SLinus Torvalds }
1140*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
1141*1da177e4SLinus Torvalds 
1142*1da177e4SLinus Torvalds 
1143*1da177e4SLinus Torvalds 
1144*1da177e4SLinus Torvalds /*********************************************************************
1145*1da177e4SLinus Torvalds  *                          POLICY INTERFACE                         *
1146*1da177e4SLinus Torvalds  *********************************************************************/
1147*1da177e4SLinus Torvalds 
1148*1da177e4SLinus Torvalds /**
1149*1da177e4SLinus Torvalds  * cpufreq_get_policy - get the current cpufreq_policy
1150*1da177e4SLinus Torvalds  * @policy: struct cpufreq_policy into which the current cpufreq_policy is written
1151*1da177e4SLinus Torvalds  *
1152*1da177e4SLinus Torvalds  * Reads the current cpufreq policy.
1153*1da177e4SLinus Torvalds  */
1154*1da177e4SLinus Torvalds int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
1155*1da177e4SLinus Torvalds {
1156*1da177e4SLinus Torvalds 	struct cpufreq_policy *cpu_policy;
1157*1da177e4SLinus Torvalds 	if (!policy)
1158*1da177e4SLinus Torvalds 		return -EINVAL;
1159*1da177e4SLinus Torvalds 
1160*1da177e4SLinus Torvalds 	cpu_policy = cpufreq_cpu_get(cpu);
1161*1da177e4SLinus Torvalds 	if (!cpu_policy)
1162*1da177e4SLinus Torvalds 		return -EINVAL;
1163*1da177e4SLinus Torvalds 
1164*1da177e4SLinus Torvalds 	down(&cpu_policy->lock);
1165*1da177e4SLinus Torvalds 	memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
1166*1da177e4SLinus Torvalds 	up(&cpu_policy->lock);
1167*1da177e4SLinus Torvalds 
1168*1da177e4SLinus Torvalds 	cpufreq_cpu_put(cpu_policy);
1169*1da177e4SLinus Torvalds 
1170*1da177e4SLinus Torvalds 	return 0;
1171*1da177e4SLinus Torvalds }
1172*1da177e4SLinus Torvalds EXPORT_SYMBOL(cpufreq_get_policy);
1173*1da177e4SLinus Torvalds 
1174*1da177e4SLinus Torvalds 
1175*1da177e4SLinus Torvalds static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy)
1176*1da177e4SLinus Torvalds {
1177*1da177e4SLinus Torvalds 	int ret = 0;
1178*1da177e4SLinus Torvalds 
1179*1da177e4SLinus Torvalds 	cpufreq_debug_disable_ratelimit();
1180*1da177e4SLinus Torvalds 	dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
1181*1da177e4SLinus Torvalds 		policy->min, policy->max);
1182*1da177e4SLinus Torvalds 
1183*1da177e4SLinus Torvalds 	memcpy(&policy->cpuinfo,
1184*1da177e4SLinus Torvalds 	       &data->cpuinfo,
1185*1da177e4SLinus Torvalds 	       sizeof(struct cpufreq_cpuinfo));
1186*1da177e4SLinus Torvalds 
1187*1da177e4SLinus Torvalds 	/* verify the cpu speed can be set within this limit */
1188*1da177e4SLinus Torvalds 	ret = cpufreq_driver->verify(policy);
1189*1da177e4SLinus Torvalds 	if (ret)
1190*1da177e4SLinus Torvalds 		goto error_out;
1191*1da177e4SLinus Torvalds 
1192*1da177e4SLinus Torvalds 	down_read(&cpufreq_notifier_rwsem);
1193*1da177e4SLinus Torvalds 
1194*1da177e4SLinus Torvalds 	/* adjust if necessary - all reasons */
1195*1da177e4SLinus Torvalds 	notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST,
1196*1da177e4SLinus Torvalds 			    policy);
1197*1da177e4SLinus Torvalds 
1198*1da177e4SLinus Torvalds 	/* adjust if necessary - hardware incompatibility*/
1199*1da177e4SLinus Torvalds 	notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_INCOMPATIBLE,
1200*1da177e4SLinus Torvalds 			    policy);
1201*1da177e4SLinus Torvalds 
1202*1da177e4SLinus Torvalds 	/* verify the cpu speed can be set within this limit,
1203*1da177e4SLinus Torvalds 	   which might be different to the first one */
1204*1da177e4SLinus Torvalds 	ret = cpufreq_driver->verify(policy);
1205*1da177e4SLinus Torvalds 	if (ret) {
1206*1da177e4SLinus Torvalds 		up_read(&cpufreq_notifier_rwsem);
1207*1da177e4SLinus Torvalds 		goto error_out;
1208*1da177e4SLinus Torvalds 	}
1209*1da177e4SLinus Torvalds 
1210*1da177e4SLinus Torvalds 	/* notification of the new policy */
1211*1da177e4SLinus Torvalds 	notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY,
1212*1da177e4SLinus Torvalds 			    policy);
1213*1da177e4SLinus Torvalds 
1214*1da177e4SLinus Torvalds 	up_read(&cpufreq_notifier_rwsem);
1215*1da177e4SLinus Torvalds 
1216*1da177e4SLinus Torvalds 	data->min    = policy->min;
1217*1da177e4SLinus Torvalds 	data->max    = policy->max;
1218*1da177e4SLinus Torvalds 
1219*1da177e4SLinus Torvalds 	dprintk("new min and max freqs are %u - %u kHz\n", data->min, data->max);
1220*1da177e4SLinus Torvalds 
1221*1da177e4SLinus Torvalds 	if (cpufreq_driver->setpolicy) {
1222*1da177e4SLinus Torvalds 		data->policy = policy->policy;
1223*1da177e4SLinus Torvalds 		dprintk("setting range\n");
1224*1da177e4SLinus Torvalds 		ret = cpufreq_driver->setpolicy(policy);
1225*1da177e4SLinus Torvalds 	} else {
1226*1da177e4SLinus Torvalds 		if (policy->governor != data->governor) {
1227*1da177e4SLinus Torvalds 			/* save old, working values */
1228*1da177e4SLinus Torvalds 			struct cpufreq_governor *old_gov = data->governor;
1229*1da177e4SLinus Torvalds 
1230*1da177e4SLinus Torvalds 			dprintk("governor switch\n");
1231*1da177e4SLinus Torvalds 
1232*1da177e4SLinus Torvalds 			/* end old governor */
1233*1da177e4SLinus Torvalds 			if (data->governor)
1234*1da177e4SLinus Torvalds 				__cpufreq_governor(data, CPUFREQ_GOV_STOP);
1235*1da177e4SLinus Torvalds 
1236*1da177e4SLinus Torvalds 			/* start new governor */
1237*1da177e4SLinus Torvalds 			data->governor = policy->governor;
1238*1da177e4SLinus Torvalds 			if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
1239*1da177e4SLinus Torvalds 				/* new governor failed, so re-start old one */
1240*1da177e4SLinus Torvalds 				dprintk("starting governor %s failed\n", data->governor->name);
1241*1da177e4SLinus Torvalds 				if (old_gov) {
1242*1da177e4SLinus Torvalds 					data->governor = old_gov;
1243*1da177e4SLinus Torvalds 					__cpufreq_governor(data, CPUFREQ_GOV_START);
1244*1da177e4SLinus Torvalds 				}
1245*1da177e4SLinus Torvalds 				ret = -EINVAL;
1246*1da177e4SLinus Torvalds 				goto error_out;
1247*1da177e4SLinus Torvalds 			}
1248*1da177e4SLinus Torvalds 			/* might be a policy change, too, so fall through */
1249*1da177e4SLinus Torvalds 		}
1250*1da177e4SLinus Torvalds 		dprintk("governor: change or update limits\n");
1251*1da177e4SLinus Torvalds 		__cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
1252*1da177e4SLinus Torvalds 	}
1253*1da177e4SLinus Torvalds 
1254*1da177e4SLinus Torvalds  error_out:
1255*1da177e4SLinus Torvalds 	cpufreq_debug_enable_ratelimit();
1256*1da177e4SLinus Torvalds 	return ret;
1257*1da177e4SLinus Torvalds }
1258*1da177e4SLinus Torvalds 
1259*1da177e4SLinus Torvalds /**
1260*1da177e4SLinus Torvalds  *	cpufreq_set_policy - set a new CPUFreq policy
1261*1da177e4SLinus Torvalds  *	@policy: policy to be set.
1262*1da177e4SLinus Torvalds  *
1263*1da177e4SLinus Torvalds  *	Sets a new CPU frequency and voltage scaling policy.
1264*1da177e4SLinus Torvalds  */
1265*1da177e4SLinus Torvalds int cpufreq_set_policy(struct cpufreq_policy *policy)
1266*1da177e4SLinus Torvalds {
1267*1da177e4SLinus Torvalds 	int ret = 0;
1268*1da177e4SLinus Torvalds 	struct cpufreq_policy *data;
1269*1da177e4SLinus Torvalds 
1270*1da177e4SLinus Torvalds 	if (!policy)
1271*1da177e4SLinus Torvalds 		return -EINVAL;
1272*1da177e4SLinus Torvalds 
1273*1da177e4SLinus Torvalds 	data = cpufreq_cpu_get(policy->cpu);
1274*1da177e4SLinus Torvalds 	if (!data)
1275*1da177e4SLinus Torvalds 		return -EINVAL;
1276*1da177e4SLinus Torvalds 
1277*1da177e4SLinus Torvalds 	/* lock this CPU */
1278*1da177e4SLinus Torvalds 	down(&data->lock);
1279*1da177e4SLinus Torvalds 
1280*1da177e4SLinus Torvalds 	ret = __cpufreq_set_policy(data, policy);
1281*1da177e4SLinus Torvalds 	data->user_policy.min = data->min;
1282*1da177e4SLinus Torvalds 	data->user_policy.max = data->max;
1283*1da177e4SLinus Torvalds 	data->user_policy.policy = data->policy;
1284*1da177e4SLinus Torvalds 	data->user_policy.governor = data->governor;
1285*1da177e4SLinus Torvalds 
1286*1da177e4SLinus Torvalds 	up(&data->lock);
1287*1da177e4SLinus Torvalds 	cpufreq_cpu_put(data);
1288*1da177e4SLinus Torvalds 
1289*1da177e4SLinus Torvalds 	return ret;
1290*1da177e4SLinus Torvalds }
1291*1da177e4SLinus Torvalds EXPORT_SYMBOL(cpufreq_set_policy);
1292*1da177e4SLinus Torvalds 
1293*1da177e4SLinus Torvalds 
1294*1da177e4SLinus Torvalds /**
1295*1da177e4SLinus Torvalds  *	cpufreq_update_policy - re-evaluate an existing cpufreq policy
1296*1da177e4SLinus Torvalds  *	@cpu: CPU which shall be re-evaluated
1297*1da177e4SLinus Torvalds  *
1298*1da177e4SLinus Torvalds  *	Usefull for policy notifiers which have different necessities
1299*1da177e4SLinus Torvalds  *	at different times.
1300*1da177e4SLinus Torvalds  */
1301*1da177e4SLinus Torvalds int cpufreq_update_policy(unsigned int cpu)
1302*1da177e4SLinus Torvalds {
1303*1da177e4SLinus Torvalds 	struct cpufreq_policy *data = cpufreq_cpu_get(cpu);
1304*1da177e4SLinus Torvalds 	struct cpufreq_policy policy;
1305*1da177e4SLinus Torvalds 	int ret = 0;
1306*1da177e4SLinus Torvalds 
1307*1da177e4SLinus Torvalds 	if (!data)
1308*1da177e4SLinus Torvalds 		return -ENODEV;
1309*1da177e4SLinus Torvalds 
1310*1da177e4SLinus Torvalds 	down(&data->lock);
1311*1da177e4SLinus Torvalds 
1312*1da177e4SLinus Torvalds 	dprintk("updating policy for CPU %u\n", cpu);
1313*1da177e4SLinus Torvalds 	memcpy(&policy,
1314*1da177e4SLinus Torvalds 	       data,
1315*1da177e4SLinus Torvalds 	       sizeof(struct cpufreq_policy));
1316*1da177e4SLinus Torvalds 	policy.min = data->user_policy.min;
1317*1da177e4SLinus Torvalds 	policy.max = data->user_policy.max;
1318*1da177e4SLinus Torvalds 	policy.policy = data->user_policy.policy;
1319*1da177e4SLinus Torvalds 	policy.governor = data->user_policy.governor;
1320*1da177e4SLinus Torvalds 
1321*1da177e4SLinus Torvalds 	ret = __cpufreq_set_policy(data, &policy);
1322*1da177e4SLinus Torvalds 
1323*1da177e4SLinus Torvalds 	up(&data->lock);
1324*1da177e4SLinus Torvalds 
1325*1da177e4SLinus Torvalds 	cpufreq_cpu_put(data);
1326*1da177e4SLinus Torvalds 	return ret;
1327*1da177e4SLinus Torvalds }
1328*1da177e4SLinus Torvalds EXPORT_SYMBOL(cpufreq_update_policy);
1329*1da177e4SLinus Torvalds 
1330*1da177e4SLinus Torvalds 
1331*1da177e4SLinus Torvalds /*********************************************************************
1332*1da177e4SLinus Torvalds  *               REGISTER / UNREGISTER CPUFREQ DRIVER                *
1333*1da177e4SLinus Torvalds  *********************************************************************/
1334*1da177e4SLinus Torvalds 
1335*1da177e4SLinus Torvalds /**
1336*1da177e4SLinus Torvalds  * cpufreq_register_driver - register a CPU Frequency driver
1337*1da177e4SLinus Torvalds  * @driver_data: A struct cpufreq_driver containing the values#
1338*1da177e4SLinus Torvalds  * submitted by the CPU Frequency driver.
1339*1da177e4SLinus Torvalds  *
1340*1da177e4SLinus Torvalds  *   Registers a CPU Frequency driver to this core code. This code
1341*1da177e4SLinus Torvalds  * returns zero on success, -EBUSY when another driver got here first
1342*1da177e4SLinus Torvalds  * (and isn't unregistered in the meantime).
1343*1da177e4SLinus Torvalds  *
1344*1da177e4SLinus Torvalds  */
1345*1da177e4SLinus Torvalds int cpufreq_register_driver(struct cpufreq_driver *driver_data)
1346*1da177e4SLinus Torvalds {
1347*1da177e4SLinus Torvalds 	unsigned long flags;
1348*1da177e4SLinus Torvalds 	int ret;
1349*1da177e4SLinus Torvalds 
1350*1da177e4SLinus Torvalds 	if (!driver_data || !driver_data->verify || !driver_data->init ||
1351*1da177e4SLinus Torvalds 	    ((!driver_data->setpolicy) && (!driver_data->target)))
1352*1da177e4SLinus Torvalds 		return -EINVAL;
1353*1da177e4SLinus Torvalds 
1354*1da177e4SLinus Torvalds 	dprintk("trying to register driver %s\n", driver_data->name);
1355*1da177e4SLinus Torvalds 
1356*1da177e4SLinus Torvalds 	if (driver_data->setpolicy)
1357*1da177e4SLinus Torvalds 		driver_data->flags |= CPUFREQ_CONST_LOOPS;
1358*1da177e4SLinus Torvalds 
1359*1da177e4SLinus Torvalds 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
1360*1da177e4SLinus Torvalds 	if (cpufreq_driver) {
1361*1da177e4SLinus Torvalds 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1362*1da177e4SLinus Torvalds 		return -EBUSY;
1363*1da177e4SLinus Torvalds 	}
1364*1da177e4SLinus Torvalds 	cpufreq_driver = driver_data;
1365*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1366*1da177e4SLinus Torvalds 
1367*1da177e4SLinus Torvalds 	ret = sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
1368*1da177e4SLinus Torvalds 
1369*1da177e4SLinus Torvalds 	if ((!ret) && !(cpufreq_driver->flags & CPUFREQ_STICKY)) {
1370*1da177e4SLinus Torvalds 		int i;
1371*1da177e4SLinus Torvalds 		ret = -ENODEV;
1372*1da177e4SLinus Torvalds 
1373*1da177e4SLinus Torvalds 		/* check for at least one working CPU */
1374*1da177e4SLinus Torvalds 		for (i=0; i<NR_CPUS; i++)
1375*1da177e4SLinus Torvalds 			if (cpufreq_cpu_data[i])
1376*1da177e4SLinus Torvalds 				ret = 0;
1377*1da177e4SLinus Torvalds 
1378*1da177e4SLinus Torvalds 		/* if all ->init() calls failed, unregister */
1379*1da177e4SLinus Torvalds 		if (ret) {
1380*1da177e4SLinus Torvalds 			dprintk("no CPU initialized for driver %s\n", driver_data->name);
1381*1da177e4SLinus Torvalds 			sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
1382*1da177e4SLinus Torvalds 
1383*1da177e4SLinus Torvalds 			spin_lock_irqsave(&cpufreq_driver_lock, flags);
1384*1da177e4SLinus Torvalds 			cpufreq_driver = NULL;
1385*1da177e4SLinus Torvalds 			spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1386*1da177e4SLinus Torvalds 		}
1387*1da177e4SLinus Torvalds 	}
1388*1da177e4SLinus Torvalds 
1389*1da177e4SLinus Torvalds 	if (!ret) {
1390*1da177e4SLinus Torvalds 		dprintk("driver %s up and running\n", driver_data->name);
1391*1da177e4SLinus Torvalds 		cpufreq_debug_enable_ratelimit();
1392*1da177e4SLinus Torvalds 	}
1393*1da177e4SLinus Torvalds 
1394*1da177e4SLinus Torvalds 	return (ret);
1395*1da177e4SLinus Torvalds }
1396*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_register_driver);
1397*1da177e4SLinus Torvalds 
1398*1da177e4SLinus Torvalds 
1399*1da177e4SLinus Torvalds /**
1400*1da177e4SLinus Torvalds  * cpufreq_unregister_driver - unregister the current CPUFreq driver
1401*1da177e4SLinus Torvalds  *
1402*1da177e4SLinus Torvalds  *    Unregister the current CPUFreq driver. Only call this if you have
1403*1da177e4SLinus Torvalds  * the right to do so, i.e. if you have succeeded in initialising before!
1404*1da177e4SLinus Torvalds  * Returns zero if successful, and -EINVAL if the cpufreq_driver is
1405*1da177e4SLinus Torvalds  * currently not initialised.
1406*1da177e4SLinus Torvalds  */
1407*1da177e4SLinus Torvalds int cpufreq_unregister_driver(struct cpufreq_driver *driver)
1408*1da177e4SLinus Torvalds {
1409*1da177e4SLinus Torvalds 	unsigned long flags;
1410*1da177e4SLinus Torvalds 
1411*1da177e4SLinus Torvalds 	cpufreq_debug_disable_ratelimit();
1412*1da177e4SLinus Torvalds 
1413*1da177e4SLinus Torvalds 	if (!cpufreq_driver || (driver != cpufreq_driver)) {
1414*1da177e4SLinus Torvalds 		cpufreq_debug_enable_ratelimit();
1415*1da177e4SLinus Torvalds 		return -EINVAL;
1416*1da177e4SLinus Torvalds 	}
1417*1da177e4SLinus Torvalds 
1418*1da177e4SLinus Torvalds 	dprintk("unregistering driver %s\n", driver->name);
1419*1da177e4SLinus Torvalds 
1420*1da177e4SLinus Torvalds 	sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
1421*1da177e4SLinus Torvalds 
1422*1da177e4SLinus Torvalds 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
1423*1da177e4SLinus Torvalds 	cpufreq_driver = NULL;
1424*1da177e4SLinus Torvalds 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
1425*1da177e4SLinus Torvalds 
1426*1da177e4SLinus Torvalds 	return 0;
1427*1da177e4SLinus Torvalds }
1428*1da177e4SLinus Torvalds EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
1429