|
@@ -278,21 +278,50 @@ int hibernation_platform_enter(void)
|
|
{
|
|
{
|
|
int error;
|
|
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;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -309,14 +338,14 @@ static void power_down(void)
|
|
case HIBERNATION_TEST:
|
|
case HIBERNATION_TEST:
|
|
case HIBERNATION_TESTPROC:
|
|
case HIBERNATION_TESTPROC:
|
|
break;
|
|
break;
|
|
- case HIBERNATION_SHUTDOWN:
|
|
|
|
- kernel_power_off();
|
|
|
|
- break;
|
|
|
|
case HIBERNATION_REBOOT:
|
|
case HIBERNATION_REBOOT:
|
|
kernel_restart(NULL);
|
|
kernel_restart(NULL);
|
|
break;
|
|
break;
|
|
case HIBERNATION_PLATFORM:
|
|
case HIBERNATION_PLATFORM:
|
|
hibernation_platform_enter();
|
|
hibernation_platform_enter();
|
|
|
|
+ case HIBERNATION_SHUTDOWN:
|
|
|
|
+ kernel_power_off();
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
kernel_halt();
|
|
kernel_halt();
|
|
/*
|
|
/*
|