]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/acpi/sleep/main.c
pm: acpi pm: add DMI quirk list for ACPI 1.0 suspend ordering
[linux-2.6-omap-h63xx.git] / drivers / acpi / sleep / main.c
index 0489a7d1d42c91dcf404c50c56e07c722a41ea1f..d13194a031bfbe0d1f9de3c83cd25471c10eda7a 100644 (file)
@@ -280,9 +280,36 @@ static struct platform_suspend_ops acpi_suspend_ops_old = {
        .end = acpi_pm_end,
        .recover = acpi_pm_finish,
 };
+
+static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
+{
+       old_suspend_ordering = true;
+       return 0;
+}
+
+static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
+       {
+       .callback = init_old_suspend_ordering,
+       .ident = "Abit KN9 (nForce4 variant)",
+       .matches = {
+               DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
+               DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
+               },
+       },
+       {},
+};
 #endif /* CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATION
+static unsigned long s4_hardware_signature;
+static struct acpi_table_facs *facs;
+static bool nosigcheck;
+
+void __init acpi_no_s4_hw_signature(void)
+{
+       nosigcheck = true;
+}
+
 static int acpi_hibernation_begin(void)
 {
        acpi_target_sleep_state = ACPI_STATE_S4;
@@ -316,6 +343,12 @@ static void acpi_hibernation_leave(void)
        acpi_enable();
        /* Reprogram control registers and execute _BFS */
        acpi_leave_sleep_state_prep(ACPI_STATE_S4);
+       /* Check the hardware signature */
+       if (facs && s4_hardware_signature != facs->hardware_signature) {
+               printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
+                       "cannot resume!\n");
+               panic("ACPI S4 hardware signature mismatch");
+       }
 }
 
 static void acpi_pm_enable_gpes(void)
@@ -516,6 +549,8 @@ int __init acpi_sleep_init(void)
        u8 type_a, type_b;
 #ifdef CONFIG_SUSPEND
        int i = 0;
+
+       dmi_check_system(acpisleep_dmi_table);
 #endif
 
        if (acpi_disabled)
@@ -544,6 +579,13 @@ int __init acpi_sleep_init(void)
                        &acpi_hibernation_ops_old : &acpi_hibernation_ops);
                sleep_states[ACPI_STATE_S4] = 1;
                printk(" S4");
+               if (!nosigcheck) {
+                       acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
+                               (struct acpi_table_header **)&facs);
+                       if (facs)
+                               s4_hardware_signature =
+                                       facs->hardware_signature;
+               }
        }
 #endif
        status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);