diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2006-11-03 01:07:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-11-03 15:27:58 -0500 |
commit | b918f6e62cd46774f9fc0a3fbba6bd10ad85ee14 (patch) | |
tree | d73dc0e8823c8445d84701cc3d527e0e34494a32 /kernel/power/disk.c | |
parent | 90d53909443b3986569b38ef145f09ea2359af75 (diff) |
[PATCH] swsusp: debugging
Add a swsusp debugging mode. This does everything that's needed for a suspend
except for actually suspending. So we can look in the log messages and work
out a) what code is being slow and b) which drivers are misbehaving.
(1)
# echo testproc > /sys/power/disk
# echo disk > /sys/power/state
This should turn off the non-boot CPU, freeze all processes, wait for 5
seconds and then thaw the processes and the CPU.
(2)
# echo test > /sys/power/disk
# echo disk > /sys/power/state
This should turn off the non-boot CPU, freeze all processes, shrink
memory, suspend all devices, wait for 5 seconds, resume the devices etc.
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Stefan Seyfried <seife@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r-- | kernel/power/disk.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index d3a158a60312..b1fb7866b0b3 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -71,7 +71,7 @@ static inline void platform_finish(void) | |||
71 | 71 | ||
72 | static int prepare_processes(void) | 72 | static int prepare_processes(void) |
73 | { | 73 | { |
74 | int error; | 74 | int error = 0; |
75 | 75 | ||
76 | pm_prepare_console(); | 76 | pm_prepare_console(); |
77 | 77 | ||
@@ -84,6 +84,12 @@ static int prepare_processes(void) | |||
84 | goto thaw; | 84 | goto thaw; |
85 | } | 85 | } |
86 | 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 | |||
87 | /* Free memory before shutting down devices. */ | 93 | /* Free memory before shutting down devices. */ |
88 | if (!(error = swsusp_shrink_memory())) | 94 | if (!(error = swsusp_shrink_memory())) |
89 | return 0; | 95 | return 0; |
@@ -120,13 +126,21 @@ int pm_suspend_disk(void) | |||
120 | if (error) | 126 | if (error) |
121 | return error; | 127 | return error; |
122 | 128 | ||
129 | if (pm_disk_mode == PM_DISK_TESTPROC) | ||
130 | goto Thaw; | ||
131 | |||
123 | suspend_console(); | 132 | suspend_console(); |
124 | error = device_suspend(PMSG_FREEZE); | 133 | error = device_suspend(PMSG_FREEZE); |
125 | if (error) { | 134 | if (error) { |
126 | resume_console(); | 135 | resume_console(); |
127 | printk("Some devices failed to suspend\n"); | 136 | printk("Some devices failed to suspend\n"); |
128 | unprepare_processes(); | 137 | goto Thaw; |
129 | 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; | ||
130 | } | 144 | } |
131 | 145 | ||
132 | pr_debug("PM: snapshotting memory.\n"); | 146 | pr_debug("PM: snapshotting memory.\n"); |
@@ -143,16 +157,17 @@ int pm_suspend_disk(void) | |||
143 | power_down(pm_disk_mode); | 157 | power_down(pm_disk_mode); |
144 | else { | 158 | else { |
145 | swsusp_free(); | 159 | swsusp_free(); |
146 | unprepare_processes(); | 160 | goto Thaw; |
147 | return error; | ||
148 | } | 161 | } |
149 | } else | 162 | } else { |
150 | pr_debug("PM: Image restored successfully.\n"); | 163 | pr_debug("PM: Image restored successfully.\n"); |
164 | } | ||
151 | 165 | ||
152 | swsusp_free(); | 166 | swsusp_free(); |
153 | Done: | 167 | Done: |
154 | device_resume(); | 168 | device_resume(); |
155 | resume_console(); | 169 | resume_console(); |
170 | Thaw: | ||
156 | unprepare_processes(); | 171 | unprepare_processes(); |
157 | return error; | 172 | return error; |
158 | } | 173 | } |
@@ -249,6 +264,8 @@ static const char * const pm_disk_modes[] = { | |||
249 | [PM_DISK_PLATFORM] = "platform", | 264 | [PM_DISK_PLATFORM] = "platform", |
250 | [PM_DISK_SHUTDOWN] = "shutdown", | 265 | [PM_DISK_SHUTDOWN] = "shutdown", |
251 | [PM_DISK_REBOOT] = "reboot", | 266 | [PM_DISK_REBOOT] = "reboot", |
267 | [PM_DISK_TEST] = "test", | ||
268 | [PM_DISK_TESTPROC] = "testproc", | ||
252 | }; | 269 | }; |
253 | 270 | ||
254 | /** | 271 | /** |
@@ -303,17 +320,19 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) | |||
303 | } | 320 | } |
304 | } | 321 | } |
305 | if (mode) { | 322 | if (mode) { |
306 | 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) { | ||
307 | pm_disk_mode = mode; | 325 | pm_disk_mode = mode; |
308 | else { | 326 | } else { |
309 | if (pm_ops && pm_ops->enter && | 327 | if (pm_ops && pm_ops->enter && |
310 | (mode == pm_ops->pm_disk_mode)) | 328 | (mode == pm_ops->pm_disk_mode)) |
311 | pm_disk_mode = mode; | 329 | pm_disk_mode = mode; |
312 | else | 330 | else |
313 | error = -EINVAL; | 331 | error = -EINVAL; |
314 | } | 332 | } |
315 | } else | 333 | } else { |
316 | error = -EINVAL; | 334 | error = -EINVAL; |
335 | } | ||
317 | 336 | ||
318 | pr_debug("PM: suspend-to-disk mode set to '%s'\n", | 337 | pr_debug("PM: suspend-to-disk mode set to '%s'\n", |
319 | pm_disk_modes[mode]); | 338 | pm_disk_modes[mode]); |