diff options
| -rw-r--r-- | arch/arm/mach-at91/pm.c | 17 | ||||
| -rw-r--r-- | arch/powerpc/platforms/52xx/lite5200_pm.c | 10 | ||||
| -rw-r--r-- | drivers/acpi/sleep/main.c | 22 | ||||
| -rw-r--r-- | include/linux/suspend.h | 29 | ||||
| -rw-r--r-- | kernel/power/main.c | 9 |
5 files changed, 63 insertions, 24 deletions
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 4b120cc36135..a67defd50438 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
| @@ -52,7 +52,7 @@ static suspend_state_t target_state; | |||
| 52 | /* | 52 | /* |
| 53 | * Called after processes are frozen, but before we shutdown devices. | 53 | * Called after processes are frozen, but before we shutdown devices. |
| 54 | */ | 54 | */ |
| 55 | static int at91_pm_set_target(suspend_state_t state) | 55 | static int at91_pm_begin(suspend_state_t state) |
| 56 | { | 56 | { |
| 57 | target_state = state; | 57 | target_state = state; |
| 58 | return 0; | 58 | return 0; |
| @@ -202,11 +202,20 @@ error: | |||
| 202 | return 0; | 202 | return 0; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | /* | ||
| 206 | * Called right prior to thawing processes. | ||
| 207 | */ | ||
| 208 | static void at91_pm_end(void) | ||
| 209 | { | ||
| 210 | target_state = PM_SUSPEND_ON; | ||
| 211 | } | ||
| 212 | |||
| 205 | 213 | ||
| 206 | static struct platform_suspend_ops at91_pm_ops ={ | 214 | static struct platform_suspend_ops at91_pm_ops ={ |
| 207 | .valid = at91_pm_valid_state, | 215 | .valid = at91_pm_valid_state, |
| 208 | .set_target = at91_pm_set_target, | 216 | .begin = at91_pm_begin, |
| 209 | .enter = at91_pm_enter, | 217 | .enter = at91_pm_enter, |
| 218 | .end = at91_pm_end, | ||
| 210 | }; | 219 | }; |
| 211 | 220 | ||
| 212 | static int __init at91_pm_init(void) | 221 | static int __init at91_pm_init(void) |
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index c0f13e8deb0b..41c7fd91e99e 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c | |||
| @@ -31,7 +31,7 @@ static int lite5200_pm_valid(suspend_state_t state) | |||
| 31 | } | 31 | } |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | static int lite5200_pm_set_target(suspend_state_t state) | 34 | static int lite5200_pm_begin(suspend_state_t state) |
| 35 | { | 35 | { |
| 36 | if (lite5200_pm_valid(state)) { | 36 | if (lite5200_pm_valid(state)) { |
| 37 | lite5200_pm_target_state = state; | 37 | lite5200_pm_target_state = state; |
| @@ -219,12 +219,18 @@ static void lite5200_pm_finish(void) | |||
| 219 | mpc52xx_pm_finish(); | 219 | mpc52xx_pm_finish(); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static void lite5200_pm_end(void) | ||
| 223 | { | ||
| 224 | lite5200_pm_target_state = PM_SUSPEND_ON; | ||
| 225 | } | ||
| 226 | |||
| 222 | static struct platform_suspend_ops lite5200_pm_ops = { | 227 | static struct platform_suspend_ops lite5200_pm_ops = { |
| 223 | .valid = lite5200_pm_valid, | 228 | .valid = lite5200_pm_valid, |
| 224 | .set_target = lite5200_pm_set_target, | 229 | .begin = lite5200_pm_begin, |
| 225 | .prepare = lite5200_pm_prepare, | 230 | .prepare = lite5200_pm_prepare, |
| 226 | .enter = lite5200_pm_enter, | 231 | .enter = lite5200_pm_enter, |
| 227 | .finish = lite5200_pm_finish, | 232 | .finish = lite5200_pm_finish, |
| 233 | .end = lite5200_pm_end, | ||
| 228 | }; | 234 | }; |
| 229 | 235 | ||
| 230 | int __init lite5200_pm_init(void) | 236 | int __init lite5200_pm_init(void) |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 96d23b3cfc4e..e2e4e617952b 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
| @@ -63,11 +63,11 @@ static u32 acpi_suspend_states[] = { | |||
| 63 | static int init_8259A_after_S1; | 63 | static int init_8259A_after_S1; |
| 64 | 64 | ||
| 65 | /** | 65 | /** |
| 66 | * acpi_pm_set_target - Set the target system sleep state to the state | 66 | * acpi_pm_begin - Set the target system sleep state to the state |
| 67 | * associated with given @pm_state, if supported. | 67 | * associated with given @pm_state, if supported. |
| 68 | */ | 68 | */ |
| 69 | 69 | ||
| 70 | static int acpi_pm_set_target(suspend_state_t pm_state) | 70 | static int acpi_pm_begin(suspend_state_t pm_state) |
| 71 | { | 71 | { |
| 72 | u32 acpi_state = acpi_suspend_states[pm_state]; | 72 | u32 acpi_state = acpi_suspend_states[pm_state]; |
| 73 | int error = 0; | 73 | int error = 0; |
| @@ -164,7 +164,7 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | /** | 166 | /** |
| 167 | * acpi_pm_finish - Finish up suspend sequence. | 167 | * acpi_pm_finish - Instruct the platform to leave a sleep state. |
| 168 | * | 168 | * |
| 169 | * This is called after we wake back up (or if entering the sleep state | 169 | * This is called after we wake back up (or if entering the sleep state |
| 170 | * failed). | 170 | * failed). |
| @@ -190,6 +190,19 @@ static void acpi_pm_finish(void) | |||
| 190 | #endif | 190 | #endif |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | /** | ||
| 194 | * acpi_pm_end - Finish up suspend sequence. | ||
| 195 | */ | ||
| 196 | |||
| 197 | static void acpi_pm_end(void) | ||
| 198 | { | ||
| 199 | /* | ||
| 200 | * This is necessary in case acpi_pm_finish() is not called during a | ||
| 201 | * failing transition to a sleep state. | ||
| 202 | */ | ||
| 203 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
| 204 | } | ||
| 205 | |||
| 193 | static int acpi_pm_state_valid(suspend_state_t pm_state) | 206 | static int acpi_pm_state_valid(suspend_state_t pm_state) |
| 194 | { | 207 | { |
| 195 | u32 acpi_state; | 208 | u32 acpi_state; |
| @@ -208,10 +221,11 @@ static int acpi_pm_state_valid(suspend_state_t pm_state) | |||
| 208 | 221 | ||
| 209 | static struct platform_suspend_ops acpi_pm_ops = { | 222 | static struct platform_suspend_ops acpi_pm_ops = { |
| 210 | .valid = acpi_pm_state_valid, | 223 | .valid = acpi_pm_state_valid, |
| 211 | .set_target = acpi_pm_set_target, | 224 | .begin = acpi_pm_begin, |
| 212 | .prepare = acpi_pm_prepare, | 225 | .prepare = acpi_pm_prepare, |
| 213 | .enter = acpi_pm_enter, | 226 | .enter = acpi_pm_enter, |
| 214 | .finish = acpi_pm_finish, | 227 | .finish = acpi_pm_finish, |
| 228 | .end = acpi_pm_end, | ||
| 215 | }; | 229 | }; |
| 216 | 230 | ||
| 217 | /* | 231 | /* |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 51283e0745b3..a0b1dbb5919f 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
| @@ -38,18 +38,16 @@ typedef int __bitwise suspend_state_t; | |||
| 38 | * There is the %suspend_valid_only_mem function available that can be | 38 | * There is the %suspend_valid_only_mem function available that can be |
| 39 | * assigned to this if the platform only supports mem sleep. | 39 | * assigned to this if the platform only supports mem sleep. |
| 40 | * | 40 | * |
| 41 | * @set_target: Tell the platform which system sleep state is going to be | 41 | * @begin: Initialise a transition to given system sleep state. |
| 42 | * entered. | 42 | * @begin() is executed right prior to suspending devices. The information |
| 43 | * @set_target() is executed right prior to suspending devices. The | 43 | * conveyed to the platform code by @begin() should be disregarded by it as |
| 44 | * information conveyed to the platform code by @set_target() should be | 44 | * soon as @end() is executed. If @begin() fails (ie. returns nonzero), |
| 45 | * disregarded by the platform as soon as @finish() is executed and if | ||
| 46 | * @prepare() fails. If @set_target() fails (ie. returns nonzero), | ||
| 47 | * @prepare(), @enter() and @finish() will not be called by the PM core. | 45 | * @prepare(), @enter() and @finish() will not be called by the PM core. |
| 48 | * This callback is optional. However, if it is implemented, the argument | 46 | * This callback is optional. However, if it is implemented, the argument |
| 49 | * passed to @enter() is meaningless and should be ignored. | 47 | * passed to @enter() is redundant and should be ignored. |
| 50 | * | 48 | * |
| 51 | * @prepare: Prepare the platform for entering the system sleep state indicated | 49 | * @prepare: Prepare the platform for entering the system sleep state indicated |
| 52 | * by @set_target(). | 50 | * by @begin(). |
| 53 | * @prepare() is called right after devices have been suspended (ie. the | 51 | * @prepare() is called right after devices have been suspended (ie. the |
| 54 | * appropriate .suspend() method has been executed for each device) and | 52 | * appropriate .suspend() method has been executed for each device) and |
| 55 | * before the nonboot CPUs are disabled (it is executed with IRQs enabled). | 53 | * before the nonboot CPUs are disabled (it is executed with IRQs enabled). |
| @@ -57,8 +55,8 @@ typedef int __bitwise suspend_state_t; | |||
| 57 | * error code otherwise, in which case the system cannot enter the desired | 55 | * error code otherwise, in which case the system cannot enter the desired |
| 58 | * sleep state (@enter() and @finish() will not be called in that case). | 56 | * sleep state (@enter() and @finish() will not be called in that case). |
| 59 | * | 57 | * |
| 60 | * @enter: Enter the system sleep state indicated by @set_target() or | 58 | * @enter: Enter the system sleep state indicated by @begin() or represented by |
| 61 | * represented by the argument if @set_target() is not implemented. | 59 | * the argument if @begin() is not implemented. |
| 62 | * This callback is mandatory. It returns 0 on success or a negative | 60 | * This callback is mandatory. It returns 0 on success or a negative |
| 63 | * error code otherwise, in which case the system cannot enter the desired | 61 | * error code otherwise, in which case the system cannot enter the desired |
| 64 | * sleep state. | 62 | * sleep state. |
| @@ -69,13 +67,22 @@ typedef int __bitwise suspend_state_t; | |||
| 69 | * This callback is optional, but should be implemented by the platforms | 67 | * This callback is optional, but should be implemented by the platforms |
| 70 | * that implement @prepare(). If implemented, it is always called after | 68 | * that implement @prepare(). If implemented, it is always called after |
| 71 | * @enter() (even if @enter() fails). | 69 | * @enter() (even if @enter() fails). |
| 70 | * | ||
| 71 | * @end: Called by the PM core right after resuming devices, to indicate to | ||
| 72 | * the platform that the system has returned to the working state or | ||
| 73 | * the transition to the sleep state has been aborted. | ||
| 74 | * This callback is optional, but should be implemented by the platforms | ||
| 75 | * that implement @begin(), but platforms implementing @begin() should | ||
| 76 | * also provide a @end() which cleans up transitions aborted before | ||
| 77 | * @enter(). | ||
| 72 | */ | 78 | */ |
| 73 | struct platform_suspend_ops { | 79 | struct platform_suspend_ops { |
| 74 | int (*valid)(suspend_state_t state); | 80 | int (*valid)(suspend_state_t state); |
| 75 | int (*set_target)(suspend_state_t state); | 81 | int (*begin)(suspend_state_t state); |
| 76 | int (*prepare)(void); | 82 | int (*prepare)(void); |
| 77 | int (*enter)(suspend_state_t state); | 83 | int (*enter)(suspend_state_t state); |
| 78 | void (*finish)(void); | 84 | void (*finish)(void); |
| 85 | void (*end)(void); | ||
| 79 | }; | 86 | }; |
| 80 | 87 | ||
| 81 | #ifdef CONFIG_SUSPEND | 88 | #ifdef CONFIG_SUSPEND |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 050a6077ea45..d9bba452764b 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
| @@ -258,10 +258,10 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
| 258 | if (!suspend_ops) | 258 | if (!suspend_ops) |
| 259 | return -ENOSYS; | 259 | return -ENOSYS; |
| 260 | 260 | ||
| 261 | if (suspend_ops->set_target) { | 261 | if (suspend_ops->begin) { |
| 262 | error = suspend_ops->set_target(state); | 262 | error = suspend_ops->begin(state); |
| 263 | if (error) | 263 | if (error) |
| 264 | return error; | 264 | goto Close; |
| 265 | } | 265 | } |
| 266 | suspend_console(); | 266 | suspend_console(); |
| 267 | error = device_suspend(PMSG_SUSPEND); | 267 | error = device_suspend(PMSG_SUSPEND); |
| @@ -294,6 +294,9 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
| 294 | device_resume(); | 294 | device_resume(); |
| 295 | Resume_console: | 295 | Resume_console: |
| 296 | resume_console(); | 296 | resume_console(); |
| 297 | Close: | ||
| 298 | if (suspend_ops->end) | ||
| 299 | suspend_ops->end(); | ||
| 297 | return error; | 300 | return error; |
| 298 | } | 301 | } |
| 299 | 302 | ||
