{
        int error;
 
-       if (hibernation_ops) {
-               kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
-               /*
-                * We have cancelled the power transition by running
-                * hibernation_ops->finish() before saving the image, so we
-                * should let the firmware know that we're going to enter the
-                * sleep state after all
-                */
-               error = hibernation_ops->prepare();
-               sysdev_shutdown();
-               if (!error)
-                       error = hibernation_ops->enter();
-       } else {
-               error = -ENOSYS;
+       if (!hibernation_ops)
+               return -ENOSYS;
+
+       /*
+        * We have cancelled the power transition by running
+        * hibernation_ops->finish() before saving the image, so we should let
+        * the firmware know that we're going to enter the sleep state after all
+        */
+       error = hibernation_ops->start();
+       if (error)
+               return error;
+
+       suspend_console();
+       error = device_suspend(PMSG_SUSPEND);
+       if (error)
+               goto Resume_console;
+
+       error = hibernation_ops->prepare();
+       if (error)
+               goto Resume_devices;
+
+       error = disable_nonboot_cpus();
+       if (error)
+               goto Finish;
+
+       local_irq_disable();
+       error = device_power_down(PMSG_SUSPEND);
+       if (!error) {
+               hibernation_ops->enter();
+               /* We should never get here */
+               while (1);
        }
+       local_irq_enable();
+
+       /*
+        * We don't need to reenable the nonboot CPUs or resume consoles, since
+        * the system is going to be halted anyway.
+        */
+ Finish:
+       hibernation_ops->finish();
+ Resume_devices:
+       device_resume();
+ Resume_console:
+       resume_console();
        return error;
 }
 
        case HIBERNATION_TEST:
        case HIBERNATION_TESTPROC:
                break;
-       case HIBERNATION_SHUTDOWN:
-               kernel_power_off();
-               break;
        case HIBERNATION_REBOOT:
                kernel_restart(NULL);
                break;
        case HIBERNATION_PLATFORM:
                hibernation_platform_enter();
+       case HIBERNATION_SHUTDOWN:
+               kernel_power_off();
+               break;
        }
        kernel_halt();
        /*