Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
371deb95
Commit
371deb95
authored
Apr 29, 2013
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pm-cpufreq'
* pm-cpufreq: cpufreq: Revert incorrect commit
5800043b
parents
885f925e
1c3d85dd
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
69 additions
and
214 deletions
+69
-214
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+69
-214
No files found.
drivers/cpufreq/cpufreq.c
View file @
371deb95
...
...
@@ -39,7 +39,7 @@
* level driver of CPUFreq support, and its spinlock. This lock
* also protects the cpufreq_cpu_data array.
*/
static
struct
cpufreq_driver
__rcu
*
cpufreq_driver
;
static
struct
cpufreq_driver
*
cpufreq_driver
;
static
DEFINE_PER_CPU
(
struct
cpufreq_policy
*
,
cpufreq_cpu_data
);
#ifdef CONFIG_HOTPLUG_CPU
/* This one keeps track of the previously set governor of a removed CPU */
...
...
@@ -130,34 +130,26 @@ static DEFINE_MUTEX(cpufreq_governor_mutex);
bool
have_governor_per_policy
(
void
)
{
bool
have_governor_per_policy
;
rcu_read_lock
();
have_governor_per_policy
=
rcu_dereference
(
cpufreq_driver
)
->
have_governor_per_policy
;
rcu_read_unlock
();
return
have_governor_per_policy
;
return
cpufreq_driver
->
have_governor_per_policy
;
}
static
struct
cpufreq_policy
*
__cpufreq_cpu_get
(
unsigned
int
cpu
,
bool
sysfs
)
{
struct
cpufreq_policy
*
data
;
struct
cpufreq_driver
*
driver
;
unsigned
long
flags
;
if
(
cpu
>=
nr_cpu_ids
)
goto
err_out
;
/* get the cpufreq driver */
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
read_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
if
(
!
driver
)
if
(
!
cpufreq_
driver
)
goto
err_out_unlock
;
if
(
!
try_module_get
(
driver
->
owner
))
if
(
!
try_module_get
(
cpufreq_
driver
->
owner
))
goto
err_out_unlock
;
read_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
/* get the CPU */
data
=
per_cpu
(
cpufreq_cpu_data
,
cpu
);
...
...
@@ -169,14 +161,12 @@ static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs)
goto
err_out_put_module
;
read_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
rcu_read_unlock
();
return
data
;
err_out_put_module:
module_put
(
driver
->
owner
);
read_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
module_put
(
cpufreq_driver
->
owner
);
err_out_unlock:
r
cu_read_unlock
(
);
r
ead_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
err_out:
return
NULL
;
}
...
...
@@ -199,9 +189,7 @@ static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs)
{
if
(
!
sysfs
)
kobject_put
(
&
data
->
kobj
);
rcu_read_lock
();
module_put
(
rcu_dereference
(
cpufreq_driver
)
->
owner
);
rcu_read_unlock
();
module_put
(
cpufreq_driver
->
owner
);
}
void
cpufreq_cpu_put
(
struct
cpufreq_policy
*
data
)
...
...
@@ -269,9 +257,7 @@ void __cpufreq_notify_transition(struct cpufreq_policy *policy,
if
(
cpufreq_disabled
())
return
;
rcu_read_lock
();
freqs
->
flags
=
rcu_dereference
(
cpufreq_driver
)
->
flags
;
rcu_read_unlock
();
freqs
->
flags
=
cpufreq_driver
->
flags
;
pr_debug
(
"notification %u of frequency transition to %u kHz
\n
"
,
state
,
freqs
->
new
);
...
...
@@ -282,7 +268,7 @@ void __cpufreq_notify_transition(struct cpufreq_policy *policy,
* which is not equal to what the cpufreq core thinks is
* "old frequency".
*/
if
(
!
(
freqs
->
flags
&
CPUFREQ_CONST_LOOPS
))
{
if
(
!
(
cpufreq_driver
->
flags
&
CPUFREQ_CONST_LOOPS
))
{
if
((
policy
)
&&
(
policy
->
cpu
==
freqs
->
cpu
)
&&
(
policy
->
cur
)
&&
(
policy
->
cur
!=
freqs
->
old
))
{
pr_debug
(
"Warning: CPU frequency is"
...
...
@@ -348,21 +334,11 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
struct
cpufreq_governor
**
governor
)
{
int
err
=
-
EINVAL
;
struct
cpufreq_driver
*
driver
;
bool
has_setpolicy
;
bool
has_target
;
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
if
(
!
driver
)
{
rcu_read_unlock
();
if
(
!
cpufreq_driver
)
goto
out
;
}
has_setpolicy
=
driver
->
setpolicy
?
true
:
false
;
has_target
=
driver
->
target
?
true
:
false
;
rcu_read_unlock
();
if
(
has_
setpolicy
)
{
if
(
cpufreq_driver
->
setpolicy
)
{
if
(
!
strnicmp
(
str_governor
,
"performance"
,
CPUFREQ_NAME_LEN
))
{
*
policy
=
CPUFREQ_POLICY_PERFORMANCE
;
err
=
0
;
...
...
@@ -371,7 +347,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
*
policy
=
CPUFREQ_POLICY_POWERSAVE
;
err
=
0
;
}
}
else
if
(
has_
target
)
{
}
else
if
(
cpufreq_driver
->
target
)
{
struct
cpufreq_governor
*
t
;
mutex_lock
(
&
cpufreq_governor_mutex
);
...
...
@@ -522,12 +498,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy,
*/
static
ssize_t
show_scaling_driver
(
struct
cpufreq_policy
*
policy
,
char
*
buf
)
{
ssize_t
size
;
rcu_read_lock
();
size
=
scnprintf
(
buf
,
CPUFREQ_NAME_PLEN
,
"%s
\n
"
,
rcu_dereference
(
cpufreq_driver
)
->
name
);
rcu_read_unlock
();
return
size
;
return
scnprintf
(
buf
,
CPUFREQ_NAME_PLEN
,
"%s
\n
"
,
cpufreq_driver
->
name
);
}
/**
...
...
@@ -539,13 +510,10 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
ssize_t
i
=
0
;
struct
cpufreq_governor
*
t
;
rcu_read_lock
();
if
(
!
rcu_dereference
(
cpufreq_driver
)
->
target
)
{
rcu_read_unlock
();
if
(
!
cpufreq_driver
->
target
)
{
i
+=
sprintf
(
buf
,
"performance powersave"
);
goto
out
;
}
rcu_read_unlock
();
list_for_each_entry
(
t
,
&
cpufreq_governor_list
,
governor_list
)
{
if
(
i
>=
(
ssize_t
)
((
PAGE_SIZE
/
sizeof
(
char
))
...
...
@@ -623,15 +591,9 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf)
static
ssize_t
show_bios_limit
(
struct
cpufreq_policy
*
policy
,
char
*
buf
)
{
unsigned
int
limit
;
int
(
*
bios_limit
)(
int
cpu
,
unsigned
int
*
limit
);
int
ret
;
rcu_read_lock
();
bios_limit
=
rcu_dereference
(
cpufreq_driver
)
->
bios_limit
;
rcu_read_unlock
();
if
(
bios_limit
)
{
ret
=
bios_limit
(
policy
->
cpu
,
&
limit
);
if
(
cpufreq_driver
->
bios_limit
)
{
ret
=
cpufreq_driver
->
bios_limit
(
policy
->
cpu
,
&
limit
);
if
(
!
ret
)
return
sprintf
(
buf
,
"%u
\n
"
,
limit
);
}
...
...
@@ -774,7 +736,6 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
{
struct
cpufreq_policy
new_policy
;
struct
freq_attr
**
drv_attr
;
struct
cpufreq_driver
*
driver
;
unsigned
long
flags
;
int
ret
=
0
;
unsigned
int
j
;
...
...
@@ -786,31 +747,28 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
return
ret
;
/* set up files for this cpu device */
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
drv_attr
=
driver
->
attr
;
drv_attr
=
cpufreq_driver
->
attr
;
while
((
drv_attr
)
&&
(
*
drv_attr
))
{
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
((
*
drv_attr
)
->
attr
));
if
(
ret
)
goto
err_out_
unlock
;
goto
err_out_
kobj_put
;
drv_attr
++
;
}
if
(
driver
->
get
)
{
if
(
cpufreq_
driver
->
get
)
{
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
cpuinfo_cur_freq
.
attr
);
if
(
ret
)
goto
err_out_
unlock
;
goto
err_out_
kobj_put
;
}
if
(
driver
->
target
)
{
if
(
cpufreq_
driver
->
target
)
{
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
scaling_cur_freq
.
attr
);
if
(
ret
)
goto
err_out_
unlock
;
goto
err_out_
kobj_put
;
}
if
(
driver
->
bios_limit
)
{
if
(
cpufreq_
driver
->
bios_limit
)
{
ret
=
sysfs_create_file
(
&
policy
->
kobj
,
&
bios_limit
.
attr
);
if
(
ret
)
goto
err_out_
unlock
;
goto
err_out_
kobj_put
;
}
rcu_read_unlock
();
write_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
for_each_cpu
(
j
,
policy
->
cpus
)
{
...
...
@@ -833,20 +791,12 @@ static int cpufreq_add_dev_interface(unsigned int cpu,
policy
->
user_policy
.
governor
=
policy
->
governor
;
if
(
ret
)
{
int
(
*
exit
)(
struct
cpufreq_policy
*
policy
);
pr_debug
(
"setting policy failed
\n
"
);
rcu_read_lock
();
exit
=
rcu_dereference
(
cpufreq_driver
)
->
exit
;
rcu_read_unlock
();
if
(
exit
)
exit
(
policy
);
if
(
cpufreq_driver
->
exit
)
cpufreq_driver
->
exit
(
policy
);
}
return
ret
;
err_out_unlock:
rcu_read_unlock
();
err_out_kobj_put:
kobject_put
(
&
policy
->
kobj
);
wait_for_completion
(
&
policy
->
kobj_unregister
);
...
...
@@ -858,16 +808,12 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling,
struct
device
*
dev
)
{
struct
cpufreq_policy
*
policy
;
int
ret
=
0
,
has_target
=
0
;
int
ret
=
0
,
has_target
=
!!
cpufreq_driver
->
target
;
unsigned
long
flags
;
policy
=
cpufreq_cpu_get
(
sibling
);
WARN_ON
(
!
policy
);
rcu_read_lock
();
has_target
=
!!
rcu_dereference
(
cpufreq_driver
)
->
target
;
rcu_read_unlock
();
if
(
has_target
)
__cpufreq_governor
(
policy
,
CPUFREQ_GOV_STOP
);
...
...
@@ -911,8 +857,6 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
unsigned
int
j
,
cpu
=
dev
->
id
;
int
ret
=
-
ENOMEM
;
struct
cpufreq_policy
*
policy
;
struct
cpufreq_driver
*
driver
;
int
(
*
init
)(
struct
cpufreq_policy
*
policy
);
unsigned
long
flags
;
#ifdef CONFIG_HOTPLUG_CPU
struct
cpufreq_governor
*
gov
;
...
...
@@ -947,15 +891,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
#endif
#endif
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
if
(
!
try_module_get
(
driver
->
owner
))
{
rcu_read_unlock
();
if
(
!
try_module_get
(
cpufreq_driver
->
owner
))
{
ret
=
-
EINVAL
;
goto
module_out
;
}
init
=
driver
->
init
;
rcu_read_unlock
();
policy
=
kzalloc
(
sizeof
(
struct
cpufreq_policy
),
GFP_KERNEL
);
if
(
!
policy
)
...
...
@@ -980,7 +919,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
/* call driver. From then on the cpufreq must be able
* to accept all calls to ->verify and ->setpolicy for this CPU
*/
ret
=
init
(
policy
);
ret
=
cpufreq_driver
->
init
(
policy
);
if
(
ret
)
{
pr_debug
(
"initialization failed
\n
"
);
goto
err_set_policy_cpu
;
...
...
@@ -1015,9 +954,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
goto
err_out_unregister
;
kobject_uevent
(
&
policy
->
kobj
,
KOBJ_ADD
);
rcu_read_lock
();
module_put
(
rcu_dereference
(
cpufreq_driver
)
->
owner
);
rcu_read_unlock
();
module_put
(
cpufreq_driver
->
owner
);
pr_debug
(
"initialization complete
\n
"
);
return
0
;
...
...
@@ -1039,9 +976,7 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
err_free_policy:
kfree
(
policy
);
nomem_out:
rcu_read_lock
();
module_put
(
rcu_dereference
(
cpufreq_driver
)
->
owner
);
rcu_read_unlock
();
module_put
(
cpufreq_driver
->
owner
);
module_out:
return
ret
;
}
...
...
@@ -1075,12 +1010,9 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
unsigned
int
cpu
=
dev
->
id
,
ret
,
cpus
;
unsigned
long
flags
;
struct
cpufreq_policy
*
data
;
struct
cpufreq_driver
*
driver
;
struct
kobject
*
kobj
;
struct
completion
*
cmp
;
struct
device
*
cpu_dev
;
bool
has_target
;
int
(
*
exit
)(
struct
cpufreq_policy
*
policy
);
pr_debug
(
"%s: unregistering CPU %u
\n
"
,
__func__
,
cpu
);
...
...
@@ -1096,19 +1028,14 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
return
-
EINVAL
;
}
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
has_target
=
driver
->
target
?
true
:
false
;
exit
=
driver
->
exit
;
if
(
has_target
)
if
(
cpufreq_driver
->
target
)
__cpufreq_governor
(
data
,
CPUFREQ_GOV_STOP
);
#ifdef CONFIG_HOTPLUG_CPU
if
(
!
driver
->
setpolicy
)
if
(
!
cpufreq_
driver
->
setpolicy
)
strncpy
(
per_cpu
(
cpufreq_cpu_governor
,
cpu
),
data
->
governor
->
name
,
CPUFREQ_NAME_LEN
);
#endif
rcu_read_unlock
();
WARN_ON
(
lock_policy_rwsem_write
(
cpu
));
cpus
=
cpumask_weight
(
data
->
cpus
);
...
...
@@ -1153,7 +1080,7 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
/* If cpu is last user of policy, free policy */
if
(
cpus
==
1
)
{
if
(
has_
target
)
if
(
cpufreq_driver
->
target
)
__cpufreq_governor
(
data
,
CPUFREQ_GOV_POLICY_EXIT
);
lock_policy_rwsem_read
(
cpu
);
...
...
@@ -1170,13 +1097,13 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif
wait_for_completion
(
cmp
);
pr_debug
(
"wait complete
\n
"
);
if
(
exit
)
exit
(
data
);
if
(
cpufreq_driver
->
exit
)
cpufreq_driver
->
exit
(
data
);
free_cpumask_var
(
data
->
related_cpus
);
free_cpumask_var
(
data
->
cpus
);
kfree
(
data
);
}
else
if
(
has_
target
)
{
}
else
if
(
cpufreq_driver
->
target
)
{
__cpufreq_governor
(
data
,
CPUFREQ_GOV_START
);
__cpufreq_governor
(
data
,
CPUFREQ_GOV_LIMITS
);
}
...
...
@@ -1250,18 +1177,10 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
unsigned
int
cpufreq_quick_get
(
unsigned
int
cpu
)
{
struct
cpufreq_policy
*
policy
;
struct
cpufreq_driver
*
driver
;
unsigned
int
(
*
get
)(
unsigned
int
cpu
);
unsigned
int
ret_freq
=
0
;
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
if
(
driver
&&
driver
->
setpolicy
&&
driver
->
get
)
{
get
=
driver
->
get
;
rcu_read_unlock
();
return
get
(
cpu
);
}
rcu_read_unlock
();
if
(
cpufreq_driver
&&
cpufreq_driver
->
setpolicy
&&
cpufreq_driver
->
get
)
return
cpufreq_driver
->
get
(
cpu
);
policy
=
cpufreq_cpu_get
(
cpu
);
if
(
policy
)
{
...
...
@@ -1297,26 +1216,15 @@ EXPORT_SYMBOL(cpufreq_quick_get_max);
static
unsigned
int
__cpufreq_get
(
unsigned
int
cpu
)
{
struct
cpufreq_policy
*
policy
=
per_cpu
(
cpufreq_cpu_data
,
cpu
);
struct
cpufreq_driver
*
driver
;
unsigned
int
(
*
get
)(
unsigned
int
cpu
);
unsigned
int
ret_freq
=
0
;
u8
flags
;
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
if
(
!
driver
->
get
)
{
rcu_read_unlock
();
if
(
!
cpufreq_driver
->
get
)
return
ret_freq
;
}
flags
=
driver
->
flags
;
get
=
driver
->
get
;
rcu_read_unlock
();
ret_freq
=
get
(
cpu
);
ret_freq
=
cpufreq_driver
->
get
(
cpu
);
if
(
ret_freq
&&
policy
->
cur
&&
!
(
flags
&
CPUFREQ_CONST_LOOPS
))
{
!
(
cpufreq_driver
->
flags
&
CPUFREQ_CONST_LOOPS
))
{
/* verify no discrepancy between actual and
saved value exists */
if
(
unlikely
(
ret_freq
!=
policy
->
cur
))
{
...
...
@@ -1372,7 +1280,6 @@ static struct subsys_interface cpufreq_interface = {
*/
static
int
cpufreq_bp_suspend
(
void
)
{
int
(
*
suspend
)(
struct
cpufreq_policy
*
policy
);
int
ret
=
0
;
int
cpu
=
smp_processor_id
();
...
...
@@ -1385,11 +1292,8 @@ static int cpufreq_bp_suspend(void)
if
(
!
cpu_policy
)
return
0
;
rcu_read_lock
();
suspend
=
rcu_dereference
(
cpufreq_driver
)
->
suspend
;
rcu_read_unlock
();
if
(
suspend
)
{
ret
=
suspend
(
cpu_policy
);
if
(
cpufreq_driver
->
suspend
)
{
ret
=
cpufreq_driver
->
suspend
(
cpu_policy
);
if
(
ret
)
printk
(
KERN_ERR
"cpufreq: suspend failed in ->suspend "
"step on CPU %u
\n
"
,
cpu_policy
->
cpu
);
...
...
@@ -1415,7 +1319,6 @@ static int cpufreq_bp_suspend(void)
static
void
cpufreq_bp_resume
(
void
)
{
int
ret
=
0
;
int
(
*
resume
)(
struct
cpufreq_policy
*
policy
);
int
cpu
=
smp_processor_id
();
struct
cpufreq_policy
*
cpu_policy
;
...
...
@@ -1427,12 +1330,8 @@ static void cpufreq_bp_resume(void)
if
(
!
cpu_policy
)
return
;
rcu_read_lock
();
resume
=
rcu_dereference
(
cpufreq_driver
)
->
resume
;
rcu_read_unlock
();
if
(
resume
)
{
ret
=
resume
(
cpu_policy
);
if
(
cpufreq_driver
->
resume
)
{
ret
=
cpufreq_driver
->
resume
(
cpu_policy
);
if
(
ret
)
{
printk
(
KERN_ERR
"cpufreq: resume failed in ->resume "
"step on CPU %u
\n
"
,
cpu_policy
->
cpu
);
...
...
@@ -1459,14 +1358,10 @@ static struct syscore_ops cpufreq_syscore_ops = {
*/
const
char
*
cpufreq_get_current_driver
(
void
)
{
struct
cpufreq_driver
*
driver
;
const
char
*
name
=
NULL
;
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
if
(
driver
)
name
=
driver
->
name
;
rcu_read_unlock
();
return
name
;
if
(
cpufreq_driver
)
return
cpufreq_driver
->
name
;
return
NULL
;
}
EXPORT_SYMBOL_GPL
(
cpufreq_get_current_driver
);
...
...
@@ -1560,9 +1455,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
{
int
retval
=
-
EINVAL
;
unsigned
int
old_target_freq
=
target_freq
;
int
(
*
target
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
);
if
(
cpufreq_disabled
())
return
-
ENODEV
;
...
...
@@ -1579,11 +1471,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
if
(
target_freq
==
policy
->
cur
)
return
0
;
rcu_read_lock
();
target
=
rcu_dereference
(
cpufreq_driver
)
->
target
;
rcu_read_unlock
();
if
(
target
)
retval
=
target
(
policy
,
target_freq
,
relation
);
if
(
cpufreq_driver
->
target
)
retval
=
cpufreq_driver
->
target
(
policy
,
target_freq
,
relation
);
return
retval
;
}
...
...
@@ -1616,24 +1505,18 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target);
int
__cpufreq_driver_getavg
(
struct
cpufreq_policy
*
policy
,
unsigned
int
cpu
)
{
int
ret
=
0
;
unsigned
int
(
*
getavg
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
cpu
);
if
(
cpufreq_disabled
())
return
ret
;
rcu_read_lock
();
getavg
=
rcu_dereference
(
cpufreq_driver
)
->
getavg
;
rcu_read_unlock
();
if
(
!
getavg
)
if
(
!
cpufreq_driver
->
getavg
)
return
0
;
policy
=
cpufreq_cpu_get
(
policy
->
cpu
);
if
(
!
policy
)
return
-
EINVAL
;
ret
=
getavg
(
policy
,
cpu
);
ret
=
cpufreq_driver
->
getavg
(
policy
,
cpu
);
cpufreq_cpu_put
(
policy
);
return
ret
;
...
...
@@ -1791,9 +1674,6 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
struct
cpufreq_policy
*
policy
)
{
int
ret
=
0
,
failed
=
1
;
struct
cpufreq_driver
*
driver
;
int
(
*
verify
)(
struct
cpufreq_policy
*
policy
);
int
(
*
setpolicy
)(
struct
cpufreq_policy
*
policy
);
pr_debug
(
"setting new policy for CPU %u: %u - %u kHz
\n
"
,
policy
->
cpu
,
policy
->
min
,
policy
->
max
);
...
...
@@ -1807,13 +1687,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
}
/* verify the cpu speed can be set within this limit */
rcu_read_lock
();
driver
=
rcu_dereference
(
cpufreq_driver
);
verify
=
driver
->
verify
;
setpolicy
=
driver
->
setpolicy
;
rcu_read_unlock
();
ret
=
verify
(
policy
);
ret
=
cpufreq_driver
->
verify
(
policy
);
if
(
ret
)
goto
error_out
;
...
...
@@ -1827,7 +1701,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
/* verify the cpu speed can be set within this limit,
which might be different to the first one */
ret
=
verify
(
policy
);
ret
=
cpufreq_driver
->
verify
(
policy
);
if
(
ret
)
goto
error_out
;
...
...
@@ -1841,10 +1715,10 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
pr_debug
(
"new min and max freqs are %u - %u kHz
\n
"
,
data
->
min
,
data
->
max
);
if
(
setpolicy
)
{
if
(
cpufreq_driver
->
setpolicy
)
{
data
->
policy
=
policy
->
policy
;
pr_debug
(
"setting range
\n
"
);
ret
=
setpolicy
(
policy
);
ret
=
cpufreq_driver
->
setpolicy
(
policy
);
}
else
{
if
(
policy
->
governor
!=
data
->
governor
)
{
/* save old, working values */
...
...
@@ -1904,11 +1778,6 @@ int cpufreq_update_policy(unsigned int cpu)
{
struct
cpufreq_policy
*
data
=
cpufreq_cpu_get
(
cpu
);
struct
cpufreq_policy
policy
;
struct
cpufreq_driver
*
driver
;
unsigned
int
(
*
get
)(
unsigned
int
cpu
);
int
(
*
target
)(
struct
cpufreq_policy
*
policy
,
unsigned
int
target_freq
,
unsigned
int
relation
);
int
ret
;
if
(
!
data
)
{
...
...
@@ -1930,18 +1799,13 @@ int cpufreq_update_policy(unsigned int cpu)
/* BIOS might change freq behind our back
-> ask driver for current freq and notify governors about a change */
rcu_read_lock
();
driver
=
rcu_access_pointer
(
cpufreq_driver
);
get
=
driver
->
get
;
target
=
driver
->
target
;
rcu_read_unlock
();
if
(
get
)
{
policy
.
cur
=
get
(
cpu
);
if
(
cpufreq_driver
->
get
)
{
policy
.
cur
=
cpufreq_driver
->
get
(
cpu
);
if
(
!
data
->
cur
)
{
pr_debug
(
"Driver did not initialize current freq"
);
data
->
cur
=
policy
.
cur
;
}
else
{
if
(
data
->
cur
!=
policy
.
cur
&&
target
)
if
(
data
->
cur
!=
policy
.
cur
&&
cpufreq_driver
->
target
)
cpufreq_out_of_sync
(
cpu
,
data
->
cur
,
policy
.
cur
);
}
...
...
@@ -2020,19 +1884,18 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
driver_data
->
flags
|=
CPUFREQ_CONST_LOOPS
;
write_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
if
(
rcu_access_pointer
(
cpufreq_driver
)
)
{
if
(
cpufreq_driver
)
{
write_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
return
-
EBUSY
;
}
rcu_assign_pointer
(
cpufreq_driver
,
driver_data
)
;
cpufreq_driver
=
driver_data
;
write_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
synchronize_rcu
();
ret
=
subsys_interface_register
(
&
cpufreq_interface
);
if
(
ret
)
goto
err_null_driver
;
if
(
!
(
driver_data
->
flags
&
CPUFREQ_STICKY
))
{
if
(
!
(
cpufreq_driver
->
flags
&
CPUFREQ_STICKY
))
{
int
i
;
ret
=
-
ENODEV
;
...
...
@@ -2059,9 +1922,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
subsys_interface_unregister
(
&
cpufreq_interface
);
err_null_driver:
write_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
rcu_assign_pointer
(
cpufreq_driver
,
NULL
)
;
cpufreq_driver
=
NULL
;
write_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
synchronize_rcu
();
return
ret
;
}
EXPORT_SYMBOL_GPL
(
cpufreq_register_driver
);
...
...
@@ -2078,15 +1940,9 @@ EXPORT_SYMBOL_GPL(cpufreq_register_driver);
int
cpufreq_unregister_driver
(
struct
cpufreq_driver
*
driver
)
{
unsigned
long
flags
;
struct
cpufreq_driver
*
old_driver
;
rcu_read_lock
();
old_driver
=
rcu_access_pointer
(
cpufreq_driver
);
if
(
!
old_driver
||
(
driver
!=
old_driver
))
{
rcu_read_unlock
();
if
(
!
cpufreq_driver
||
(
driver
!=
cpufreq_driver
))
return
-
EINVAL
;
}
rcu_read_unlock
();
pr_debug
(
"unregistering driver %s
\n
"
,
driver
->
name
);
...
...
@@ -2094,9 +1950,8 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
unregister_hotcpu_notifier
(
&
cpufreq_cpu_notifier
);
write_lock_irqsave
(
&
cpufreq_driver_lock
,
flags
);
rcu_assign_pointer
(
cpufreq_driver
,
NULL
)
;
cpufreq_driver
=
NULL
;
write_unlock_irqrestore
(
&
cpufreq_driver_lock
,
flags
);
synchronize_rcu
();
return
0
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment