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.c155
1 files changed, 105 insertions, 50 deletions
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 432ee575c9ee..5f21ab2bbcdf 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -22,6 +22,7 @@
22#include <linux/console.h> 22#include <linux/console.h>
23#include <linux/cpu.h> 23#include <linux/cpu.h>
24#include <linux/freezer.h> 24#include <linux/freezer.h>
25#include <asm/suspend.h>
25 26
26#include "power.h" 27#include "power.h"
27 28
@@ -214,7 +215,7 @@ static int create_image(int platform_mode)
214 return error; 215 return error;
215 216
216 device_pm_lock(); 217 device_pm_lock();
217 local_irq_disable(); 218
218 /* At this point, device_suspend() has been called, but *not* 219 /* At this point, device_suspend() has been called, but *not*
219 * device_power_down(). We *must* call device_power_down() now. 220 * device_power_down(). We *must* call device_power_down() now.
220 * Otherwise, drivers for some devices (e.g. interrupt controllers) 221 * Otherwise, drivers for some devices (e.g. interrupt controllers)
@@ -225,6 +226,24 @@ static int create_image(int platform_mode)
225 if (error) { 226 if (error) {
226 printk(KERN_ERR "PM: Some devices failed to power down, " 227 printk(KERN_ERR "PM: Some devices failed to power down, "
227 "aborting hibernation\n"); 228 "aborting hibernation\n");
229 goto Unlock;
230 }
231
232 error = platform_pre_snapshot(platform_mode);
233 if (error || hibernation_test(TEST_PLATFORM))
234 goto Platform_finish;
235
236 error = disable_nonboot_cpus();
237 if (error || hibernation_test(TEST_CPUS)
238 || hibernation_testmode(HIBERNATION_TEST))
239 goto Enable_cpus;
240
241 local_irq_disable();
242
243 sysdev_suspend(PMSG_FREEZE);
244 if (error) {
245 printk(KERN_ERR "PM: Some devices failed to power down, "
246 "aborting hibernation\n");
228 goto Enable_irqs; 247 goto Enable_irqs;
229 } 248 }
230 249
@@ -241,15 +260,28 @@ static int create_image(int platform_mode)
241 restore_processor_state(); 260 restore_processor_state();
242 if (!in_suspend) 261 if (!in_suspend)
243 platform_leave(platform_mode); 262 platform_leave(platform_mode);
263
244 Power_up: 264 Power_up:
265 sysdev_resume();
245 /* NOTE: device_power_up() is just a resume() for devices 266 /* NOTE: device_power_up() is just a resume() for devices
246 * that suspended with irqs off ... no overall powerup. 267 * that suspended with irqs off ... no overall powerup.
247 */ 268 */
248 device_power_up(in_suspend ? 269
249 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
250 Enable_irqs: 270 Enable_irqs:
251 local_irq_enable(); 271 local_irq_enable();
272
273 Enable_cpus:
274 enable_nonboot_cpus();
275
276 Platform_finish:
277 platform_finish(platform_mode);
278
279 device_power_up(in_suspend ?
280 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
281
282 Unlock:
252 device_pm_unlock(); 283 device_pm_unlock();
284
253 return error; 285 return error;
254} 286}
255 287
@@ -257,7 +289,7 @@ static int create_image(int platform_mode)
257 * hibernation_snapshot - quiesce devices and create the hibernation 289 * hibernation_snapshot - quiesce devices and create the hibernation
258 * snapshot image. 290 * snapshot image.
259 * @platform_mode - if set, use the platform driver, if available, to 291 * @platform_mode - if set, use the platform driver, if available, to
260 * prepare the platform frimware for the power transition. 292 * prepare the platform firmware for the power transition.
261 * 293 *
262 * Must be called with pm_mutex held 294 * Must be called with pm_mutex held
263 */ 295 */
@@ -283,25 +315,9 @@ int hibernation_snapshot(int platform_mode)
283 if (hibernation_test(TEST_DEVICES)) 315 if (hibernation_test(TEST_DEVICES))
284 goto Recover_platform; 316 goto Recover_platform;
285 317
286 error = platform_pre_snapshot(platform_mode); 318 error = create_image(platform_mode);
287 if (error || hibernation_test(TEST_PLATFORM)) 319 /* Control returns here after successful restore */
288 goto Finish;
289
290 error = disable_nonboot_cpus();
291 if (!error) {
292 if (hibernation_test(TEST_CPUS))
293 goto Enable_cpus;
294 320
295 if (hibernation_testmode(HIBERNATION_TEST))
296 goto Enable_cpus;
297
298 error = create_image(platform_mode);
299 /* Control returns here after successful restore */
300 }
301 Enable_cpus:
302 enable_nonboot_cpus();
303 Finish:
304 platform_finish(platform_mode);
305 Resume_devices: 321 Resume_devices:
306 device_resume(in_suspend ? 322 device_resume(in_suspend ?
307 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); 323 (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
@@ -323,18 +339,33 @@ int hibernation_snapshot(int platform_mode)
323 * kernel. 339 * kernel.
324 */ 340 */
325 341
326static int resume_target_kernel(void) 342static int resume_target_kernel(bool platform_mode)
327{ 343{
328 int error; 344 int error;
329 345
330 device_pm_lock(); 346 device_pm_lock();
331 local_irq_disable(); 347
332 error = device_power_down(PMSG_QUIESCE); 348 error = device_power_down(PMSG_QUIESCE);
333 if (error) { 349 if (error) {
334 printk(KERN_ERR "PM: Some devices failed to power down, " 350 printk(KERN_ERR "PM: Some devices failed to power down, "
335 "aborting resume\n"); 351 "aborting resume\n");
336 goto Enable_irqs; 352 goto Unlock;
337 } 353 }
354
355 error = platform_pre_restore(platform_mode);
356 if (error)
357 goto Cleanup;
358
359 error = disable_nonboot_cpus();
360 if (error)
361 goto Enable_cpus;
362
363 local_irq_disable();
364
365 error = sysdev_suspend(PMSG_QUIESCE);
366 if (error)
367 goto Enable_irqs;
368
338 /* We'll ignore saved state, but this gets preempt count (etc) right */ 369 /* We'll ignore saved state, but this gets preempt count (etc) right */
339 save_processor_state(); 370 save_processor_state();
340 error = restore_highmem(); 371 error = restore_highmem();
@@ -357,10 +388,23 @@ static int resume_target_kernel(void)
357 swsusp_free(); 388 swsusp_free();
358 restore_processor_state(); 389 restore_processor_state();
359 touch_softlockup_watchdog(); 390 touch_softlockup_watchdog();
360 device_power_up(PMSG_RECOVER); 391
392 sysdev_resume();
393
361 Enable_irqs: 394 Enable_irqs:
362 local_irq_enable(); 395 local_irq_enable();
396
397 Enable_cpus:
398 enable_nonboot_cpus();
399
400 Cleanup:
401 platform_restore_cleanup(platform_mode);
402
403 device_power_up(PMSG_RECOVER);
404
405 Unlock:
363 device_pm_unlock(); 406 device_pm_unlock();
407
364 return error; 408 return error;
365} 409}
366 410
@@ -368,7 +412,7 @@ static int resume_target_kernel(void)
368 * hibernation_restore - quiesce devices and restore the hibernation 412 * hibernation_restore - quiesce devices and restore the hibernation
369 * snapshot image. If successful, control returns in hibernation_snaphot() 413 * snapshot image. If successful, control returns in hibernation_snaphot()
370 * @platform_mode - if set, use the platform driver, if available, to 414 * @platform_mode - if set, use the platform driver, if available, to
371 * prepare the platform frimware for the transition. 415 * prepare the platform firmware for the transition.
372 * 416 *
373 * Must be called with pm_mutex held 417 * Must be called with pm_mutex held
374 */ 418 */
@@ -380,19 +424,10 @@ int hibernation_restore(int platform_mode)
380 pm_prepare_console(); 424 pm_prepare_console();
381 suspend_console(); 425 suspend_console();
382 error = device_suspend(PMSG_QUIESCE); 426 error = device_suspend(PMSG_QUIESCE);
383 if (error)
384 goto Finish;
385
386 error = platform_pre_restore(platform_mode);
387 if (!error) { 427 if (!error) {
388 error = disable_nonboot_cpus(); 428 error = resume_target_kernel(platform_mode);
389 if (!error) 429 device_resume(PMSG_RECOVER);
390 error = resume_target_kernel();
391 enable_nonboot_cpus();
392 } 430 }
393 platform_restore_cleanup(platform_mode);
394 device_resume(PMSG_RECOVER);
395 Finish:
396 resume_console(); 431 resume_console();
397 pm_restore_console(); 432 pm_restore_console();
398 return error; 433 return error;
@@ -428,37 +463,46 @@ int hibernation_platform_enter(void)
428 goto Resume_devices; 463 goto Resume_devices;
429 } 464 }
430 465
466 device_pm_lock();
467
468 error = device_power_down(PMSG_HIBERNATE);
469 if (error)
470 goto Unlock;
471
431 error = hibernation_ops->prepare(); 472 error = hibernation_ops->prepare();
432 if (error) 473 if (error)
433 goto Resume_devices; 474 goto Platofrm_finish;
434 475
435 error = disable_nonboot_cpus(); 476 error = disable_nonboot_cpus();
436 if (error) 477 if (error)
437 goto Finish; 478 goto Platofrm_finish;
438 479
439 device_pm_lock();
440 local_irq_disable(); 480 local_irq_disable();
441 error = device_power_down(PMSG_HIBERNATE); 481 sysdev_suspend(PMSG_HIBERNATE);
442 if (!error) { 482 hibernation_ops->enter();
443 hibernation_ops->enter(); 483 /* We should never get here */
444 /* We should never get here */ 484 while (1);
445 while (1);
446 }
447 local_irq_enable();
448 device_pm_unlock();
449 485
450 /* 486 /*
451 * We don't need to reenable the nonboot CPUs or resume consoles, since 487 * We don't need to reenable the nonboot CPUs or resume consoles, since
452 * the system is going to be halted anyway. 488 * the system is going to be halted anyway.
453 */ 489 */
454 Finish: 490 Platofrm_finish:
455 hibernation_ops->finish(); 491 hibernation_ops->finish();
492
493 device_power_up(PMSG_RESTORE);
494
495 Unlock:
496 device_pm_unlock();
497
456 Resume_devices: 498 Resume_devices:
457 entering_platform_hibernation = false; 499 entering_platform_hibernation = false;
458 device_resume(PMSG_RESTORE); 500 device_resume(PMSG_RESTORE);
459 resume_console(); 501 resume_console();
502
460 Close: 503 Close:
461 hibernation_ops->end(); 504 hibernation_ops->end();
505
462 return error; 506 return error;
463} 507}
464 508
@@ -595,6 +639,12 @@ static int software_resume(void)
595 unsigned int flags; 639 unsigned int flags;
596 640
597 /* 641 /*
642 * If the user said "noresume".. bail out early.
643 */
644 if (noresume)
645 return 0;
646
647 /*
598 * name_to_dev_t() below takes a sysfs buffer mutex when sysfs 648 * name_to_dev_t() below takes a sysfs buffer mutex when sysfs
599 * is configured into the kernel. Since the regular hibernate 649 * is configured into the kernel. Since the regular hibernate
600 * trigger path is via sysfs which takes a buffer mutex before 650 * trigger path is via sysfs which takes a buffer mutex before
@@ -610,6 +660,11 @@ static int software_resume(void)
610 mutex_unlock(&pm_mutex); 660 mutex_unlock(&pm_mutex);
611 return -ENOENT; 661 return -ENOENT;
612 } 662 }
663 /*
664 * Some device discovery might still be in progress; we need
665 * to wait for this to finish.
666 */
667 wait_for_device_probe();
613 swsusp_resume_device = name_to_dev_t(resume_file); 668 swsusp_resume_device = name_to_dev_t(resume_file);
614 pr_debug("PM: Resume from partition %s\n", resume_file); 669 pr_debug("PM: Resume from partition %s\n", resume_file);
615 } else { 670 } else {