diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2007-05-09 05:33:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 15:30:48 -0400 |
commit | a3d25c275d383975504dc53c25b691df59bd3c48 (patch) | |
tree | 161a2ae12a20a630c2f639e144872db2b92eb098 /kernel/power/main.c | |
parent | d60846c4d16f9518b098b905af2b87cb6bf6dc42 (diff) |
PM: Separate hibernation code from suspend code
[ With Johannes Berg <johannes@sipsolutions.net> ]
Separate the hibernation (aka suspend to disk code) from the other suspend
code. In particular:
* Remove the definitions related to hibernation from include/linux/pm.h
* Introduce struct hibernation_ops and a new hibernate() function to hibernate
the system, defined in include/linux/suspend.h
* Separate suspend code in kernel/power/main.c from hibernation-related code
in kernel/power/disk.c and kernel/power/user.c (with the help of
hibernation_ops)
* Switch ACPI (the only user of pm_ops.pm_disk_mode) to hibernation_ops
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Cc: Greg KH <greg@kroah.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Nigel Cunningham <nigel@nigel.suspend2.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/power/main.c')
-rw-r--r-- | kernel/power/main.c | 42 |
1 files changed, 16 insertions, 26 deletions
diff --git a/kernel/power/main.c b/kernel/power/main.c index f6dda685e7e2..40d56a31245e 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -30,7 +30,6 @@ | |||
30 | DEFINE_MUTEX(pm_mutex); | 30 | DEFINE_MUTEX(pm_mutex); |
31 | 31 | ||
32 | struct pm_ops *pm_ops; | 32 | struct pm_ops *pm_ops; |
33 | suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN; | ||
34 | 33 | ||
35 | /** | 34 | /** |
36 | * pm_set_ops - Set the global power method table. | 35 | * pm_set_ops - Set the global power method table. |
@@ -41,10 +40,6 @@ void pm_set_ops(struct pm_ops * ops) | |||
41 | { | 40 | { |
42 | mutex_lock(&pm_mutex); | 41 | mutex_lock(&pm_mutex); |
43 | pm_ops = ops; | 42 | pm_ops = ops; |
44 | if (ops && ops->pm_disk_mode != PM_DISK_INVALID) { | ||
45 | pm_disk_mode = ops->pm_disk_mode; | ||
46 | } else | ||
47 | pm_disk_mode = PM_DISK_SHUTDOWN; | ||
48 | mutex_unlock(&pm_mutex); | 43 | mutex_unlock(&pm_mutex); |
49 | } | 44 | } |
50 | 45 | ||
@@ -184,24 +179,12 @@ static void suspend_finish(suspend_state_t state) | |||
184 | static const char * const pm_states[PM_SUSPEND_MAX] = { | 179 | static const char * const pm_states[PM_SUSPEND_MAX] = { |
185 | [PM_SUSPEND_STANDBY] = "standby", | 180 | [PM_SUSPEND_STANDBY] = "standby", |
186 | [PM_SUSPEND_MEM] = "mem", | 181 | [PM_SUSPEND_MEM] = "mem", |
187 | [PM_SUSPEND_DISK] = "disk", | ||
188 | }; | 182 | }; |
189 | 183 | ||
190 | static inline int valid_state(suspend_state_t state) | 184 | static inline int valid_state(suspend_state_t state) |
191 | { | 185 | { |
192 | /* Suspend-to-disk does not really need low-level support. | 186 | /* All states need lowlevel support and need to be valid |
193 | * It can work with shutdown/reboot if needed. If it isn't | 187 | * to the lowlevel implementation, no valid callback |
194 | * configured, then it cannot be supported. | ||
195 | */ | ||
196 | if (state == PM_SUSPEND_DISK) | ||
197 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
198 | return 1; | ||
199 | #else | ||
200 | return 0; | ||
201 | #endif | ||
202 | |||
203 | /* all other states need lowlevel support and need to be | ||
204 | * valid to the lowlevel implementation, no valid callback | ||
205 | * implies that none are valid. */ | 188 | * implies that none are valid. */ |
206 | if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state)) | 189 | if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state)) |
207 | return 0; | 190 | return 0; |
@@ -229,11 +212,6 @@ static int enter_state(suspend_state_t state) | |||
229 | if (!mutex_trylock(&pm_mutex)) | 212 | if (!mutex_trylock(&pm_mutex)) |
230 | return -EBUSY; | 213 | return -EBUSY; |
231 | 214 | ||
232 | if (state == PM_SUSPEND_DISK) { | ||
233 | error = pm_suspend_disk(); | ||
234 | goto Unlock; | ||
235 | } | ||
236 | |||
237 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); | 215 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); |
238 | if ((error = suspend_prepare(state))) | 216 | if ((error = suspend_prepare(state))) |
239 | goto Unlock; | 217 | goto Unlock; |
@@ -251,7 +229,7 @@ static int enter_state(suspend_state_t state) | |||
251 | 229 | ||
252 | /** | 230 | /** |
253 | * pm_suspend - Externally visible function for suspending system. | 231 | * pm_suspend - Externally visible function for suspending system. |
254 | * @state: Enumarted value of state to enter. | 232 | * @state: Enumerated value of state to enter. |
255 | * | 233 | * |
256 | * Determine whether or not value is within range, get state | 234 | * Determine whether or not value is within range, get state |
257 | * structure, and enter (above). | 235 | * structure, and enter (above). |
@@ -289,7 +267,13 @@ static ssize_t state_show(struct kset *kset, char *buf) | |||
289 | if (pm_states[i] && valid_state(i)) | 267 | if (pm_states[i] && valid_state(i)) |
290 | s += sprintf(s,"%s ", pm_states[i]); | 268 | s += sprintf(s,"%s ", pm_states[i]); |
291 | } | 269 | } |
292 | s += sprintf(s,"\n"); | 270 | #ifdef CONFIG_SOFTWARE_SUSPEND |
271 | s += sprintf(s, "%s\n", "disk"); | ||
272 | #else | ||
273 | if (s != buf) | ||
274 | /* convert the last space to a newline */ | ||
275 | *(s-1) = '\n'; | ||
276 | #endif | ||
293 | return (s - buf); | 277 | return (s - buf); |
294 | } | 278 | } |
295 | 279 | ||
@@ -304,6 +288,12 @@ static ssize_t state_store(struct kset *kset, const char *buf, size_t n) | |||
304 | p = memchr(buf, '\n', n); | 288 | p = memchr(buf, '\n', n); |
305 | len = p ? p - buf : n; | 289 | len = p ? p - buf : n; |
306 | 290 | ||
291 | /* First, check if we are requested to hibernate */ | ||
292 | if (!strncmp(buf, "disk", len)) { | ||
293 | error = hibernate(); | ||
294 | return error ? error : n; | ||
295 | } | ||
296 | |||
307 | for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) { | 297 | for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) { |
308 | if (*s && !strncmp(buf, *s, len)) | 298 | if (*s && !strncmp(buf, *s, len)) |
309 | break; | 299 | break; |