Commit d7f0eea9e431e1b8b0742a74db1a9490730b2a25
Committed by
Len Brown
1 parent
6b7b284958
Exists in
master
and in
7 other branches
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>
Showing 4 changed files with 24 additions and 13 deletions Side-by-side Diff
Documentation/kernel-parameters.txt
... | ... | @@ -240,7 +240,7 @@ |
240 | 240 | |
241 | 241 | acpi_sleep= [HW,ACPI] Sleep options |
242 | 242 | Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, |
243 | - old_ordering, s4_nonvs } | |
243 | + old_ordering, s4_nonvs, sci_force_enable } | |
244 | 244 | See Documentation/power/video.txt for information on |
245 | 245 | s3_bios and s3_mode. |
246 | 246 | s3_beep is for debugging; it makes the PC's speaker beep |
... | ... | @@ -253,6 +253,9 @@ |
253 | 253 | of _PTS is used by default). |
254 | 254 | s4_nonvs prevents the kernel from saving/restoring the |
255 | 255 | ACPI NVS memory during hibernation. |
256 | + sci_force_enable causes the kernel to set SCI_EN directly | |
257 | + on resume from S1/S3 (which is against the ACPI spec, | |
258 | + but some broken systems don't work without it). | |
256 | 259 | |
257 | 260 | acpi_use_timer_override [HW,ACPI] |
258 | 261 | Use timer override. For some broken Nvidia NF5 boards |
arch/x86/kernel/acpi/sleep.c
... | ... | @@ -162,6 +162,8 @@ |
162 | 162 | #endif |
163 | 163 | if (strncmp(str, "old_ordering", 12) == 0) |
164 | 164 | acpi_old_suspend_ordering(); |
165 | + if (strncmp(str, "sci_force_enable", 16) == 0) | |
166 | + acpi_set_sci_en_on_resume(); | |
165 | 167 | str = strchr(str, ','); |
166 | 168 | if (str != NULL) |
167 | 169 | str += strspn(str, ", \t"); |
drivers/acpi/sleep.c
... | ... | @@ -81,6 +81,23 @@ |
81 | 81 | #ifdef CONFIG_ACPI_SLEEP |
82 | 82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
83 | 83 | /* |
84 | + * According to the ACPI specification the BIOS should make sure that ACPI is | |
85 | + * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | |
86 | + * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | |
87 | + * on such systems during resume. Unfortunately that doesn't help in | |
88 | + * particularly pathological cases in which SCI_EN has to be set directly on | |
89 | + * resume, although the specification states very clearly that this flag is | |
90 | + * owned by the hardware. The set_sci_en_on_resume variable will be set in such | |
91 | + * cases. | |
92 | + */ | |
93 | +static bool set_sci_en_on_resume; | |
94 | + | |
95 | +void __init acpi_set_sci_en_on_resume(void) | |
96 | +{ | |
97 | + set_sci_en_on_resume = true; | |
98 | +} | |
99 | + | |
100 | +/* | |
84 | 101 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
85 | 102 | * user to request that behavior by using the 'acpi_old_suspend_ordering' |
86 | 103 | * kernel command line option that causes the following variable to be set. |
... | ... | @@ -170,18 +187,6 @@ |
170 | 187 | #endif /* CONFIG_ACPI_SLEEP */ |
171 | 188 | |
172 | 189 | #ifdef CONFIG_SUSPEND |
173 | -/* | |
174 | - * According to the ACPI specification the BIOS should make sure that ACPI is | |
175 | - * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | |
176 | - * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | |
177 | - * on such systems during resume. Unfortunately that doesn't help in | |
178 | - * particularly pathological cases in which SCI_EN has to be set directly on | |
179 | - * resume, although the specification states very clearly that this flag is | |
180 | - * owned by the hardware. The set_sci_en_on_resume variable will be set in such | |
181 | - * cases. | |
182 | - */ | |
183 | -static bool set_sci_en_on_resume; | |
184 | - | |
185 | 190 | extern void do_suspend_lowlevel(void); |
186 | 191 | |
187 | 192 | static u32 acpi_suspend_states[] = { |
include/linux/acpi.h
... | ... | @@ -251,6 +251,7 @@ |
251 | 251 | void __init acpi_no_s4_hw_signature(void); |
252 | 252 | void __init acpi_old_suspend_ordering(void); |
253 | 253 | void __init acpi_s4_no_nvs(void); |
254 | +void __init acpi_set_sci_en_on_resume(void); | |
254 | 255 | #endif /* CONFIG_PM_SLEEP */ |
255 | 256 | |
256 | 257 | struct acpi_osc_context { |