aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-07-23 16:59:09 -0400
committerLen Brown <len.brown@intel.com>2010-07-24 23:26:09 -0400
commit72ad5d77fb981963edae15eee8196c80238f5ed0 (patch)
treea6fa9a0b9ba924fd2dd91debf3e8ab04e8084338
parentb37fa16e78d6f9790462b3181602a26b5af36260 (diff)
ACPI / Sleep: Allow the NVS saving to be skipped during suspend to RAM
Commit 2a6b69765ad794389f2fc3e14a0afa1a995221c2 (ACPI: Store NVS state even when entering suspend to RAM) caused the ACPI suspend code save the NVS area during suspend and restore it during resume unconditionally, although it is known that some systems need to use acpi_sleep=s4_nonvs for hibernation to work. To allow the affected systems to avoid saving and restoring the NVS area during suspend to RAM and resume, introduce kernel command line option acpi_sleep=nonvs and make acpi_sleep=s4_nonvs work as its alias temporarily (add acpi_sleep=s4_nonvs to the feature removal file). Addresses https://bugzilla.kernel.org/show_bug.cgi?id=16396 . Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Reported-and-tested-by: tomas m <tmezzadra@gmail.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--Documentation/feature-removal-schedule.txt7
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--arch/x86/kernel/acpi/sleep.c9
-rw-r--r--drivers/acpi/sleep.c35
-rw-r--r--include/linux/acpi.h2
5 files changed, 34 insertions, 23 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c268783bc4e7..1571c0c83dba 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -647,3 +647,10 @@ Who: Stefan Richter <stefanr@s5r6.in-berlin.de>
647 647
648---------------------------- 648----------------------------
649 649
650What: The acpi_sleep=s4_nonvs command line option
651When: 2.6.37
652Files: arch/x86/kernel/acpi/sleep.c
653Why: superseded by acpi_sleep=nonvs
654Who: Rafael J. Wysocki <rjw@sisk.pl>
655
656----------------------------
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4ddb58df081e..2b2407d9a6d0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -254,8 +254,8 @@ and is between 256 and 4096 characters. It is defined in the file
254 control method, with respect to putting devices into 254 control method, with respect to putting devices into
255 low power states, to be enforced (the ACPI 2.0 ordering 255 low power states, to be enforced (the ACPI 2.0 ordering
256 of _PTS is used by default). 256 of _PTS is used by default).
257 s4_nonvs prevents the kernel from saving/restoring the 257 nonvs prevents the kernel from saving/restoring the
258 ACPI NVS memory during hibernation. 258 ACPI NVS memory during suspend/hibernation and resume.
259 sci_force_enable causes the kernel to set SCI_EN directly 259 sci_force_enable causes the kernel to set SCI_EN directly
260 on resume from S1/S3 (which is against the ACPI spec, 260 on resume from S1/S3 (which is against the ACPI spec,
261 but some broken systems don't work without it). 261 but some broken systems don't work without it).
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 82e508677b91..fcc3c61fdecc 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -157,9 +157,14 @@ static int __init acpi_sleep_setup(char *str)
157#ifdef CONFIG_HIBERNATION 157#ifdef CONFIG_HIBERNATION
158 if (strncmp(str, "s4_nohwsig", 10) == 0) 158 if (strncmp(str, "s4_nohwsig", 10) == 0)
159 acpi_no_s4_hw_signature(); 159 acpi_no_s4_hw_signature();
160 if (strncmp(str, "s4_nonvs", 8) == 0) 160 if (strncmp(str, "s4_nonvs", 8) == 0) {
161 acpi_s4_no_nvs(); 161 pr_warning("ACPI: acpi_sleep=s4_nonvs is deprecated, "
162 "please use acpi_sleep=nonvs instead");
163 acpi_nvs_nosave();
164 }
162#endif 165#endif
166 if (strncmp(str, "nonvs", 5) == 0)
167 acpi_nvs_nosave();
163 if (strncmp(str, "old_ordering", 12) == 0) 168 if (strncmp(str, "old_ordering", 12) == 0)
164 acpi_old_suspend_ordering(); 169 acpi_old_suspend_ordering();
165 str = strchr(str, ','); 170 str = strchr(str, ',');
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 5b7c52e4a00f..2862c781b372 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -82,6 +82,20 @@ static int acpi_sleep_prepare(u32 acpi_state)
82static u32 acpi_target_sleep_state = ACPI_STATE_S0; 82static u32 acpi_target_sleep_state = ACPI_STATE_S0;
83 83
84/* 84/*
85 * The ACPI specification wants us to save NVS memory regions during hibernation
86 * and to restore them during the subsequent resume. Windows does that also for
87 * suspend to RAM. However, it is known that this mechanism does not work on
88 * all machines, so we allow the user to disable it with the help of the
89 * 'acpi_sleep=nonvs' kernel command line option.
90 */
91static bool nvs_nosave;
92
93void __init acpi_nvs_nosave(void)
94{
95 nvs_nosave = true;
96}
97
98/*
85 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the 99 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
86 * user to request that behavior by using the 'acpi_old_suspend_ordering' 100 * user to request that behavior by using the 'acpi_old_suspend_ordering'
87 * kernel command line option that causes the following variable to be set. 101 * kernel command line option that causes the following variable to be set.
@@ -197,8 +211,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
197 u32 acpi_state = acpi_suspend_states[pm_state]; 211 u32 acpi_state = acpi_suspend_states[pm_state];
198 int error = 0; 212 int error = 0;
199 213
200 error = suspend_nvs_alloc(); 214 error = nvs_nosave ? 0 : suspend_nvs_alloc();
201
202 if (error) 215 if (error)
203 return error; 216 return error;
204 217
@@ -388,20 +401,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
388#endif /* CONFIG_SUSPEND */ 401#endif /* CONFIG_SUSPEND */
389 402
390#ifdef CONFIG_HIBERNATION 403#ifdef CONFIG_HIBERNATION
391/*
392 * The ACPI specification wants us to save NVS memory regions during hibernation
393 * and to restore them during the subsequent resume. However, it is not certain
394 * if this mechanism is going to work on all machines, so we allow the user to
395 * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line
396 * option.
397 */
398static bool s4_no_nvs;
399
400void __init acpi_s4_no_nvs(void)
401{
402 s4_no_nvs = true;
403}
404
405static unsigned long s4_hardware_signature; 404static unsigned long s4_hardware_signature;
406static struct acpi_table_facs *facs; 405static struct acpi_table_facs *facs;
407static bool nosigcheck; 406static bool nosigcheck;
@@ -415,7 +414,7 @@ static int acpi_hibernation_begin(void)
415{ 414{
416 int error; 415 int error;
417 416
418 error = s4_no_nvs ? 0 : suspend_nvs_alloc(); 417 error = nvs_nosave ? 0 : suspend_nvs_alloc();
419 if (!error) { 418 if (!error) {
420 acpi_target_sleep_state = ACPI_STATE_S4; 419 acpi_target_sleep_state = ACPI_STATE_S4;
421 acpi_sleep_tts_switch(acpi_target_sleep_state); 420 acpi_sleep_tts_switch(acpi_target_sleep_state);
@@ -510,7 +509,7 @@ static int acpi_hibernation_begin_old(void)
510 error = acpi_sleep_prepare(ACPI_STATE_S4); 509 error = acpi_sleep_prepare(ACPI_STATE_S4);
511 510
512 if (!error) { 511 if (!error) {
513 if (!s4_no_nvs) 512 if (!nvs_nosave)
514 error = suspend_nvs_alloc(); 513 error = suspend_nvs_alloc();
515 if (!error) 514 if (!error)
516 acpi_target_sleep_state = ACPI_STATE_S4; 515 acpi_target_sleep_state = ACPI_STATE_S4;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 224a38c960d4..ccf94dc5acdf 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -253,7 +253,7 @@ int acpi_resources_are_enforced(void);
253#ifdef CONFIG_PM_SLEEP 253#ifdef CONFIG_PM_SLEEP
254void __init acpi_no_s4_hw_signature(void); 254void __init acpi_no_s4_hw_signature(void);
255void __init acpi_old_suspend_ordering(void); 255void __init acpi_old_suspend_ordering(void);
256void __init acpi_s4_no_nvs(void); 256void __init acpi_nvs_nosave(void);
257#endif /* CONFIG_PM_SLEEP */ 257#endif /* CONFIG_PM_SLEEP */
258 258
259struct acpi_osc_context { 259struct acpi_osc_context {