aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-power17
-rw-r--r--Documentation/power/interface.txt13
-rw-r--r--include/linux/pm.h4
-rw-r--r--kernel/power/disk.c37
4 files changed, 60 insertions, 11 deletions
diff --git a/Documentation/ABI/testing/sysfs-power b/Documentation/ABI/testing/sysfs-power
index d882f8093871..dcff4d0623ad 100644
--- a/Documentation/ABI/testing/sysfs-power
+++ b/Documentation/ABI/testing/sysfs-power
@@ -21,7 +21,7 @@ Description:
21 these states. 21 these states.
22 22
23What: /sys/power/disk 23What: /sys/power/disk
24Date: August 2006 24Date: September 2006
25Contact: Rafael J. Wysocki <rjw@sisk.pl> 25Contact: Rafael J. Wysocki <rjw@sisk.pl>
26Description: 26Description:
27 The /sys/power/disk file controls the operating mode of the 27 The /sys/power/disk file controls the operating mode of the
@@ -39,6 +39,19 @@ Description:
39 'reboot' - the memory image will be saved by the kernel and 39 'reboot' - the memory image will be saved by the kernel and
40 the system will be rebooted. 40 the system will be rebooted.
41 41
42 Additionally, /sys/power/disk can be used to turn on one of the
43 two testing modes of the suspend-to-disk mechanism: 'testproc'
44 or 'test'. If the suspend-to-disk mechanism is in the
45 'testproc' mode, writing 'disk' to /sys/power/state will cause
46 the kernel to disable nonboot CPUs and freeze tasks, wait for 5
47 seconds, unfreeze tasks and enable nonboot CPUs. If it is in
48 the 'test' mode, writing 'disk' to /sys/power/state will cause
49 the kernel to disable nonboot CPUs and freeze tasks, shrink
50 memory, suspend devices, wait for 5 seconds, resume devices,
51 unfreeze tasks and enable nonboot CPUs. Then, we are able to
52 look in the log messages and work out, for example, which code
53 is being slow and which device drivers are misbehaving.
54
42 The suspend-to-disk method may be chosen by writing to this 55 The suspend-to-disk method may be chosen by writing to this
43 file one of the accepted strings: 56 file one of the accepted strings:
44 57
@@ -46,6 +59,8 @@ Description:
46 'platform' 59 'platform'
47 'shutdown' 60 'shutdown'
48 'reboot' 61 'reboot'
62 'testproc'
63 'test'
49 64
50 It will only change to 'firmware' or 'platform' if the system 65 It will only change to 'firmware' or 'platform' if the system
51 supports that. 66 supports that.
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index a66bec222b16..74311d7e0f3c 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -30,6 +30,17 @@ testing). The system will support either 'firmware' or 'platform', and
30that is known a priori. But, the user may choose 'shutdown' or 30that is known a priori. But, the user may choose 'shutdown' or
31'reboot' as alternatives. 31'reboot' as alternatives.
32 32
33Additionally, /sys/power/disk can be used to turn on one of the two testing
34modes of the suspend-to-disk mechanism: 'testproc' or 'test'. If the
35suspend-to-disk mechanism is in the 'testproc' mode, writing 'disk' to
36/sys/power/state will cause the kernel to disable nonboot CPUs and freeze
37tasks, wait for 5 seconds, unfreeze tasks and enable nonboot CPUs. If it is
38in the 'test' mode, writing 'disk' to /sys/power/state will cause the kernel
39to disable nonboot CPUs and freeze tasks, shrink memory, suspend devices, wait
40for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then,
41we are able to look in the log messages and work out, for example, which code
42is being slow and which device drivers are misbehaving.
43
33Reading from this file will display what the mode is currently set 44Reading from this file will display what the mode is currently set
34to. Writing to this file will accept one of 45to. Writing to this file will accept one of
35 46
@@ -37,6 +48,8 @@ to. Writing to this file will accept one of
37 'platform' 48 'platform'
38 'shutdown' 49 'shutdown'
39 'reboot' 50 'reboot'
51 'testproc'
52 'test'
40 53
41It will only change to 'firmware' or 'platform' if the system supports 54It will only change to 'firmware' or 'platform' if the system supports
42it. 55it.
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 6b27e07aef19..070394e846d0 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -116,7 +116,9 @@ typedef int __bitwise suspend_disk_method_t;
116#define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2) 116#define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2)
117#define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3) 117#define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3)
118#define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4) 118#define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4)
119#define PM_DISK_MAX ((__force suspend_disk_method_t) 5) 119#define PM_DISK_TEST ((__force suspend_disk_method_t) 5)
120#define PM_DISK_TESTPROC ((__force suspend_disk_method_t) 6)
121#define PM_DISK_MAX ((__force suspend_disk_method_t) 7)
120 122
121struct pm_ops { 123struct pm_ops {
122 suspend_disk_method_t pm_disk_mode; 124 suspend_disk_method_t pm_disk_mode;
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]);