aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/power/disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/power/disk.c')
-rw-r--r--kernel/power/disk.c77
1 files changed, 65 insertions, 12 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 02e4fb69111a..06331374d862 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -130,15 +130,25 @@ int pm_suspend_disk(void)
130{ 130{
131 int error; 131 int error;
132 132
133 /* The snapshot device should not be opened while we're running */
134 if (!atomic_add_unless(&snapshot_device_available, -1, 0))
135 return -EBUSY;
136
137 /* Allocate memory management structures */
138 error = create_basic_memory_bitmaps();
139 if (error)
140 goto Exit;
141
133 error = prepare_processes(); 142 error = prepare_processes();
134 if (error) 143 if (error)
135 return error; 144 goto Finish;
136 145
137 if (pm_disk_mode == PM_DISK_TESTPROC) { 146 if (pm_disk_mode == PM_DISK_TESTPROC) {
138 printk("swsusp debug: Waiting for 5 seconds.\n"); 147 printk("swsusp debug: Waiting for 5 seconds.\n");
139 mdelay(5000); 148 mdelay(5000);
140 goto Thaw; 149 goto Thaw;
141 } 150 }
151
142 /* Free memory before shutting down devices. */ 152 /* Free memory before shutting down devices. */
143 error = swsusp_shrink_memory(); 153 error = swsusp_shrink_memory();
144 if (error) 154 if (error)
@@ -196,6 +206,10 @@ int pm_suspend_disk(void)
196 resume_console(); 206 resume_console();
197 Thaw: 207 Thaw:
198 unprepare_processes(); 208 unprepare_processes();
209 Finish:
210 free_basic_memory_bitmaps();
211 Exit:
212 atomic_inc(&snapshot_device_available);
199 return error; 213 return error;
200} 214}
201 215
@@ -239,13 +253,21 @@ static int software_resume(void)
239 } 253 }
240 254
241 pr_debug("PM: Checking swsusp image.\n"); 255 pr_debug("PM: Checking swsusp image.\n");
242
243 error = swsusp_check(); 256 error = swsusp_check();
244 if (error) 257 if (error)
245 goto Done; 258 goto Unlock;
246 259
247 pr_debug("PM: Preparing processes for restore.\n"); 260 /* The snapshot device should not be opened while we're running */
261 if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
262 error = -EBUSY;
263 goto Unlock;
264 }
248 265
266 error = create_basic_memory_bitmaps();
267 if (error)
268 goto Finish;
269
270 pr_debug("PM: Preparing processes for restore.\n");
249 error = prepare_processes(); 271 error = prepare_processes();
250 if (error) { 272 if (error) {
251 swsusp_close(); 273 swsusp_close();
@@ -280,7 +302,11 @@ static int software_resume(void)
280 printk(KERN_ERR "PM: Restore failed, recovering.\n"); 302 printk(KERN_ERR "PM: Restore failed, recovering.\n");
281 unprepare_processes(); 303 unprepare_processes();
282 Done: 304 Done:
305 free_basic_memory_bitmaps();
306 Finish:
307 atomic_inc(&snapshot_device_available);
283 /* For success case, the suspend path will release the lock */ 308 /* For success case, the suspend path will release the lock */
309 Unlock:
284 mutex_unlock(&pm_mutex); 310 mutex_unlock(&pm_mutex);
285 pr_debug("PM: Resume from disk failed.\n"); 311 pr_debug("PM: Resume from disk failed.\n");
286 return 0; 312 return 0;
@@ -322,13 +348,40 @@ static const char * const pm_disk_modes[] = {
322 * supports it (as determined from pm_ops->pm_disk_mode). 348 * supports it (as determined from pm_ops->pm_disk_mode).
323 */ 349 */
324 350
325static ssize_t disk_show(struct subsystem * subsys, char * buf) 351static ssize_t disk_show(struct kset *kset, char *buf)
326{ 352{
327 return sprintf(buf, "%s\n", pm_disk_modes[pm_disk_mode]); 353 int i;
354 char *start = buf;
355
356 for (i = PM_DISK_PLATFORM; i < PM_DISK_MAX; i++) {
357 if (!pm_disk_modes[i])
358 continue;
359 switch (i) {
360 case PM_DISK_SHUTDOWN:
361 case PM_DISK_REBOOT:
362 case PM_DISK_TEST:
363 case PM_DISK_TESTPROC:
364 break;
365 default:
366 if (pm_ops && pm_ops->enter &&
367 (i == pm_ops->pm_disk_mode))
368 break;
369 /* not a valid mode, continue with loop */
370 continue;
371 }
372 if (i == pm_disk_mode)
373 buf += sprintf(buf, "[%s]", pm_disk_modes[i]);
374 else
375 buf += sprintf(buf, "%s", pm_disk_modes[i]);
376 if (i+1 != PM_DISK_MAX)
377 buf += sprintf(buf, " ");
378 }
379 buf += sprintf(buf, "\n");
380 return buf-start;
328} 381}
329 382
330 383
331static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) 384static ssize_t disk_store(struct kset *kset, const char *buf, size_t n)
332{ 385{
333 int error = 0; 386 int error = 0;
334 int i; 387 int i;
@@ -373,13 +426,13 @@ static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n)
373 426
374power_attr(disk); 427power_attr(disk);
375 428
376static ssize_t resume_show(struct subsystem * subsys, char *buf) 429static ssize_t resume_show(struct kset *kset, char *buf)
377{ 430{
378 return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device), 431 return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device),
379 MINOR(swsusp_resume_device)); 432 MINOR(swsusp_resume_device));
380} 433}
381 434
382static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n) 435static ssize_t resume_store(struct kset *kset, const char *buf, size_t n)
383{ 436{
384 unsigned int maj, min; 437 unsigned int maj, min;
385 dev_t res; 438 dev_t res;
@@ -405,12 +458,12 @@ static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n)
405 458
406power_attr(resume); 459power_attr(resume);
407 460
408static ssize_t image_size_show(struct subsystem * subsys, char *buf) 461static ssize_t image_size_show(struct kset *kset, char *buf)
409{ 462{
410 return sprintf(buf, "%lu\n", image_size); 463 return sprintf(buf, "%lu\n", image_size);
411} 464}
412 465
413static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n) 466static ssize_t image_size_store(struct kset *kset, const char *buf, size_t n)
414{ 467{
415 unsigned long size; 468 unsigned long size;
416 469
@@ -439,7 +492,7 @@ static struct attribute_group attr_group = {
439 492
440static int __init pm_disk_init(void) 493static int __init pm_disk_init(void)
441{ 494{
442 return sysfs_create_group(&power_subsys.kset.kobj,&attr_group); 495 return sysfs_create_group(&power_subsys.kobj, &attr_group);
443} 496}
444 497
445core_initcall(pm_disk_init); 498core_initcall(pm_disk_init);