diff options
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r-- | kernel/power/disk.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index d72234942798..b1fb7866b0b3 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
20 | #include <linux/pm.h> | 20 | #include <linux/pm.h> |
21 | #include <linux/console.h> | ||
21 | #include <linux/cpu.h> | 22 | #include <linux/cpu.h> |
22 | 23 | ||
23 | #include "power.h" | 24 | #include "power.h" |
@@ -70,7 +71,7 @@ static inline void platform_finish(void) | |||
70 | 71 | ||
71 | static int prepare_processes(void) | 72 | static int prepare_processes(void) |
72 | { | 73 | { |
73 | int error; | 74 | int error = 0; |
74 | 75 | ||
75 | pm_prepare_console(); | 76 | pm_prepare_console(); |
76 | 77 | ||
@@ -83,6 +84,12 @@ static int prepare_processes(void) | |||
83 | goto thaw; | 84 | goto thaw; |
84 | } | 85 | } |
85 | 86 | ||
87 | if (pm_disk_mode == PM_DISK_TESTPROC) { | ||
88 | printk("swsusp debug: Waiting for 5 seconds.\n"); | ||
89 | mdelay(5000); | ||
90 | goto thaw; | ||
91 | } | ||
92 | |||
86 | /* Free memory before shutting down devices. */ | 93 | /* Free memory before shutting down devices. */ |
87 | if (!(error = swsusp_shrink_memory())) | 94 | if (!(error = swsusp_shrink_memory())) |
88 | return 0; | 95 | return 0; |
@@ -119,11 +126,21 @@ int pm_suspend_disk(void) | |||
119 | if (error) | 126 | if (error) |
120 | return error; | 127 | return error; |
121 | 128 | ||
129 | if (pm_disk_mode == PM_DISK_TESTPROC) | ||
130 | goto Thaw; | ||
131 | |||
132 | suspend_console(); | ||
122 | error = device_suspend(PMSG_FREEZE); | 133 | error = device_suspend(PMSG_FREEZE); |
123 | if (error) { | 134 | if (error) { |
135 | resume_console(); | ||
124 | printk("Some devices failed to suspend\n"); | 136 | printk("Some devices failed to suspend\n"); |
125 | unprepare_processes(); | 137 | goto Thaw; |
126 | return error; | 138 | } |
139 | |||
140 | if (pm_disk_mode == PM_DISK_TEST) { | ||
141 | printk("swsusp debug: Waiting for 5 seconds.\n"); | ||
142 | mdelay(5000); | ||
143 | goto Done; | ||
127 | } | 144 | } |
128 | 145 | ||
129 | pr_debug("PM: snapshotting memory.\n"); | 146 | pr_debug("PM: snapshotting memory.\n"); |
@@ -133,21 +150,24 @@ int pm_suspend_disk(void) | |||
133 | 150 | ||
134 | if (in_suspend) { | 151 | if (in_suspend) { |
135 | device_resume(); | 152 | device_resume(); |
153 | resume_console(); | ||
136 | pr_debug("PM: writing image.\n"); | 154 | pr_debug("PM: writing image.\n"); |
137 | error = swsusp_write(); | 155 | error = swsusp_write(); |
138 | if (!error) | 156 | if (!error) |
139 | power_down(pm_disk_mode); | 157 | power_down(pm_disk_mode); |
140 | else { | 158 | else { |
141 | swsusp_free(); | 159 | swsusp_free(); |
142 | unprepare_processes(); | 160 | goto Thaw; |
143 | return error; | ||
144 | } | 161 | } |
145 | } else | 162 | } else { |
146 | pr_debug("PM: Image restored successfully.\n"); | 163 | pr_debug("PM: Image restored successfully.\n"); |
164 | } | ||
147 | 165 | ||
148 | swsusp_free(); | 166 | swsusp_free(); |
149 | Done: | 167 | Done: |
150 | device_resume(); | 168 | device_resume(); |
169 | resume_console(); | ||
170 | Thaw: | ||
151 | unprepare_processes(); | 171 | unprepare_processes(); |
152 | return error; | 172 | return error; |
153 | } | 173 | } |
@@ -212,7 +232,9 @@ static int software_resume(void) | |||
212 | 232 | ||
213 | pr_debug("PM: Preparing devices for restore.\n"); | 233 | pr_debug("PM: Preparing devices for restore.\n"); |
214 | 234 | ||
235 | suspend_console(); | ||
215 | if ((error = device_suspend(PMSG_PRETHAW))) { | 236 | if ((error = device_suspend(PMSG_PRETHAW))) { |
237 | resume_console(); | ||
216 | printk("Some devices failed to suspend\n"); | 238 | printk("Some devices failed to suspend\n"); |
217 | swsusp_free(); | 239 | swsusp_free(); |
218 | goto Thaw; | 240 | goto Thaw; |
@@ -224,6 +246,7 @@ static int software_resume(void) | |||
224 | swsusp_resume(); | 246 | swsusp_resume(); |
225 | pr_debug("PM: Restore failed, recovering.n"); | 247 | pr_debug("PM: Restore failed, recovering.n"); |
226 | device_resume(); | 248 | device_resume(); |
249 | resume_console(); | ||
227 | Thaw: | 250 | Thaw: |
228 | unprepare_processes(); | 251 | unprepare_processes(); |
229 | Done: | 252 | Done: |
@@ -241,6 +264,8 @@ static const char * const pm_disk_modes[] = { | |||
241 | [PM_DISK_PLATFORM] = "platform", | 264 | [PM_DISK_PLATFORM] = "platform", |
242 | [PM_DISK_SHUTDOWN] = "shutdown", | 265 | [PM_DISK_SHUTDOWN] = "shutdown", |
243 | [PM_DISK_REBOOT] = "reboot", | 266 | [PM_DISK_REBOOT] = "reboot", |
267 | [PM_DISK_TEST] = "test", | ||
268 | [PM_DISK_TESTPROC] = "testproc", | ||
244 | }; | 269 | }; |
245 | 270 | ||
246 | /** | 271 | /** |
@@ -295,17 +320,19 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) | |||
295 | } | 320 | } |
296 | } | 321 | } |
297 | if (mode) { | 322 | if (mode) { |
298 | if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT) | 323 | if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT || |
324 | mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) { | ||
299 | pm_disk_mode = mode; | 325 | pm_disk_mode = mode; |
300 | else { | 326 | } else { |
301 | if (pm_ops && pm_ops->enter && | 327 | if (pm_ops && pm_ops->enter && |
302 | (mode == pm_ops->pm_disk_mode)) | 328 | (mode == pm_ops->pm_disk_mode)) |
303 | pm_disk_mode = mode; | 329 | pm_disk_mode = mode; |
304 | else | 330 | else |
305 | error = -EINVAL; | 331 | error = -EINVAL; |
306 | } | 332 | } |
307 | } else | 333 | } else { |
308 | error = -EINVAL; | 334 | error = -EINVAL; |
335 | } | ||
309 | 336 | ||
310 | pr_debug("PM: suspend-to-disk mode set to '%s'\n", | 337 | pr_debug("PM: suspend-to-disk mode set to '%s'\n", |
311 | pm_disk_modes[mode]); | 338 | pm_disk_modes[mode]); |