diff options
| -rw-r--r-- | drivers/acpi/ec.c | 10 | ||||
| -rw-r--r-- | drivers/acpi/internal.h | 1 | ||||
| -rw-r--r-- | drivers/acpi/sleep.c | 55 |
3 files changed, 40 insertions, 26 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index f2234db85da0..2c2b73a2a7c2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -485,6 +485,16 @@ void acpi_ec_resume_transactions(void) | |||
| 485 | mutex_unlock(&ec->lock); | 485 | mutex_unlock(&ec->lock); |
| 486 | } | 486 | } |
| 487 | 487 | ||
| 488 | void acpi_ec_resume_transactions_early(void) | ||
| 489 | { | ||
| 490 | /* | ||
| 491 | * Allow transactions to happen again (this function is called from | ||
| 492 | * atomic context during wakeup, so we don't need to acquire the mutex). | ||
| 493 | */ | ||
| 494 | if (first_ec) | ||
| 495 | clear_bit(EC_FLAGS_FROZEN, &first_ec->flags); | ||
| 496 | } | ||
| 497 | |||
| 488 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) | 498 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) |
| 489 | { | 499 | { |
| 490 | int result; | 500 | int result; |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index e28411367239..0ec48c7efa9b 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -51,6 +51,7 @@ int acpi_ec_ecdt_probe(void); | |||
| 51 | int acpi_boot_ec_enable(void); | 51 | int acpi_boot_ec_enable(void); |
| 52 | void acpi_ec_suspend_transactions(void); | 52 | void acpi_ec_suspend_transactions(void); |
| 53 | void acpi_ec_resume_transactions(void); | 53 | void acpi_ec_resume_transactions(void); |
| 54 | void acpi_ec_resume_transactions_early(void); | ||
| 54 | 55 | ||
| 55 | /*-------------------------------------------------------------------------- | 56 | /*-------------------------------------------------------------------------- |
| 56 | Suspend/Resume | 57 | Suspend/Resume |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index baa76bbf244a..24741ac65897 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -110,11 +110,13 @@ void __init acpi_old_suspend_ordering(void) | |||
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | /** | 112 | /** |
| 113 | * acpi_pm_disable_gpes - Disable the GPEs. | 113 | * acpi_pm_freeze - Disable the GPEs and suspend EC transactions. |
| 114 | */ | 114 | */ |
| 115 | static int acpi_pm_disable_gpes(void) | 115 | static int acpi_pm_freeze(void) |
| 116 | { | 116 | { |
| 117 | acpi_disable_all_gpes(); | 117 | acpi_disable_all_gpes(); |
| 118 | acpi_os_wait_events_complete(NULL); | ||
| 119 | acpi_ec_suspend_transactions(); | ||
| 118 | return 0; | 120 | return 0; |
| 119 | } | 121 | } |
| 120 | 122 | ||
| @@ -142,7 +144,8 @@ static int acpi_pm_prepare(void) | |||
| 142 | int error = __acpi_pm_prepare(); | 144 | int error = __acpi_pm_prepare(); |
| 143 | 145 | ||
| 144 | if (!error) | 146 | if (!error) |
| 145 | acpi_disable_all_gpes(); | 147 | acpi_pm_freeze(); |
| 148 | |||
| 146 | return error; | 149 | return error; |
| 147 | } | 150 | } |
| 148 | 151 | ||
| @@ -275,6 +278,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 275 | * acpi_leave_sleep_state will reenable specific GPEs later | 278 | * acpi_leave_sleep_state will reenable specific GPEs later |
| 276 | */ | 279 | */ |
| 277 | acpi_disable_all_gpes(); | 280 | acpi_disable_all_gpes(); |
| 281 | /* Allow EC transactions to happen. */ | ||
| 282 | acpi_ec_resume_transactions_early(); | ||
| 278 | 283 | ||
| 279 | local_irq_restore(flags); | 284 | local_irq_restore(flags); |
| 280 | printk(KERN_DEBUG "Back to C!\n"); | 285 | printk(KERN_DEBUG "Back to C!\n"); |
| @@ -286,6 +291,12 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 286 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 291 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
| 287 | } | 292 | } |
| 288 | 293 | ||
| 294 | static void acpi_suspend_finish(void) | ||
| 295 | { | ||
| 296 | acpi_ec_resume_transactions(); | ||
| 297 | acpi_pm_finish(); | ||
| 298 | } | ||
| 299 | |||
| 289 | static int acpi_suspend_state_valid(suspend_state_t pm_state) | 300 | static int acpi_suspend_state_valid(suspend_state_t pm_state) |
| 290 | { | 301 | { |
| 291 | u32 acpi_state; | 302 | u32 acpi_state; |
| @@ -307,7 +318,7 @@ static struct platform_suspend_ops acpi_suspend_ops = { | |||
| 307 | .begin = acpi_suspend_begin, | 318 | .begin = acpi_suspend_begin, |
| 308 | .prepare_late = acpi_pm_prepare, | 319 | .prepare_late = acpi_pm_prepare, |
| 309 | .enter = acpi_suspend_enter, | 320 | .enter = acpi_suspend_enter, |
| 310 | .wake = acpi_pm_finish, | 321 | .wake = acpi_suspend_finish, |
| 311 | .end = acpi_pm_end, | 322 | .end = acpi_pm_end, |
| 312 | }; | 323 | }; |
| 313 | 324 | ||
| @@ -333,9 +344,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) | |||
| 333 | static struct platform_suspend_ops acpi_suspend_ops_old = { | 344 | static struct platform_suspend_ops acpi_suspend_ops_old = { |
| 334 | .valid = acpi_suspend_state_valid, | 345 | .valid = acpi_suspend_state_valid, |
| 335 | .begin = acpi_suspend_begin_old, | 346 | .begin = acpi_suspend_begin_old, |
| 336 | .prepare_late = acpi_pm_disable_gpes, | 347 | .prepare_late = acpi_pm_freeze, |
| 337 | .enter = acpi_suspend_enter, | 348 | .enter = acpi_suspend_enter, |
| 338 | .wake = acpi_pm_finish, | 349 | .wake = acpi_suspend_finish, |
| 339 | .end = acpi_pm_end, | 350 | .end = acpi_pm_end, |
| 340 | .recover = acpi_pm_finish, | 351 | .recover = acpi_pm_finish, |
| 341 | }; | 352 | }; |
| @@ -586,6 +597,7 @@ static int acpi_hibernation_enter(void) | |||
| 586 | static void acpi_hibernation_finish(void) | 597 | static void acpi_hibernation_finish(void) |
| 587 | { | 598 | { |
| 588 | hibernate_nvs_free(); | 599 | hibernate_nvs_free(); |
| 600 | acpi_ec_resume_transactions(); | ||
| 589 | acpi_pm_finish(); | 601 | acpi_pm_finish(); |
| 590 | } | 602 | } |
| 591 | 603 | ||
| @@ -606,17 +618,11 @@ static void acpi_hibernation_leave(void) | |||
| 606 | } | 618 | } |
| 607 | /* Restore the NVS memory area */ | 619 | /* Restore the NVS memory area */ |
| 608 | hibernate_nvs_restore(); | 620 | hibernate_nvs_restore(); |
| 621 | /* Allow EC transactions to happen. */ | ||
| 622 | acpi_ec_resume_transactions_early(); | ||
| 609 | } | 623 | } |
| 610 | 624 | ||
| 611 | static int acpi_pm_pre_restore(void) | 625 | static void acpi_pm_thaw(void) |
| 612 | { | ||
| 613 | acpi_disable_all_gpes(); | ||
| 614 | acpi_os_wait_events_complete(NULL); | ||
| 615 | acpi_ec_suspend_transactions(); | ||
| 616 | return 0; | ||
| 617 | } | ||
| 618 | |||
| 619 | static void acpi_pm_restore_cleanup(void) | ||
| 620 | { | 626 | { |
| 621 | acpi_ec_resume_transactions(); | 627 | acpi_ec_resume_transactions(); |
| 622 | acpi_enable_all_runtime_gpes(); | 628 | acpi_enable_all_runtime_gpes(); |
| @@ -630,8 +636,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { | |||
| 630 | .prepare = acpi_pm_prepare, | 636 | .prepare = acpi_pm_prepare, |
| 631 | .enter = acpi_hibernation_enter, | 637 | .enter = acpi_hibernation_enter, |
| 632 | .leave = acpi_hibernation_leave, | 638 | .leave = acpi_hibernation_leave, |
| 633 | .pre_restore = acpi_pm_pre_restore, | 639 | .pre_restore = acpi_pm_freeze, |
| 634 | .restore_cleanup = acpi_pm_restore_cleanup, | 640 | .restore_cleanup = acpi_pm_thaw, |
| 635 | }; | 641 | }; |
| 636 | 642 | ||
| 637 | /** | 643 | /** |
| @@ -663,12 +669,9 @@ static int acpi_hibernation_begin_old(void) | |||
| 663 | 669 | ||
| 664 | static int acpi_hibernation_pre_snapshot_old(void) | 670 | static int acpi_hibernation_pre_snapshot_old(void) |
| 665 | { | 671 | { |
| 666 | int error = acpi_pm_disable_gpes(); | 672 | acpi_pm_freeze(); |
| 667 | 673 | hibernate_nvs_save(); | |
| 668 | if (!error) | 674 | return 0; |
| 669 | hibernate_nvs_save(); | ||
| 670 | |||
| 671 | return error; | ||
| 672 | } | 675 | } |
| 673 | 676 | ||
| 674 | /* | 677 | /* |
| @@ -680,11 +683,11 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { | |||
| 680 | .end = acpi_pm_end, | 683 | .end = acpi_pm_end, |
| 681 | .pre_snapshot = acpi_hibernation_pre_snapshot_old, | 684 | .pre_snapshot = acpi_hibernation_pre_snapshot_old, |
| 682 | .finish = acpi_hibernation_finish, | 685 | .finish = acpi_hibernation_finish, |
| 683 | .prepare = acpi_pm_disable_gpes, | 686 | .prepare = acpi_pm_freeze, |
| 684 | .enter = acpi_hibernation_enter, | 687 | .enter = acpi_hibernation_enter, |
| 685 | .leave = acpi_hibernation_leave, | 688 | .leave = acpi_hibernation_leave, |
| 686 | .pre_restore = acpi_pm_pre_restore, | 689 | .pre_restore = acpi_pm_freeze, |
| 687 | .restore_cleanup = acpi_pm_restore_cleanup, | 690 | .restore_cleanup = acpi_pm_thaw, |
| 688 | .recover = acpi_pm_finish, | 691 | .recover = acpi_pm_finish, |
| 689 | }; | 692 | }; |
| 690 | #endif /* CONFIG_HIBERNATION */ | 693 | #endif /* CONFIG_HIBERNATION */ |
