]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/power/disk.c
Merge branch 'bzip2-lzma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-omap-h63xx.git] / kernel / power / disk.c
index 320bb0949bdf97e0a62356f2e54b6dbb2392d9ee..5f21ab2bbcdf0cf5c85985f8612f923ad6ad3d03 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/freezer.h>
+#include <asm/suspend.h>
 
 #include "power.h"
 
@@ -228,13 +229,22 @@ static int create_image(int platform_mode)
                goto Unlock;
        }
 
+       error = platform_pre_snapshot(platform_mode);
+       if (error || hibernation_test(TEST_PLATFORM))
+               goto Platform_finish;
+
+       error = disable_nonboot_cpus();
+       if (error || hibernation_test(TEST_CPUS)
+           || hibernation_testmode(HIBERNATION_TEST))
+               goto Enable_cpus;
+
        local_irq_disable();
 
        sysdev_suspend(PMSG_FREEZE);
        if (error) {
                printk(KERN_ERR "PM: Some devices failed to power down, "
                        "aborting hibernation\n");
-               goto Power_up_devices;
+               goto Enable_irqs;
        }
 
        if (hibernation_test(TEST_CORE))
@@ -250,15 +260,22 @@ static int create_image(int platform_mode)
        restore_processor_state();
        if (!in_suspend)
                platform_leave(platform_mode);
+
  Power_up:
        sysdev_resume();
        /* NOTE:  device_power_up() is just a resume() for devices
         * that suspended with irqs off ... no overall powerup.
         */
 
Power_up_devices:
Enable_irqs:
        local_irq_enable();
 
+ Enable_cpus:
+       enable_nonboot_cpus();
+
+ Platform_finish:
+       platform_finish(platform_mode);
+
        device_power_up(in_suspend ?
                (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
 
@@ -272,7 +289,7 @@ static int create_image(int platform_mode)
  *     hibernation_snapshot - quiesce devices and create the hibernation
  *     snapshot image.
  *     @platform_mode - if set, use the platform driver, if available, to
- *                      prepare the platform frimware for the power transition.
+ *                      prepare the platform firmware for the power transition.
  *
  *     Must be called with pm_mutex held
  */
@@ -298,25 +315,9 @@ int hibernation_snapshot(int platform_mode)
        if (hibernation_test(TEST_DEVICES))
                goto Recover_platform;
 
-       error = platform_pre_snapshot(platform_mode);
-       if (error || hibernation_test(TEST_PLATFORM))
-               goto Finish;
-
-       error = disable_nonboot_cpus();
-       if (!error) {
-               if (hibernation_test(TEST_CPUS))
-                       goto Enable_cpus;
-
-               if (hibernation_testmode(HIBERNATION_TEST))
-                       goto Enable_cpus;
+       error = create_image(platform_mode);
+       /* Control returns here after successful restore */
 
-               error = create_image(platform_mode);
-               /* Control returns here after successful restore */
-       }
- Enable_cpus:
-       enable_nonboot_cpus();
- Finish:
-       platform_finish(platform_mode);
  Resume_devices:
        device_resume(in_suspend ?
                (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
@@ -338,7 +339,7 @@ int hibernation_snapshot(int platform_mode)
  *     kernel.
  */
 
-static int resume_target_kernel(void)
+static int resume_target_kernel(bool platform_mode)
 {
        int error;
 
@@ -351,9 +352,20 @@ static int resume_target_kernel(void)
                goto Unlock;
        }
 
+       error = platform_pre_restore(platform_mode);
+       if (error)
+               goto Cleanup;
+
+       error = disable_nonboot_cpus();
+       if (error)
+               goto Enable_cpus;
+
        local_irq_disable();
 
-       sysdev_suspend(PMSG_QUIESCE);
+       error = sysdev_suspend(PMSG_QUIESCE);
+       if (error)
+               goto Enable_irqs;
+
        /* We'll ignore saved state, but this gets preempt count (etc) right */
        save_processor_state();
        error = restore_highmem();
@@ -379,8 +391,15 @@ static int resume_target_kernel(void)
 
        sysdev_resume();
 
+ Enable_irqs:
        local_irq_enable();
 
+ Enable_cpus:
+       enable_nonboot_cpus();
+
+ Cleanup:
+       platform_restore_cleanup(platform_mode);
+
        device_power_up(PMSG_RECOVER);
 
  Unlock:
@@ -393,7 +412,7 @@ static int resume_target_kernel(void)
  *     hibernation_restore - quiesce devices and restore the hibernation
  *     snapshot image.  If successful, control returns in hibernation_snaphot()
  *     @platform_mode - if set, use the platform driver, if available, to
- *                      prepare the platform frimware for the transition.
+ *                      prepare the platform firmware for the transition.
  *
  *     Must be called with pm_mutex held
  */
@@ -405,19 +424,10 @@ int hibernation_restore(int platform_mode)
        pm_prepare_console();
        suspend_console();
        error = device_suspend(PMSG_QUIESCE);
-       if (error)
-               goto Finish;
-
-       error = platform_pre_restore(platform_mode);
        if (!error) {
-               error = disable_nonboot_cpus();
-               if (!error)
-                       error = resume_target_kernel();
-               enable_nonboot_cpus();
+               error = resume_target_kernel(platform_mode);
+               device_resume(PMSG_RECOVER);
        }
-       platform_restore_cleanup(platform_mode);
-       device_resume(PMSG_RECOVER);
- Finish:
        resume_console();
        pm_restore_console();
        return error;
@@ -453,34 +463,38 @@ int hibernation_platform_enter(void)
                goto Resume_devices;
        }
 
+       device_pm_lock();
+
+       error = device_power_down(PMSG_HIBERNATE);
+       if (error)
+               goto Unlock;
+
        error = hibernation_ops->prepare();
        if (error)
-               goto Resume_devices;
+               goto Platofrm_finish;
 
        error = disable_nonboot_cpus();
        if (error)
-               goto Finish;
-
-       device_pm_lock();
-
-       error = device_power_down(PMSG_HIBERNATE);
-       if (!error) {
-               local_irq_disable();
-               sysdev_suspend(PMSG_HIBERNATE);
-               hibernation_ops->enter();
-               /* We should never get here */
-               while (1);
-       }
+               goto Platofrm_finish;
 
-       device_pm_unlock();
+       local_irq_disable();
+       sysdev_suspend(PMSG_HIBERNATE);
+       hibernation_ops->enter();
+       /* We should never get here */
+       while (1);
 
        /*
         * We don't need to reenable the nonboot CPUs or resume consoles, since
         * the system is going to be halted anyway.
         */
Finish:
Platofrm_finish:
        hibernation_ops->finish();
 
+       device_power_up(PMSG_RESTORE);
+
+ Unlock:
+       device_pm_unlock();
+
  Resume_devices:
        entering_platform_hibernation = false;
        device_resume(PMSG_RESTORE);