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 | ||