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
2dc36ecf
Commit
2dc36ecf
authored
Aug 07, 2015
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pm-cpufreq' into pm-opp
parents
19445b25
144c8e17
Changes
17
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
638 additions
and
404 deletions
+638
-404
arch/powerpc/include/asm/opal-api.h
arch/powerpc/include/asm/opal-api.h
+12
-0
drivers/acpi/processor_perflib.c
drivers/acpi/processor_perflib.c
+1
-3
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/acpi-cpufreq.c
+51
-42
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq.c
+145
-177
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_conservative.c
+7
-18
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.c
+146
-50
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/cpufreq_governor.h
+22
-18
drivers/cpufreq/cpufreq_ondemand.c
drivers/cpufreq/cpufreq_ondemand.c
+32
-35
drivers/cpufreq/e_powersaver.c
drivers/cpufreq/e_powersaver.c
+1
-1
drivers/cpufreq/ia64-acpi-cpufreq.c
drivers/cpufreq/ia64-acpi-cpufreq.c
+10
-10
drivers/cpufreq/integrator-cpufreq.c
drivers/cpufreq/integrator-cpufreq.c
+8
-10
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/intel_pstate.c
+9
-6
drivers/cpufreq/powernow-k7.c
drivers/cpufreq/powernow-k7.c
+2
-2
drivers/cpufreq/powernow-k8.c
drivers/cpufreq/powernow-k8.c
+2
-3
drivers/cpufreq/powernv-cpufreq.c
drivers/cpufreq/powernv-cpufreq.c
+183
-15
drivers/xen/xen-acpi-processor.c
drivers/xen/xen-acpi-processor.c
+6
-10
include/acpi/processor.h
include/acpi/processor.h
+1
-4
No files found.
arch/powerpc/include/asm/opal-api.h
View file @
2dc36ecf
...
...
@@ -361,6 +361,7 @@ enum opal_msg_type {
OPAL_MSG_HMI_EVT
,
OPAL_MSG_DPO
,
OPAL_MSG_PRD
,
OPAL_MSG_OCC
,
OPAL_MSG_TYPE_MAX
,
};
...
...
@@ -700,6 +701,17 @@ struct opal_prd_msg_header {
struct
opal_prd_msg
;
#define OCC_RESET 0
#define OCC_LOAD 1
#define OCC_THROTTLE 2
#define OCC_MAX_THROTTLE_STATUS 5
struct
opal_occ_msg
{
__be64
type
;
__be64
chip
;
__be64
throttle_status
;
};
/*
* SG entries
*
...
...
drivers/acpi/processor_perflib.c
View file @
2dc36ecf
...
...
@@ -784,9 +784,7 @@ acpi_processor_register_performance(struct acpi_processor_performance
EXPORT_SYMBOL
(
acpi_processor_register_performance
);
void
acpi_processor_unregister_performance
(
struct
acpi_processor_performance
*
performance
,
unsigned
int
cpu
)
void
acpi_processor_unregister_performance
(
unsigned
int
cpu
)
{
struct
acpi_processor
*
pr
;
...
...
drivers/cpufreq/acpi-cpufreq.c
View file @
2dc36ecf
...
...
@@ -65,18 +65,21 @@ enum {
#define MSR_K7_HWCR_CPB_DIS (1ULL << 25)
struct
acpi_cpufreq_data
{
struct
acpi_processor_performance
*
acpi_data
;
struct
cpufreq_frequency_table
*
freq_table
;
unsigned
int
resume
;
unsigned
int
cpu_feature
;
unsigned
int
acpi_perf_cpu
;
cpumask_var_t
freqdomain_cpus
;
};
static
DEFINE_PER_CPU
(
struct
acpi_cpufreq_data
*
,
acfreq_data
);
/* acpi_perf_data is a pointer to percpu data. */
static
struct
acpi_processor_performance
__percpu
*
acpi_perf_data
;
static
inline
struct
acpi_processor_performance
*
to_perf_data
(
struct
acpi_cpufreq_data
*
data
)
{
return
per_cpu_ptr
(
acpi_perf_data
,
data
->
acpi_perf_cpu
);
}
static
struct
cpufreq_driver
acpi_cpufreq_driver
;
static
unsigned
int
acpi_pstate_strict
;
...
...
@@ -144,7 +147,7 @@ static int _store_boost(int val)
static
ssize_t
show_freqdomain_cpus
(
struct
cpufreq_policy
*
policy
,
char
*
buf
)
{
struct
acpi_cpufreq_data
*
data
=
p
er_cpu
(
acfreq_data
,
policy
->
cpu
)
;
struct
acpi_cpufreq_data
*
data
=
p
olicy
->
driver_data
;
return
cpufreq_show_cpus
(
data
->
freqdomain_cpus
,
buf
);
}
...
...
@@ -202,7 +205,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
struct
acpi_processor_performance
*
perf
;
int
i
;
perf
=
data
->
acpi_data
;
perf
=
to_perf_data
(
data
)
;
for
(
i
=
0
;
i
<
perf
->
state_count
;
i
++
)
{
if
(
value
==
perf
->
states
[
i
].
status
)
...
...
@@ -221,7 +224,7 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
else
msr
&=
INTEL_MSR_RANGE
;
perf
=
data
->
acpi_data
;
perf
=
to_perf_data
(
data
)
;
cpufreq_for_each_entry
(
pos
,
data
->
freq_table
)
if
(
msr
==
perf
->
states
[
pos
->
driver_data
].
status
)
...
...
@@ -327,7 +330,8 @@ static void drv_write(struct drv_cmd *cmd)
put_cpu
();
}
static
u32
get_cur_val
(
const
struct
cpumask
*
mask
)
static
u32
get_cur_val
(
const
struct
cpumask
*
mask
,
struct
acpi_cpufreq_data
*
data
)
{
struct
acpi_processor_performance
*
perf
;
struct
drv_cmd
cmd
;
...
...
@@ -335,7 +339,7 @@ static u32 get_cur_val(const struct cpumask *mask)
if
(
unlikely
(
cpumask_empty
(
mask
)))
return
0
;
switch
(
per_cpu
(
acfreq_data
,
cpumask_first
(
mask
))
->
cpu_feature
)
{
switch
(
data
->
cpu_feature
)
{
case
SYSTEM_INTEL_MSR_CAPABLE
:
cmd
.
type
=
SYSTEM_INTEL_MSR_CAPABLE
;
cmd
.
addr
.
msr
.
reg
=
MSR_IA32_PERF_CTL
;
...
...
@@ -346,7 +350,7 @@ static u32 get_cur_val(const struct cpumask *mask)
break
;
case
SYSTEM_IO_CAPABLE
:
cmd
.
type
=
SYSTEM_IO_CAPABLE
;
perf
=
per_cpu
(
acfreq_data
,
cpumask_first
(
mask
))
->
acpi_data
;
perf
=
to_perf_data
(
data
)
;
cmd
.
addr
.
io
.
port
=
perf
->
control_register
.
address
;
cmd
.
addr
.
io
.
bit_width
=
perf
->
control_register
.
bit_width
;
break
;
...
...
@@ -364,19 +368,24 @@ static u32 get_cur_val(const struct cpumask *mask)
static
unsigned
int
get_cur_freq_on_cpu
(
unsigned
int
cpu
)
{
struct
acpi_cpufreq_data
*
data
=
per_cpu
(
acfreq_data
,
cpu
);
struct
acpi_cpufreq_data
*
data
;
struct
cpufreq_policy
*
policy
;
unsigned
int
freq
;
unsigned
int
cached_freq
;
pr_debug
(
"get_cur_freq_on_cpu (%d)
\n
"
,
cpu
);
if
(
unlikely
(
data
==
NULL
||
data
->
acpi_data
==
NULL
||
data
->
freq_table
==
NULL
))
{
policy
=
cpufreq_cpu_get
(
cpu
);
if
(
unlikely
(
!
policy
))
return
0
;
}
cached_freq
=
data
->
freq_table
[
data
->
acpi_data
->
state
].
frequency
;
freq
=
extract_freq
(
get_cur_val
(
cpumask_of
(
cpu
)),
data
);
data
=
policy
->
driver_data
;
cpufreq_cpu_put
(
policy
);
if
(
unlikely
(
!
data
||
!
data
->
freq_table
))
return
0
;
cached_freq
=
data
->
freq_table
[
to_perf_data
(
data
)
->
state
].
frequency
;
freq
=
extract_freq
(
get_cur_val
(
cpumask_of
(
cpu
),
data
),
data
);
if
(
freq
!=
cached_freq
)
{
/*
* The dreaded BIOS frequency change behind our back.
...
...
@@ -397,7 +406,7 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
unsigned
int
i
;
for
(
i
=
0
;
i
<
100
;
i
++
)
{
cur_freq
=
extract_freq
(
get_cur_val
(
mask
),
data
);
cur_freq
=
extract_freq
(
get_cur_val
(
mask
,
data
),
data
);
if
(
cur_freq
==
freq
)
return
1
;
udelay
(
10
);
...
...
@@ -408,18 +417,17 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
static
int
acpi_cpufreq_target
(
struct
cpufreq_policy
*
policy
,
unsigned
int
index
)
{
struct
acpi_cpufreq_data
*
data
=
p
er_cpu
(
acfreq_data
,
policy
->
cpu
)
;
struct
acpi_cpufreq_data
*
data
=
p
olicy
->
driver_data
;
struct
acpi_processor_performance
*
perf
;
struct
drv_cmd
cmd
;
unsigned
int
next_perf_state
=
0
;
/* Index into perf table */
int
result
=
0
;
if
(
unlikely
(
data
==
NULL
||
data
->
acpi_data
==
NULL
||
data
->
freq_table
==
NULL
))
{
if
(
unlikely
(
data
==
NULL
||
data
->
freq_table
==
NULL
))
{
return
-
ENODEV
;
}
perf
=
data
->
acpi_data
;
perf
=
to_perf_data
(
data
)
;
next_perf_state
=
data
->
freq_table
[
index
].
driver_data
;
if
(
perf
->
state
==
next_perf_state
)
{
if
(
unlikely
(
data
->
resume
))
{
...
...
@@ -482,8 +490,9 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
static
unsigned
long
acpi_cpufreq_guess_freq
(
struct
acpi_cpufreq_data
*
data
,
unsigned
int
cpu
)
{
struct
acpi_processor_performance
*
perf
=
data
->
acpi_data
;
struct
acpi_processor_performance
*
perf
;
perf
=
to_perf_data
(
data
);
if
(
cpu_khz
)
{
/* search the closest match to cpu_khz */
unsigned
int
i
;
...
...
@@ -672,17 +681,17 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto
err_free
;
}
data
->
acpi_data
=
per_cpu_ptr
(
acpi_perf_data
,
cpu
);
per_cpu
(
acfreq_data
,
cpu
)
=
data
;
perf
=
per_cpu_ptr
(
acpi_perf_data
,
cpu
);
data
->
acpi_perf_cpu
=
cpu
;
policy
->
driver_data
=
data
;
if
(
cpu_has
(
c
,
X86_FEATURE_CONSTANT_TSC
))
acpi_cpufreq_driver
.
flags
|=
CPUFREQ_CONST_LOOPS
;
result
=
acpi_processor_register_performance
(
data
->
acpi_data
,
cpu
);
result
=
acpi_processor_register_performance
(
perf
,
cpu
);
if
(
result
)
goto
err_free_mask
;
perf
=
data
->
acpi_data
;
policy
->
shared_type
=
perf
->
shared_type
;
/*
...
...
@@ -838,26 +847,25 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
err_freqfree:
kfree
(
data
->
freq_table
);
err_unreg:
acpi_processor_unregister_performance
(
perf
,
cpu
);
acpi_processor_unregister_performance
(
cpu
);
err_free_mask:
free_cpumask_var
(
data
->
freqdomain_cpus
);
err_free:
kfree
(
data
);
p
er_cpu
(
acfreq_data
,
cpu
)
=
NULL
;
p
olicy
->
driver_data
=
NULL
;
return
result
;
}
static
int
acpi_cpufreq_cpu_exit
(
struct
cpufreq_policy
*
policy
)
{
struct
acpi_cpufreq_data
*
data
=
p
er_cpu
(
acfreq_data
,
policy
->
cpu
)
;
struct
acpi_cpufreq_data
*
data
=
p
olicy
->
driver_data
;
pr_debug
(
"acpi_cpufreq_cpu_exit
\n
"
);
if
(
data
)
{
per_cpu
(
acfreq_data
,
policy
->
cpu
)
=
NULL
;
acpi_processor_unregister_performance
(
data
->
acpi_data
,
policy
->
cpu
);
policy
->
driver_data
=
NULL
;
acpi_processor_unregister_performance
(
data
->
acpi_perf_cpu
);
free_cpumask_var
(
data
->
freqdomain_cpus
);
kfree
(
data
->
freq_table
);
kfree
(
data
);
...
...
@@ -868,7 +876,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
static
int
acpi_cpufreq_resume
(
struct
cpufreq_policy
*
policy
)
{
struct
acpi_cpufreq_data
*
data
=
p
er_cpu
(
acfreq_data
,
policy
->
cpu
)
;
struct
acpi_cpufreq_data
*
data
=
p
olicy
->
driver_data
;
pr_debug
(
"acpi_cpufreq_resume
\n
"
);
...
...
@@ -880,7 +888,9 @@ static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
static
struct
freq_attr
*
acpi_cpufreq_attr
[]
=
{
&
cpufreq_freq_attr_scaling_available_freqs
,
&
freqdomain_cpus
,
NULL
,
/* this is a placeholder for cpb, do not remove */
#ifdef CONFIG_X86_ACPI_CPUFREQ_CPB
&
cpb
,
#endif
NULL
,
};
...
...
@@ -953,17 +963,16 @@ static int __init acpi_cpufreq_init(void)
* only if configured. This is considered legacy code, which
* will probably be removed at some point in the future.
*/
if
(
check_amd_hwpstate_cpu
(
0
))
{
struct
freq_attr
**
iter
;
pr_debug
(
"adding sysfs entry for cpb
\n
"
);
if
(
!
check_amd_hwpstate_cpu
(
0
))
{
struct
freq_attr
**
attr
;
for
(
iter
=
acpi_cpufreq_attr
;
*
iter
!=
NULL
;
iter
++
)
;
pr_debug
(
"CPB unsupported, do not expose it
\n
"
);
/* make sure there is a terminator behind it */
if
(
iter
[
1
]
==
NULL
)
*
iter
=
&
cpb
;
for
(
attr
=
acpi_cpufreq_attr
;
*
attr
;
attr
++
)
if
(
*
attr
==
&
cpb
)
{
*
attr
=
NULL
;
break
;
}
}
#endif
acpi_cpufreq_boost_init
();
...
...
drivers/cpufreq/cpufreq.c
View file @
2dc36ecf
This diff is collapsed.
Click to expand it.
drivers/cpufreq/cpufreq_conservative.c
View file @
2dc36ecf
...
...
@@ -47,7 +47,7 @@ static inline unsigned int get_freq_target(struct cs_dbs_tuners *cs_tuners,
static
void
cs_check_cpu
(
int
cpu
,
unsigned
int
load
)
{
struct
cs_cpu_dbs_info_s
*
dbs_info
=
&
per_cpu
(
cs_cpu_dbs_info
,
cpu
);
struct
cpufreq_policy
*
policy
=
dbs_info
->
cdbs
.
cur_
policy
;
struct
cpufreq_policy
*
policy
=
dbs_info
->
cdbs
.
shared
->
policy
;
struct
dbs_data
*
dbs_data
=
policy
->
governor_data
;
struct
cs_dbs_tuners
*
cs_tuners
=
dbs_data
->
tuners
;
...
...
@@ -102,26 +102,15 @@ static void cs_check_cpu(int cpu, unsigned int load)
}
}
static
void
cs_dbs_timer
(
struct
work_struct
*
work
)
static
unsigned
int
cs_dbs_timer
(
struct
cpu_dbs_info
*
cdbs
,
struct
dbs_data
*
dbs_data
,
bool
modify_all
)
{
struct
cs_cpu_dbs_info_s
*
dbs_info
=
container_of
(
work
,
struct
cs_cpu_dbs_info_s
,
cdbs
.
work
.
work
);
unsigned
int
cpu
=
dbs_info
->
cdbs
.
cur_policy
->
cpu
;
struct
cs_cpu_dbs_info_s
*
core_dbs_info
=
&
per_cpu
(
cs_cpu_dbs_info
,
cpu
);
struct
dbs_data
*
dbs_data
=
dbs_info
->
cdbs
.
cur_policy
->
governor_data
;
struct
cs_dbs_tuners
*
cs_tuners
=
dbs_data
->
tuners
;
int
delay
=
delay_for_sampling_rate
(
cs_tuners
->
sampling_rate
);
bool
modify_all
=
true
;
mutex_lock
(
&
core_dbs_info
->
cdbs
.
timer_mutex
);
if
(
!
need_load_eval
(
&
core_dbs_info
->
cdbs
,
cs_tuners
->
sampling_rate
))
modify_all
=
false
;
else
dbs_check_cpu
(
dbs_data
,
cpu
);
if
(
modify_all
)
dbs_check_cpu
(
dbs_data
,
cdbs
->
shared
->
policy
->
cpu
);
gov_queue_work
(
dbs_data
,
dbs_info
->
cdbs
.
cur_policy
,
delay
,
modify_all
);
mutex_unlock
(
&
core_dbs_info
->
cdbs
.
timer_mutex
);
return
delay_for_sampling_rate
(
cs_tuners
->
sampling_rate
);
}
static
int
dbs_cpufreq_notifier
(
struct
notifier_block
*
nb
,
unsigned
long
val
,
...
...
@@ -135,7 +124,7 @@ static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
if
(
!
dbs_info
->
enable
)
return
0
;
policy
=
dbs_info
->
cdbs
.
cur_
policy
;
policy
=
dbs_info
->
cdbs
.
shared
->
policy
;
/*
* we only care if our internally tracked freq moves outside the 'valid'
...
...
drivers/cpufreq/cpufreq_governor.c
View file @
2dc36ecf
This diff is collapsed.
Click to expand it.
drivers/cpufreq/cpufreq_governor.h
View file @
2dc36ecf
...
...
@@ -109,7 +109,7 @@ store_one(_gov, file_name)
/* create helper routines */
#define define_get_cpu_dbs_routines(_dbs_info) \
static struct cpu_dbs_
common_info *get_cpu_cdbs(int cpu)
\
static struct cpu_dbs_
info *get_cpu_cdbs(int cpu)
\
{ \
return &per_cpu(_dbs_info, cpu).cdbs; \
} \
...
...
@@ -128,9 +128,20 @@ static void *get_cpu_dbs_info_s(int cpu) \
* cs_*: Conservative governor
*/
/* Common to all CPUs of a policy */
struct
cpu_common_dbs_info
{
struct
cpufreq_policy
*
policy
;
/*
* percpu mutex that serializes governor limit change with dbs_timer
* invocation. We do not want dbs_timer to run when user is changing
* the governor or limits.
*/
struct
mutex
timer_mutex
;
ktime_t
time_stamp
;
};
/* Per cpu structures */
struct
cpu_dbs_common_info
{
int
cpu
;
struct
cpu_dbs_info
{
u64
prev_cpu_idle
;
u64
prev_cpu_wall
;
u64
prev_cpu_nice
;
...
...
@@ -141,19 +152,12 @@ struct cpu_dbs_common_info {
* wake-up from idle.
*/
unsigned
int
prev_load
;
struct
cpufreq_policy
*
cur_policy
;
struct
delayed_work
work
;
/*
* percpu mutex that serializes governor limit change with gov_dbs_timer
* invocation. We do not want gov_dbs_timer to run when user is changing
* the governor or limits.
*/
struct
mutex
timer_mutex
;
ktime_t
time_stamp
;
struct
delayed_work
dwork
;
struct
cpu_common_dbs_info
*
shared
;
};
struct
od_cpu_dbs_info_s
{
struct
cpu_dbs_
common_
info
cdbs
;
struct
cpu_dbs_info
cdbs
;
struct
cpufreq_frequency_table
*
freq_table
;
unsigned
int
freq_lo
;
unsigned
int
freq_lo_jiffies
;
...
...
@@ -163,7 +167,7 @@ struct od_cpu_dbs_info_s {
};
struct
cs_cpu_dbs_info_s
{
struct
cpu_dbs_
common_
info
cdbs
;
struct
cpu_dbs_info
cdbs
;
unsigned
int
down_skip
;
unsigned
int
requested_freq
;
unsigned
int
enable
:
1
;
...
...
@@ -204,9 +208,11 @@ struct common_dbs_data {
*/
struct
dbs_data
*
gdbs_data
;
struct
cpu_dbs_
common_
info
*
(
*
get_cpu_cdbs
)(
int
cpu
);
struct
cpu_dbs_info
*
(
*
get_cpu_cdbs
)(
int
cpu
);
void
*
(
*
get_cpu_dbs_info_s
)(
int
cpu
);
void
(
*
gov_dbs_timer
)(
struct
work_struct
*
work
);
unsigned
int
(
*
gov_dbs_timer
)(
struct
cpu_dbs_info
*
cdbs
,
struct
dbs_data
*
dbs_data
,
bool
modify_all
);
void
(
*
gov_check_cpu
)(
int
cpu
,
unsigned
int
load
);
int
(
*
init
)(
struct
dbs_data
*
dbs_data
,
bool
notify
);
void
(
*
exit
)(
struct
dbs_data
*
dbs_data
,
bool
notify
);
...
...
@@ -265,8 +271,6 @@ static ssize_t show_sampling_rate_min_gov_pol \
extern
struct
mutex
cpufreq_governor_lock
;
void
dbs_check_cpu
(
struct
dbs_data
*
dbs_data
,
int
cpu
);
bool
need_load_eval
(
struct
cpu_dbs_common_info
*
cdbs
,
unsigned
int
sampling_rate
);
int
cpufreq_governor_dbs
(
struct
cpufreq_policy
*
policy
,
struct
common_dbs_data
*
cdata
,
unsigned
int
event
);
void
gov_queue_work
(
struct
dbs_data
*
dbs_data
,
struct
cpufreq_policy
*
policy
,
...
...
drivers/cpufreq/cpufreq_ondemand.c
View file @
2dc36ecf
...
...
@@ -155,7 +155,7 @@ static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq)
static
void
od_check_cpu
(
int
cpu
,
unsigned
int
load
)
{
struct
od_cpu_dbs_info_s
*
dbs_info
=
&
per_cpu
(
od_cpu_dbs_info
,
cpu
);
struct
cpufreq_policy
*
policy
=
dbs_info
->
cdbs
.
cur_
policy
;
struct
cpufreq_policy
*
policy
=
dbs_info
->
cdbs
.
shared
->
policy
;
struct
dbs_data
*
dbs_data
=
policy
->
governor_data
;
struct
od_dbs_tuners
*
od_tuners
=
dbs_data
->
tuners
;
...
...
@@ -191,46 +191,40 @@ static void od_check_cpu(int cpu, unsigned int load)
}
}
static
void
od_dbs_timer
(
struct
work_struct
*
work
)
static
unsigned
int
od_dbs_timer
(
struct
cpu_dbs_info
*
cdbs
,
struct
dbs_data
*
dbs_data
,
bool
modify_all
)
{
struct
od_cpu_dbs_info_s
*
dbs_info
=
container_of
(
work
,
struct
od_cpu_dbs_info_s
,
cdbs
.
work
.
work
);
unsigned
int
cpu
=
dbs_info
->
cdbs
.
cur_policy
->
cpu
;
struct
od_cpu_dbs_info_s
*
core_dbs_info
=
&
per_cpu
(
od_cpu_dbs_info
,
struct
cpufreq_policy
*
policy
=
cdbs
->
shared
->
policy
;
unsigned
int
cpu
=
policy
->
cpu
;
struct
od_cpu_dbs_info_s
*
dbs_info
=
&
per_cpu
(
od_cpu_dbs_info
,
cpu
);
struct
dbs_data
*
dbs_data
=
dbs_info
->
cdbs
.
cur_policy
->
governor_data
;
struct
od_dbs_tuners
*
od_tuners
=
dbs_data
->
tuners
;
int
delay
=
0
,
sample_type
=
core_dbs_info
->
sample_type
;
bool
modify_all
=
true
;
int
delay
=
0
,
sample_type
=
dbs_info
->
sample_type
;
mutex_lock
(
&
core_dbs_info
->
cdbs
.
timer_mutex
);
if
(
!
need_load_eval
(
&
core_dbs_info
->
cdbs
,
od_tuners
->
sampling_rate
))
{
modify_all
=
false
;
if
(
!
modify_all
)
goto
max_delay
;
}
/* Common NORMAL_SAMPLE setup */
core_
dbs_info
->
sample_type
=
OD_NORMAL_SAMPLE
;
dbs_info
->
sample_type
=
OD_NORMAL_SAMPLE
;
if
(
sample_type
==
OD_SUB_SAMPLE
)
{
delay
=
core_
dbs_info
->
freq_lo_jiffies
;
__cpufreq_driver_target
(
core_dbs_info
->
cdbs
.
cur_policy
,
core_dbs_info
->
freq_lo
,
CPUFREQ_RELATION_H
);
delay
=
dbs_info
->
freq_lo_jiffies
;
__cpufreq_driver_target
(
policy
,
dbs_info
->
freq_lo
,
CPUFREQ_RELATION_H
);
}
else
{
dbs_check_cpu
(
dbs_data
,
cpu
);
if
(
core_
dbs_info
->
freq_lo
)
{
if
(
dbs_info
->
freq_lo
)
{
/* Setup timer for SUB_SAMPLE */
core_
dbs_info
->
sample_type
=
OD_SUB_SAMPLE
;
delay
=
core_
dbs_info
->
freq_hi_jiffies
;
dbs_info
->
sample_type
=
OD_SUB_SAMPLE
;
delay
=
dbs_info
->
freq_hi_jiffies
;
}
}
max_delay:
if
(
!
delay
)
delay
=
delay_for_sampling_rate
(
od_tuners
->
sampling_rate
*
core_
dbs_info
->
rate_mult
);
*
dbs_info
->
rate_mult
);
gov_queue_work
(
dbs_data
,
dbs_info
->
cdbs
.
cur_policy
,
delay
,
modify_all
);
mutex_unlock
(
&
core_dbs_info
->
cdbs
.
timer_mutex
);
return
delay
;
}
/************************** sysfs interface ************************/
...
...
@@ -273,27 +267,27 @@ static void update_sampling_rate(struct dbs_data *dbs_data,
dbs_info
=
&
per_cpu
(
od_cpu_dbs_info
,
cpu
);
cpufreq_cpu_put
(
policy
);
mutex_lock
(
&
dbs_info
->
cdbs
.
timer_mutex
);
mutex_lock
(
&
dbs_info
->
cdbs
.
shared
->
timer_mutex
);
if
(
!
delayed_work_pending
(
&
dbs_info
->
cdbs
.
work
))
{
mutex_unlock
(
&
dbs_info
->
cdbs
.
timer_mutex
);
if
(
!
delayed_work_pending
(
&
dbs_info
->
cdbs
.
d
work
))
{
mutex_unlock
(
&
dbs_info
->
cdbs
.
shared
->
timer_mutex
);
continue
;
}
next_sampling
=
jiffies
+
usecs_to_jiffies
(
new_rate
);
appointed_at
=
dbs_info
->
cdbs
.
work
.
timer
.
expires
;
appointed_at
=
dbs_info
->
cdbs
.
d
work
.
timer
.
expires
;
if
(
time_before
(
next_sampling
,
appointed_at
))
{
mutex_unlock
(
&
dbs_info
->
cdbs
.
timer_mutex
);
cancel_delayed_work_sync
(
&
dbs_info
->
cdbs
.
work
);
mutex_lock
(
&
dbs_info
->
cdbs
.
timer_mutex
);
mutex_unlock
(
&
dbs_info
->
cdbs
.
shared
->
timer_mutex
);
cancel_delayed_work_sync
(
&
dbs_info
->
cdbs
.
d
work
);
mutex_lock
(
&
dbs_info
->
cdbs
.
shared
->
timer_mutex
);
gov_queue_work
(
dbs_data
,
dbs_info
->
cdbs
.
cur_
policy
,
usecs_to_jiffies
(
new_rate
),
true
);
gov_queue_work
(
dbs_data
,
policy
,
usecs_to_jiffies
(
new_rate
),
true
);
}
mutex_unlock
(
&
dbs_info
->
cdbs
.
timer_mutex
);
mutex_unlock
(
&
dbs_info
->
cdbs
.
shared
->
timer_mutex
);
}
}
...
...
@@ -556,13 +550,16 @@ static void od_set_powersave_bias(unsigned int powersave_bias)
get_online_cpus
();
for_each_online_cpu
(
cpu
)
{
struct
cpu_common_dbs_info
*
shared
;
if
(
cpumask_test_cpu
(
cpu
,
&
done
))
continue
;
policy
=
per_cpu
(
od_cpu_dbs_info
,
cpu
).
cdbs
.
cur_policy
;
if
(
!
policy
)
shared
=
per_cpu
(
od_cpu_dbs_info
,
cpu
).
cdbs
.
shared
;
if
(
!
shared
)
continue
;
policy
=
shared
->
policy
;
cpumask_or
(
&
done
,
&
done
,
policy
->
cpus
);
if
(
policy
->
governor
!=
&
cpufreq_gov_ondemand
)
...
...
drivers/cpufreq/e_powersaver.c
View file @
2dc36ecf
...
...
@@ -78,7 +78,7 @@ static int eps_acpi_init(void)
static
int
eps_acpi_exit
(
struct
cpufreq_policy
*
policy
)
{
if
(
eps_acpi_cpu_perf
)
{
acpi_processor_unregister_performance
(
eps_acpi_cpu_perf
,
0
);
acpi_processor_unregister_performance
(
0
);
free_cpumask_var
(
eps_acpi_cpu_perf
->
shared_cpu_map
);
kfree
(
eps_acpi_cpu_perf
);
eps_acpi_cpu_perf
=
NULL
;
...
...
drivers/cpufreq/ia64-acpi-cpufreq.c
View file @
2dc36ecf
...
...
@@ -29,7 +29,6 @@ MODULE_LICENSE("GPL");
struct
cpufreq_acpi_io
{
struct
acpi_processor_performance
acpi_data
;
struct
cpufreq_frequency_table
*
freq_table
;
unsigned
int
resume
;
};
...
...
@@ -221,6 +220,7 @@ acpi_cpufreq_cpu_init (
unsigned
int
cpu
=
policy
->
cpu
;
struct
cpufreq_acpi_io
*
data
;
unsigned
int
result
=
0
;
struct
cpufreq_frequency_table
*
freq_table
;
pr_debug
(
"acpi_cpufreq_cpu_init
\n
"
);
...
...
@@ -254,10 +254,10 @@ acpi_cpufreq_cpu_init (
}
/* alloc freq_table */
data
->
freq_table
=
kzalloc
(
sizeof
(
*
data
->
freq_table
)
*
freq_table
=
kzalloc
(
sizeof
(
*
freq_table
)
*
(
data
->
acpi_data
.
state_count
+
1
),
GFP_KERNEL
);
if
(
!
data
->
freq_table
)
{
if
(
!
freq_table
)
{
result
=
-
ENOMEM
;
goto
err_unreg
;
}
...
...
@@ -276,14 +276,14 @@ acpi_cpufreq_cpu_init (
for
(
i
=
0
;
i
<=
data
->
acpi_data
.
state_count
;
i
++
)
{
if
(
i
<
data
->
acpi_data
.
state_count
)
{
data
->
freq_table
[
i
].
frequency
=
freq_table
[
i
].
frequency
=
data
->
acpi_data
.
states
[
i
].
core_frequency
*
1000
;
}
else
{
data
->
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
freq_table
[
i
].
frequency
=
CPUFREQ_TABLE_END
;
}
}
result
=
cpufreq_table_validate_and_show
(
policy
,
data
->
freq_table
);
result
=
cpufreq_table_validate_and_show
(
policy
,
freq_table
);
if
(
result
)
{
goto
err_freqfree
;
}
...
...
@@ -311,9 +311,9 @@ acpi_cpufreq_cpu_init (
return
(
result
);
err_freqfree:
kfree
(
data
->
freq_table
);
kfree
(
freq_table
);
err_unreg:
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
cpu
);
acpi_processor_unregister_performance
(
cpu
);
err_free:
kfree
(
data
);
acpi_io_data
[
cpu
]
=
NULL
;
...
...
@@ -332,8 +332,8 @@ acpi_cpufreq_cpu_exit (
if
(
data
)
{
acpi_io_data
[
policy
->
cpu
]
=
NULL
;
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
policy
->
cpu
);
acpi_processor_unregister_performance
(
policy
->
cpu
);
kfree
(
policy
->
freq_table
);
kfree
(
data
);
}
...
...
drivers/cpufreq/integrator-cpufreq.c
View file @
2dc36ecf
...
...
@@ -98,11 +98,10 @@ static int integrator_set_target(struct cpufreq_policy *policy,
/* get current setting */
cm_osc
=
__raw_readl
(
cm_base
+
INTEGRATOR_HDR_OSC_OFFSET
);
if
(
machine_is_integrator
())
{
if
(
machine_is_integrator
())
vco
.
s
=
(
cm_osc
>>
8
)
&
7
;
}
else
if
(
machine_is_cintegrator
())
{
else
if
(
machine_is_cintegrator
())
vco
.
s
=
1
;
}
vco
.
v
=
cm_osc
&
255
;
vco
.
r
=
22
;
freqs
.
old
=
icst_hz
(
&
cclk_params
,
vco
)
/
1000
;
...
...
@@ -163,11 +162,10 @@ static unsigned int integrator_get(unsigned int cpu)
/* detect memory etc. */
cm_osc
=
__raw_readl
(
cm_base
+
INTEGRATOR_HDR_OSC_OFFSET
);
if
(
machine_is_integrator
())
{
if
(
machine_is_integrator
())
vco
.
s
=
(
cm_osc
>>
8
)
&
7
;
}
else
{
else
vco
.
s
=
1
;
}
vco
.
v
=
cm_osc
&
255
;
vco
.
r
=
22
;
...
...
@@ -203,7 +201,7 @@ static int __init integrator_cpufreq_probe(struct platform_device *pdev)
struct
resource
*
res
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
!
res
)
if
(
!
res
)
return
-
ENODEV
;
cm_base
=
devm_ioremap
(
&
pdev
->
dev
,
res
->
start
,
resource_size
(
res
));
...
...
@@ -234,6 +232,6 @@ static struct platform_driver integrator_cpufreq_driver = {
module_platform_driver_probe
(
integrator_cpufreq_driver
,
integrator_cpufreq_probe
);
MODULE_AUTHOR
(
"Russell M. King"
);
MODULE_DESCRIPTION
(
"cpufreq driver for ARM Integrator CPUs"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Russell M. King"
);
MODULE_DESCRIPTION
(
"cpufreq driver for ARM Integrator CPUs"
);
MODULE_LICENSE
(
"GPL"
);
drivers/cpufreq/intel_pstate.c
View file @
2dc36ecf
...
...
@@ -484,12 +484,11 @@ static void __init intel_pstate_sysfs_expose_params(void)
}
/************************** sysfs end ************************/
static
void
intel_pstate_hwp_enable
(
void
)
static
void
intel_pstate_hwp_enable
(
struct
cpudata
*
cpudata
)
{
hwp_active
++
;
pr_info
(
"intel_pstate: HWP enabled
\n
"
);
wrmsrl
(
MSR_PM_ENABLE
,
0x1
);
wrmsrl
_on_cpu
(
cpudata
->
cpu
,
MSR_PM_ENABLE
,
0x1
);
}
static
int
byt_get_min_pstate
(
void
)
...
...
@@ -522,7 +521,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate)
int32_t
vid_fp
;
u32
vid
;
val
=
pstate
<<
8
;
val
=
(
u64
)
pstate
<<
8
;
if
(
limits
.
no_turbo
&&
!
limits
.
turbo_disabled
)
val
|=
(
u64
)
1
<<
32
;
...
...
@@ -611,7 +610,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate)
{
u64
val
;
val
=
pstate
<<
8
;
val
=
(
u64
)
pstate
<<
8
;
if
(
limits
.
no_turbo
&&
!
limits
.
turbo_disabled
)
val
|=
(
u64
)
1
<<
32
;
...
...
@@ -933,6 +932,10 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
cpu
=
all_cpu_data
[
cpunum
];
cpu
->
cpu
=
cpunum
;
if
(
hwp_active
)
intel_pstate_hwp_enable
(
cpu
);
intel_pstate_get_cpu_pstates
(
cpu
);
init_timer_deferrable
(
&
cpu
->
timer
);
...
...
@@ -1246,7 +1249,7 @@ static int __init intel_pstate_init(void)
return
-
ENOMEM
;
if
(
static_cpu_has_safe
(
X86_FEATURE_HWP
)
&&
!
no_hwp
)
intel_pstate_hwp_enable
()
;
hwp_active
++
;
if
(
!
hwp_active
&&
hwp_only
)
goto
out
;
...
...
drivers/cpufreq/powernow-k7.c
View file @
2dc36ecf
...
...
@@ -421,7 +421,7 @@ static int powernow_acpi_init(void)
return
0
;
err2:
acpi_processor_unregister_performance
(
acpi_processor_perf
,
0
);
acpi_processor_unregister_performance
(
0
);
err1:
free_cpumask_var
(
acpi_processor_perf
->
shared_cpu_map
);
err05:
...
...
@@ -661,7 +661,7 @@ static int powernow_cpu_exit(struct cpufreq_policy *policy)
{
#ifdef CONFIG_X86_POWERNOW_K7_ACPI
if
(
acpi_processor_perf
)
{
acpi_processor_unregister_performance
(
acpi_processor_perf
,
0
);
acpi_processor_unregister_performance
(
0
);
free_cpumask_var
(
acpi_processor_perf
->
shared_cpu_map
);
kfree
(
acpi_processor_perf
);
}
...
...
drivers/cpufreq/powernow-k8.c
View file @
2dc36ecf
...
...
@@ -795,7 +795,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
kfree
(
powernow_table
);
err_out:
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
data
->
cpu
);
acpi_processor_unregister_performance
(
data
->
cpu
);
/* data->acpi_data.state_count informs us at ->exit()
* whether ACPI was used */
...
...
@@ -863,8 +863,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
static
void
powernow_k8_cpu_exit_acpi
(
struct
powernow_k8_data
*
data
)
{
if
(
data
->
acpi_data
.
state_count
)
acpi_processor_unregister_performance
(
&
data
->
acpi_data
,
data
->
cpu
);
acpi_processor_unregister_performance
(
data
->
cpu
);
free_cpumask_var
(
data
->
acpi_data
.
shared_cpu_map
);
}
...
...
drivers/cpufreq/powernv-cpufreq.c
View file @
2dc36ecf
...
...
@@ -27,20 +27,31 @@
#include <linux/smp.h>
#include <linux/of.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <asm/cputhreads.h>
#include <asm/firmware.h>
#include <asm/reg.h>
#include <asm/smp.h>
/* Required for cpu_sibling_mask() in UP configs */
#include <asm/opal.h>
#define POWERNV_MAX_PSTATES 256
#define PMSR_PSAFE_ENABLE (1UL << 30)
#define PMSR_SPR_EM_DISABLE (1UL << 31)
#define PMSR_MAX(x) ((x >> 32) & 0xFF)
#define PMSR_LP(x) ((x >> 48) & 0xFF)
static
struct
cpufreq_frequency_table
powernv_freqs
[
POWERNV_MAX_PSTATES
+
1
];
static
bool
rebooting
,
throttled
;
static
bool
rebooting
,
throttled
,
occ_reset
;
static
struct
chip
{
unsigned
int
id
;
bool
throttled
;
cpumask_t
mask
;
struct
work_struct
throttle
;
bool
restore
;
}
*
chips
;
static
int
nr_chips
;
/*
* Note: The set of pstates consists of contiguous integers, the
...
...
@@ -298,28 +309,35 @@ static inline unsigned int get_nominal_index(void)
return
powernv_pstate_info
.
max
-
powernv_pstate_info
.
nominal
;
}
static
void
powernv_cpufreq_throttle_check
(
unsigned
int
cpu
)
static
void
powernv_cpufreq_throttle_check
(
void
*
data
)
{
unsigned
int
cpu
=
smp_processor_id
();
unsigned
long
pmsr
;
int
pmsr_pmax
,
pmsr_lp
;
int
pmsr_pmax
,
i
;
pmsr
=
get_pmspr
(
SPRN_PMSR
);
for
(
i
=
0
;
i
<
nr_chips
;
i
++
)
if
(
chips
[
i
].
id
==
cpu_to_chip_id
(
cpu
))
break
;
/* Check for Pmax Capping */
pmsr_pmax
=
(
s8
)
PMSR_MAX
(
pmsr
);
if
(
pmsr_pmax
!=
powernv_pstate_info
.
max
)
{
throttled
=
true
;
pr_info
(
"CPU %d Pmax is reduced to %d
\n
"
,
cpu
,
pmsr_pmax
);
pr_info
(
"Max allowed Pstate is capped
\n
"
);
if
(
chips
[
i
].
throttled
)
goto
next
;
chips
[
i
].
throttled
=
true
;
pr_info
(
"CPU %d on Chip %u has Pmax reduced to %d
\n
"
,
cpu
,
chips
[
i
].
id
,
pmsr_pmax
);
}
else
if
(
chips
[
i
].
throttled
)
{
chips
[
i
].
throttled
=
false
;
pr_info
(
"CPU %d on Chip %u has Pmax restored to %d
\n
"
,
cpu
,
chips
[
i
].
id
,
pmsr_pmax
);
}
/*
* Check for Psafe by reading LocalPstate
* or check if Psafe_mode_active is set in PMSR.
*/
pmsr_lp
=
(
s8
)
PMSR_LP
(
pmsr
);
if
((
pmsr_lp
<
powernv_pstate_info
.
min
)
||
(
pmsr
&
PMSR_PSAFE_ENABLE
))
{
/* Check if Psafe_mode_active is set in PMSR. */
next:
if
(
pmsr
&
PMSR_PSAFE_ENABLE
)
{
throttled
=
true
;
pr_info
(
"Pstate set to safe frequency
\n
"
);
}
...
...
@@ -350,7 +368,7 @@ static int powernv_cpufreq_target_index(struct cpufreq_policy *policy,
return
0
;
if
(
!
throttled
)
powernv_cpufreq_throttle_check
(
smp_processor_id
()
);
powernv_cpufreq_throttle_check
(
NULL
);
freq_data
.
pstate_id
=
powernv_freqs
[
new_index
].
driver_data
;
...
...
@@ -395,6 +413,118 @@ static struct notifier_block powernv_cpufreq_reboot_nb = {
.
notifier_call
=
powernv_cpufreq_reboot_notifier
,
};
void
powernv_cpufreq_work_fn
(
struct
work_struct
*
work
)
{
struct
chip
*
chip
=
container_of
(
work
,
struct
chip
,
throttle
);
unsigned
int
cpu
;
cpumask_var_t
mask
;
smp_call_function_any
(
&
chip
->
mask
,
powernv_cpufreq_throttle_check
,
NULL
,
0
);
if
(
!
chip
->
restore
)
return
;
chip
->
restore
=
false
;
cpumask_copy
(
mask
,
&
chip
->
mask
);
for_each_cpu_and
(
cpu
,
mask
,
cpu_online_mask
)
{
int
index
,
tcpu
;
struct
cpufreq_policy
policy
;
cpufreq_get_policy
(
&
policy
,
cpu
);
cpufreq_frequency_table_target
(
&
policy
,
policy
.
freq_table
,
policy
.
cur
,
CPUFREQ_RELATION_C
,
&
index
);
powernv_cpufreq_target_index
(
&
policy
,
index
);
for_each_cpu
(
tcpu
,
policy
.
cpus
)
cpumask_clear_cpu
(
tcpu
,
mask
);
}
}
static
char
throttle_reason
[][
30
]
=
{
"No throttling"
,
"Power Cap"
,
"Processor Over Temperature"
,
"Power Supply Failure"
,
"Over Current"
,
"OCC Reset"
};
static
int
powernv_cpufreq_occ_msg
(
struct
notifier_block
*
nb
,
unsigned
long
msg_type
,
void
*
_msg
)
{
struct
opal_msg
*
msg
=
_msg
;
struct
opal_occ_msg
omsg
;
int
i
;
if
(
msg_type
!=
OPAL_MSG_OCC
)
return
0
;
omsg
.
type
=
be64_to_cpu
(
msg
->
params
[
0
]);
switch
(
omsg
.
type
)
{
case
OCC_RESET
:
occ_reset
=
true
;
/*
* powernv_cpufreq_throttle_check() is called in
* target() callback which can detect the throttle state
* for governors like ondemand.
* But static governors will not call target() often thus
* report throttling here.
*/
if
(
!
throttled
)
{
throttled
=
true
;
pr_crit
(
"CPU Frequency is throttled
\n
"
);
}
pr_info
(
"OCC: Reset
\n
"
);
break
;
case
OCC_LOAD
:
pr_info
(
"OCC: Loaded
\n
"
);
break
;
case
OCC_THROTTLE
:
omsg
.
chip
=
be64_to_cpu
(
msg
->
params
[
1
]);
omsg
.
throttle_status
=
be64_to_cpu
(
msg
->
params
[
2
]);
if
(
occ_reset
)
{
occ_reset
=
false
;
throttled
=
false
;
pr_info
(
"OCC: Active
\n
"
);
for
(
i
=
0
;
i
<
nr_chips
;
i
++
)
{
chips
[
i
].
restore
=
true
;
schedule_work
(
&
chips
[
i
].
throttle
);
}
return
0
;
}
if
(
omsg
.
throttle_status
&&
omsg
.
throttle_status
<=
OCC_MAX_THROTTLE_STATUS
)
pr_info
(
"OCC: Chip %u Pmax reduced due to %s
\n
"
,
(
unsigned
int
)
omsg
.
chip
,
throttle_reason
[
omsg
.
throttle_status
]);
else
if
(
!
omsg
.
throttle_status
)
pr_info
(
"OCC: Chip %u %s
\n
"
,
(
unsigned
int
)
omsg
.
chip
,
throttle_reason
[
omsg
.
throttle_status
]);
else
return
0
;
for
(
i
=
0
;
i
<
nr_chips
;
i
++
)
if
(
chips
[
i
].
id
==
omsg
.
chip
)
{
if
(
!
omsg
.
throttle_status
)
chips
[
i
].
restore
=
true
;
schedule_work
(
&
chips
[
i
].
throttle
);
}
}
return
0
;
}
static
struct
notifier_block
powernv_cpufreq_opal_nb
=
{
.
notifier_call
=
powernv_cpufreq_occ_msg
,
.
next
=
NULL
,
.
priority
=
0
,
};
static
void
powernv_cpufreq_stop_cpu
(
struct
cpufreq_policy
*
policy
)
{
struct
powernv_smp_call_data
freq_data
;
...
...
@@ -414,6 +544,36 @@ static struct cpufreq_driver powernv_cpufreq_driver = {
.
attr
=
powernv_cpu_freq_attr
,
};
static
int
init_chip_info
(
void
)
{
unsigned
int
chip
[
256
];
unsigned
int
cpu
,
i
;
unsigned
int
prev_chip_id
=
UINT_MAX
;
for_each_possible_cpu
(
cpu
)
{
unsigned
int
id
=
cpu_to_chip_id
(
cpu
);
if
(
prev_chip_id
!=
id
)
{
prev_chip_id
=
id
;
chip
[
nr_chips
++
]
=
id
;
}
}
chips
=
kmalloc_array
(
nr_chips
,
sizeof
(
struct
chip
),
GFP_KERNEL
);
if
(
!
chips
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
nr_chips
;
i
++
)
{
chips
[
i
].
id
=
chip
[
i
];
chips
[
i
].
throttled
=
false
;
cpumask_copy
(
&
chips
[
i
].
mask
,
cpumask_of_node
(
chip
[
i
]));
INIT_WORK
(
&
chips
[
i
].
throttle
,
powernv_cpufreq_work_fn
);
chips
[
i
].
restore
=
false
;
}
return
0
;
}
static
int
__init
powernv_cpufreq_init
(
void
)
{
int
rc
=
0
;
...
...
@@ -429,7 +589,13 @@ static int __init powernv_cpufreq_init(void)
return
rc
;
}
/* Populate chip info */
rc
=
init_chip_info
();
if
(
rc
)
return
rc
;
register_reboot_notifier
(
&
powernv_cpufreq_reboot_nb
);
opal_message_notifier_register
(
OPAL_MSG_OCC
,
&
powernv_cpufreq_opal_nb
);
return
cpufreq_register_driver
(
&
powernv_cpufreq_driver
);
}
module_init
(
powernv_cpufreq_init
);
...
...
@@ -437,6 +603,8 @@ module_init(powernv_cpufreq_init);
static
void
__exit
powernv_cpufreq_exit
(
void
)
{
unregister_reboot_notifier
(
&
powernv_cpufreq_reboot_nb
);
opal_message_notifier_unregister
(
OPAL_MSG_OCC
,
&
powernv_cpufreq_opal_nb
);
cpufreq_unregister_driver
(
&
powernv_cpufreq_driver
);
}
module_exit
(
powernv_cpufreq_exit
);
...
...
drivers/xen/xen-acpi-processor.c
View file @
2dc36ecf
...
...
@@ -560,11 +560,9 @@ static int __init xen_acpi_processor_init(void)
return
0
;
err_unregister:
for_each_possible_cpu
(
i
)
{
struct
acpi_processor_performance
*
perf
;
perf
=
per_cpu_ptr
(
acpi_perf_data
,
i
);
acpi_processor_unregister_performance
(
perf
,
i
);
}
for_each_possible_cpu
(
i
)
acpi_processor_unregister_performance
(
i
);
err_out:
/* Freeing a NULL pointer is OK: alloc_percpu zeroes. */
free_acpi_perf_data
();
...
...
@@ -579,11 +577,9 @@ static void __exit xen_acpi_processor_exit(void)
kfree
(
acpi_ids_done
);
kfree
(
acpi_id_present
);
kfree
(
acpi_id_cst_present
);
for_each_possible_cpu
(
i
)
{
struct
acpi_processor_performance
*
perf
;
perf
=
per_cpu_ptr
(
acpi_perf_data
,
i
);
acpi_processor_unregister_performance
(
perf
,
i
);
}
for_each_possible_cpu
(
i
)
acpi_processor_unregister_performance
(
i
);
free_acpi_perf_data
();
}
...
...
include/acpi/processor.h
View file @
2dc36ecf
...
...
@@ -228,10 +228,7 @@ extern int acpi_processor_preregister_performance(struct
extern
int
acpi_processor_register_performance
(
struct
acpi_processor_performance
*
performance
,
unsigned
int
cpu
);
extern
void
acpi_processor_unregister_performance
(
struct
acpi_processor_performance
*
performance
,
unsigned
int
cpu
);
extern
void
acpi_processor_unregister_performance
(
unsigned
int
cpu
);
/* note: this locks both the calling module and the processor module
if a _PPC object exists, rmmod is disallowed then */
...
...
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