@@ -363,6 +363,8 @@ static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state)
case PM_EVENT_RESTORE:
return ops->restore;
#endif /* CONFIG_HIBERNATE_CALLBACKS */
+ case PM_EVENT_SHUTDOWN:
+ return ops->poweroff;
}
return NULL;
@@ -397,6 +399,8 @@ static pm_callback_t pm_late_early_op(const struct dev_pm_ops *ops,
case PM_EVENT_RESTORE:
return ops->restore_early;
#endif /* CONFIG_HIBERNATE_CALLBACKS */
+ case PM_EVENT_SHUTDOWN:
+ return ops->poweroff_late;
}
return NULL;
@@ -431,6 +435,8 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t stat
case PM_EVENT_RESTORE:
return ops->restore_noirq;
#endif /* CONFIG_HIBERNATE_CALLBACKS */
+ case PM_EVENT_SHUTDOWN:
+ return ops->poweroff_noirq;
}
return NULL;
@@ -490,6 +490,9 @@ const struct dev_pm_ops name = { \
* HIBERNATE Hibernation image has been saved, call ->prepare() and
* ->poweroff() for all devices.
*
+ * SHUTDOWN System is going to shut down, call ->prepare() and ->poweroff()
+ * for all devices.
+ *
* QUIESCE Contents of main memory are going to be restored from a (loaded)
* hibernation image, call ->prepare() and ->freeze() for all
* devices.
@@ -536,6 +539,7 @@ const struct dev_pm_ops name = { \
#define PM_EVENT_USER 0x0100
#define PM_EVENT_REMOTE 0x0200
#define PM_EVENT_AUTO 0x0400
+#define PM_EVENT_SHUTDOWN 0x0800
#define PM_EVENT_SLEEP (PM_EVENT_SUSPEND | PM_EVENT_HIBERNATE)
#define PM_EVENT_USER_SUSPEND (PM_EVENT_USER | PM_EVENT_SUSPEND)
@@ -550,6 +554,7 @@ const struct dev_pm_ops name = { \
#define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, })
#define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, })
#define PMSG_HIBERNATE ((struct pm_message){ .event = PM_EVENT_HIBERNATE, })
+#define PMSG_SHUTDOWN ((struct pm_message){ .event = PM_EVENT_SHUTDOWN, })
#define PMSG_RESUME ((struct pm_message){ .event = PM_EVENT_RESUME, })
#define PMSG_THAW ((struct pm_message){ .event = PM_EVENT_THAW, })
#define PMSG_RESTORE ((struct pm_message){ .event = PM_EVENT_RESTORE, })
@@ -13,6 +13,7 @@
#include <linux/kexec.h>
#include <linux/kmod.h>
#include <linux/kmsg_dump.h>
+#include <linux/pm.h>
#include <linux/reboot.h>
#include <linux/suspend.h>
#include <linux/syscalls.h>
@@ -305,7 +306,12 @@ static void kernel_shutdown_prepare(enum system_states state)
(state == SYSTEM_HALT) ? SYS_HALT : SYS_POWER_OFF, NULL);
system_state = state;
usermodehelper_disable();
+#ifdef CONFIG_PM_SLEEP
+ dpm_suspend_start(PMSG_SHUTDOWN);
+ dpm_suspend_end(PMSG_SHUTDOWN);
+#else
device_shutdown();
+#endif
}
/**
* kernel_halt - halt the system