aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power')
-rw-r--r--kernel/power/disk.c115
1 files changed, 58 insertions, 57 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 88fc5d7ac73..406b20adb27 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -87,52 +87,24 @@ static inline void platform_finish(void)
87 } 87 }
88} 88}
89 89
90static void unprepare_processes(void)
91{
92 thaw_processes();
93 pm_restore_console();
94}
95
90static int prepare_processes(void) 96static int prepare_processes(void)
91{ 97{
92 int error = 0; 98 int error = 0;
93 99
94 pm_prepare_console(); 100 pm_prepare_console();
95
96 error = disable_nonboot_cpus();
97 if (error)
98 goto enable_cpus;
99
100 if (freeze_processes()) { 101 if (freeze_processes()) {
101 error = -EBUSY; 102 error = -EBUSY;
102 goto thaw; 103 unprepare_processes();
103 } 104 }
104
105 if (pm_disk_mode == PM_DISK_TESTPROC) {
106 printk("swsusp debug: Waiting for 5 seconds.\n");
107 mdelay(5000);
108 goto thaw;
109 }
110
111 error = platform_prepare();
112 if (error)
113 goto thaw;
114
115 /* Free memory before shutting down devices. */
116 if (!(error = swsusp_shrink_memory()))
117 return 0;
118
119 platform_finish();
120 thaw:
121 thaw_processes();
122 enable_cpus:
123 enable_nonboot_cpus();
124 pm_restore_console();
125 return error; 105 return error;
126} 106}
127 107
128static void unprepare_processes(void)
129{
130 platform_finish();
131 thaw_processes();
132 enable_nonboot_cpus();
133 pm_restore_console();
134}
135
136/** 108/**
137 * pm_suspend_disk - The granpappy of hibernation power management. 109 * pm_suspend_disk - The granpappy of hibernation power management.
138 * 110 *
@@ -150,29 +122,45 @@ int pm_suspend_disk(void)
150 if (error) 122 if (error)
151 return error; 123 return error;
152 124
153 if (pm_disk_mode == PM_DISK_TESTPROC) 125 if (pm_disk_mode == PM_DISK_TESTPROC) {
154 return 0; 126 printk("swsusp debug: Waiting for 5 seconds.\n");
127 mdelay(5000);
128 goto Thaw;
129 }
130 /* Free memory before shutting down devices. */
131 error = swsusp_shrink_memory();
132 if (error)
133 goto Thaw;
134
135 error = platform_prepare();
136 if (error)
137 goto Thaw;
155 138
156 suspend_console(); 139 suspend_console();
157 error = device_suspend(PMSG_FREEZE); 140 error = device_suspend(PMSG_FREEZE);
158 if (error) { 141 if (error) {
159 resume_console(); 142 printk(KERN_ERR "PM: Some devices failed to suspend\n");
160 printk("Some devices failed to suspend\n"); 143 goto Resume_devices;
161 goto Thaw;
162 } 144 }
145 error = disable_nonboot_cpus();
146 if (error)
147 goto Enable_cpus;
163 148
164 if (pm_disk_mode == PM_DISK_TEST) { 149 if (pm_disk_mode == PM_DISK_TEST) {
165 printk("swsusp debug: Waiting for 5 seconds.\n"); 150 printk("swsusp debug: Waiting for 5 seconds.\n");
166 mdelay(5000); 151 mdelay(5000);
167 goto Done; 152 goto Enable_cpus;
168 } 153 }
169 154
170 pr_debug("PM: snapshotting memory.\n"); 155 pr_debug("PM: snapshotting memory.\n");
171 in_suspend = 1; 156 in_suspend = 1;
172 if ((error = swsusp_suspend())) 157 error = swsusp_suspend();
173 goto Done; 158 if (error)
159 goto Enable_cpus;
174 160
175 if (in_suspend) { 161 if (in_suspend) {
162 enable_nonboot_cpus();
163 platform_finish();
176 device_resume(); 164 device_resume();
177 resume_console(); 165 resume_console();
178 pr_debug("PM: writing image.\n"); 166 pr_debug("PM: writing image.\n");
@@ -188,7 +176,10 @@ int pm_suspend_disk(void)
188 } 176 }
189 177
190 swsusp_free(); 178 swsusp_free();
191 Done: 179 Enable_cpus:
180 enable_nonboot_cpus();
181 Resume_devices:
182 platform_finish();
192 device_resume(); 183 device_resume();
193 resume_console(); 184 resume_console();
194 Thaw: 185 Thaw:
@@ -237,19 +228,28 @@ static int software_resume(void)
237 228
238 pr_debug("PM: Checking swsusp image.\n"); 229 pr_debug("PM: Checking swsusp image.\n");
239 230
240 if ((error = swsusp_check())) 231 error = swsusp_check();
232 if (error)
241 goto Done; 233 goto Done;
242 234
243 pr_debug("PM: Preparing processes for restore.\n"); 235 pr_debug("PM: Preparing processes for restore.\n");
244 236
245 if ((error = prepare_processes())) { 237 error = prepare_processes();
238 if (error) {
246 swsusp_close(); 239 swsusp_close();
247 goto Done; 240 goto Done;
248 } 241 }
249 242
243 error = platform_prepare();
244 if (error) {
245 swsusp_free();
246 goto Thaw;
247 }
248
250 pr_debug("PM: Reading swsusp image.\n"); 249 pr_debug("PM: Reading swsusp image.\n");
251 250
252 if ((error = swsusp_read())) { 251 error = swsusp_read();
252 if (error) {
253 swsusp_free(); 253 swsusp_free();
254 goto Thaw; 254 goto Thaw;
255 } 255 }
@@ -257,21 +257,22 @@ static int software_resume(void)
257 pr_debug("PM: Preparing devices for restore.\n"); 257 pr_debug("PM: Preparing devices for restore.\n");
258 258
259 suspend_console(); 259 suspend_console();
260 if ((error = device_suspend(PMSG_PRETHAW))) { 260 error = device_suspend(PMSG_PRETHAW);
261 resume_console(); 261 if (error)
262 printk("Some devices failed to suspend\n"); 262 goto Free;
263 swsusp_free();
264 goto Thaw;
265 }
266 263
267 mb(); 264 error = disable_nonboot_cpus();
265 if (!error)
266 swsusp_resume();
268 267
269 pr_debug("PM: Restoring saved image.\n"); 268 enable_nonboot_cpus();
270 swsusp_resume(); 269 Free:
271 pr_debug("PM: Restore failed, recovering.n"); 270 swsusp_free();
271 platform_finish();
272 device_resume(); 272 device_resume();
273 resume_console(); 273 resume_console();
274 Thaw: 274 Thaw:
275 printk(KERN_ERR "PM: Restore failed, recovering.\n");
275 unprepare_processes(); 276 unprepare_processes();
276 Done: 277 Done:
277 /* For success case, the suspend path will release the lock */ 278 /* For success case, the suspend path will release the lock */