论坛风格切换切换到宽版
发帖 回复
返回列表  提醒:不能用迅雷等P2P下载,否则下载失败标(二级)的板块,需二级才能下载,没二级不要购买,下载不了
  • 1115阅读
  • 0回复

RK3188的频率在这里改的哦 [复制链接]

上一主题 下一主题
离线mark83136
 

性别:
帅哥
发帖
1210
金币
360
提示:会员销售的附件,下载积分 = 版块积分 + 销售积分       只看楼主 倒序阅读 使用道具 0楼 发表于: 2015-07-08
1s1$J2LX  
* >pn?~  
*  linux/drivers/cpufreq/cpufreq.c ^IC|3sr   
* m@TU2  
*  Copyright (C) 2001 Russell King !$&K~>`  
*            (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de> `+i<:,z-gs  
* g.z/%Lp K  
*  Oct 2005 - Ashok Raj <ashok.raj@intel.com> AC 3 ;i  
*    Added handling for CPU hotplug m:K/ )v*  
*  Feb 2006 - Jacob Shin <jacob.shin@amd.com> h( Iti&  
*    Fix handling for CPU hotplug -- affected CPUs ?_ p3^kl  
* G0<m3 Up  
* This program is free software; you can redistribute it and/or modify $ABW|r  
* it under the terms of the GNU General Public License version 2 as ?HU(0Vgn'  
* published by the Free Software Foundation. M`S >Q2{  
* \GBv@  
*/ B(E+2;!QF  
;B!&( 50e  
#include <linux/kernel.h> 0~"{z >s '  
#include <linux/module.h> 7eZ,; x  
#include <linux/init.h> I)n%aTfo8  
#include <linux/notifier.h> -k!UcMWP  
#include <linux/cpufreq.h> 9D-PmSnv  
#include <linux/delay.h> 91[(K'=&  
#include <linux/interrupt.h> _AK-AY  
#include <linux/spinlock.h> &(irri_  
#include <linux/device.h> _PQQ&e)E  
#include <linux/slab.h> 7)<&,BWc  
#include <linux/cpu.h> qJrK?:O;  
#include <linux/completion.h> I+ydVj(Op  
#include <linux/mutex.h> $Z$BF  
#include <linux/syscore_ops.h> <Y<%=`  
UG 9uNgzQ/  
#include <trace/events/power.h> l2z@t3{  
}zj_Pp  
/** Un@dWf6'  
* The "cpufreq driver" - the arch- or hardware-dependent low @ 2Z{en?  
* level driver of CPUFreq support, and its spinlock. This lock 8,=,'gFO  
* also protects the cpufreq_cpu_data array. ,n^{!^JW  
*/ V+-%$-w>  
static struct cpufreq_driver *cpufreq_driver; f D2. Zh  
static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); 8)/d8@  
#ifdef CONFIG_HOTPLUG_CPU f6u<.b  
/* This one keeps track of the previously set governor of a removed CPU */ 9K~X}]u  
static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); "! m6U#^  
#endif GK~uoz:^O  
static DEFINE_SPINLOCK(cpufreq_driver_lock); !CY: XQm  
9J$N5  
/* _-$(=`8|<{  
* cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure <D%.'=%pZ  
* all cpufreq/hotplug/workqueue/etc related lock issues. 4ba[*R2  
* Y2W|b5  
* The rules for this semaphore: cY0NQKUk~  
* - Any routine that wants to read from the policy structure will \0). ODA(  
*   do a down_read on this semaphore. o7;lR?  
* - Any routine that will write to the policy structure and/or may take away ~5q1zr)E  
*   the policy altogether (eg. CPU hotplug), will hold this lock in write ot($aY,t  
*   mode before doing so. :Ugf3%sQ  
* _<qe= hie!  
* Additional rules: l1l=52r   
* - All holders of the lock should check to make sure that the CPU they +0_e a~{  
*   are concerned with are online after they get the lock. C6Lc   
* - Governor routines that can be called in cpufreq hotplug path should not )%dxfwd6  
*   take this sem as top level hotplug notifier handler takes this. Q V)>+6\  
* - Lock should not be held across _Dr9 w&;<  
*     __cpufreq_governor(data, CPUFREQ_GOV_STOP); u0zF::  
*/ I() =Ufs5z  
static DEFINE_PER_CPU(int, cpufreq_policy_cpu);  k{d]  
static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); c#( Hh{0  
X6 *4IE  
#define lock_policy_rwsem(mode, cpu)                    \ X|y(B%:  
static int lock_policy_rwsem_##mode                    \ G5vp(%j  
(int cpu)                                \ . |%n"{  
{                                    \ ' Dcj\=8  
    int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu);        \ x{4{.s%+:  
    BUG_ON(policy_cpu == -1);                    \ :y'EIf  
    down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu));        \ z?dd5.k  
    if (unlikely(!cpu_online(cpu))) {                \ GZH{"_$  
        up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu));    \ hz:h>Hwy  
        return -1;                        \ %e^GfZ  
    }                                \ {ppzg`G\  
                                    \ K*I!:1;3N  
    return 0;                            \ e`n+U-)z  
} d^MRu#]  
,_iq$I;  
lock_policy_rwsem(read, cpu); aKjP{Z0k$  
ttOk6-  
lock_policy_rwsem(write, cpu); ]-8WM5\qJM  
e[ yN  
static void unlock_policy_rwsem_read(int cpu) `6$|d,m5  
{ s@Dln Du .  
    int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); ;3x*pjLG:Q  
    BUG_ON(policy_cpu == -1); {Y-~7@  
    up_read(&per_cpu(cpu_policy_rwsem, policy_cpu)); TZ&X0x8  
} qG@YNc  
3ew4QPT'  
static void unlock_policy_rwsem_write(int cpu) {ETM >  
{ HS[($  
    int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); ]Hp>~Zvbb  
    BUG_ON(policy_cpu == -1); IjGPiC  
    up_write(&per_cpu(cpu_policy_rwsem, policy_cpu)); @}=(4%  
} G %'xEr0n  
H2H`7 +I,  
CYRZ2Yrk?"  
/* internal prototypes */ /~M H]Gh  
static int __cpufreq_governor(struct cpufreq_policy *policy, 1U% /~  
        unsigned int event); 2n)?)w]!M  
static unsigned int __cpufreq_get(unsigned int cpu); KL3Z(  
static void handle_update(struct work_struct *work); h PL]B_<  
C];P yQS  
/** v3#,Z!  
* Two notifier lists: the "policy" list is involved in the oNZ_7tU  
* validation process for a new CPU frequency policy; the  0:f]&Ng  
* "transition" list for kernel code that needs to handle \ ?pyax8  
* changes to devices when the CPU clock speed changes. Y{D%v  
* The mutex locks both lists. 8[;vC$  
*/ _0(%^5Y  
static BLOCKING_NOTIFIER_HEAD(cpufreq_policy_notifier_list); ]} dQ~lOE  
static struct srcu_notifier_head cpufreq_transition_notifier_list; !$A/.;0$  
V"m S$MN  
static bool init_cpufreq_transition_notifier_list_called; U.KQjBi  
static int __init init_cpufreq_transition_notifier_list(void) MjU|XQS:  
{ As<B8e]  
    srcu_init_notifier_head(&cpufreq_transition_notifier_list); l|=4FIMD  
    init_cpufreq_transition_notifier_list_called = true; O&1qL)  
    return 0; RFMPh<Ac  
} +? h}e  
pure_initcall(init_cpufreq_transition_notifier_list); 3w</B- |nQ  
s'h;a5Q1'Q  
static LIST_HEAD(cpufreq_governor_list); qT48Y  
static DEFINE_MUTEX(cpufreq_governor_mutex); 8LbwEKl  
8 q@Z  
struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) !bP%\)5  
{ 5?lc%,-&  
    struct cpufreq_policy *data; [ n7>g   
    unsigned long flags; T1]?E]m{  
L.Qz29\  
    if (cpu >= nr_cpu_ids) IdQ./@?  
        goto err_out; =j62tDS  
HR}O:2'  
    /* get the cpufreq driver */ 27EK +$  
    spin_lock_irqsave(&cpufreq_driver_lock, flags); f#= c=e-A  
ovdJ[bO  
    if (!cpufreq_driver) Iko]c_W0  
        goto err_out_unlock; ]K"&Vd  
hq)1YO  
    if (!try_module_get(cpufreq_driver->owner)) {%f{U"m  
        goto err_out_unlock; /]_t->  
{drc}BL_  
Ho>Np&  
    /* get the CPU */ (k?H T'3)  
    data = per_cpu(cpufreq_cpu_data, cpu); TxX=(7V  
){*+s RBW  
    if (!data) yOq@w!xz  
        goto err_out_put_module; K]hp-QK<  
T.4&P#a1  
    if (!kobject_get(&data->kobj)) 7uF|Z(  
        goto err_out_put_module; Upe}9xf  
qhEv6Yxfw6  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); `7CK;NeT  
    return data; ;V xRaj?  
>?, Zn  
err_out_put_module: T3X'73M  
    module_put(cpufreq_driver->owner); j*jUcD *  
err_out_unlock: rO'DT{Yt  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); # z|Q $  
err_out: WMSJU/-P  
    return NULL; l4OrlS/5  
} aQCu3T  
EXPORT_SYMBOL_GPL(cpufreq_cpu_get); uM-,}7f7  
D|N4X`T`  
 !+eH8  
void cpufreq_cpu_put(struct cpufreq_policy *data) A&Y5z[p  
{ qCV<-o  
    kobject_put(&data->kobj); qqrjI.  
    module_put(cpufreq_driver->owner); '<R>cN"  
} [9 W@<p  
EXPORT_SYMBOL_GPL(cpufreq_cpu_put); eU[g@Pq:Y  
fpD$%.y'J  
"& ,ov#  
/********************************************************************* JvpGxj  
*            EXTERNALLY AFFECTING FREQUENCY CHANGES                 * cHs3:F~~  
*********************************************************************/ Ld4U  
i%hCV o  
/** 0l!#u`cCI  
* adjust_jiffies - adjust the system "loops_per_jiffy" WYw#mSp  
* gcJ!_KZK  
* This function alters the system "loops_per_jiffy" for the clock C=: <[_m`  
* speed change. Note that loops_per_jiffy cannot be updated on SMP &X=7b@r  
* systems as each CPU might be scaled differently. So, use the arch szI7 I$Qb  
* per-CPU loops_per_jiffy value wherever possible. Dac)`/  
*/ XKoY!Y\  
#ifndef CONFIG_SMP A,}M ^$@  
static unsigned long l_p_j_ref; p3I"LY  
static unsigned int  l_p_j_ref_freq; ]A*}Dem*5  
v}G^+-?  
static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) i5'&u:  
{ UUah5$Iy  
    if (ci->flags & CPUFREQ_CONST_LOOPS) !"rPSGK*  
        return; #B `?}a=  
=!q% 1mP  
    if (!l_p_j_ref_freq) { w!.@64-  
        l_p_j_ref = loops_per_jiffy; wA) Hot  
        l_p_j_ref_freq = ci->old; bSB%hFp=Cp  
        pr_debug("saving %lu as reference value for loops_per_jiffy; " (WM3(US|  
            "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq); oBzl=N3<  
    } 1F@k9[d~  
    if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) || @~3--  
        (val == CPUFREQ_POSTCHANGE && ci->old > ci->new) || W(,j2pU  
        (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { oQ!M+sRmF  
        loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, %TB(E<p`  
                                ci->new); K\Ea\b[  
        pr_debug("scaling loops_per_jiffy to %lu " _?{7%(C  
            "for frequency %u kHz\n", loops_per_jiffy, ci->new); }A#IBqf5  
    } _P>YG<*"kQ  
} ;_<R +w3-  
#else K7 e~%mY  
static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) 5xQ-f  
{ swKkY`g  
    return; *rxr:y#Ve  
} +$2{u_m,  
#endif Gw M:f/eV  
$3-v W{<  
rP@#_(22  
/** sX>u.  
* cpufreq_notify_transition - call notifier chain and adjust_jiffies D /eH~  
* on frequency transition. $|K d<wv  
* l$42MRi/  
* This function calls the transition notifiers and the "adjust_jiffies" v+c>iI  
* function. It is called twice on all CPU frequency changes that have 3EoCEPb#  
* external effects. d*(aue=  
*/ K,b M9>}  
void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) YeH!v, >  
{ >I5:@6 Z  
    struct cpufreq_policy *policy; [$N_YcN?  
aSL`yuXu  
    BUG_ON(irqs_disabled()); Q$jEmmm%V[  
/d`"WK,  
    freqs->flags = cpufreq_driver->flags; rzjVUPdnh  
    pr_debug("notification %u of frequency transition to %u kHz\n", 'ofj1%c  
        state, freqs->new); n3^(y"q  
Z8$}Rpo  
    policy = per_cpu(cpufreq_cpu_data, freqs->cpu); Q&9 yrx.  
    switch (state) { 7|rH9Bc{U  
3h@]cWp  
    case CPUFREQ_PRECHANGE: RNg?o [S  
        /* detect if the driver reported a value as "old frequency" IqOg{#sm  
         * which is not equal to what the cpufreq core thinks is s**<=M GK  
         * "old frequency". G\.~/<Mg+  
         */ _)A|JC!jId  
        if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { X{9^$/XsJ  
            if ((policy) && (policy->cpu == freqs->cpu) && {#,<)wFV\  
                (policy->cur) && (policy->cur != freqs->old)) { /{M<FVXK+|  
                pr_debug("Warning: CPU frequency is" r pNb.  
                    " %u, cpufreq assumed %u kHz.\n", 6j#JhcS+  
                    freqs->old, policy->cur); ,75)  
                freqs->old = policy->cur; KA3U W  
            } \pmS*Dt  
        } NOb`)qb  
        srcu_notifier_call_chain(&cpufreq_transition_notifier_list, J<) qw  
                CPUFREQ_PRECHANGE, freqs); }@DCcf$<  
        adjust_jiffies(CPUFREQ_PRECHANGE, freqs); 9&mSF0q  
        break; `lf_wB+I  
aDlp>p^E>  
    case CPUFREQ_POSTCHANGE: nt.LiM/L  
        adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); 8K%N7RL|  
        pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, /l$x}  
            (unsigned long)freqs->cpu); Na\ZV|;*tu  
        trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu); b@CB +8 $  
        trace_cpu_frequency(freqs->new, freqs->cpu); [KDxB>R<{  
        srcu_notifier_call_chain(&cpufreq_transition_notifier_list, BN/ 4O?jD9  
                CPUFREQ_POSTCHANGE, freqs); 6FS%9.Ws  
        if (likely(policy) && likely(policy->cpu == freqs->cpu)) ( ?FH`<  
            policy->cur = freqs->new; JsEJ6!1  
        break; Q|y }mC/  
    } ~.a"jYb7A}  
} Zxk~X}K\P  
EXPORT_SYMBOL_GPL(cpufreq_notify_transition); FO{=^I5YA  
C.j+Zb1Z(  
\#sD`O  
2"/MM2s  
/********************************************************************* OL'Ito  
*                          SYSFS INTERFACE                          * GgO5=|  
*********************************************************************/ 3?OQ-7,  
(d9~z  
static struct cpufreq_governor *__find_governor(const char *str_governor) 5LeZ ?'"c  
{ q'3{M]Tk  
    struct cpufreq_governor *t; lu utyK!  
_&KqmQ8$7  
    list_for_each_entry(t, &cpufreq_governor_list, governor_list) }F08o,`?  
        if (!strnicmp(str_governor, t->name, CPUFREQ_NAME_LEN)) 7iB!Uuc  
            return t; ?hoOSur+  
,p2UshOmd  
    return NULL; \;;M")$  
} 2+]5}'M  
1{uxpYAP=  
/** 4.A^5J'W  
* cpufreq_parse_governor - parse a governor string #G9 W65f  
*/ 1]xk:u4LA  
static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, 3:nhZN/95T  
                struct cpufreq_governor **governor) ?0qVyK_1  
{ Iix,}kzss  
    int err = -EINVAL; S ?Zh#`(*  
<JPN< Kv  
    if (!cpufreq_driver) .1QGNW  
        goto out; pn"!wqg  
q<Rj Ai  
    if (cpufreq_driver->setpolicy) { @2(u=E:^  
        if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { G':3U  
            *policy = CPUFREQ_POLICY_PERFORMANCE; Ou[K7-m%&  
            err = 0; ]4~Yi1]  
        } else if (!strnicmp(str_governor, "powersave",  3@Ndn  
                        CPUFREQ_NAME_LEN)) { >t+ ENYb  
            *policy = CPUFREQ_POLICY_POWERSAVE; ]3r}>/2(  
            err = 0; V 6}5^W  
        } dCx63rF`G  
    } else if (cpufreq_driver->target) { d<c29Y  
        struct cpufreq_governor *t; U1\EwBK8*T  
oXo>pl  
        mutex_lock(&cpufreq_governor_mutex); vG|!d+  
GrF4*I`q  
        t = __find_governor(str_governor); =<\22d5L  
,%!m%+K9a  
        if (t == NULL) { X G#?fr}L  
            int ret; w4 yrAj 2  
H3wJ5-q(  
            mutex_unlock(&cpufreq_governor_mutex); Q  :kg  
            ret = request_module("cpufreq_%s", str_governor); )x-b+SC  
            mutex_lock(&cpufreq_governor_mutex); \zd[A~!  
(l5p_x  
            if (ret == 0) (Jp~=6&lKf  
                t = __find_governor(str_governor); FDo PW~+[  
        } #p+iwW-  
N^ +q^iW  
        if (t != NULL) { a\sK{`|X*  
            *governor = t; lpi"@3  
            err = 0; Y S3~sA  
        } P" c@V,.  
kBP?_ O  
        mutex_unlock(&cpufreq_governor_mutex); .AN1Yt  
    } MqJTRBs%  
out: ^y,h0?Z9  
    return err; ^f[6NYS?  
} eKLvBa-{@  
xMbgBx4+  
4!sK>l!  
/** $(}rTm  
* cpufreq_per_cpu_attr_read() / show_##file_name() - F:/x7]7??Z  
* print out cpufreq information _'D(>e?  
* `%YMUBaI  
* Write out information from cpufreq_driver->policy[cpu]; object must be 9hr7+fW]t  
* "unsigned int". =r]l"T  
*/ ):N#X<b':  
Kebr>t8^  
#define show_one(file_name, object)            \ %g :Q?   
static ssize_t show_##file_name                \ NQD5=/o  
(struct cpufreq_policy *policy, char *buf)        \ %??v?M*  
{                            \ e5mu-  
    return sprintf(buf, "%u\n", policy->object);    \ y\v#qFVOZ  
} R*GBxJaw  
NV5qF/<M  
show_one(cpuinfo_min_freq, cpuinfo.min_freq); /? %V% n  
show_one(cpuinfo_max_freq, cpuinfo.max_freq); sOqFEvzo1%  
show_one(cpuinfo_transition_latency, cpuinfo.transition_latency); )qx;/=D  
show_one(scaling_min_freq, min); y)zZ:lyIq  
show_one(scaling_max_freq, max); kA=5Kc  
show_one(scaling_cur_freq, cur); 97Dq;  
2 G.y.#W  
static int __cpufreq_set_policy(struct cpufreq_policy *data,  Z 9:  
                struct cpufreq_policy *policy); {Q>OZm\+  
L#S W!  
/** k"#gSCW$  
* cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access ]9_gbQ   
*/ =`x }9|[  
#define store_one(file_name, object)            \ F'MX9P  
static ssize_t store_##file_name                    \ zgY VB}  
(struct cpufreq_policy *policy, const char *buf, size_t count)        \ rC@VMe|0  
{                                    \ =%8 yEb*5#  
    unsigned int ret = -EINVAL;                    \ 0SvPr [ >  
    struct cpufreq_policy new_policy;                \ G^B> C  
                                    \ 9(t(sP_  
    ret = cpufreq_get_policy(&new_policy, policy->cpu);        \ _1[Wv?  
    if (ret)                            \ I^EZs6~  
        return -EINVAL;                        \ kqX=3Zo  
                                    \ *=i&n>  
    ret = sscanf(buf, "%u", &new_policy.object);            \ '( I0VJJ   
    if (ret != 1)                            \  Gd A!8  
        return -EINVAL;                        \ -] wEk%j  
                                    \ xHt7/8wF  
    ret = __cpufreq_set_policy(policy, &new_policy);        \ Jqb~RP~  
    policy->user_policy.object = policy->object;            \ 0{vT`e'  
                                    \ CHTK.%AQH!  
    return ret ? ret : count;                    \ (F^R9G|  
} /"J 6``MV  
=?$~=1SL+  
store_one(scaling_min_freq, min); U 2-{p  
store_one(scaling_max_freq, max); xO_>%F^?  
JPF6zzl)  
/** g8cBb5(L  
* show_cpuinfo_cur_freq - current CPU frequency as detected by hardware /4O))}TX  
*/ wU|@fm"  
static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, ~~Bks{"BS  
                    char *buf) N!c FUZ5]  
{ R*vQvO%)h  
    unsigned int cur_freq = __cpufreq_get(policy->cpu); t Aq0Z)  
    if (!cur_freq) =/K)hI!u  
        return sprintf(buf, "<unknown>"); eP" B3Jw  
    return sprintf(buf, "%u\n", cur_freq); "dP-e  
} S?CT6moXA  
* EGzFXa  
G@/iK/>5|`  
/** O*v&C Hd3  
* show_scaling_governor - show the current policy for the specified CPU `Pc6 G*p  
*/ W8S sv  
static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) 1J0gjO)AZ  
{ {U2AAQSa  
    if (policy->policy == CPUFREQ_POLICY_POWERSAVE) |kK5:\H  
        return sprintf(buf, "powersave\n"); sJKr%2nVV  
    else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) "a].v 8l!  
        return sprintf(buf, "performance\n"); tx7 zG.,  
    else if (policy->governor) Uj;JN}k  
        return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", O)`L( x  
                policy->governor->name); Xk.OyQ@  
    return -EINVAL; ef^GJTv&k  
} ]7}!3m  
UhqTn$=fb  
vYm-$KQ"o  
/** y>}r  
* store_scaling_governor - store policy for the specified CPU .^*;hZ~4%  
*/ 8!|vp7/  
static ssize_t store_scaling_governor(struct cpufreq_policy *policy, IQU1 JVk Z  
                    const char *buf, size_t count) .O"a:^i  
{ b 9rQQS  
    unsigned int ret = -EINVAL; |;NfH|43;  
    char    str_governor[16]; -XXsob}/8  
    struct cpufreq_policy new_policy; i=\)[;U  
C]2-V1,ZX  
    ret = cpufreq_get_policy(&new_policy, policy->cpu); g;=VuQuP|  
    if (ret) ic`BDkNO  
        return ret; %W9R08`  
)qb'tZz/g_  
    ret = sscanf(buf, "%15s", str_governor); UstUPO  
    if (ret != 1) hy~[7:/<I&  
        return -EINVAL; <L8|Wz  
keLeD1  
    if (cpufreq_parse_governor(str_governor, &new_policy.policy, {Vj&i.2,  
                        &new_policy.governor)) k*?T^<c3  
        return -EINVAL; msgR"T3'  
p#jAEY p  
    /* Do not use cpufreq_set_policy here or the user_policy.max P}~MO)*1  
       will be wrongly overridden */ &u[{VR:  
    ret = __cpufreq_set_policy(policy, &new_policy); |hxiARr4  
Fc@R,9  
    policy->user_policy.policy = policy->policy; 7:olStK  
    policy->user_policy.governor = policy->governor; =S{OzF  
mP\V.^  
    if (ret) by'KJxl[  
        return ret; Xi%Og\vm5  
    else cy.r/Z}  
        return count; z(A[xN@/W<  
} 0zNbux_  
2|^@=.4\  
/** ^O*-|ecA  
* show_scaling_driver - show the cpufreq driver currently loaded :pdX  
*/ Y]L4,V  
static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf) K7`6G[RMb  
{ F8Ety^9>9  
    return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name); OJpfiZ@Q_  
} : wS&3:h  
pM@8T25=  
/** N-QS/*C.~  
* show_scaling_available_governors - show the available CPUfreq governors pZ'q_Oux  
*/ " Bx@(  
static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, fY9+m}$S$  
                        char *buf) 'wEQvCS  
{ :W,S  
    ssize_t i = 0; FShjUl>mV  
    struct cpufreq_governor *t; y#B=9Ri=z  
`;Tf_6c  
    if (!cpufreq_driver->target) { 6=]Gom&S  
        i += sprintf(buf, "performance powersave"); N\*oL*[j  
        goto out; I`{*QU  
    } :41Y  
RJ@79L *#  
    list_for_each_entry(t, &cpufreq_governor_list, governor_list) { @CzFzVmF"  
        if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) 0YFXF  
            - (CPUFREQ_NAME_LEN + 2))) 12U]=  
            goto out; O8 .xt|  
        i += scnprintf(&buf, CPUFREQ_NAME_LEN, "%s ", t->name); %urvX$r4K  
    } }R<t=):  
out: Q&:)D7m\)S  
    i += sprintf(&buf, "\n"); :@i+yN cV  
    return i; IOZw[9](+  
} 1<'z)r4  
4,LS08&gh  
static ssize_t show_cpus(const struct cpumask *mask, char *buf) FDD=I\Ic  
{ A#cFO)"  
    ssize_t i = 0; */h(4Hz  
    unsigned int cpu; Oq~{HJ{  
9Of;8R  
    for_each_cpu(cpu, mask) { |p[Mp:^^  
        if (i) _">F]ptI;  
            i += scnprintf(&buf, (PAGE_SIZE - i - 2), " "); Y"bm4&'  
        i += scnprintf(&buf, (PAGE_SIZE - i - 2), "%u", cpu); -:%QoRC y  
        if (i >= (PAGE_SIZE - 5)) Pv5S k8  
            break; [<@T%yq  
    } 'Hx#DhiFz  
    i += sprintf(&buf, "\n"); >`UqS`YQK  
    return i; e2 c'Wab  
} ]|g2V a~-  
6d]4 %QT  
/** k_]'?f7Z  
* show_related_cpus - show the CPUs affected by each transition even if Pg T3E  
* hw coordination is in use Dst;sLr[,  
*/ wA$7SWC  
static ssize_t show_related_cpus(struct cpufreq_policy *policy, char *buf) "qq$i35x  
{ 8*u'D@0  
    if (cpumask_empty(policy->related_cpus)) HjA~3l7  
        return show_cpus(policy->cpus, buf); g/.FJ-I*  
    return show_cpus(policy->related_cpus, buf); =F_uK7W  
} n~6$CQ5dF(  
DGGySO6=$e  
/** 2x<BU3  
* show_affected_cpus - show the CPUs affected by each transition HD KF>S_S  
*/ Jn{)CZ  
static ssize_t show_affected_cpus(struct cpufreq_policy *policy, char *buf) Pr} l y  
{ >P j#?j*Y  
    return show_cpus(policy->cpus, buf); 1R8tR#l  
} !QwB8yK@  
V]--d33/a  
static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, >I@&"&d  
                    const char *buf, size_t count) sZ=!*tb-  
{ {2q"9Ox"  
    unsigned int freq = 0; ?VotIruR  
    unsigned int ret; $O\m~r4  
1oO(;--u_  
    if (!policy->governor || !policy->governor->store_setspeed) S*G^U1Sc+  
        return -EINVAL; D,.`mX  
}Y7P2W+4?  
    ret = sscanf(buf, "%u", &freq); WVyDE1K <  
    if (ret != 1) Q<6* UUQm  
        return -EINVAL; QaO9-:]eN  
&I-:=ir  
    policy->governor->store_setspeed(policy, freq); O<p=&=TD7  
DtBvfYO8)>  
    return count; ).jQ+XE'>  
} VvIUAn  
%TI3Eb  
static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) f B<Qs.T  
{ | t:UpP  
    if (!policy->governor || !policy->governor->show_setspeed) l\L71|3"g  
        return sprintf(buf, "<unsupported>\n"); Caj H;K\  
tb?TPd-OY  
    return policy->governor->show_setspeed(policy, buf); ;V~x[J|x  
} s2,6aW C  
cu1!WD  
/** p,z>:3M  
* show_scaling_driver - show the current cpufreq HW/BIOS limitation VTL_I^p  
*/ 2<UC^vZ  
static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf) 3. dSS  
{ F6 ~ ;f;  
    unsigned int limit; tOVTHx3E]  
    int ret; ;rL>{UhG  
    if (cpufreq_driver->bios_limit) { 1^]IuPxq  
        ret = cpufreq_driver->bios_limit(policy->cpu, &limit); "\Dqtr w  
        if (!ret) 1:<n(?5JI  
            return sprintf(buf, "%u\n", limit); uG'S&8i_  
    } J;XO1}9  
    return sprintf(buf, "%u\n", policy->cpuinfo.max_freq); ='.b/]!_  
} q<.k:v&  
S@pdCH, n  
cpufreq_freq_attr_ro_perm(cpuinfo_cur_freq, 0400); #@YKNS[  
cpufreq_freq_attr_ro(cpuinfo_min_freq); &&$*MHJ  
cpufreq_freq_attr_ro(cpuinfo_max_freq); nT:<_'!  
cpufreq_freq_attr_ro(cpuinfo_transition_latency); 9+*{3 t  
cpufreq_freq_attr_ro(scaling_available_governors); 6miXaAA8  
cpufreq_freq_attr_ro(scaling_driver); Tr>_R%bK  
cpufreq_freq_attr_ro(scaling_cur_freq); < `;Mf>V  
cpufreq_freq_attr_ro(bios_limit); y)|d`qC\  
cpufreq_freq_attr_ro(related_cpus); GBZu<t/  
cpufreq_freq_attr_ro(affected_cpus); j@nK6`d+1  
cpufreq_freq_attr_rw(scaling_min_freq); jHT^I as  
cpufreq_freq_attr_rw(scaling_max_freq); =@O&$&  
cpufreq_freq_attr_rw(scaling_governor); rg[#(  
cpufreq_freq_attr_rw(scaling_setspeed); I3.JAoB>!  
Edc3YSg%;  
static struct attribute *default_attrs[] = { 3s]o~I2x  
    &cpuinfo_min_freq.attr, }Uj-R3]}K  
    &cpuinfo_max_freq.attr, DJdhOLx  
    &cpuinfo_transition_latency.attr, A]QGaWK  
    &scaling_min_freq.attr, 21<Sfsc$  
    &scaling_max_freq.attr, SefF Ci%4  
    &affected_cpus.attr, -h|[8UG^b  
    &related_cpus.attr, g@O?0,+1  
    &scaling_governor.attr, WllQM,h  
    &scaling_driver.attr, ,^1 #Uz8  
    &scaling_available_governors.attr, 4VF]t X?o  
    &scaling_setspeed.attr, 1)}hzA  
    NULL "<egm^Yq  
}; >G?*rg4  
7^.g\Kt?  
struct kobject *cpufreq_global_kobject; dw}ge,bBic  
EXPORT_SYMBOL(cpufreq_global_kobject); 3LQ u+EsS  
&)q>Z!C-l  
#define to_policy(k) container_of(k, struct cpufreq_policy, kobj) d+h~4'ebv  
#define to_attr(a) container_of(a, struct freq_attr, attr)  m5J@kE%  
r;(^]Soz  
static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) ;x_T*} CH  
{ ~|~2B$JeV  
    struct cpufreq_policy *policy = to_policy(kobj); u9q#L.Ij  
    struct freq_attr *fattr = to_attr(attr); 6e,IjocsB  
    ssize_t ret = -EINVAL; YJz06E1 -9  
    policy = cpufreq_cpu_get(policy->cpu); 7/]Ra  
    if (!policy) " 5Pqvi  
        goto no_policy; .pxUO3g  
x^`P[>  
    if (lock_policy_rwsem_read(policy->cpu) < 0) V@G|2ZI  
        goto fail; {J)gS  
rx#GrV*y  
    if (fattr->show) Wxj(3lg/  
        ret = fattr->show(policy, buf); 4%yeEc ;z  
    else {O=_c|u{N  
        ret = -EIO; R SWw4}  
~r})&`5  
    unlock_policy_rwsem_read(policy->cpu); W>CG;x{  
fail: ;&w_.j*Is  
    cpufreq_cpu_put(policy); jX$U)O  
no_policy: "_rpErm }  
    return ret; 6m(+X M S  
} -idbR[1{?  
L Do~  
static ssize_t store(struct kobject *kobj, struct attribute *attr, g_Y$5ft`  
             const char *buf, size_t count) oO &%&;[/A  
{ w2!5TKZ`  
    struct cpufreq_policy *policy = to_policy(kobj); K.?S,qg  
    struct freq_attr *fattr = to_attr(attr); 04X/(74  
    ssize_t ret = -EINVAL; ~2Mcw`<  
    policy = cpufreq_cpu_get(policy->cpu); j=Q ?d]  
    if (!policy) D_z&G)  
        goto no_policy; F CfU=4O  
L?(1 [jB4G  
    if (lock_policy_rwsem_write(policy->cpu) < 0) }p9#Bzc  
        goto fail; C91'dM  
rc{F17~vX  
    if (fattr->store) KAT^vbR  
        ret = fattr->store(policy, buf, count); Z2]\k|%<Fa  
    else >I/~)B`jhE  
        ret = -EIO; 1OK~*=/4  
S6yLq|W0  
    unlock_policy_rwsem_write(policy->cpu); L6=5]?B=  
fail: ,I f9w$(z  
    cpufreq_cpu_put(policy); kQ6YQsJ.*  
no_policy: :N4?W}r.  
    return ret; dlV HyCW  
} P=4o)e7E!  
<;Td8T;  
static void cpufreq_sysfs_release(struct kobject *kobj) ~05(92bK  
{ ~X) 1!Sr  
    struct cpufreq_policy *policy = to_policy(kobj); y 0fI7:e3  
    pr_debug("last reference is dropped\n"); 2 :^  
    complete(&policy->kobj_unregister); Eo <N  
} te3\MSv;O  
GtqA@&5&  
static const struct sysfs_ops sysfs_ops = { 0o?2Sf`L\*  
    .show    = show, >$A,B  
    .store    = store, &nn+X%m9g  
}; [k,FJ5X  
=:^f6"p&Z  
static struct kobj_type ktype_cpufreq = { Oimq P  
    .sysfs_ops    = &sysfs_ops, .Dyxul  
    .default_attrs    = default_attrs, "4QD\k5  
    .release    = cpufreq_sysfs_release, G:PcV_ihx  
}; +d8?=LX  
d a.6Z!a  
/* c~Z\|Y`#B  
* Returns: rx(z::  
*   Negative: Failure 3)~z~p7  
*   0:        Success [iG4qI  
*   Positive: When we have a managed CPU and the sysfs got symlinked lH oV>k  
*/ 6Y= MW{=F  
static int cpufreq_add_dev_policy(unsigned int cpu, MB(l*ju0  
                  struct cpufreq_policy *policy, BIEeHN4  
                  struct sys_device *sys_dev) @1peJJ{  
{ naW!Mga  
    int ret = 0;  .Aa(  
#ifdef CONFIG_SMP rWzO> v  
    unsigned long flags; ( |Xc_nC  
    unsigned int j; bQ_N^[oxQ  
#ifdef CONFIG_HOTPLUG_CPU i<uk}  
    struct cpufreq_governor *gov; JKYkS*.a}  
zlN<yZB^  
    gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); 0VlB7oF  
    if (gov) { <nT).S>+  
        policy->governor = gov; .Vb\f  
        pr_debug("Restoring governor %s for cpu %d\n", 3ES3, uR  
               policy->governor->name, cpu); ]g0\3A  
    } "+ 8Y{T  
#endif A^hFRAg4  
9iQc\@eGd  
    for_each_cpu(j, policy->cpus) { Ft$tL;  
        struct cpufreq_policy *managed_policy; gJI(d6  
Mhj.3nN  
        if (cpu == j) D4CiB"g3*  
            continue; x[H9<&)D  
73d7'Fw  
        /* Check for existing affected CPUs. XnI)s^  
         * They may not be aware of it due to CPU Hotplug. O'<cEv'B*  
         * cpufreq_cpu_put is called when the device is removed M8' GbF=1  
         * in __cpufreq_remove_dev() #1` lJ  
         */ <gc\ ,P<ru  
        managed_policy = cpufreq_cpu_get(j); SPK% ' s  
        if (unlikely(managed_policy)) { bMpCQ  
Oe*+pReSD  
            /* Set proper policy_cpu */ vT>ki0P_;  
            unlock_policy_rwsem_write(cpu); 6H_7M(f  
            per_cpu(cpufreq_policy_cpu, cpu) = managed_policy->cpu; /5c;,.hm1R  
^(8(z@y  
            if (lock_policy_rwsem_write(cpu) < 0) { \a6knd  
                /* Should not go through policy unlock path */ ]@MBE1M  
                if (cpufreq_driver->exit) Ss~dK-{e7  
                    cpufreq_driver->exit(policy); n9Xssl0  
                cpufreq_cpu_put(managed_policy); v"dj%75O?e  
                return -EBUSY; 92HxZ*t7km  
            } _~b$6Nf!83  
27!9LU  
            spin_lock_irqsave(&cpufreq_driver_lock, flags); &7\q1X&Rr  
            cpumask_copy(managed_policy->cpus, policy->cpus); zS##YR  
            per_cpu(cpufreq_cpu_data, cpu) = managed_policy; tv1Z%Mx?Cp  
            spin_unlock_irqrestore(&cpufreq_driver_lock, flags); e+5]l>3)f  
406.6jmv  
            pr_debug("CPU already managed, adding link\n"); tu6Q7CjW8  
            ret = sysfs_create_link(&sys_dev->kobj, z rV  
                        &managed_policy->kobj, gqf*;Z eU  
                        "cpufreq"); J~[A8o  
            if (ret) `II/nv0jn  
                cpufreq_cpu_put(managed_policy); U0kEhMIIf  
            /* s1eGItx[w  
             * Success. We only needed to be added to the mask. ~~_!&  
             * Call driver->exit() because only the cpu parent of ;w_f^R #  
             * the kobj needed to call init(). IT u6m<V  
             */ K;wd2/jmJ  
            if (cpufreq_driver->exit) _DK%-,Spu  
                cpufreq_driver->exit(policy); phA^ kdW  
KF[P /cFI  
            if (!ret) )./%/ _*K  
                return 1; FM3DJ?\L-  
            else `E),G;I  
                return ret; ]`2=<n;=  
        } )"IBw0]  
    } K 9X0/  
#endif +h$) l/>:  
    return ret; A:3:Cr  
} '}D$"2I*  
{T]^C  
 OBY  
/* symlink affected CPUs */ tDl1UX  
static int cpufreq_add_dev_symlink(unsigned int cpu, ;n Pjyu'g  
                   struct cpufreq_policy *policy) 5Y\wXqlY  
{ 9*+%Qt,{B  
    unsigned int j; D e>'  
    int ret = 0; >~kSe=Hsb4  
_[,oP s:+  
    for_each_cpu(j, policy->cpus) { NiwJ$Ah~X  
        struct cpufreq_policy *managed_policy; F~cvob{  
        struct sys_device *cpu_sys_dev; luyU!  
Qifjv0&;u  
        if (j == cpu) "]dNN{Wka  
            continue; RQZ|:SvV  
        if (!cpu_online(j)) YJlpP0;++  
            continue; v}v! hs Q  
pr2b<(Pm  
        pr_debug("CPU %u already managed, adding link\n", j); $ePBw~yu  
        managed_policy = cpufreq_cpu_get(cpu); >4A~?=  
        cpu_sys_dev = get_cpu_sysdev(j); Xi]WDH \  
        ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, 0k?ph$  
                    "cpufreq"); 9Se7 1  
        if (ret) { F j_r n  
            cpufreq_cpu_put(managed_policy); \(PC#H%  
            return ret; KB$s7S"=  
        } L-  -  
    } 5YlY=J  
    return ret; qYHAXc}$  
} qV%t[>  
+X4O.6Mn  
static int cpufreq_add_dev_interface(unsigned int cpu, km; M!}D  
                     struct cpufreq_policy *policy, Zc"Vf]:  
                     struct sys_device *sys_dev) .!ThqYo  
{ 9{?L3V!+r  
    struct cpufreq_policy new_policy; >g%^hjJ  
    struct freq_attr **drv_attr; %rpJZ t  
    unsigned long flags; fX,L;Se"  
    int ret = 0; @_tQ:U,v  
    unsigned int j; bqwQi>^Cw  
E\V-< ]o  
    /* prepare interface data */ e Ir|%  
    ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, AnV\{A^  
                   &sys_dev->kobj, "cpufreq"); "p43#  
    if (ret) K|-?1)Um  
        return ret; j +j2_\  
!c`K zqP  
    /* set up files for this cpu device */ sN^3bfi!i  
    drv_attr = cpufreq_driver->attr; SMr ]Gf.  
    while ((drv_attr) && (*drv_attr)) { 289@O-  
        ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); M <oy  
        if (ret) D"WqJcDt  
            goto err_out_kobj_put; B!|<<;Da6  
        drv_attr++; mC P*v-  
    } ;}!hgyq  
    if (cpufreq_driver->get) { $MF U9<O  
        ret = sysfs_create_file(&policy->kobj, &cpuinfo_cur_freq.attr); o2 =UUD&  
        if (ret) \#P>k;D  
            goto err_out_kobj_put; d, fX3  
    } 3PB#m.N<  
    if (cpufreq_driver->target) { >E;-asD  
        ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr); |wASeZMO2  
        if (ret) \Kph?l9Ww  
            goto err_out_kobj_put; :` >|N|i  
    } (9_~R^='y  
    if (cpufreq_driver->bios_limit) { j';V(ZY&BB  
        ret = sysfs_create_file(&policy->kobj, &bios_limit.attr); D-8N Da(`  
        if (ret) C9-IJj  
            goto err_out_kobj_put; E5d?toZ,8"  
    } S^,1N 4  
$sDvE~f0n  
    spin_lock_irqsave(&cpufreq_driver_lock, flags); 'j84-U{&)  
    for_each_cpu(j, policy->cpus) { #}50oWE  
        if (!cpu_online(j)) usb.cE3 z  
            continue; ;[*jLi,uc  
        per_cpu(cpufreq_cpu_data, j) = policy; }cK<2J#  
        per_cpu(cpufreq_policy_cpu, j) = policy->cpu; <eU28M?\  
    } 8}m bfu o1  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); +{V"a<D$m  
]I9Hbw  
    ret = cpufreq_add_dev_symlink(cpu, policy); O$}p}%%y7  
    if (ret) 4q"x|}a  
        goto err_out_kobj_put; }`g:) g J  
> }#h  
    memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); d52l)8  
    /* assure that the starting sequence is run in __cpufreq_set_policy */ t+'|&b][Qi  
    policy->governor = NULL; @5n!t1(  
{R[FwB^7wJ  
    /* set default policy */ n:zoN2lC  
    ret = __cpufreq_set_policy(policy, &new_policy); sY4sq5'!  
    policy->user_policy.policy = policy->policy; Ha l,%W~e  
    policy->user_policy.governor = policy->governor; a []Iz8*6e  
cE}R7,y  
    if (ret) { pkjf5DWp  
        pr_debug("setting policy failed\n"); 82% ~WQnS  
        if (cpufreq_driver->exit) FLI\SF<  
            cpufreq_driver->exit(policy); WVc3C-h,  
    } kTG4h@w  
    return ret; 3L$_OXx  
(lwrk(  
err_out_kobj_put: H`/Q hE  
    kobject_put(&policy->kobj); rrK&XP&  
    wait_for_completion(&policy->kobj_unregister); 5y7rY!]Bf  
    return ret; =[8EQdR  
} jU2Dpxkt  
hC ^|  
uU v yZ  
/** BKDs3?&  
* cpufreq_add_dev - add a CPU device +TW9BU'a^  
* c$),/0td|  
* Adds the cpufreq interface for a CPU device. E"l&<U  
*  Ad)Po  
* The Oracle says: try running cpufreq registration/unregistration concurrently %4#,y(dO  
* with with cpu hotplugging and all hell will break loose. Tried to clean this NvH9?Ek"  
* mess up, but more thorough testing is needed. - Mathieu wjk-$p  
*/ hzIP ?0^E  
static int cpufreq_add_dev(struct sys_device *sys_dev) " , c1z\  
{ >$,A [|R  
    unsigned int cpu = sys_dev->id; =a>a A Z  
    int ret = 0, found = 0; `YTagUq7  
    struct cpufreq_policy *policy; !@mV$nTA  
    unsigned long flags; "p>$^   
    unsigned int j; ,L#Qy>MOb  
#ifdef CONFIG_HOTPLUG_CPU s BP.P7u  
    int sibling; 3V:{_~~  
#endif ~_WsjD0O  
GOJ*>GpS  
    if (cpu_is_offline(cpu)) v3|-eWet^  
        return 0; (9:MIP  
3-cCdn  
    pr_debug("adding CPU %u\n", cpu); E"!I[  
B6)d2O9C  
#ifdef CONFIG_SMP 0yW#).D^b  
    /* check whether a different CPU already registered this w~J 7|8Y  
     * CPU because it is in the same boat. */ %bo0-lnp  
    policy = cpufreq_cpu_get(cpu); "&jA CI  
    if (unlikely(policy)) { f8`K8Y]4  
        cpufreq_cpu_put(policy); ~l$u~:4Ob  
        return 0; bJc<FL<E  
    } n4Fh*d ixg  
#endif IC&xL9  
P3|_R HIb  
    if (!try_module_get(cpufreq_driver->owner)) { q{v:T}Q|A  
        ret = -EINVAL; zbHNj(~  
        goto module_out; "Y(stRa  
    } lSv?!2  
/DOV/>@5%  
    ret = -ENOMEM; S9~X#tpKe  
    policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL); C^ngdba\  
    if (!policy) tL0<xGI5^  
        goto nomem_out; =zw=J p  
<<#-IsT  
    if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) 4W7  
        goto err_free_policy; H/8H`9S$  
6 &~8TH  
    if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) W}&[p=PAS  
        goto err_free_cpumask; Yud]s~N  
JCoDe.  
    policy->cpu = cpu; *_G(*yAe(  
    cpumask_copy(policy->cpus, cpumask_of(cpu)); ]IbX<  
Oax*3TD  
    /* Initially set CPU itself as the policy_cpu */ [J0f:&7\  
    per_cpu(cpufreq_policy_cpu, cpu) = cpu; L ]HtmI  
    ret = (lock_policy_rwsem_write(cpu) < 0); ovv<7`  
    WARN_ON(ret); l*^J}oY  
hV5Aw;7C  
    init_completion(&policy->kobj_unregister); r{y&}gA  
    INIT_WORK(&policy->update, handle_update); N$1ZA)M  
6H+'ezM  
    /* Set governor before ->init, so that driver could check it */ 9Q{-4yF9k  
#ifdef CONFIG_HOTPLUG_CPU npsDy&  
    for_each_online_cpu(sibling) { on?<3eED  
        struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); W\mj?R   
        if (cp && cp->governor && E'3=qTbiD  
            (cpumask_test_cpu(cpu, cp->related_cpus))) { /Y=Cg%+  
            policy->governor = cp->governor; wf47Ulx  
            found = 1; hY$gzls4  
            break; >*jcXao^  
        } ;pk4Voo$  
    } 8 MIn~  
#endif V_b"^911r  
    if (!found) a!UQ]prT  
        policy->governor = CPUFREQ_DEFAULT_GOVERNOR; [ j'L *j  
    /* call driver. From then on the cpufreq must be able L$R"?O7  
     * to accept all calls to ->verify and ->setpolicy for this CPU l=EnK"aU  
     */ aYTVYg  
    ret = cpufreq_driver->init(policy); 3khsGD@  
    if (ret) { #2*l"3.$.R  
        pr_debug("initialization failed\n"); +tsF.Is!t  
        goto err_unlock_policy; 5^kLNNum  
    } VaYL#\;c<  
    policy->user_policy.min = policy->min; tC;L A 4  
    policy->user_policy.max = policy->max; {wUbr^  
7Mx F? I  
    blocking_notifier_call_chain(&cpufreq_policy_notifier_list, >Z0F n  
                     CPUFREQ_START, policy); m\9R;$ \  
"*08?KA  
    ret = cpufreq_add_dev_policy(cpu, policy, sys_dev); L`sg60z  
    if (ret) { JQ5E;8J>  
        if (ret > 0) i.QS(gM  
            /* This is a managed cpu, symlink created, 3y&N}'R(F  
               exit with 0 */ 6"3-8orj   
            ret = 0; t:MeSO  
        goto err_unlock_policy; }XmrfegF  
    } Eb 8vnB#  
>"LHr&;m&h  
    ret = cpufreq_add_dev_interface(cpu, policy, sys_dev); *\#/4_yB}  
    if (ret) TcW-pY<N  
        goto err_out_unregister; qp#Is{=m  
zL8Z8eh">  
    unlock_policy_rwsem_write(cpu); dO?zLc0f  
4OX2GH=W  
    kobject_uevent(&policy->kobj, KOBJ_ADD); AN193o   
    module_put(cpufreq_driver->owner); @= E~`  
    pr_debug("initialization complete\n"); PjwDth A1  
*R'r=C`  
    return 0; |uUGvIsXn  
%@L[=\ 9  
_v/w ,z  
err_out_unregister: /,C;fT<R  
    spin_lock_irqsave(&cpufreq_driver_lock, flags); h#hx(5"6  
    for_each_cpu(j, policy->cpus) ;2#9q9(  
        per_cpu(cpufreq_cpu_data, j) = NULL; _ MsO2A  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); $7bLw)7  
% w\   
    kobject_put(&policy->kobj); V/.Na(C~  
    wait_for_completion(&policy->kobj_unregister); CdEQiu  
G3.*fSY$.<  
err_unlock_policy: lw\+!}8(  
    unlock_policy_rwsem_write(cpu); HZASIsl  
    free_cpumask_var(policy->related_cpus); <QuIXA  
err_free_cpumask: ?xa70Pb{;  
    free_cpumask_var(policy->cpus); LiG!xs  
err_free_policy: UWW^g@d4  
    kfree(policy); 0sMNp  
nomem_out: bA_/ 6r)u  
    module_put(cpufreq_driver->owner); kC,=E9)O  
module_out: |~K 5]  
    return ret; Z Zs@P#]  
} "U"phLX  
|mMK9OEu  
|?cL>]t  
/** GyC/39<P  
* __cpufreq_remove_dev - remove a CPU device kk`K)PESi  
* tG7F!um(  
* Removes the cpufreq interface for a CPU device. c;X%Ar  
* Caller should already have policy_rwsem in write mode for this CPU. SD/=e3  
* This routine frees the rwsem before returning. 1+F0$<e}  
*/ @=7[KMb  
static int __cpufreq_remove_dev(struct sys_device *sys_dev) f};RtRo2  
{ 8t;vZ&  
    unsigned int cpu = sys_dev->id; elqm/u  
    unsigned long flags; JRw<v4pZ  
    struct cpufreq_policy *data; QGCg~TV;  
    struct kobject *kobj; Af" p:;^z  
    struct completion *cmp; +P &S0/  
#ifdef CONFIG_SMP exZgk2[0  
    struct sys_device *cpu_sys_dev; ]x1;uE?1J  
    unsigned int j; AqA.,;G  
#endif 4 -CGe  
}>5R9  
    pr_debug("unregistering CPU %u\n", cpu); A'tv[T d8,  
} =p e;l  
    spin_lock_irqsave(&cpufreq_driver_lock, flags); UVd ^tg  
    data = per_cpu(cpufreq_cpu_data, cpu); -k?K|w*X  
SHc?C&^S  
    if (!data) { ]')  
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags); \wKnX]xGf  
        unlock_policy_rwsem_write(cpu); B,q)<z6<  
        return -EINVAL; ]+k]Gbty6  
    } >"q?P^f/  
    per_cpu(cpufreq_cpu_data, cpu) = NULL; >vR7l&"  
w t6&N{@  
w61*jnvi@  
#ifdef CONFIG_SMP mP] a}[  
    /* if this isn't the CPU which is the parent of the kobj, we uv&4 A,h  
     * only need to unlink, put and exit hcqg94R#_  
     */ dw-o71(1d  
    if (unlikely(cpu != data->cpu)) { h3[x ZJO  
        pr_debug("removing link\n"); ${5E  
        cpumask_clear_cpu(cpu, data->cpus); p[K!.vOt+  
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags); O@>ZYA%  
        kobj = &sys_dev->kobj; [w*]\x'S  
        cpufreq_cpu_put(data); a)8;P7  
        unlock_policy_rwsem_write(cpu); X%98k'h.y  
        sysfs_remove_link(kobj, "cpufreq"); AZE  
        return 0; aH&Efz^  
    } ;04< 9i  
#endif Q-?6o  
uC! dy  
#ifdef CONFIG_SMP FN<S agj  
V/+D]  
#ifdef CONFIG_HOTPLUG_CPU sd _DG8V  
    strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,  \62!{  
            CPUFREQ_NAME_LEN); $!vK#8-&{  
#endif 1d!TU=*  
c 'rn8Jo}  
    /* if we have other CPUs still registered, we need to unlink them, 7fC:' 1]G  
     * or else wait_for_completion below will lock up. Clean the m@W>ku  
     * per_cpu(cpufreq_cpu_data) while holding the lock, and remove g_JSgH!4  
     * the sysfs links afterwards. pE {yVs  
     */ zGwM# -  
    if (unlikely(cpumask_weight(data->cpus) > 1)) { YCq:]  
        for_each_cpu(j, data->cpus) { _/J`v`}G  
            if (j == cpu) Ltk-1zhI  
                continue; 6@;sOiN+  
            per_cpu(cpufreq_cpu_data, j) = NULL; #]h&GX  
        } A!v:W6yiz  
    } &a+=@Z)kf  
LvCX(yjZ*  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); Ki>XLX,er=  
h2 y<vO  
    if (unlikely(cpumask_weight(data->cpus) > 1)) { ]2c0?f*Y7  
        for_each_cpu(j, data->cpus) { LMNmG]#!  
            if (j == cpu) b"nD5r  
                continue; 6!C>J#T  
            pr_debug("removing link for cpu %u\n", j); %us#p|Ya  
#ifdef CONFIG_HOTPLUG_CPU 0_N.s5~N  
            strncpy(per_cpu(cpufreq_cpu_governor, j), -' =?Hs.  
                data->governor->name, CPUFREQ_NAME_LEN); q8}he~a  
#endif h!7Lvh`o  
            cpu_sys_dev = get_cpu_sysdev(j); tC5>K9Ed  
            kobj = &cpu_sys_dev->kobj;  L+CPT  
            unlock_policy_rwsem_write(cpu); 9w6 uoM  
            sysfs_remove_link(kobj, "cpufreq"); Wjli(sT#-  
            lock_policy_rwsem_write(cpu); AYAbq}'Yt  
            cpufreq_cpu_put(data); k3T374t1b  
        } <cFj-Ys(T  
    } 6$K@s  
#else p/HGI)'  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); !8YA1 o  
#endif & @${@  
&YBZuq2?  
    if (cpufreq_driver->target) %Iiu#- 'B  
        __cpufreq_governor(data, CPUFREQ_GOV_STOP); LKA/s ~G  
}^ =f%EjV  
    kobj = &data->kobj; BDCyeC,Q3  
    cmp = &data->kobj_unregister; @}s EP&$  
    unlock_policy_rwsem_write(cpu); /CUBs!  
    kobject_put(kobj); mNsd&Rk'  
,20l` :  
    /* we need to make sure that the underlying kobj is actually :sttGXQX  
     * not referenced anymore by anybody before we proceed with &UNQ4-s  
     * unloading. bwa*|{R  
     */  `fE'$2  
    pr_debug("waiting for dropping of refcount\n"); {q^UWv?1  
    wait_for_completion(cmp); PsZ>L  
    pr_debug("wait complete\n"); av_ +M;G  
MY^o0N  
    lock_policy_rwsem_write(cpu); [ P,gEYk  
    if (cpufreq_driver->exit) VB`% u=  
        cpufreq_driver->exit(data); csA-<}S5]b  
    unlock_policy_rwsem_write(cpu); /&9R*xNST#  
3"sXN)j  
#ifdef CONFIG_HOTPLUG_CPU |7Qe{  
    /* when the CPU which is the parent of the kobj is hotplugged 6  $`l  
     * offline, check for siblings, and create cpufreq sysfs interface 7* [  
     * and symlinks RRQIlI<  
     */ 3#Iq5vT  
    if (unlikely(cpumask_weight(data->cpus) > 1)) { uL ~wMX  
        /* first sibling now owns the new sysfs dir */ IyM:9=}5  
        cpumask_clear_cpu(cpu, data->cpus); "y5bODq3t  
        cpufreq_add_dev(get_cpu_sysdev(cpumask_first(data->cpus))); zFQm3!.  
z`p9vlS[  
        /* finally remove our own symlink */ u\"/EaQ{  
        lock_policy_rwsem_write(cpu); QMy1!:Z&!  
        __cpufreq_remove_dev(sys_dev); R7KV @n  
    } 0M?zotv0#  
#endif wk{]eD%  
KT17I&:  
    free_cpumask_var(data->related_cpus); a!f71k r  
    free_cpumask_var(data->cpus); dkqyn"^  
    kfree(data); SbQ:vAE*ho  
K=r~+4F  
    return 0; qJ .XI   
}  d^zuo  
i52JY&N  
>UV}^OO  
static int cpufreq_remove_dev(struct sys_device *sys_dev) 4?bvJJuf)  
{ RS@[ +!:t  
    unsigned int cpu = sys_dev->id; QjD=JC+  
    int retval; 18p4]:L  
,6o tm  
    if (cpu_is_offline(cpu)) H}q$6W E  
        return 0; P s<k2  
?b"'w  
    if (unlikely(lock_policy_rwsem_write(cpu))) nyxoa/  
        BUG(); D6"d\F m<  
~)zxIO!  
    retval = __cpufreq_remove_dev(sys_dev); $=`d[04  
    return retval; <_]W1V:0  
} ]h=5d09z  
$~VIx% h  
<@l j\,  
static void handle_update(struct work_struct *work) V F b  
{ |68u4zK  
    struct cpufreq_policy *policy = S <-5<Pg  
        container_of(work, struct cpufreq_policy, update); E25w^x2  
    unsigned int cpu = policy->cpu; /5Vv5d/Z4!  
    pr_debug("handle_update for cpu %u called\n", cpu); d+6q% U  
    cpufreq_update_policy(cpu); Pjxj$>&;*j  
} 9XhH*tBn7(  
TB=_r(:l+  
/** IYHNN  
*    cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're in deep trouble. UoUQ6Ij  
*    @cpu: cpu number >YsM'.EFD  
*    @old_freq: CPU frequency the kernel thinks the CPU runs at Pc7p2  
*    @new_freq: CPU frequency the CPU actually runs at cYXL3)p*Q  
* I?Z"YR+MQ  
*    We adjust to current frequency first, and need to clean up later. TP~1-(M)}  
*    So either call to cpufreq_update_policy() or schedule handle_update()). IGi9YpI&K  
*/ Bk^o$3#  
static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, HL dHyK/S  
                unsigned int new_freq) =BJe}AV  
{ YW&`PJ9o  
    struct cpufreq_freqs freqs; p L^3*B.Nr  
N2Ysi$  
    pr_debug("Warning: CPU frequency out of sync: cpufreq and timing " g#Ta03\  
           "core thinks of %u, is %u kHz.\n", old_freq, new_freq); Rha|Rk~  
BjA$^i|8  
    freqs.cpu = cpu; A)Rh Bi  
    freqs.old = old_freq; @,-D P41g  
    freqs.new = new_freq; |[>yJXxEL@  
    cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); Aon.Y Z  
    cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); z.?slYe[  
} @A<~bod  
6V}xgfB  
o^MoU2c  
/** @8+v6z  
* cpufreq_quick_get - get the CPU frequency (in kHz) from policy->cur O: #Sj jK  
* @cpu: CPU number Fs(S!;  
* Zb|a\z8?  
* This is the last known freq, without actually getting it from the driver. ,nGQVb   
* Return value will be same as what is shown in scaling_cur_freq in sysfs. ^]~!:Ej0  
*/ /L5:/Z  
unsigned int cpufreq_quick_get(unsigned int cpu) Li$2 Gpc/  
{ td23Z1Elk#  
    struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); GCX?W`  
    unsigned int ret_freq = 0;  M%W#0  
b`,Sd.2=('  
    if (policy) { &-X51O C  
        ret_freq = policy->cur; 065=I+Vo  
        cpufreq_cpu_put(policy); yy&L&v'  
    } ^U96p0H"T  
t}?-ao  
    return ret_freq; gW9`k,U  
} <h}x7y?  
EXPORT_SYMBOL(cpufreq_quick_get); mZmEE2h  
+c, ^KHW  
`&xdSH  
static unsigned int __cpufreq_get(unsigned int cpu) 7^mQfQv  
{ " vc4QH$  
    struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); H*P+>j&  
    unsigned int ret_freq = 0; IiE^HgM  
(I'{ pF)  
    if (!cpufreq_driver->get) inZ0iU9dy  
        return ret_freq; `D$^SHfyz  
rmtCCPF?0  
    ret_freq = cpufreq_driver->get(cpu); LnN:;h  
YI> xxWA  
    if (ret_freq && policy->cur && }[MkJ21!  
        !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { apgKC;  
        /* verify no discrepancy between actual and q5@Nd3~h  
                    saved value exists */ x K\i&A  
        if (unlikely(ret_freq != policy->cur)) { m({ q<&]Qp  
            cpufreq_out_of_sync(cpu, policy->cur, ret_freq); bAuiMw7!  
            schedule_work(&policy->update); 8 Gy*BpmJn  
        } }d iE'  
    } 0Zo><=  
w(t1m]pF[  
    return ret_freq; e7\gd\  
} P4c3kO0  
#o9CC)q5G  
/** :(tKc3z  
* cpufreq_get - get the current CPU frequency (in kHz) p>:.js5.a  
* @cpu: CPU number {4f%UnSz(  
* TcJJ"[0  
* Get the CPU current (static) CPU frequency 8}4.x3uw  
*/ jVN=_Y}\  
unsigned int cpufreq_get(unsigned int cpu) G\,B*$3   
{ |ITb1O`_P  
    unsigned int ret_freq = 0; x!pd50-   
    struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); jUR* |  
}1+2&Ps50  
    if (!policy) [;F!\B-  
        goto out; 2Ur&_c6 P  
(nuTfmt>  
    if (unlikely(lock_policy_rwsem_read(cpu))) -eS r  
        goto out_policy; \u[5O@v#  
HU4h.Lm  
    ret_freq = __cpufreq_get(cpu); 4gdXO  
l[m*csDk"  
    unlock_policy_rwsem_read(cpu); =?wDQ:  
>1]hR)Ip  
out_policy: ) hoVB  
    cpufreq_cpu_put(policy); QQS "K g  
out: v$(Z}Hg  
    return ret_freq; es.Y  
} 9L4;#cy  
EXPORT_SYMBOL(cpufreq_get); Zu4CFX-4  
xS+xUi  
static struct sysdev_driver cpufreq_sysdev_driver = { xy$aFPH!-  
    .add        = cpufreq_add_dev, O*,O]Q  
    .remove        = cpufreq_remove_dev, ZC<EPUV(  
}; '.S02=/  
<@+L^Ps~z  
p-rQ'e  
/** 48G^$T{  
* cpufreq_bp_suspend - Prepare the boot CPU for system suspend. h4Arg~Or  
* Q`Pe4CrWvu  
* This function is only executed for the boot processor.  The other CPUs T-kHk(  
* have been put offline by means of CPU hotplug. %]tW2s"  
*/ }NdLd!  
static int cpufreq_bp_suspend(void) 2.v`J=R  
{ V2@( BliP  
    int ret = 0; !O'p{dj][  
';D>Z ?l  
    int cpu = smp_processor_id(); aYHs35  
    struct cpufreq_policy *cpu_policy; ^"vmIC.h  
 :fy,%su  
    pr_debug("suspending cpu %u\n", cpu); `w@z Fc!"  
Fy$ C._C$  
    /* If there's no policy for the boot CPU, we have nothing to do. */ n: {f\  
    cpu_policy = cpufreq_cpu_get(cpu); IEJ)Q$GI#  
    if (!cpu_policy) @$$ J}~{  
        return 0; > #9 a&O  
d& v 7l  
    if (cpufreq_driver->suspend) { 4Sdj#w  
        ret = cpufreq_driver->suspend(cpu_policy); /; 21?o  
        if (ret) ^U,C])n  
            printk(KERN_ERR "cpufreq: suspend failed in ->suspend " <+b~E,  
                    "step on CPU %u\n", cpu_policy->cpu); _ |HA\!  
    } L/vw7XNrX  
WUQa2$.  
    cpufreq_cpu_put(cpu_policy); aE"dpYQ  
    return ret; j"zW0g!S  
} $~ d6KFT  
[=Nv=d<[p  
/** q_BMZEM  
* cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. ('d,Sh  
* ,MHF  
*    1.) resume CPUfreq hardware support (cpufreq_driver->resume()) /!/Pk'p=/  
*    2.) schedule call cpufreq_update_policy() ASAP as interrupts are B/hQvA;(  
*        restored. It will verify that the current freq is in sync with Ze[\y(K!  
*        what we believe it to be. This is a bit later than when it PtL8Kd0`C  
*        should be, but nonethteless it's better than calling b#t5Dve  
*        cpufreq_driver->get() here which might re-enable interrupts... EF=5[$ u  
* L"jjD:  
* This function is only executed for the boot CPU.  The other CPUs have not 8/u kzY1!  
* been turned on yet. "l#"c{ee{  
*/ 6vJ S"+ <  
static void cpufreq_bp_resume(void) )RWukr+  
{ 20J-VN:  
    int ret = 0; $h=v ;1"  
mfDt_Iq  
    int cpu = smp_processor_id(); RcO.1@2  
    struct cpufreq_policy *cpu_policy; u-V( 2?  
L` rrT   
    pr_debug("resuming cpu %u\n", cpu); 6bf!v  
=~)rT8+)  
    /* If there's no policy for the boot CPU, we have nothing to do. */  _Vc4F_  
    cpu_policy = cpufreq_cpu_get(cpu); -h8Z@r~a/  
    if (!cpu_policy) u`!Dp$P  
        return; 0}9jl  
n1'i!NWt  
    if (cpufreq_driver->resume) { #}tdA( -  
        ret = cpufreq_driver->resume(cpu_policy); [w+1<ou;j  
        if (ret) { O\%0D.HEz  
            printk(KERN_ERR "cpufreq: resume failed in ->resume " Wm)Id_  
                    "step on CPU %u\n", cpu_policy->cpu); OsYZ a`$,  
            goto fail; 2IkyC`  
        } :kjs: 6f]  
    } Ou f\%E<  
]{ch]m  
    schedule_work(&cpu_policy->update); \3F)M`g  
xz +;1JAL3  
fail: 7.kH="@  
    cpufreq_cpu_put(cpu_policy); ?1eu9;q\*  
} ~)ysEZl  
KyqP@ {  
static struct syscore_ops cpufreq_syscore_ops = { #9qX:*>h   
    .suspend    = cpufreq_bp_suspend, s]D1s%Mx  
    .resume        = cpufreq_bp_resume, iI*qx+>f?  
}; :x?G [x=  
_,p/2m-Pj  
<9;X1XtpI  
/********************************************************************* t+0/$  
*                     NOTIFIER LISTS INTERFACE                      * yK_$d0ZGE~  
*********************************************************************/ |H 5$VSw  
yv)-QIC3  
/** 'P%&*%  
*    cpufreq_register_notifier - register a driver with cpufreq iqsR]mab  
*    @nb: notifier function to register m/,8\+  
*      @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER _u~`RlA  
* %UV"@I+  
*    Add a driver to one of two lists: either a list of drivers that r -uu`=,  
*      are notified about clock rate changes (once before and once after VArMFP)cz  
*      the transition), or a list of drivers that are notified about =65XT^  
*      changes in cpufreq policy. 7Q&S [])  
* 'loko#6  
*    This function may sleep, and has the same return conditions as WO^]bR  
*    blocking_notifier_chain_register. J*^ i=y  
*/ P(L iH  
int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list) I3}I7oc_  
{ 6/Z_r0^O  
    int ret; dw| VH1fS  
&nY#G HB  
    WARN_ON(!init_cpufreq_transition_notifier_list_called); +.*=Fn22  
fA), ^  
    switch (list) { ;iUO1t)^  
    case CPUFREQ_TRANSITION_NOTIFIER: ykxAm\O  
        ret = srcu_notifier_chain_register( $ ]^Io)}f@  
                &cpufreq_transition_notifier_list, nb); LftGA7uGJ)  
        break; -"bC[WN  
    case CPUFREQ_POLICY_NOTIFIER: jgfr_"@A  
        ret = blocking_notifier_chain_register( ;g<y{o"Q3p  
                &cpufreq_policy_notifier_list, nb); i3$pqNe  
        break; Nfmr5MU_  
    default: (/i|3P  
        ret = -EINVAL; (>*L-&-  
    } UGoB7TEfn  
Z)}2bJwA  
    return ret; %+C6#cj  
} D\DwBZ>  
EXPORT_SYMBOL(cpufreq_register_notifier); |HwEwL+  
[X@JH6U r  
LvL2[xh%&  
/** *nV"X0&  
*    cpufreq_unregister_notifier - unregister a driver with cpufreq $3eoZ1q'U-  
*    @nb: notifier block to be unregistered mdcsL~R  
*      @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER 9]I{GyH  
* Xp fw2;`U'  
*    Remove a driver from the CPU frequency notifier list. TA~ZN^xI  
* )X8N|W>vh  
*    This function may sleep, and has the same return conditions as t&_X{!1X"w  
*    blocking_notifier_chain_unregister. LK>;\BRe?  
*/ i\o * =+{r  
int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list) Ghar hJ>v  
{ iaRCV 6cl  
    int ret; *mW2vJ/B  
Mh}vr%0;)  
    switch (list) { s Dsq:z  
    case CPUFREQ_TRANSITION_NOTIFIER: d$n<^ ~Z  
        ret = srcu_notifier_chain_unregister( $A T kCO  
                &cpufreq_transition_notifier_list, nb); h)z2#qfc  
        break; ,!P}Y[|  
    case CPUFREQ_POLICY_NOTIFIER: b]N&4t  
        ret = blocking_notifier_chain_unregister( Qp>Z&LvC5  
                &cpufreq_policy_notifier_list, nb); ylQ9Su>o  
        break; FRayB VHL  
    default: R pT7Nr  
        ret = -EINVAL; lZ) qV!<  
    } }|Bs|$q  
F|8;Swb5  
    return ret; n`T4P$pt  
} 9d!mGnl  
EXPORT_SYMBOL(cpufreq_unregister_notifier); Xu|2@?l9  
{~XnmBs  
@eq.&{&  
/********************************************************************* x]t$Zb/Uxa  
*                              GOVERNORS                            * BteeQ&A|~  
*********************************************************************/ c Ze59  
f5/s+H!  
/+m2|Ij(  
int __cpufreq_driver_target(struct cpufreq_policy *policy, 0: B%,n UM  
                unsigned int target_freq, }eveNPB{5  
                unsigned int relation) gq="&  
{ ! w;/J^  
    int retval = -EINVAL; r Cb#E}  
A>_,tt  
    pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu, Tf('iZ2+  
        target_freq, relation); `O0y8  
    if (cpu_online(policy->cpu) && cpufreq_driver->target) QH?sx k2  
        retval = cpufreq_driver->target(policy, target_freq, relation); x1Z*R+|>2  
^|2m&2  
    return retval; 5gb:,+  
} jWdZ ]0m  
EXPORT_SYMBOL_GPL(__cpufreq_driver_target); F&    
z|\n^ZK=  
int cpufreq_driver_target(struct cpufreq_policy *policy, FW{K[km^P  
              unsigned int target_freq, QXgfjo  
              unsigned int relation) t=fP^bJ  
{ @|e we. r  
    int ret = -EINVAL; 3jHg9M23[^  
#L57d  
    policy = cpufreq_cpu_get(policy->cpu); Q8$;##hzt  
    if (!policy) %Hhk 6tR,  
        goto no_policy; -"?~By}<C  
W{~ y< `D  
    if (unlikely(lock_policy_rwsem_write(policy->cpu))) c:<a"$  
        goto fail; ?-8DS5  
4vCUVo r  
    ret = __cpufreq_driver_target(policy, target_freq, relation); ):y^g:  
jB l$r{L  
    unlock_policy_rwsem_write(policy->cpu); vG\ b `  
wc&D[M]-/  
fail: {SD%{  
    cpufreq_cpu_put(policy); ,LDL%<7t  
no_policy: W_,7hvE?"H  
    return ret; ~ H/ZiBL@  
} JVr8O`>T  
EXPORT_SYMBOL_GPL(cpufreq_driver_target); h0I5zQZm  
Bx6,U4o*  
int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) *B9xL[}  
{ )<qL8#["U  
    int ret = 0; ^Y5I OX:  
|$~]|SK  
    policy = cpufreq_cpu_get(policy->cpu); wSPmiJ/!  
    if (!policy) u7j,Vc'~  
        return -EINVAL; ]q4(%Q  
=%s6QFR  
    if (cpu_online(cpu) && cpufreq_driver->getavg) g yhy0  
        ret = cpufreq_driver->getavg(policy, cpu); ~$hR:I1  
iSg0X8J)  
    cpufreq_cpu_put(policy); $: |`DCC  
    return ret; Ge7B%p8  
} mIqm/5  
EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg); g:GywX W  
uh\Tf5  
/* E&5S[n9{3  
* when "event" is CPUFREQ_GOV_LIMITS L4bYVTm|  
*/ :{B']~Xf  
z4$9,p `  
static int __cpufreq_governor(struct cpufreq_policy *policy, :R>RCR2g)  
                    unsigned int event) TQ0ZBhd  
{ `(=?k[48  
    int ret; #;?/fZjY  
,KU%"{6  
    /* Only must be defined when default governor is known to have latency "fUNrhCx  
       restrictions, like e.g. conservative or ondemand. 6a_U[-a9;  
       That this is the case is already ensured in Kconfig MUGoW;}v )  
    */ S\Le;,5Z  
#ifdef CONFIG_CPU_FREQ_GOV_PERFORMANCE He}?\C Bo  
    struct cpufreq_governor *gov = &cpufreq_gov_performance; o=K9\l  
#else LsaX HI/?b  
    struct cpufreq_governor *gov = NULL; 'cQ,;y  
#endif $)BPtGMGo  
NJVkn~<  
    if (policy->governor->max_transition_latency && J9DI(`  
        policy->cpuinfo.transition_latency > -Dy<B  
        policy->governor->max_transition_latency) { LZ.Xcy  
        if (!gov) u3E =r  
            return -EINVAL; `%"x'B`mM  
        else { ,v#n\LD`  
            printk(KERN_WARNING "%s governor failed, too long" ]<L~f~vU  
                   " transition latency of HW, fallback" pl)?4[`LUc  
                   " to %s governor\n", j+{cc: h"X  
                   policy->governor->name, MNb9~kM  
                   gov->name); CDsl)  
            policy->governor = gov; T?6<1nU)  
        } %lGOExV%  
    } !$>b}w'  
:]CL}n$*  
    if (!try_module_get(policy->governor->owner)) svb7-.!  
        return -EINVAL; z!18Jh  
`~"'\Hw  
    pr_debug("__cpufreq_governor for CPU %u, event %u\n", >5"e<mwD7d  
                        policy->cpu, event); 'mTY56Yq  
    ret = policy->governor->governor(policy, event); OLm@-I*  
Uxik&M  
    /* we keep one module reference alive for -3azA7tzz  
            each CPU governed by this CPU */ !!)$?R;1  
    if ((event != CPUFREQ_GOV_START) || ret) 4[MTEBx  
        module_put(policy->governor->owner); R[S1<m;  
    if ((event == CPUFREQ_GOV_STOP) && !ret) `wU['{=  
        module_put(policy->governor->owner); ~J> ;l s1  
}#%Y eCA?  
    return ret; \=mLL|a  
} ;aX?K/  
\_6  
|yzv o"3  
int cpufreq_register_governor(struct cpufreq_governor *governor) %#eQN ~  
{ =Y6W Qf  
    int err; T!>hPg  
b6sf1E  
    if (!governor) r jxkgd  
        return -EINVAL; N5ZO pRH{  
~gGkw#  
    mutex_lock(&cpufreq_governor_mutex); 5|N`:h'9M  
q5-i=lw  
    err = -EBUSY; wvxz:~M  
    if (__find_governor(governor->name) == NULL) { &GJVFr~z  
        err = 0; JMo r[*  
        list_add(&governor->governor_list, &cpufreq_governor_list); c$L1aZo  
    } GEh(pJ  
Z f<T`'_d  
    mutex_unlock(&cpufreq_governor_mutex); y Rl   
    return err; wy${EY^h  
} S-Vj$asv!  
EXPORT_SYMBOL_GPL(cpufreq_register_governor); NCG;`B`i  
^B} m~qT  
%O"Whe  
void cpufreq_unregister_governor(struct cpufreq_governor *governor) K%mR=u#%&  
{ qGEp 6b H  
#ifdef CONFIG_HOTPLUG_CPU a`#lYM%(>  
    int cpu; -WF((s;<#  
#endif ]4 c+{  
qm:C1#<p   
    if (!governor) X9]} UX  
        return; HF_8661g  
hhZ%{lqL  
#ifdef CONFIG_HOTPLUG_CPU Ng*-Bw)p]  
    for_each_present_cpu(cpu) { I^![)# FC  
        if (cpu_online(cpu)) &Mudu/KTr  
            continue; SlR//h  
        if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) *.k*JsU~B  
            strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); -)')PV_+  
    } /_{ZWLi(  
#endif t[>UAr1Vt  
UdM2!f  
    mutex_lock(&cpufreq_governor_mutex); at@tS>Dv  
    list_del(&governor->governor_list); nQ+5jGP1  
    mutex_unlock(&cpufreq_governor_mutex); {j]cL !Od  
    return; JW^ ${4  
} JJ_ Z{  
EXPORT_SYMBOL_GPL(cpufreq_unregister_governor); Qg(;>ops  
6?KUS}nRS  
F!)[H["_  
wS#Uw_[  
/********************************************************************* rXD:^wUSc  
*                          POLICY INTERFACE                         * H{=G\N{  
*********************************************************************/ `Ng Q>KV!  
:}Yk0*  
/** B; e<.M)e  
* cpufreq_get_policy - get the current cpufreq_policy js <Up/1  
* @policy: struct cpufreq_policy into which the current cpufreq_policy 5o>`7(t`  
*    is written UWV%  y P  
* >uq0}HB$a  
* Reads the current cpufreq policy.  'F.P93  
*/ J@_^]  
int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) vn$=be8l4  
{ q6C`hVM l  
    struct cpufreq_policy *cpu_policy; YARL/V  
    if (!policy) "49dsKIOH  
        return -EINVAL; *P`wuXn}  
#\m.3!Hcr  
    cpu_policy = cpufreq_cpu_get(cpu); z`E=V  
    if (!cpu_policy) a@W9\b@I  
        return -EINVAL; 2 A!*8w  
Um4zI>  
    memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); .Hqq!&  
mR@d4(:J?  
    cpufreq_cpu_put(cpu_policy); r2.w4RMFua  
    return 0; !0Nf`iCQ(  
} nf"#F@dk  
EXPORT_SYMBOL(cpufreq_get_policy); Wd)\r.pJ  
hZ e{Ri  
K)J_q3qo  
/* P<vU!`x% q  
* data   : current policy. _%D7D~2r|  
* policy : policy to be set. sZ&|omN  
*/ $G"\@YC<  
static int __cpufreq_set_policy(struct cpufreq_policy *data, J.4U;A5  
                struct cpufreq_policy *policy) Nr>UZlU8  
{ [5p9p1@u{C  
    int ret = 0; [y'blCb  
W& 0R/y7  
    pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, 1#_ pj eG  
        policy->min, policy->max); |w*s:p  
E:**gvfq  
    memcpy(&policy->cpuinfo, &data->cpuinfo, zqNzWX  
                sizeof(struct cpufreq_cpuinfo)); X0P +[.i  
]j/= x2p  
    if (policy->min > data->max || policy->max < data->min) { |*g#7 YL  
        ret = -EINVAL; OH2IO  
        goto error_out; Lv%t*s2$/  
    } *a CVkFp  
qX-5/;n  
    /* verify the cpu speed can be set within this limit */ hui #<2{  
    ret = cpufreq_driver->verify(policy); Sj(>G;  
    if (ret) MW rhVn{R  
        goto error_out; > VIFQ\  
(b#M4ho*f  
    /* adjust if necessary - all reasons */ _yN5sLLyb  
    blocking_notifier_call_chain(&cpufreq_policy_notifier_list, W1"NKg~4  
            CPUFREQ_ADJUST, policy); .p e3L7g  
%pjeA[-m#  
    /* adjust if necessary - hardware incompatibility*/ A9BoH[is7  
    blocking_notifier_call_chain(&cpufreq_policy_notifier_list, ,ESli/6  
            CPUFREQ_INCOMPATIBLE, policy); g{}<ptx]  
Y(7&3+'K  
    /* verify the cpu speed can be set within this limit, gtMR/P:S  
       which might be different to the first one */ uVU)LOx  
    ret = cpufreq_driver->verify(policy); hfY/)-60o  
    if (ret) ">wvd*w0"(  
        goto error_out; r7R'beiH  
4_QfM}Fyp  
    /* notification of the new policy */ /fT"WaTEK  
    blocking_notifier_call_chain(&cpufreq_policy_notifier_list, %4!^AA%  
            CPUFREQ_NOTIFY, policy); d<j`=QH  
_dk[k@5W{'  
    data->min = policy->min; 1DcBF@3sWG  
    data->max = policy->max; X+A@//,7  
tUULpx.h  
    pr_debug("new min and max freqs are %u - %u kHz\n", J  Y8Rk=  
                    data->min, data->max); de W1>yh^_  
u,8)M' UU  
    if (cpufreq_driver->setpolicy) { ;AOLbmb)H4  
        data->policy = policy->policy; jnJ*e-AW  
        pr_debug("setting range\n"); >fP;H}S6  
        ret = cpufreq_driver->setpolicy(policy); KM[0aXOtv  
    } else { E%v0@  
        if (policy->governor != data->governor) { :B5*?x  
            /* save old, working values */ hv#$Zo<  
            struct cpufreq_governor *old_gov = data->governor; BXdk0  
P<&bAsje  
            pr_debug("governor switch\n"); \w1XOm [)  
y ]@JkF(  
            /* end old governor */ *Xk5H,:  
            if (data->governor) DQW)^j h  
                __cpufreq_governor(data, CPUFREQ_GOV_STOP); LBD],Ba!  
ghB&wOm/  
            /* start new governor */ aeN #<M&$<  
            data->governor = policy->governor; *l =f=  
            if (__cpufreq_governor(data, CPUFREQ_GOV_START)) { Rf`_q7fm  
                /* new governor failed, so re-start old one */ B$2GEg]Ri  
                pr_debug("starting governor %s failed\n", YL|)`m0-^5  
                            data->governor->name); /YZMP'v  
                if (old_gov) { H0"'jd  
                    data->governor = old_gov; $k&v juB.  
                    __cpufreq_governor(data, qZ[HILh!  
                               CPUFREQ_GOV_START); /Q7q2Ne^*  
                } e6_8f*o|s  
                ret = -EINVAL; "TaLvworb4  
                goto error_out; bFN/{^SB  
            } , 2#Q >  
            /* might be a policy change, too, so fall through */ D%3$"4M7!  
        } |k}L=oWE  
        pr_debug("governor: change or update limits\n"); Ua|iAD 1  
        __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); XTX/vbge3m  
    } Q.Nw#r+m  
/# Jvt  
error_out: 7NT} Zwf  
    return ret; oZ/"^5  
} Ek `bPQ5  
_PPC?k{z!  
/** C@ q#s  
*    cpufreq_update_policy - re-evaluate an existing cpufreq policy ?F]P=S:x  
*    @cpu: CPU which shall be re-evaluated TE o  
* :35h0;8+  
*    Useful for policy notifiers which have different necessities <?IDCOt ?  
*    at different times. XZk%5t|t  
*/ x^)?V7[t  
int cpufreq_update_policy(unsigned int cpu) {:"<E?+  
{ 3YLfh`6  
    struct cpufreq_policy *data = cpufreq_cpu_get(cpu); `T+>E0H(f  
    struct cpufreq_policy policy; xV+\R/)x  
    int ret; q['D?)sy  
/q>ExXsEC  
    if (!data) { AKjobA#  
        ret = -ENODEV; 9*FA=E  
        goto no_policy; \;'#8  
    } #y#TEw,  
<Ez@cZ"  
    if (unlikely(lock_policy_rwsem_write(cpu))) { a"xRc  
        ret = -EINVAL; *jc >?)k  
        goto fail; {ST8'hY  
    } k0I$x:c  
t*Ro2QZ  
    pr_debug("updating policy for CPU %u\n", cpu); Ji,;ri2i  
    memcpy(&policy, data, sizeof(struct cpufreq_policy));  Xp<O  
    policy.min = data->user_policy.min; ]7k:3"wH  
    policy.max = data->user_policy.max; P]^8Enp  
    policy.policy = data->user_policy.policy; BTr;F]W  
    policy.governor = data->user_policy.governor; 1&e8vVN  
g&p(XuN  
    /* BIOS might change freq behind our back p@Os  
      -> ask driver for current freq and notify governors about a change */ q7aqbkwz}  
    if (cpufreq_driver->get) { D +0il=5  
        policy.cur = cpufreq_driver->get(cpu); "dv\ 9O  
        if (!data->cur) { j8e=],sQ  
            pr_debug("Driver did not initialize current freq"); @ ^F{  
            data->cur = policy.cur; L T`T~|pz  
        } else { |b='DJz2  
            if (data->cur != policy.cur) GNmP_N  
                cpufreq_out_of_sync(cpu, data->cur, rusM]Z  
                                policy.cur); -,/6 Wn'j  
        } @(=?x:j  
    } rr`_\ut  
,ynN801\m  
    ret = __cpufreq_set_policy(data, &policy); o-_,l J7o^  
VWdTnu  
    unlock_policy_rwsem_write(cpu); fuHNsrNlm  
34)l3UI~  
fail: C<:wSS^@1  
    cpufreq_cpu_put(data); @~$=96^  
no_policy: 0[ "CP:u  
    return ret; o\W>$$EXD  
} !}P^O(oY  
EXPORT_SYMBOL(cpufreq_update_policy); MTE 1\,  
X0ugnQ6  
static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, *j,noHUT~>  
                    unsigned long action, void *hcpu) "S{GjOlEDF  
{ @fo(#i&  
    unsigned int cpu = (unsigned long)hcpu; JM0+-,dl[  
    struct sys_device *sys_dev; M^l%*QF[,q  
\hlS?uD\  
    sys_dev = get_cpu_sysdev(cpu); ''9K(p6  
    if (sys_dev) { ixM#|Yq  
        switch (action) { *R4=4e2#S  
        case CPU_ONLINE: :G9d,B7*  
        case CPU_ONLINE_FROZEN: {Gfsiz6  
            cpufreq_add_dev(sys_dev); .aWwJZ=[  
            break; (mi=I3A(  
        case CPU_DOWN_PREPARE: Gz\wmH&rVz  
        case CPU_DOWN_PREPARE_FROZEN: 9P <1/W!  
            if (unlikely(lock_policy_rwsem_write(cpu))) 'dQGb-<_<  
                BUG(); 9@M;\ @&g  
d\A7}_r*x  
            __cpufreq_remove_dev(sys_dev); (NnE\2  
            break; s;Zi   
        case CPU_DOWN_FAILED: 0V"(}!=2a  
        case CPU_DOWN_FAILED_FROZEN: {Ho_U&<  
            cpufreq_add_dev(sys_dev); tQxAZ0B^  
            break; g(jn /Cx  
        } kp?_ir  
    } t]3:vp5N]  
    return NOTIFY_OK; b4KNIP7E  
} J~ @W":v  
Rdj3dg'<  
static struct notifier_block __refdata cpufreq_cpu_notifier = { 5``usn/&Kj  
    .notifier_call = cpufreq_cpu_callback, u[wDOw  
}; )!zg=}V  
?g K|R  
/********************************************************************* tnb'\}Vn  
*               REGISTER / UNREGISTER CPUFREQ DRIVER                * Y?oeP^V'u  
*********************************************************************/ c2gZ<[~  
5P);t9O6  
/** qMO(j%N5  
* cpufreq_register_driver - register a CPU Frequency driver bWCtRli}  
* @driver_data: A struct cpufreq_driver containing the values# *&_(kq z'1  
* submitted by the CPU Frequency driver. 7|ACJv6%9  
* |9m*? 7  
*   Registers a CPU Frequency driver to this core code. This code Kx;la  
* returns zero on success, -EBUSY when another driver got here first Aba%QQQ  
* (and isn't unregistered in the meantime). 33"!K>wC  
* Oeg^%Y   
*/ \H PB{ ;  
int cpufreq_register_driver(struct cpufreq_driver *driver_data) ~WmA55  
{ (G>g0(;D-  
    unsigned long flags; o|s|Wm x>u  
    int ret; *L<<S=g$2  
KpQ@cc  
    if (!driver_data || !driver_data->verify || !driver_data->init || ?|hYtV  
        ((!driver_data->setpolicy) && (!driver_data->target))) 6SAYe%e  
        return -EINVAL; `- 9p)@'8k  
>T14 J'\  
    pr_debug("trying to register driver %s\n", driver_data->name); H7{kl  
o8A(Cg}  
    if (driver_data->setpolicy) %NhZTmWm  
        driver_data->flags |= CPUFREQ_CONST_LOOPS; D|C!KF (  
-OgC.6  
    spin_lock_irqsave(&cpufreq_driver_lock, flags); b u/GaE~  
    if (cpufreq_driver) { <5|:QLqy  
        spin_unlock_irqrestore(&cpufreq_driver_lock, flags); %x^U3"7  
        return -EBUSY; dP/1E6*m  
    } .T~Oc'wGo  
    cpufreq_driver = driver_data; K>2Bz&)  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); SQG9m2  
U]E~7C  
    ret = sysdev_driver_register(&cpu_sysdev_class, jpiBHi]5+  
                    &cpufreq_sysdev_driver); .Jc<Gg  
    if (ret) @ w,O1Xwj  
        goto err_null_driver; kbx4I?  
Jj+Hj[(@  
    if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { |s !7U  
        int i; Pfg.'Bl  
        ret = -ENODEV;  OJ# d  
~N+H7T.L  
        /* check for at least one working CPU */ bqZ5GKUo  
        for (i = 0; i < nr_cpu_ids; i++) ~5~Cpu2v7  
            if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) { {@X)=.Zf  
                ret = 0; J}VG4}L  
                break; 6oR5q 4  
            } 5&Le?-/\  
>s ;dooZ  
        /* if all ->init() calls failed, unregister */ Ij7[2V]c  
        if (ret) { gCI{g. [I!  
            pr_debug("no CPU initialized for driver %s\n", KN\tRE  
                            driver_data->name); p}a0z?  
            goto err_sysdev_unreg; zW; sr.  
        } IKeO&]k  
    } (5=B^9{R  
z dUSmb  
    register_hotcpu_notifier(&cpufreq_cpu_notifier); Uj)`(}r  
    pr_debug("driver %s up and running\n", driver_data->name); ^r 9  
7MwS[N%#  
    return 0; _VLA2#V>   
err_sysdev_unreg: f;a55%3c  
    sysdev_driver_unregister(&cpu_sysdev_class, c"S{5xh0&  
            &cpufreq_sysdev_driver); rIAbr5CG  
err_null_driver: G@6F<L~$1  
    spin_lock_irqsave(&cpufreq_driver_lock, flags); &jE@i#  
    cpufreq_driver = NULL; /baSAoh/e  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); 2fMKS  
    return ret; r[KX"U-  
} Uf\U~wM<  
EXPORT_SYMBOL_GPL(cpufreq_register_driver); y9Q.TL>=[  
E Ks4N4k  
2j-^F  
/** WKONK;U+7  
* cpufreq_unregister_driver - unregister the current CPUFreq driver @`:z$52  
* JR4fJG  
*    Unregister the current CPUFreq driver. Only call this if you have o#=O5@>ai  
* the right to do so, i.e. if you have succeeded in initialising before! 6{?B`gm7g  
* Returns zero if successful, and -EINVAL if the cpufreq_driver is N|  
* currently not initialised. a/lTQj]A  
*/ t'bhA20Z\  
int cpufreq_unregister_driver(struct cpufreq_driver *driver) ECvTmU'=  
{ AP/#?   
    unsigned long flags; V*F |Yo:  
lw_PQ4Hp  
    if (!cpufreq_driver || (driver != cpufreq_driver)) C"g bol^  
        return -EINVAL; h~u|v[@{J  
$VUX?ii$7=  
    pr_debug("unregistering driver %s\n", driver->name); k[]2S8K2  
AkVgFQg" n  
    sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver); .%+y_.l  
    unregister_hotcpu_notifier(&cpufreq_cpu_notifier); P?j;&@$^e  
J42/S [Rt  
    spin_lock_irqsave(&cpufreq_driver_lock, flags); %<^j=K= 0  
    cpufreq_driver = NULL; ow K)]t  
    spin_unlock_irqrestore(&cpufreq_driver_lock, flags); IOOK[g.?h  
F0/!+ho  
    return 0; (A\\s$fE/1  
} ^.@F1k  
EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); U'0e<IcY  
.._UI2MA  
static int __init cpufreq_core_init(void) :r}C&3  
{ w7QYWf'  
    int cpu; @k||gQqIB  
;><m[l6  
    for_each_possible_cpu(cpu) { }sW%i#CV  
        per_cpu(cpufreq_policy_cpu, cpu) = -1; ^_\%?K_u  
        init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); &r1]A&  
    } nXfd f-  
cng166}1A  
    cpufreq_global_kobject = kobject_create_and_add("cpufreq", b>L?0p$ej  
                        &cpu_sysdev_class.kset.kobj); p|Nh:4iN  
    BUG_ON(!cpufreq_global_kobject); A/88WC$v  
    register_syscore_ops(&cpufreq_syscore_ops); Tx|y!uHh  
WlmkM?@  
    return 0; WGHf?G/s  
} nG0R1<  
core_initcall(cpufreq_core_init); EjP9/V G@=  


评价一下你浏览此帖子的感受

精彩

感动

搞笑

开心

愤怒

一般

差劲
快速回复
限150 字节
 
上一个 下一个