From e96c4b081df0991a57b244f68c3955a9ea00bd0a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 6 Jul 2010 18:28:35 -0400 Subject: ACPI / Sleep: Free NVS copy if suspending of devices fails If suspending of devices fails or system suspend is tested in the "devices" mode, the memory allocated for storing a copy of the ACPI NVS area will not be freed, because acpi_pm_finish() is not called in that case. Fix this by moving the suspend_nvs_free() call to acpi_pm_end(). Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi/sleep.c') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5b7c52e4a00..da68ed24f4c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -145,7 +145,6 @@ static void acpi_pm_finish(void) { u32 acpi_state = acpi_target_sleep_state; - suspend_nvs_free(); acpi_ec_unblock_transactions(); if (acpi_state == ACPI_STATE_S0) @@ -167,6 +166,7 @@ static void acpi_pm_finish(void) */ static void acpi_pm_end(void) { + suspend_nvs_free(); /* * This is necessary in case acpi_pm_finish() is not called during a * failing transition to a sleep state. -- cgit v1.2.3-18-g5258 From 25bed55753b8cf243406e8837990b55946c5278d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Jul 2010 00:12:26 +0200 Subject: ACPI / Sleep: Rework enabling wakeup devices There is no reason why acpi_enable_wakeup_device() should be called with interrupts disabled, because it doesn't access hardware. Thus it is possible to move it next to acpi_enable_wakeup_device_prep() and make the ACPI suspend, hibernate and poweroff code more straightforward. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/acpi/sleep.c') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index da68ed24f4c..8704ca78a8c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -70,10 +70,11 @@ static int acpi_sleep_prepare(u32 acpi_state) } ACPI_FLUSH_CPU_CACHE(); - acpi_enable_wakeup_device_prep(acpi_state); #endif printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", acpi_state); + acpi_enable_wakeup_device_prep(acpi_state); + acpi_enable_wakeup_device(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } @@ -238,7 +239,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) } local_irq_save(flags); - acpi_enable_wakeup_device(acpi_state); switch (acpi_state) { case ACPI_STATE_S1: barrier(); @@ -442,7 +442,6 @@ static int acpi_hibernation_enter(void) ACPI_FLUSH_CPU_CACHE(); local_irq_save(flags); - acpi_enable_wakeup_device(ACPI_STATE_S4); /* This shouldn't return. If it returns, we have a problem */ status = acpi_enter_sleep_state(ACPI_STATE_S4); /* Reprogram control registers and execute _BFS */ @@ -696,7 +695,6 @@ static void acpi_power_off(void) /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ printk(KERN_DEBUG "%s called\n", __func__); local_irq_disable(); - acpi_enable_wakeup_device(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5); } -- cgit v1.2.3-18-g5258 From 78f5f023167813130d2cf657d1b9eadc32f0e992 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 6 Jul 2010 22:09:38 -0400 Subject: ACPI / Wakeup: Simplify enabling of wakeup devices To simplify the enabling of wakeup devices during system suspend and hibernation, merge acpi_enable_wakeup_device_prep() with acpi_disable_wakeup_device() and remove unnecessary (and no longer valid) comments from the latter. Rename acpi_enable_wakeup_device() to acpi_enable_wakeup_devices() and acpi_disable_wakeup_device() to acpi_disable_wakeup_devices(), because these functions usually operate on multiple device objects. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/acpi/sleep.c') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 8704ca78a8c..93441c95c53 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -73,8 +73,7 @@ static int acpi_sleep_prepare(u32 acpi_state) #endif printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", acpi_state); - acpi_enable_wakeup_device_prep(acpi_state); - acpi_enable_wakeup_device(acpi_state); + acpi_enable_wakeup_devices(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } @@ -153,7 +152,7 @@ static void acpi_pm_finish(void) printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", acpi_state); - acpi_disable_wakeup_device(acpi_state); + acpi_disable_wakeup_devices(acpi_state); acpi_leave_sleep_state(acpi_state); /* reset firmware waking vector */ -- cgit v1.2.3-18-g5258 From c5f7a1bb65bca03253c189e946b3ca79669f08af Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Jul 2010 00:14:09 +0200 Subject: ACPI / Sleep: Consolidate suspend and hibernation routines Some hibernation and suspend routines can be merged, which reduces the complexity of code a bit. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'drivers/acpi/sleep.c') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 93441c95c53..61c5bd03f73 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -104,6 +104,16 @@ static int acpi_pm_freeze(void) return 0; } +/** + * acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS. + */ +static int acpi_pm_pre_suspend(void) +{ + acpi_pm_freeze(); + suspend_nvs_save(); + return 0; +} + /** * __acpi_pm_prepare - Prepare the platform to enter the target state. * @@ -113,11 +123,9 @@ static int acpi_pm_freeze(void) static int __acpi_pm_prepare(void) { int error = acpi_sleep_prepare(acpi_target_sleep_state); - - suspend_nvs_save(); - if (error) acpi_target_sleep_state = ACPI_STATE_S0; + return error; } @@ -128,9 +136,8 @@ static int __acpi_pm_prepare(void) static int acpi_pm_prepare(void) { int error = __acpi_pm_prepare(); - if (!error) - acpi_pm_freeze(); + acpi_pm_pre_suspend(); return error; } @@ -322,9 +329,9 @@ static struct platform_suspend_ops acpi_suspend_ops = { static int acpi_suspend_begin_old(suspend_state_t pm_state) { int error = acpi_suspend_begin(pm_state); - if (!error) error = __acpi_pm_prepare(); + return error; } @@ -335,7 +342,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) static struct platform_suspend_ops acpi_suspend_ops_old = { .valid = acpi_suspend_state_valid, .begin = acpi_suspend_begin_old, - .prepare_late = acpi_pm_freeze, + .prepare_late = acpi_pm_pre_suspend, .enter = acpi_suspend_enter, .wake = acpi_suspend_finish, .end = acpi_pm_end, @@ -423,16 +430,6 @@ static int acpi_hibernation_begin(void) return error; } -static int acpi_hibernation_pre_snapshot(void) -{ - int error = acpi_pm_prepare(); - - if (!error) - suspend_nvs_save(); - - return error; -} - static int acpi_hibernation_enter(void) { acpi_status status = AE_OK; @@ -480,7 +477,7 @@ static void acpi_pm_thaw(void) static struct platform_hibernation_ops acpi_hibernation_ops = { .begin = acpi_hibernation_begin, .end = acpi_pm_end, - .pre_snapshot = acpi_hibernation_pre_snapshot, + .pre_snapshot = acpi_pm_prepare, .finish = acpi_pm_finish, .prepare = acpi_pm_prepare, .enter = acpi_hibernation_enter, @@ -516,13 +513,6 @@ static int acpi_hibernation_begin_old(void) return error; } -static int acpi_hibernation_pre_snapshot_old(void) -{ - acpi_pm_freeze(); - suspend_nvs_save(); - return 0; -} - /* * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has * been requested. @@ -530,7 +520,7 @@ static int acpi_hibernation_pre_snapshot_old(void) static struct platform_hibernation_ops acpi_hibernation_ops_old = { .begin = acpi_hibernation_begin_old, .end = acpi_pm_end, - .pre_snapshot = acpi_hibernation_pre_snapshot_old, + .pre_snapshot = acpi_pm_pre_suspend, .prepare = acpi_pm_freeze, .finish = acpi_pm_finish, .enter = acpi_hibernation_enter, -- cgit v1.2.3-18-g5258 From 618d7fd0d4e51a45d25d9bc6097a0cb1e5a2f226 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Jul 2010 00:14:57 +0200 Subject: ACPI / Sleep: Drop acpi_suspend_finish() The function acpi_suspend_finish() is not necessary any more, because acpi_pm_finish() can be used instead of it just fine. Remove it. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/acpi/sleep.c') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 61c5bd03f73..5529c702395 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -290,11 +290,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) return ACPI_SUCCESS(status) ? 0 : -EFAULT; } -static void acpi_suspend_finish(void) -{ - acpi_pm_finish(); -} - static int acpi_suspend_state_valid(suspend_state_t pm_state) { u32 acpi_state; @@ -316,7 +311,7 @@ static struct platform_suspend_ops acpi_suspend_ops = { .begin = acpi_suspend_begin, .prepare_late = acpi_pm_prepare, .enter = acpi_suspend_enter, - .wake = acpi_suspend_finish, + .wake = acpi_pm_finish, .end = acpi_pm_end, }; @@ -344,7 +339,7 @@ static struct platform_suspend_ops acpi_suspend_ops_old = { .begin = acpi_suspend_begin_old, .prepare_late = acpi_pm_pre_suspend, .enter = acpi_suspend_enter, - .wake = acpi_suspend_finish, + .wake = acpi_pm_finish, .end = acpi_pm_end, .recover = acpi_pm_finish, }; -- cgit v1.2.3-18-g5258