aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-11-19 17:42:31 -0500
committerLen Brown <len.brown@intel.com>2008-02-01 18:30:54 -0500
commit4cc79776c9ea431790e04fcacbebb30d28eb1570 (patch)
tree42eb5b8c5f2a2d1fcfb1dae8fa77ad70be209cbb
parent039a75c6e17ba4ff76998d6ac6ee3d508fff1930 (diff)
Hibernation: New testing facility (rev. 2)
Make it possible to test the hibernation core code with the help of the /sys/power/pm_test attribute introduced for suspend testing in the previous patch. Writing an appropriate string to this file causes the hibernation code to work in one of the test modes defined as follows: freezer - test the freezing of processes devices - test the freezing of processes and suspending of devices platform - test the freezing of processes, suspending of devices and platform global   control methods(*) processors - test the freezing of processes, suspending of devices, platform global   control methods(*) and the disabling of nonboot CPUs core - test the freezing of processes, suspending of devices, platform global   control methods(*), the disabling of nonboot CPUs and suspending of   platform/system devices (*) - the platform global control methods are only available on ACPI systems       and are only tested if the hibernation mode is set to "platform" Then, if a hibernation is started by normal means, the hibernation core will perform its normal operations up to the point indicated by given test level. Next, it will wait for 5 seconds and carry out the resume operations needed to transition the system back to the fully functional state. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--kernel/power/disk.c70
-rw-r--r--kernel/power/power.h2
2 files changed, 57 insertions, 15 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 659736508239..0866b163c6bb 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -70,6 +70,35 @@ void hibernation_set_ops(struct platform_hibernation_ops *ops)
70 mutex_unlock(&pm_mutex); 70 mutex_unlock(&pm_mutex);
71} 71}
72 72
73#ifdef CONFIG_PM_DEBUG
74static void hibernation_debug_sleep(void)
75{
76 printk(KERN_INFO "hibernation debug: Waiting for 5 seconds.\n");
77 mdelay(5000);
78}
79
80static int hibernation_testmode(int mode)
81{
82 if (hibernation_mode == mode) {
83 hibernation_debug_sleep();
84 return 1;
85 }
86 return 0;
87}
88
89static int hibernation_test(int level)
90{
91 if (pm_test_level == level) {
92 hibernation_debug_sleep();
93 return 1;
94 }
95 return 0;
96}
97#else /* !CONFIG_PM_DEBUG */
98static int hibernation_testmode(int mode) { return 0; }
99static int hibernation_test(int level) { return 0; }
100#endif /* !CONFIG_PM_DEBUG */
101
73/** 102/**
74 * platform_start - tell the platform driver that we're starting 103 * platform_start - tell the platform driver that we're starting
75 * hibernation 104 * hibernation
@@ -167,6 +196,10 @@ int create_image(int platform_mode)
167 goto Enable_irqs; 196 goto Enable_irqs;
168 } 197 }
169 198
199 if (hibernation_test(TEST_CORE))
200 goto Power_up;
201
202 in_suspend = 1;
170 save_processor_state(); 203 save_processor_state();
171 error = swsusp_arch_suspend(); 204 error = swsusp_arch_suspend();
172 if (error) 205 if (error)
@@ -175,6 +208,7 @@ int create_image(int platform_mode)
175 restore_processor_state(); 208 restore_processor_state();
176 if (!in_suspend) 209 if (!in_suspend)
177 platform_leave(platform_mode); 210 platform_leave(platform_mode);
211 Power_up:
178 /* NOTE: device_power_up() is just a resume() for devices 212 /* NOTE: device_power_up() is just a resume() for devices
179 * that suspended with irqs off ... no overall powerup. 213 * that suspended with irqs off ... no overall powerup.
180 */ 214 */
@@ -211,24 +245,29 @@ int hibernation_snapshot(int platform_mode)
211 if (error) 245 if (error)
212 goto Resume_console; 246 goto Resume_console;
213 247
214 error = platform_pre_snapshot(platform_mode); 248 if (hibernation_test(TEST_DEVICES))
215 if (error)
216 goto Resume_devices; 249 goto Resume_devices;
217 250
251 error = platform_pre_snapshot(platform_mode);
252 if (error || hibernation_test(TEST_PLATFORM))
253 goto Finish;
254
218 error = disable_nonboot_cpus(); 255 error = disable_nonboot_cpus();
219 if (!error) { 256 if (!error) {
220 if (hibernation_mode != HIBERNATION_TEST) { 257 if (hibernation_test(TEST_CPUS))
221 in_suspend = 1; 258 goto Enable_cpus;
222 error = create_image(platform_mode); 259
223 /* Control returns here after successful restore */ 260 if (hibernation_testmode(HIBERNATION_TEST))
224 } else { 261 goto Enable_cpus;
225 printk("swsusp debug: Waiting for 5 seconds.\n"); 262
226 mdelay(5000); 263 error = create_image(platform_mode);
227 } 264 /* Control returns here after successful restore */
228 } 265 }
266 Enable_cpus:
229 enable_nonboot_cpus(); 267 enable_nonboot_cpus();
230 Resume_devices: 268 Finish:
231 platform_finish(platform_mode); 269 platform_finish(platform_mode);
270 Resume_devices:
232 device_resume(); 271 device_resume();
233 Resume_console: 272 Resume_console:
234 resume_console(); 273 resume_console();
@@ -406,11 +445,12 @@ int hibernate(void)
406 if (error) 445 if (error)
407 goto Finish; 446 goto Finish;
408 447
409 if (hibernation_mode == HIBERNATION_TESTPROC) { 448 if (hibernation_test(TEST_FREEZER))
410 printk("swsusp debug: Waiting for 5 seconds.\n");
411 mdelay(5000);
412 goto Thaw; 449 goto Thaw;
413 } 450
451 if (hibernation_testmode(HIBERNATION_TESTPROC))
452 goto Thaw;
453
414 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM); 454 error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
415 if (in_suspend && !error) { 455 if (in_suspend && !error) {
416 unsigned int flags = 0; 456 unsigned int flags = 0;
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 9f9e16e33962..f9f0d4d26c50 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -206,3 +206,5 @@ enum {
206 206
207#define TEST_FIRST TEST_NONE 207#define TEST_FIRST TEST_NONE
208#define TEST_MAX (__TEST_AFTER_LAST - 1) 208#define TEST_MAX (__TEST_AFTER_LAST - 1)
209
210extern int pm_test_level;