Skip to content

Commit

Permalink
PM / ACPI: Fix suspend/resume regression caused by cpuidle cleanup.
Browse files Browse the repository at this point in the history
Commit e978aa7 ( cpuidle: Move
dev->last_residency update to driver enter routine; remove dev->last_state)
was  breaking suspend on laptops, as reported in the below link
	- https://lkml.org/lkml/2011/11/11/164

This was fixed in commit 3439a8d
(ACPI / cpuidle: Remove acpi_idle_suspend (to fix suspend regression)
by removing acpi_idle_suspend flag.
	- https://lkml.org/lkml/2011/11/14/74

But this did fix did not work on all systems
as Suspend/resume regression was reported on Lenovo S10-3
recently by Dave.
	- https://lkml.org/lkml/2012/5/27/115
It looked like with commit e978aa7 broke suspend and
with commit 3439a8d resume was not working with acpi_idle driver.

This patch fixes the regression that caused this issue
in the first place. acpi_idle_suspend flag is essential on
some x86 systems to prevent the cpus from going to deeper C-states
when suspend is triggered ( commit b04e7bd )
So reverting the commit 3439a8d is essential.

By default, irqs are disabled in cpu_idle arch specific call
and re-enabled in idle state return path . During suspend,
the acpi_idle_suspend flag is set, which
prevents the cpus from going to deeper idle states,
it is essential to enabling the irqs in this return path too.

To address the suspend issue,
we were not re-enabling the interrupts while returning from
acpi_idle_enter_bm() routine if acpi_idle_suspend flag is set.
and this caused suspend failure.

In addition to the above, to improve the readability of the code,
return of -ENIVAL is replaced with -EBUSY in acpi_idle_suspend
return path. Implying that the system is currently busy when suspend
is in progress, which prevents the cpus from entering deeper C-states.

Reported-and-Tested-by: Dav Hansen <dave@linux.vnet.ibm.com>
Tested-by: Preeti Murthy <preeti@linux.vnet.ibm.com>
Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Reviewed-by: Srivatsa S Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
  • Loading branch information
Deepthi Dharwar authored and Rafael J. Wysocki committed Jun 27, 2012
1 parent 1f758b2 commit 75cc523
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions drivers/acpi/processor_idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
/*
* Suspend / resume control
*/
static int acpi_idle_suspend;
static u32 saved_bm_rld;

static void acpi_idle_bm_rld_save(void)
Expand All @@ -242,13 +243,21 @@ 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;
}

Expand Down Expand Up @@ -754,6 +763,12 @@ 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();
acpi_idle_do_entry(cx);
Expand Down Expand Up @@ -823,6 +838,12 @@ 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;
/*
Expand Down Expand Up @@ -907,14 +928,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
drv, drv->safe_state_index);
} else {
local_irq_disable();
acpi_safe_halt();
if (!acpi_idle_suspend)
acpi_safe_halt();
local_irq_enable();
return -EINVAL;
return -EBUSY;
}
}

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;
/*
Expand Down

0 comments on commit 75cc523

Please sign in to comment.