PMSG_POWEROFF will be used for the PM core to allow differentiating between
an S4 or S5 shutdown sequence when re-using callbacks.

This event should not have wakeups enabled so update PMSG_NO_WAKEUP() to
match it as well.

Tested-by: Eric Naim <dn...@cachyos.org>
Signed-off-by: Mario Limonciello (AMD) <supe...@kernel.org>
---
v5:
 * Re-order and split
 * Add tags
v4:
 * 
https://lore.kernel.org/linux-pci/20250616175019.3471583-1-supe...@kernel.org/
---
 drivers/base/power/main.c    | 7 +++++++
 include/linux/pm.h           | 5 ++++-
 include/trace/events/power.h | 3 ++-
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index dbf5456cd891b..c59ab5286d9a5 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -99,6 +99,8 @@ static const char *pm_verb(int event)
                return "restore";
        case PM_EVENT_RECOVER:
                return "recover";
+       case PM_EVENT_POWEROFF:
+               return "poweroff";
        default:
                return "(unknown PM event)";
        }
@@ -369,6 +371,7 @@ static pm_callback_t pm_op(const struct dev_pm_ops *ops, 
pm_message_t state)
        case PM_EVENT_FREEZE:
        case PM_EVENT_QUIESCE:
                return ops->freeze;
+       case PM_EVENT_POWEROFF:
        case PM_EVENT_HIBERNATE:
                return ops->poweroff;
        case PM_EVENT_THAW:
@@ -403,6 +406,7 @@ static pm_callback_t pm_late_early_op(const struct 
dev_pm_ops *ops,
        case PM_EVENT_FREEZE:
        case PM_EVENT_QUIESCE:
                return ops->freeze_late;
+       case PM_EVENT_POWEROFF:
        case PM_EVENT_HIBERNATE:
                return ops->poweroff_late;
        case PM_EVENT_THAW:
@@ -437,6 +441,7 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops 
*ops, pm_message_t stat
        case PM_EVENT_FREEZE:
        case PM_EVENT_QUIESCE:
                return ops->freeze_noirq;
+       case PM_EVENT_POWEROFF:
        case PM_EVENT_HIBERNATE:
                return ops->poweroff_noirq;
        case PM_EVENT_THAW:
@@ -1370,6 +1375,8 @@ static pm_message_t resume_event(pm_message_t sleep_state)
                return PMSG_RECOVER;
        case PM_EVENT_HIBERNATE:
                return PMSG_RESTORE;
+       case PM_EVENT_POWEROFF:
+               return PMSG_ON;
        }
        return PMSG_ON;
 }
diff --git a/include/linux/pm.h b/include/linux/pm.h
index cc7b2dc28574c..892bd93f13dad 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -507,6 +507,7 @@ const struct dev_pm_ops name = { \
  * RECOVER     Creation of a hibernation image or restoration of the main
  *             memory contents from a hibernation image has failed, call
  *             ->thaw() and ->complete() for all devices.
+ * POWEROFF    System will poweroff, call ->poweroff() for all devices.
  *
  * The following PM_EVENT_ messages are defined for internal use by
  * kernel subsystems.  They are never issued by the PM core.
@@ -537,6 +538,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_POWEROFF      0x0800
 
 #define PM_EVENT_SLEEP         (PM_EVENT_SUSPEND | PM_EVENT_HIBERNATE)
 #define PM_EVENT_USER_SUSPEND  (PM_EVENT_USER | PM_EVENT_SUSPEND)
@@ -551,6 +553,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_POWEROFF  ((struct pm_message){ .event = PM_EVENT_POWEROFF, })
 #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, })
@@ -568,7 +571,7 @@ const struct dev_pm_ops name = { \
 
 #define PMSG_IS_AUTO(msg)      (((msg).event & PM_EVENT_AUTO) != 0)
 #define PMSG_NO_WAKEUP(msg)    (((msg).event & \
-                               (PM_EVENT_FREEZE | PM_EVENT_QUIESCE)) != 0)
+                               (PM_EVENT_FREEZE | PM_EVENT_QUIESCE | 
PM_EVENT_POWEROFF)) != 0)
 /*
  * Device run-time power management status.
  *
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index 82904291c2b81..370f8df2fdb4b 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -179,7 +179,8 @@ TRACE_EVENT(pstate_sample,
                { PM_EVENT_HIBERNATE, "hibernate" }, \
                { PM_EVENT_THAW, "thaw" }, \
                { PM_EVENT_RESTORE, "restore" }, \
-               { PM_EVENT_RECOVER, "recover" })
+               { PM_EVENT_RECOVER, "recover" }, \
+               { PM_EVENT_POWEROFF, "poweroff" })
 
 DEFINE_EVENT(cpu, cpu_frequency,
 
-- 
2.43.0

Reply via email to