ACPI: introduce kernel parameter acpi_sleep=sci_force_enable

Introduce kernel parameter acpi_sleep=sci_force_enable

some laptop requires SCI_EN being set directly on resume,
or else they hung somewhere in the resume code path.

We already have a blacklist for these laptops but we still need
this option, especially when debugging some suspend/resume problems,
in case there are systems that need this workaround and are not yet
in the blacklist.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Zhang Rui 2009-12-30 15:36:42 +08:00 committed by Len Brown
parent 6b7b284958
commit d7f0eea9e4
4 changed files with 24 additions and 13 deletions

View File

@ -240,7 +240,7 @@ and is between 256 and 4096 characters. It is defined in the file
acpi_sleep= [HW,ACPI] Sleep options acpi_sleep= [HW,ACPI] Sleep options
Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
old_ordering, s4_nonvs } old_ordering, s4_nonvs, sci_force_enable }
See Documentation/power/video.txt for information on See Documentation/power/video.txt for information on
s3_bios and s3_mode. s3_bios and s3_mode.
s3_beep is for debugging; it makes the PC's speaker beep s3_beep is for debugging; it makes the PC's speaker beep
@ -253,6 +253,9 @@ and is between 256 and 4096 characters. It is defined in the file
of _PTS is used by default). of _PTS is used by default).
s4_nonvs prevents the kernel from saving/restoring the s4_nonvs prevents the kernel from saving/restoring the
ACPI NVS memory during hibernation. ACPI NVS memory during hibernation.
sci_force_enable causes the kernel to set SCI_EN directly
on resume from S1/S3 (which is against the ACPI spec,
but some broken systems don't work without it).
acpi_use_timer_override [HW,ACPI] acpi_use_timer_override [HW,ACPI]
Use timer override. For some broken Nvidia NF5 boards Use timer override. For some broken Nvidia NF5 boards

View File

@ -162,6 +162,8 @@ static int __init acpi_sleep_setup(char *str)
#endif #endif
if (strncmp(str, "old_ordering", 12) == 0) if (strncmp(str, "old_ordering", 12) == 0)
acpi_old_suspend_ordering(); acpi_old_suspend_ordering();
if (strncmp(str, "sci_force_enable", 16) == 0)
acpi_set_sci_en_on_resume();
str = strchr(str, ','); str = strchr(str, ',');
if (str != NULL) if (str != NULL)
str += strspn(str, ", \t"); str += strspn(str, ", \t");

View File

@ -80,6 +80,23 @@ static int acpi_sleep_prepare(u32 acpi_state)
#ifdef CONFIG_ACPI_SLEEP #ifdef CONFIG_ACPI_SLEEP
static u32 acpi_target_sleep_state = ACPI_STATE_S0; static u32 acpi_target_sleep_state = ACPI_STATE_S0;
/*
* According to the ACPI specification the BIOS should make sure that ACPI is
* enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
* some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
* on such systems during resume. Unfortunately that doesn't help in
* particularly pathological cases in which SCI_EN has to be set directly on
* resume, although the specification states very clearly that this flag is
* owned by the hardware. The set_sci_en_on_resume variable will be set in such
* cases.
*/
static bool set_sci_en_on_resume;
void __init acpi_set_sci_en_on_resume(void)
{
set_sci_en_on_resume = true;
}
/* /*
* ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
* user to request that behavior by using the 'acpi_old_suspend_ordering' * user to request that behavior by using the 'acpi_old_suspend_ordering'
@ -170,18 +187,6 @@ static void acpi_pm_end(void)
#endif /* CONFIG_ACPI_SLEEP */ #endif /* CONFIG_ACPI_SLEEP */
#ifdef CONFIG_SUSPEND #ifdef CONFIG_SUSPEND
/*
* According to the ACPI specification the BIOS should make sure that ACPI is
* enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still,
* some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
* on such systems during resume. Unfortunately that doesn't help in
* particularly pathological cases in which SCI_EN has to be set directly on
* resume, although the specification states very clearly that this flag is
* owned by the hardware. The set_sci_en_on_resume variable will be set in such
* cases.
*/
static bool set_sci_en_on_resume;
extern void do_suspend_lowlevel(void); extern void do_suspend_lowlevel(void);
static u32 acpi_suspend_states[] = { static u32 acpi_suspend_states[] = {

View File

@ -251,6 +251,7 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n,
void __init acpi_no_s4_hw_signature(void); void __init acpi_no_s4_hw_signature(void);
void __init acpi_old_suspend_ordering(void); void __init acpi_old_suspend_ordering(void);
void __init acpi_s4_no_nvs(void); void __init acpi_s4_no_nvs(void);
void __init acpi_set_sci_en_on_resume(void);
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
struct acpi_osc_context { struct acpi_osc_context {