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
3db0bc97
Commit
3db0bc97
authored
Jul 19, 2012
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pm-cpuidle'
parents
d9914cf6
aa713cc3
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
100 additions
and
85 deletions
+100
-85
drivers/acpi/processor_driver.c
drivers/acpi/processor_driver.c
+0
-7
drivers/acpi/processor_idle.c
drivers/acpi/processor_idle.c
+1
-38
drivers/base/power/main.c
drivers/base/power/main.c
+3
-1
drivers/cpuidle/cpuidle.c
drivers/cpuidle/cpuidle.c
+16
-1
drivers/cpuidle/driver.c
drivers/cpuidle/driver.c
+28
-1
drivers/cpuidle/governors/menu.c
drivers/cpuidle/governors/menu.c
+3
-2
drivers/cpuidle/sysfs.c
drivers/cpuidle/sysfs.c
+12
-9
drivers/idle/intel_idle.c
drivers/idle/intel_idle.c
+27
-14
include/acpi/processor.h
include/acpi/processor.h
+0
-3
include/linux/cpuidle.h
include/linux/cpuidle.h
+10
-9
No files found.
drivers/acpi/processor_driver.c
View file @
3db0bc97
...
...
@@ -427,18 +427,11 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
* Initialize missing things
*/
if
(
pr
->
flags
.
need_hotplug_init
)
{
struct
cpuidle_driver
*
idle_driver
=
cpuidle_get_driver
();
printk
(
KERN_INFO
"Will online and init hotplugged "
"CPU: %d
\n
"
,
pr
->
id
);
WARN
(
acpi_processor_start
(
pr
),
"Failed to start CPU:"
" %d
\n
"
,
pr
->
id
);
pr
->
flags
.
need_hotplug_init
=
0
;
if
(
idle_driver
&&
!
strcmp
(
idle_driver
->
name
,
"intel_idle"
))
{
intel_idle_cpu_init
(
pr
->
id
);
}
/* Normal CPU soft online event */
}
else
{
acpi_processor_ppc_has_changed
(
pr
,
0
);
...
...
drivers/acpi/processor_idle.c
View file @
3db0bc97
...
...
@@ -221,10 +221,6 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
#endif
/*
* Suspend / resume control
*/
static
int
acpi_idle_suspend
;
static
u32
saved_bm_rld
;
static
void
acpi_idle_bm_rld_save
(
void
)
...
...
@@ -243,21 +239,13 @@ static void acpi_idle_bm_rld_restore(void)
int
acpi_processor_suspend
(
struct
acpi_device
*
device
,
pm_message_t
state
)
{
if
(
acpi_idle_suspend
==
1
)
return
0
;
acpi_idle_bm_rld_save
();
acpi_idle_suspend
=
1
;
return
0
;
}
int
acpi_processor_resume
(
struct
acpi_device
*
device
)
{
if
(
acpi_idle_suspend
==
0
)
return
0
;
acpi_idle_bm_rld_restore
();
acpi_idle_suspend
=
0
;
return
0
;
}
...
...
@@ -595,7 +583,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
*/
cx
->
valid
=
1
;
cx
->
latency_ticks
=
cx
->
latency
;
/*
* On older chipsets, BM_RLD needs to be set
* in order for Bus Master activity to wake the
...
...
@@ -628,7 +615,6 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
if
(
!
cx
->
address
)
break
;
cx
->
valid
=
1
;
cx
->
latency_ticks
=
cx
->
latency
;
/* Normalize latency */
break
;
case
ACPI_STATE_C3
:
...
...
@@ -763,11 +749,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
local_irq_disable
();
if
(
acpi_idle_suspend
)
{
local_irq_enable
();
cpu_relax
();
return
-
EBUSY
;
}
lapic_timer_state_broadcast
(
pr
,
cx
,
1
);
kt1
=
ktime_get_real
();
...
...
@@ -779,7 +760,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
dev
->
last_residency
=
(
int
)
idle_time
;
local_irq_enable
();
cx
->
usage
++
;
lapic_timer_state_broadcast
(
pr
,
cx
,
0
);
return
index
;
...
...
@@ -838,11 +818,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
local_irq_disable
();
if
(
acpi_idle_suspend
)
{
local_irq_enable
();
cpu_relax
();
return
-
EBUSY
;
}
if
(
cx
->
entry_method
!=
ACPI_CSTATE_FFH
)
{
current_thread_info
()
->
status
&=
~
TS_POLLING
;
...
...
@@ -887,10 +862,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
if
(
cx
->
entry_method
!=
ACPI_CSTATE_FFH
)
current_thread_info
()
->
status
|=
TS_POLLING
;
cx
->
usage
++
;
lapic_timer_state_broadcast
(
pr
,
cx
,
0
);
cx
->
time
+=
idle_time
;
return
index
;
}
...
...
@@ -928,7 +900,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
drv
,
drv
->
safe_state_index
);
}
else
{
local_irq_disable
();
if
(
!
acpi_idle_suspend
)
acpi_safe_halt
();
local_irq_enable
();
return
-
EBUSY
;
...
...
@@ -937,11 +908,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
local_irq_disable
();
if
(
acpi_idle_suspend
)
{
local_irq_enable
();
cpu_relax
();
return
-
EBUSY
;
}
if
(
cx
->
entry_method
!=
ACPI_CSTATE_FFH
)
{
current_thread_info
()
->
status
&=
~
TS_POLLING
;
...
...
@@ -1014,10 +980,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if
(
cx
->
entry_method
!=
ACPI_CSTATE_FFH
)
current_thread_info
()
->
status
|=
TS_POLLING
;
cx
->
usage
++
;
lapic_timer_state_broadcast
(
pr
,
cx
,
0
);
cx
->
time
+=
idle_time
;
return
index
;
}
...
...
drivers/base/power/main.c
View file @
3db0bc97
...
...
@@ -28,7 +28,7 @@
#include <linux/sched.h>
#include <linux/async.h>
#include <linux/suspend.h>
#include <linux/cpuidle.h>
#include "../base.h"
#include "power.h"
...
...
@@ -467,6 +467,7 @@ static void dpm_resume_noirq(pm_message_t state)
mutex_unlock
(
&
dpm_list_mtx
);
dpm_show_time
(
starttime
,
state
,
"noirq"
);
resume_device_irqs
();
cpuidle_resume
();
}
/**
...
...
@@ -867,6 +868,7 @@ static int dpm_suspend_noirq(pm_message_t state)
ktime_t
starttime
=
ktime_get
();
int
error
=
0
;
cpuidle_pause
();
suspend_device_irqs
();
mutex_lock
(
&
dpm_list_mtx
);
while
(
!
list_empty
(
&
dpm_late_early_list
))
{
...
...
drivers/cpuidle/cpuidle.c
View file @
3db0bc97
...
...
@@ -201,6 +201,22 @@ void cpuidle_resume_and_unlock(void)
EXPORT_SYMBOL_GPL
(
cpuidle_resume_and_unlock
);
/* Currently used in suspend/resume path to suspend cpuidle */
void
cpuidle_pause
(
void
)
{
mutex_lock
(
&
cpuidle_lock
);
cpuidle_uninstall_idle_handler
();
mutex_unlock
(
&
cpuidle_lock
);
}
/* Currently used in suspend/resume path to resume cpuidle */
void
cpuidle_resume
(
void
)
{
mutex_lock
(
&
cpuidle_lock
);
cpuidle_install_idle_handler
();
mutex_unlock
(
&
cpuidle_lock
);
}
/**
* cpuidle_wrap_enter - performs timekeeping and irqen around enter function
* @dev: pointer to a valid cpuidle_device object
...
...
@@ -265,7 +281,6 @@ static void poll_idle_init(struct cpuidle_driver *drv)
state
->
power_usage
=
-
1
;
state
->
flags
=
0
;
state
->
enter
=
poll_idle
;
state
->
disable
=
0
;
}
#else
static
void
poll_idle_init
(
struct
cpuidle_driver
*
drv
)
{}
...
...
drivers/cpuidle/driver.c
View file @
3db0bc97
...
...
@@ -16,6 +16,7 @@
static
struct
cpuidle_driver
*
cpuidle_curr_driver
;
DEFINE_SPINLOCK
(
cpuidle_driver_lock
);
int
cpuidle_driver_refcount
;
static
void
__cpuidle_register_driver
(
struct
cpuidle_driver
*
drv
)
{
...
...
@@ -89,8 +90,34 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv)
}
spin_lock
(
&
cpuidle_driver_lock
);
if
(
!
WARN_ON
(
cpuidle_driver_refcount
>
0
))
cpuidle_curr_driver
=
NULL
;
spin_unlock
(
&
cpuidle_driver_lock
);
}
EXPORT_SYMBOL_GPL
(
cpuidle_unregister_driver
);
struct
cpuidle_driver
*
cpuidle_driver_ref
(
void
)
{
struct
cpuidle_driver
*
drv
;
spin_lock
(
&
cpuidle_driver_lock
);
drv
=
cpuidle_curr_driver
;
cpuidle_driver_refcount
++
;
spin_unlock
(
&
cpuidle_driver_lock
);
return
drv
;
}
void
cpuidle_driver_unref
(
void
)
{
spin_lock
(
&
cpuidle_driver_lock
);
if
(
!
WARN_ON
(
cpuidle_driver_refcount
<=
0
))
cpuidle_driver_refcount
--
;
spin_unlock
(
&
cpuidle_driver_lock
);
}
drivers/cpuidle/governors/menu.c
View file @
3db0bc97
...
...
@@ -281,7 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
* unless the timer is happening really really soon.
*/
if
(
data
->
expected_us
>
5
&&
d
rv
->
states
[
CPUIDLE_DRIVER_STATE_START
].
disable
==
0
)
d
ev
->
states_usage
[
CPUIDLE_DRIVER_STATE_START
].
disable
==
0
)
data
->
last_state_idx
=
CPUIDLE_DRIVER_STATE_START
;
/*
...
...
@@ -290,8 +290,9 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
*/
for
(
i
=
CPUIDLE_DRIVER_STATE_START
;
i
<
drv
->
state_count
;
i
++
)
{
struct
cpuidle_state
*
s
=
&
drv
->
states
[
i
];
struct
cpuidle_state_usage
*
su
=
&
dev
->
states_usage
[
i
];
if
(
s
->
disable
)
if
(
s
u
->
disable
)
continue
;
if
(
s
->
target_residency
>
data
->
predicted_us
)
continue
;
...
...
drivers/cpuidle/sysfs.c
View file @
3db0bc97
...
...
@@ -217,7 +217,8 @@ struct cpuidle_state_attr {
struct
attribute
attr
;
ssize_t
(
*
show
)(
struct
cpuidle_state
*
,
\
struct
cpuidle_state_usage
*
,
char
*
);
ssize_t
(
*
store
)(
struct
cpuidle_state
*
,
const
char
*
,
size_t
);
ssize_t
(
*
store
)(
struct
cpuidle_state
*
,
\
struct
cpuidle_state_usage
*
,
const
char
*
,
size_t
);
};
#define define_one_state_ro(_name, show) \
...
...
@@ -233,21 +234,22 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, \
return sprintf(buf, "%u\n", state->_name);\
}
#define define_store_state_function(_name) \
#define define_store_state_
ull_
function(_name) \
static ssize_t store_state_##_name(struct cpuidle_state *state, \
struct cpuidle_state_usage *state_usage, \
const char *buf, size_t size) \
{ \
long value; \
unsigned long
long value; \
int err; \
if (!capable(CAP_SYS_ADMIN)) \
return -EPERM; \
err = kstrtol(buf, 0, &value); \
err = kstrto
ul
l(buf, 0, &value); \
if (err) \
return err; \
if (value) \
state
->disabl
e = 1; \
state
_usage->_nam
e = 1; \
else \
state
->disabl
e = 0; \
state
_usage->_nam
e = 0; \
return size; \
}
...
...
@@ -273,8 +275,8 @@ define_show_state_ull_function(usage)
define_show_state_ull_function
(
time
)
define_show_state_str_function
(
name
)
define_show_state_str_function
(
desc
)
define_show_state_function
(
disable
)
define_store_state_function
(
disable
)
define_show_state_
ull_
function
(
disable
)
define_store_state_
ull_
function
(
disable
)
define_one_state_ro
(
name
,
show_state_name
);
define_one_state_ro
(
desc
,
show_state_desc
);
...
...
@@ -318,10 +320,11 @@ static ssize_t cpuidle_state_store(struct kobject *kobj,
{
int
ret
=
-
EIO
;
struct
cpuidle_state
*
state
=
kobj_to_state
(
kobj
);
struct
cpuidle_state_usage
*
state_usage
=
kobj_to_state_usage
(
kobj
);
struct
cpuidle_state_attr
*
cattr
=
attr_to_stateattr
(
attr
);
if
(
cattr
->
store
)
ret
=
cattr
->
store
(
state
,
buf
,
size
);
ret
=
cattr
->
store
(
state
,
state_usage
,
buf
,
size
);
return
ret
;
}
...
...
drivers/idle/intel_idle.c
View file @
3db0bc97
...
...
@@ -96,6 +96,7 @@ static const struct idle_cpu *icpu;
static
struct
cpuidle_device
__percpu
*
intel_idle_cpuidle_devices
;
static
int
intel_idle
(
struct
cpuidle_device
*
dev
,
struct
cpuidle_driver
*
drv
,
int
index
);
static
int
intel_idle_cpu_init
(
int
cpu
);
static
struct
cpuidle_state
*
cpuidle_state_table
;
...
...
@@ -302,22 +303,35 @@ static void __setup_broadcast_timer(void *arg)
clockevents_notify
(
reason
,
&
cpu
);
}
static
int
setup_broadcast_cpuhp
_notify
(
struct
notifier_block
*
n
,
static
int
cpu_hotplug
_notify
(
struct
notifier_block
*
n
,
unsigned
long
action
,
void
*
hcpu
)
{
int
hotcpu
=
(
unsigned
long
)
hcpu
;
struct
cpuidle_device
*
dev
;
switch
(
action
&
0xf
)
{
case
CPU_ONLINE
:
if
(
lapic_timer_reliable_states
!=
LAPIC_TIMER_ALWAYS_RELIABLE
)
smp_call_function_single
(
hotcpu
,
__setup_broadcast_timer
,
(
void
*
)
true
,
1
);
/*
* Some systems can hotplug a cpu at runtime after
* the kernel has booted, we have to initialize the
* driver in this case
*/
dev
=
per_cpu_ptr
(
intel_idle_cpuidle_devices
,
hotcpu
);
if
(
!
dev
->
registered
)
intel_idle_cpu_init
(
hotcpu
);
break
;
}
return
NOTIFY_OK
;
}
static
struct
notifier_block
setup_broadcast
_notifier
=
{
.
notifier_call
=
setup_broadcast_cpuhp
_notify
,
static
struct
notifier_block
cpu_hotplug
_notifier
=
{
.
notifier_call
=
cpu_hotplug
_notify
,
};
static
void
auto_demotion_disable
(
void
*
dummy
)
...
...
@@ -405,10 +419,10 @@ static int intel_idle_probe(void)
if
(
boot_cpu_has
(
X86_FEATURE_ARAT
))
/* Always Reliable APIC Timer */
lapic_timer_reliable_states
=
LAPIC_TIMER_ALWAYS_RELIABLE
;
else
{
else
on_each_cpu
(
__setup_broadcast_timer
,
(
void
*
)
true
,
1
);
register_cpu_notifier
(
&
setup_broadcast_notifier
);
}
register_cpu_notifier
(
&
cpu_hotplug_notifier
);
pr_debug
(
PREFIX
"v"
INTEL_IDLE_VERSION
" model 0x%X
\n
"
,
boot_cpu_data
.
x86_model
);
...
...
@@ -494,7 +508,7 @@ static int intel_idle_cpuidle_driver_init(void)
* allocate, initialize, register cpuidle_devices
* @cpu: cpu/core to initialize
*/
int
intel_idle_cpu_init
(
int
cpu
)
static
int
intel_idle_cpu_init
(
int
cpu
)
{
int
cstate
;
struct
cpuidle_device
*
dev
;
...
...
@@ -539,7 +553,6 @@ int intel_idle_cpu_init(int cpu)
return
0
;
}
EXPORT_SYMBOL_GPL
(
intel_idle_cpu_init
);
static
int
__init
intel_idle_init
(
void
)
{
...
...
@@ -581,10 +594,10 @@ static void __exit intel_idle_exit(void)
intel_idle_cpuidle_devices_uninit
();
cpuidle_unregister_driver
(
&
intel_idle_driver
);
if
(
lapic_timer_reliable_states
!=
LAPIC_TIMER_ALWAYS_RELIABLE
)
{
if
(
lapic_timer_reliable_states
!=
LAPIC_TIMER_ALWAYS_RELIABLE
)
on_each_cpu
(
__setup_broadcast_timer
,
(
void
*
)
false
,
1
);
unregister_cpu_notifier
(
&
setup_broadcast_notifier
);
}
unregister_cpu_notifier
(
&
cpu_hotplug_notifier
);
return
;
}
...
...
include/acpi/processor.h
View file @
3db0bc97
...
...
@@ -59,10 +59,7 @@ struct acpi_processor_cx {
u8
entry_method
;
u8
index
;
u32
latency
;
u32
latency_ticks
;
u32
power
;
u32
usage
;
u64
time
;
u8
bm_sts_skip
;
char
desc
[
ACPI_CX_DESC_LEN
];
};
...
...
include/linux/cpuidle.h
View file @
3db0bc97
...
...
@@ -34,6 +34,7 @@ struct cpuidle_driver;
struct
cpuidle_state_usage
{
void
*
driver_data
;
unsigned
long
long
disable
;
unsigned
long
long
usage
;
unsigned
long
long
time
;
/* in US */
};
...
...
@@ -46,7 +47,6 @@ struct cpuidle_state {
unsigned
int
exit_latency
;
/* in US */
int
power_usage
;
/* in mW */
unsigned
int
target_residency
;
/* in US */
unsigned
int
disable
;
int
(
*
enter
)
(
struct
cpuidle_device
*
dev
,
struct
cpuidle_driver
*
drv
,
...
...
@@ -136,13 +136,17 @@ struct cpuidle_driver {
extern
void
disable_cpuidle
(
void
);
extern
int
cpuidle_idle_call
(
void
);
extern
int
cpuidle_register_driver
(
struct
cpuidle_driver
*
drv
);
struct
cpuidle_driver
*
cpuidle_get_driver
(
void
);
extern
struct
cpuidle_driver
*
cpuidle_get_driver
(
void
);
extern
struct
cpuidle_driver
*
cpuidle_driver_ref
(
void
);
extern
void
cpuidle_driver_unref
(
void
);
extern
void
cpuidle_unregister_driver
(
struct
cpuidle_driver
*
drv
);
extern
int
cpuidle_register_device
(
struct
cpuidle_device
*
dev
);
extern
void
cpuidle_unregister_device
(
struct
cpuidle_device
*
dev
);
extern
void
cpuidle_pause_and_lock
(
void
);
extern
void
cpuidle_resume_and_unlock
(
void
);
extern
void
cpuidle_pause
(
void
);
extern
void
cpuidle_resume
(
void
);
extern
int
cpuidle_enable_device
(
struct
cpuidle_device
*
dev
);
extern
void
cpuidle_disable_device
(
struct
cpuidle_device
*
dev
);
extern
int
cpuidle_wrap_enter
(
struct
cpuidle_device
*
dev
,
...
...
@@ -157,6 +161,8 @@ static inline int cpuidle_idle_call(void) { return -ENODEV; }
static
inline
int
cpuidle_register_driver
(
struct
cpuidle_driver
*
drv
)
{
return
-
ENODEV
;
}
static
inline
struct
cpuidle_driver
*
cpuidle_get_driver
(
void
)
{
return
NULL
;
}
static
inline
struct
cpuidle_driver
*
cpuidle_driver_ref
(
void
)
{
return
NULL
;
}
static
inline
void
cpuidle_driver_unref
(
void
)
{}
static
inline
void
cpuidle_unregister_driver
(
struct
cpuidle_driver
*
drv
)
{
}
static
inline
int
cpuidle_register_device
(
struct
cpuidle_device
*
dev
)
{
return
-
ENODEV
;
}
...
...
@@ -164,6 +170,8 @@ static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
static
inline
void
cpuidle_pause_and_lock
(
void
)
{
}
static
inline
void
cpuidle_resume_and_unlock
(
void
)
{
}
static
inline
void
cpuidle_pause
(
void
)
{
}
static
inline
void
cpuidle_resume
(
void
)
{
}
static
inline
int
cpuidle_enable_device
(
struct
cpuidle_device
*
dev
)
{
return
-
ENODEV
;
}
static
inline
void
cpuidle_disable_device
(
struct
cpuidle_device
*
dev
)
{
}
...
...
@@ -202,14 +210,7 @@ struct cpuidle_governor {
extern
int
cpuidle_register_governor
(
struct
cpuidle_governor
*
gov
);
extern
void
cpuidle_unregister_governor
(
struct
cpuidle_governor
*
gov
);
#ifdef CONFIG_INTEL_IDLE
extern
int
intel_idle_cpu_init
(
int
cpu
);
#else
static
inline
int
intel_idle_cpu_init
(
int
cpu
)
{
return
-
1
;
}
#endif
#else
static
inline
int
intel_idle_cpu_init
(
int
cpu
)
{
return
-
1
;
}
static
inline
int
cpuidle_register_governor
(
struct
cpuidle_governor
*
gov
)
{
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