diff options
Diffstat (limited to 'drivers/acpi/sleep/main.c')
| -rw-r--r-- | drivers/acpi/sleep/main.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 80c0868d0480..28a691cc625e 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
| @@ -90,6 +90,18 @@ void __init acpi_old_suspend_ordering(void) | |||
| 90 | old_suspend_ordering = true; | 90 | old_suspend_ordering = true; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /* | ||
| 94 | * According to the ACPI specification the BIOS should make sure that ACPI is | ||
| 95 | * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states. Still, | ||
| 96 | * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI | ||
| 97 | * on such systems during resume. Unfortunately that doesn't help in | ||
| 98 | * particularly pathological cases in which SCI_EN has to be set directly on | ||
| 99 | * resume, although the specification states very clearly that this flag is | ||
| 100 | * owned by the hardware. The set_sci_en_on_resume variable will be set in such | ||
| 101 | * cases. | ||
| 102 | */ | ||
| 103 | static bool set_sci_en_on_resume; | ||
| 104 | |||
| 93 | /** | 105 | /** |
| 94 | * acpi_pm_disable_gpes - Disable the GPEs. | 106 | * acpi_pm_disable_gpes - Disable the GPEs. |
| 95 | */ | 107 | */ |
| @@ -235,7 +247,11 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 235 | } | 247 | } |
| 236 | 248 | ||
| 237 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ | 249 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ |
| 238 | acpi_enable(); | 250 | if (set_sci_en_on_resume) |
| 251 | acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); | ||
| 252 | else | ||
| 253 | acpi_enable(); | ||
| 254 | |||
| 239 | /* Reprogram control registers and execute _BFS */ | 255 | /* Reprogram control registers and execute _BFS */ |
| 240 | acpi_leave_sleep_state_prep(acpi_state); | 256 | acpi_leave_sleep_state_prep(acpi_state); |
| 241 | 257 | ||
| @@ -323,6 +339,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d) | |||
| 323 | return 0; | 339 | return 0; |
| 324 | } | 340 | } |
| 325 | 341 | ||
| 342 | static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d) | ||
| 343 | { | ||
| 344 | set_sci_en_on_resume = true; | ||
| 345 | return 0; | ||
| 346 | } | ||
| 347 | |||
| 326 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | 348 | static struct dmi_system_id __initdata acpisleep_dmi_table[] = { |
| 327 | { | 349 | { |
| 328 | .callback = init_old_suspend_ordering, | 350 | .callback = init_old_suspend_ordering, |
| @@ -340,6 +362,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
| 340 | DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), | 362 | DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), |
| 341 | }, | 363 | }, |
| 342 | }, | 364 | }, |
| 365 | { | ||
| 366 | .callback = init_set_sci_en_on_resume, | ||
| 367 | .ident = "Apple MacBook 1,1", | ||
| 368 | .matches = { | ||
| 369 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
| 370 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), | ||
| 371 | }, | ||
| 372 | }, | ||
| 373 | { | ||
| 374 | .callback = init_set_sci_en_on_resume, | ||
| 375 | .ident = "Apple MacMini 1,1", | ||
| 376 | .matches = { | ||
| 377 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
| 378 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), | ||
| 379 | }, | ||
| 380 | }, | ||
| 343 | {}, | 381 | {}, |
| 344 | }; | 382 | }; |
| 345 | #endif /* CONFIG_SUSPEND */ | 383 | #endif /* CONFIG_SUSPEND */ |
