summaryrefslogtreecommitdiff
path: root/drivers/acpi/processor_idle.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/processor_idle.c')
-rw-r--r--drivers/acpi/processor_idle.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index e8e2d8869236..55d69dce47c4 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -418,13 +418,12 @@ static void acpi_processor_idle(void)
cx = pr->power.state;
if (!cx || acpi_idle_suspend) {
- if (pm_idle_save)
- pm_idle_save();
- else
+ if (pm_idle_save) {
+ pm_idle_save(); /* enables IRQs */
+ } else {
acpi_safe_halt();
-
- if (irqs_disabled())
local_irq_enable();
+ }
return;
}
@@ -520,10 +519,12 @@ static void acpi_processor_idle(void)
* Use the appropriate idle routine, the one that would
* be used without acpi C-states.
*/
- if (pm_idle_save)
- pm_idle_save();
- else
+ if (pm_idle_save) {
+ pm_idle_save(); /* enables IRQs */
+ } else {
acpi_safe_halt();
+ local_irq_enable();
+ }
/*
* TBD: Can't get time duration while in C1, as resumes
@@ -534,8 +535,6 @@ static void acpi_processor_idle(void)
* skew otherwise.
*/
sleep_ticks = 0xFFFFFFFF;
- if (irqs_disabled())
- local_irq_enable();
break;
@@ -848,6 +847,7 @@ static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
/* all processors need to support C1 */
pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
pr->power.states[ACPI_STATE_C1].valid = 1;
+ pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;
}
/* the C0 state only exists as a filler in our array */
pr->power.states[ACPI_STATE_C0].valid = 1;
@@ -960,6 +960,9 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
cx.address);
}
+ if (cx.type == ACPI_STATE_C1) {
+ cx.valid = 1;
+ }
obj = &(element->package.elements[2]);
if (obj->type != ACPI_TYPE_INTEGER)
@@ -1295,6 +1298,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{
int result = 0;
+ if (boot_option_idle_override)
+ return 0;
if (!pr)
return -EINVAL;
@@ -1487,7 +1492,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
return 0;
}
- acpi_unlazy_tlb(smp_processor_id());
/*
* Must be done before busmaster disable as we might need to
* access HPET !
@@ -1577,6 +1581,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
return 0;
}
+ acpi_unlazy_tlb(smp_processor_id());
+
/* Tell the scheduler that we are going deep-idle: */
sched_clock_idle_sleep_event();
/*
@@ -1692,7 +1698,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
switch (cx->type) {
case ACPI_STATE_C1:
state->flags |= CPUIDLE_FLAG_SHALLOW;
- state->flags |= CPUIDLE_FLAG_TIME_VALID;
+ if (cx->entry_method == ACPI_CSTATE_FFH)
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+
state->enter = acpi_idle_enter_c1;
dev->safe_state = state;
break;
@@ -1731,6 +1739,9 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{
int ret;
+ if (boot_option_idle_override)
+ return 0;
+
if (!pr)
return -EINVAL;
@@ -1761,6 +1772,8 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
struct proc_dir_entry *entry = NULL;
unsigned int i;
+ if (boot_option_idle_override)
+ return 0;
if (!first_run) {
dmi_check_system(processor_power_dmi_table);
@@ -1796,7 +1809,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
* Note that we use previously set idle handler will be used on
* platforms that only support C1.
*/
- if ((pr->flags.power) && (!boot_option_idle_override)) {
+ if (pr->flags.power) {
#ifdef CONFIG_CPU_IDLE
acpi_processor_setup_cpuidle(pr);
pr->power.dev.cpu = pr->id;
@@ -1836,8 +1849,11 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
int acpi_processor_power_exit(struct acpi_processor *pr,
struct acpi_device *device)
{
+ if (boot_option_idle_override)
+ return 0;
+
#ifdef CONFIG_CPU_IDLE
- if ((pr->flags.power) && (!boot_option_idle_override))
+ if (pr->flags.power)
cpuidle_unregister_device(&pr->power.dev);
#endif
pr->flags.power_setup_done = 0;