aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-at91/pm.c17
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_pm.c10
-rw-r--r--drivers/acpi/sleep/main.c22
-rw-r--r--include/linux/suspend.h29
-rw-r--r--kernel/power/main.c9
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 */
55static int at91_pm_set_target(suspend_state_t state) 55static 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 */
208static void at91_pm_end(void)
209{
210 target_state = PM_SUSPEND_ON;
211}
212
205 213
206static struct platform_suspend_ops at91_pm_ops ={ 214static 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
212static int __init at91_pm_init(void) 221static 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
34static int lite5200_pm_set_target(suspend_state_t state) 34static 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
222static void lite5200_pm_end(void)
223{
224 lite5200_pm_target_state = PM_SUSPEND_ON;
225}
226
222static struct platform_suspend_ops lite5200_pm_ops = { 227static 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
230int __init lite5200_pm_init(void) 236int __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[] = {
63static int init_8259A_after_S1; 63static 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
70static int acpi_pm_set_target(suspend_state_t pm_state) 70static 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
197static 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
193static int acpi_pm_state_valid(suspend_state_t pm_state) 206static 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
209static struct platform_suspend_ops acpi_pm_ops = { 222static 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 */
73struct platform_suspend_ops { 79struct 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