aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--arch/x86/kernel/acpi/sleep.c4
-rw-r--r--drivers/acpi/sleep/main.c22
-rw-r--r--include/linux/acpi.h1
4 files changed, 30 insertions, 1 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4d705713cabc..497a98dafdaa 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -148,10 +148,12 @@ and is between 256 and 4096 characters. It is defined in the file
148 default: 0 148 default: 0
149 149
150 acpi_sleep= [HW,ACPI] Sleep options 150 acpi_sleep= [HW,ACPI] Sleep options
151 Format: { s3_bios, s3_mode, s3_beep, old_ordering } 151 Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig, old_ordering }
152 See Documentation/power/video.txt for s3_bios and s3_mode. 152 See Documentation/power/video.txt for s3_bios and s3_mode.
153 s3_beep is for debugging; it makes the PC's speaker beep 153 s3_beep is for debugging; it makes the PC's speaker beep
154 as soon as the kernel's real-mode entry point is called. 154 as soon as the kernel's real-mode entry point is called.
155 s4_nohwsig prevents ACPI hardware signature from being
156 used during resume from hibernation.
155 old_ordering causes the ACPI 1.0 ordering of the _PTS 157 old_ordering causes the ACPI 1.0 ordering of the _PTS
156 control method, wrt putting devices into low power 158 control method, wrt putting devices into low power
157 states, to be enforced (the ACPI 2.0 ordering of _PTS is 159 states, to be enforced (the ACPI 2.0 ordering of _PTS is
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index a3ddad18aaa3..fa2161d5003b 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -150,6 +150,10 @@ static int __init acpi_sleep_setup(char *str)
150 acpi_realmode_flags |= 2; 150 acpi_realmode_flags |= 2;
151 if (strncmp(str, "s3_beep", 7) == 0) 151 if (strncmp(str, "s3_beep", 7) == 0)
152 acpi_realmode_flags |= 4; 152 acpi_realmode_flags |= 4;
153#ifdef CONFIG_HIBERNATION
154 if (strncmp(str, "s4_nohwsig", 10) == 0)
155 acpi_no_s4_hw_signature();
156#endif
153 if (strncmp(str, "old_ordering", 12) == 0) 157 if (strncmp(str, "old_ordering", 12) == 0)
154 acpi_old_suspend_ordering(); 158 acpi_old_suspend_ordering();
155 str = strchr(str, ','); 159 str = strchr(str, ',');
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 0489a7d1d42c..313507accf18 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -283,6 +283,15 @@ static struct platform_suspend_ops acpi_suspend_ops_old = {
283#endif /* CONFIG_SUSPEND */ 283#endif /* CONFIG_SUSPEND */
284 284
285#ifdef CONFIG_HIBERNATION 285#ifdef CONFIG_HIBERNATION
286static unsigned long s4_hardware_signature;
287static struct acpi_table_facs *facs;
288static bool nosigcheck;
289
290void __init acpi_no_s4_hw_signature(void)
291{
292 nosigcheck = true;
293}
294
286static int acpi_hibernation_begin(void) 295static int acpi_hibernation_begin(void)
287{ 296{
288 acpi_target_sleep_state = ACPI_STATE_S4; 297 acpi_target_sleep_state = ACPI_STATE_S4;
@@ -316,6 +325,12 @@ static void acpi_hibernation_leave(void)
316 acpi_enable(); 325 acpi_enable();
317 /* Reprogram control registers and execute _BFS */ 326 /* Reprogram control registers and execute _BFS */
318 acpi_leave_sleep_state_prep(ACPI_STATE_S4); 327 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
328 /* Check the hardware signature */
329 if (facs && s4_hardware_signature != facs->hardware_signature) {
330 printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
331 "cannot resume!\n");
332 panic("ACPI S4 hardware signature mismatch");
333 }
319} 334}
320 335
321static void acpi_pm_enable_gpes(void) 336static void acpi_pm_enable_gpes(void)
@@ -544,6 +559,13 @@ int __init acpi_sleep_init(void)
544 &acpi_hibernation_ops_old : &acpi_hibernation_ops); 559 &acpi_hibernation_ops_old : &acpi_hibernation_ops);
545 sleep_states[ACPI_STATE_S4] = 1; 560 sleep_states[ACPI_STATE_S4] = 1;
546 printk(" S4"); 561 printk(" S4");
562 if (!nosigcheck) {
563 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
564 (struct acpi_table_header **)&facs);
565 if (facs)
566 s4_hardware_signature =
567 facs->hardware_signature;
568 }
547 } 569 }
548#endif 570#endif
549 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); 571 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index a17177639376..702f79dad16a 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -236,6 +236,7 @@ int acpi_check_mem_region(resource_size_t start, resource_size_t n,
236 const char *name); 236 const char *name);
237 237
238#ifdef CONFIG_PM_SLEEP 238#ifdef CONFIG_PM_SLEEP
239void __init acpi_no_s4_hw_signature(void);
239void __init acpi_old_suspend_ordering(void); 240void __init acpi_old_suspend_ordering(void);
240#endif /* CONFIG_PM_SLEEP */ 241#endif /* CONFIG_PM_SLEEP */
241#else /* CONFIG_ACPI */ 242#else /* CONFIG_ACPI */