aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/disk.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2006-11-03 01:07:19 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-11-03 15:27:58 -0500
commitb918f6e62cd46774f9fc0a3fbba6bd10ad85ee14 (patch)
treed73dc0e8823c8445d84701cc3d527e0e34494a32 /kernel/power/disk.c
parent90d53909443b3986569b38ef145f09ea2359af75 (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.c37
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
72static int prepare_processes(void) 72static 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]);