Introduce and plumb PMSG_POWEROFF
Subsystems (7)
v9 cover Introduce and plumb PMSG_POWEROFF
I've been working on a series that uses the hibernate flows (S4) during shutdown (S5) [1], but it's a bit risky because it has changes all around the kernel. To mitigate risk Rafael suggested [2] to split the series into at least 3 parts across different kernel cycles.
Here is the first part, which just introduces a PMSG_POWEROFF event and uses it in any driver that manipulates PM events.
There are no functional changes for these changes and this series is intended for 6.19.
v8->v9:
* Reword commit messages (Bjorn)
* Apply on top of 6.18-rc2 kernel base
Mario Limonciello (AMD) (4):
PM: Introduce new PMSG_POWEROFF event
scsi: Add PM_EVENT_POWEROFF into suspend callbacks
usb: sl811-hcd: Add PM_EVENT_POWEROFF into suspend callbacks
USB: Pass PMSG_POWEROFF event to suspend_common()
drivers/base/power/main.c | 7 +++++++ drivers/scsi/mesh.c | 1 + drivers/scsi/stex.c | 1 + drivers/usb/core/hcd-pci.c | 11 ++++++++++- drivers/usb/host/sl811-hcd.c | 1 + include/linux/pm.h | 3 +++ include/trace/events/power.h | 3 ++- 7 files changed, 25 insertions(+), 2 deletions(-)
Signature · 1 line
2.43.0
PATCH v9 1/4 PM: Introduce new PMSG_POWEROFF event
PMSG_POWEROFF will be used for the PM core to allow differentiating between a hibernation or shutdown sequence when re-using callbacks for common code.
Hibernation is started by writing a hibernation method (such as 'platform' 'shutdown', or 'reboot') to use into /sys/power/disk and writing 'disk' to /sys/power/state.
Shutdown is initiated with the reboot() syscall with arguments on whether to halt the system or power it off.
---
v9:
* Add more detail to commit message (Bjorn)
v8:
* Break series into 3 parts
* Drop PMSG_NO_WAKEUP change
v7:
* Reword commit
v5:
* Re-order and split
* Add tags
v4:
* https://lore.kernel.org/linux-pci/[email protected]/
--- drivers/base/power/main.c | 7 +++++++ include/linux/pm.h | 3 +++ include/trace/events/power.h | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-)
drivers/base/power/main.c +7 -0
@@ -95,6 +95,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)" ; }
@@ -367,6 +369,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 :
@@ -401,6 +404,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 :
@@ -435,6 +439,7 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t statcase 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 :
@@ -1385,6 +1390,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 ; }
include/linux/pm.h +3 -0
@@ -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, })
include/trace/events/power.h +2 -1
@@ -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,
Signature · 1 line
2.43.0
Rafael J. Wysocki
maintainerRe: [PATCH v9 1/4] PM: Introduce new PMSG_POWEROFF event
Quoted 70 lines · Mario Limonciello (AMD)
PMSG_POWEROFFwill be used for the PM core to allow differentiating between a hibernation or shutdown sequence when re-using callbacks for common code.Hibernation is started by writing a hibernation method (such as 'platform' 'shutdown', or 'reboot') to use into
/sys/power/diskand writing 'disk' to/sys/power/state.Shutdown is initiated with the
reboot()syscall with arguments on whether to halt the system or power it off.Tested-by Eric Naim <[email protected]>Signed-off-by Mario Limonciello (AMD) <[email protected]>---
v9:
* Add more detail to commit message (Bjorn)
v8:
* Break series into 3 parts
* DropPMSG_NO_WAKEUPchange
v7:
* Reword commit
v5:
* Re-order and split
* Add tags
v4:
* https://lore.kernel.org/linux-pci/[email protected]/--- drivers/base/power/main.c | 7 +++++++ include/linux/pm.h | 3 +++ include/trace/events/power.h | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-)drivers/base/power/main.c +5
-0@@ -95,6 +95,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)" ; }@@ -367,6 +369,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 :@@ -401,6 +404,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 :@@ -435,6 +439,7 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t statcase 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 :
drivers/base/power/main.c static pm_message_t resume_event(pm_message_t sleep_state) · line 1394
Quoted 5 lines
drivers/base/power/main.c +2
-0@@ -1385,6 +1390,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 ;
I'm not sure if PMSG_ON is the right choice here (as stated elsewhere, the "poweroff" transition at the end of system shutdown cannot really be rolled back and this is all about what pm_message_t value to use for the rollback), but even so, this change is unnecessary because PMSG_ON is returned by default.
Quoted 3 lines
drivers/base/power/main.c +0
-0}return PMSG_ON ; }
PATCH v9 2/4 scsi: Add PM_EVENT_POWEROFF into suspend callbacks
In reply to Mario Limonciello (AMD)If the PM core uses hibernation callbacks for powering off the system, drivers will receive PM_EVENT_POWEROFF and should handle it the same as they previously handled PM_EVENT_HIBERNATE.
Support this case in the scsi driver. No functional changes.
---
v9:
* Reword commit (Bjorn)
v8:
* Break up series to 3 parts
* Pick up tag
v5:
* Re-order
v4:
* https://lore.kernel.org/linux-pci/[email protected]/
--- drivers/scsi/mesh.c | 1 + drivers/scsi/stex.c | 1 + 2 files changed, 2 insertions(+)
drivers/scsi/mesh.c +1 -0
@@ -1762,6 +1762,7 @@ static int mesh_suspend(struct macio_dev *mdev, pm_message_t mesg)case PM_EVENT_SUSPEND :case PM_EVENT_HIBERNATE :case PM_EVENT_FREEZE : +case PM_EVENT_POWEROFF :break ;default :return 0 ;
drivers/scsi/stex.c +1 -0
@@ -1965,6 +1965,7 @@ static int stex_choice_sleep_mic(struct st_hba *hba, pm_message_t state)case PM_EVENT_SUSPEND :return ST_S3 ;case PM_EVENT_HIBERNATE : +case PM_EVENT_POWEROFF : hba->msi_lock =0 ;return ST_S4 ;default :
Signature · 1 line
2.43.0
PATCH v9 3/4 usb: sl811-hcd: Add PM_EVENT_POWEROFF into suspend callbacks
In reply to Mario Limonciello (AMD)When the ACPI core uses hibernation callbacks for shutdown drivers will receive PM_EVENT_POWEROFF and should handle it the same as PM_EVENT_HIBERNATE would have been used.
---
v8:
* Break up series to 3 parts
v5:
* Re-order
* Add tags
v4:
* https://lore.kernel.org/linux-pci/[email protected]/
--- drivers/usb/host/sl811-hcd.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/host/sl811-hcd.c +1 -0
@@ -1748,6 +1748,7 @@ sl811h_suspend(struct platform_device *dev, pm_message_t state)break ;case PM_EVENT_SUSPEND :case PM_EVENT_HIBERNATE : +case PM_EVENT_POWEROFF :case PM_EVENT_PRETHAW :/* explicitly discard hw state */ port_power (sl811,0 );break ;
Signature · 1 line
2.43.0
PATCH v9 4/4 USB: Pass PMSG_POWEROFF event to suspend_common()
In reply to Mario Limonciello (AMD)suspend_common() passes a PM message indicating what type of event is occurring. PMSG_POWEROFF is intended to be used when hibernate callbacks were utilized for turning off the system.
Add a new callback hcd_pci_poweroff() which will determine if target state is power off and pass PMSG_POWEROFF as the message.
suspend_common() doesn't do any special handling with this case at the moment, so there are no functional changes in this patch.
---
v9:
* Reword commit message (Bjorn)
v8:
* Drop SYSTEM_HALT case
v7:
* Reword commit mesasge
v6:
* Fix LKP robot issue without CONFIG_PM_SLEEP
v5:
* New patch
v4:
* https://lore.kernel.org/linux-pci/[email protected]/
--- drivers/usb/core/hcd-pci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/usb/core/hcd-pci.c +10 -1
@@ -6,6 +6,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/pm.h> #include <linux/usb.h> #include <linux/usb/hcd.h>
@@ -531,6 +532,13 @@ static int hcd_pci_freeze(struct device *dev)return suspend_common (dev,PMSG_FREEZE ); } +static int hcd_pci_poweroff (struct device *dev) +{ +if (system_state ==SYSTEM_POWER_OFF ) +return suspend_common (dev,PMSG_POWEROFF ); +return suspend_common (dev,PMSG_SUSPEND ); +} +static int hcd_pci_suspend_noirq (struct device *dev) {struct pci_dev *pci_dev =to_pci_dev (dev);
@@ -602,6 +610,7 @@ static int hcd_pci_restore(struct device *dev)#define hcd_pci_suspend NULL#define hcd_pci_freeze NULL#define hcd_pci_suspend_noirq NULL +#define hcd_pci_poweroff NULL#define hcd_pci_poweroff_late NULL#define hcd_pci_resume_noirq NULL#define hcd_pci_resume NULL
@@ -639,7 +648,7 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = { .freeze_noirq = check_root_hub_suspended, .thaw_noirq = NULL, .thaw = hcd_pci_resume, - .poweroff = hcd_pci_suspend, + .poweroff = hcd_pci_poweroff, .poweroff_late = hcd_pci_poweroff_late, .poweroff_noirq = hcd_pci_suspend_noirq, .restore_noirq = hcd_pci_resume_noirq,
Signature · 1 line
2.43.0
Rafael J. Wysocki
maintainerRe: [PATCH v9 4/4] USB: Pass PMSG_POWEROFF event to suspend_common()
Quoted 65 lines · Mario Limonciello (AMD)
suspend_common()passes a PM message indicating what type of event is occurring.PMSG_POWEROFFis intended to be used when hibernate callbacks were utilized for turning off the system.Add a new callback
hcd_pci_poweroff()which will determine if target state is power off and passPMSG_POWEROFFas the message.
suspend_common()doesn't do any special handling with this case at the moment, so there are no functional changes in this patch.Signed-off-by Mario Limonciello (AMD) <[email protected]>---
v9:
* Reword commit message (Bjorn)
v8:
* DropSYSTEM_HALTcase
v7:
* Reword commit mesasge
v6:
* Fix LKP robot issue withoutCONFIG_PM_SLEEP
v5:
* New patch
v4:
* https://lore.kernel.org/linux-pci/[email protected]/--- drivers/usb/core/hcd-pci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)drivers/usb/core/hcd-pci.c +9
-0@@ -6,6 +6,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/pm.h> #include <linux/usb.h> #include <linux/usb/hcd.h> @@ -531,6 +532,13 @@ static int hcd_pci_freeze(struct device *dev)return suspend_common (dev,PMSG_FREEZE ); } +static int hcd_pci_poweroff (struct device *dev) +{ +if (system_state ==SYSTEM_POWER_OFF ) +return suspend_common (dev,PMSG_POWEROFF ); +return suspend_common (dev,PMSG_SUSPEND ); +} +static int hcd_pci_suspend_noirq (struct device *dev) {struct pci_dev *pci_dev =to_pci_dev (dev);@@ -602,6 +610,7 @@ static int hcd_pci_restore(struct device *dev)#define hcd_pci_suspend NULL#define hcd_pci_freeze NULL#define hcd_pci_suspend_noirq NULL +#define hcd_pci_poweroff NULL#define hcd_pci_poweroff_late NULL#define hcd_pci_resume_noirq NULL#define hcd_pci_resume NULL
drivers/usb/core/hcd-pci.c const struct dev_pm_ops usb_hcd_pci_pm_ops = {
Quoted 9 lines
drivers/usb/core/hcd-pci.c +1
-2@@ -639,7 +648,7 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = { .freeze_noirq = check_root_hub_suspended, .thaw_noirq = NULL, .thaw = hcd_pci_resume, - .poweroff = hcd_pci_suspend, + .poweroff = hcd_pci_poweroff, .poweroff_late = hcd_pci_poweroff_late, .poweroff_noirq = hcd_pci_suspend_noirq, .restore_noirq = hcd_pci_resume_noirq, --
I would defer this patch until you know what exactly suspend_common() will do for PMSG_POWEROFF because it may just be simpler to check system_state == SYSTEM_POWER_OFF in it internally.
Re: [PATCH v9 4/4] USB: Pass PMSG_POWEROFF event to suspend_common()
Quoted 72 lines · Rafael J. Wysocki
Quoted 70 lines · Mario Limonciello (AMD)
suspend_common()passes a PM message indicating what type of event is occurring.PMSG_POWEROFFis intended to be used when hibernate callbacks were utilized for turning off the system.Add a new callback
hcd_pci_poweroff()which will determine if target state is power off and passPMSG_POWEROFFas the message.
suspend_common()doesn't do any special handling with this case at the moment, so there are no functional changes in this patch.Signed-off-by Mario Limonciello (AMD) <[email protected]>---
v9:
* Reword commit message (Bjorn)
v8:
* DropSYSTEM_HALTcase
v7:
* Reword commit mesasge
v6:
* Fix LKP robot issue withoutCONFIG_PM_SLEEP
v5:
* New patch
v4:
* https://lore.kernel.org/linux-pci/[email protected]/--- drivers/usb/core/hcd-pci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)drivers/usb/core/hcd-pci.c +10
-1@@ -6,6 +6,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/pm.h> #include <linux/usb.h> #include <linux/usb/hcd.h> @@ -531,6 +532,13 @@ static int hcd_pci_freeze(struct device *dev)return suspend_common (dev,PMSG_FREEZE ); } +static int hcd_pci_poweroff (struct device *dev) +{ +if (system_state ==SYSTEM_POWER_OFF ) +return suspend_common (dev,PMSG_POWEROFF ); +return suspend_common (dev,PMSG_SUSPEND ); +} +static int hcd_pci_suspend_noirq (struct device *dev) {struct pci_dev *pci_dev =to_pci_dev (dev);@@ -602,6 +610,7 @@ static int hcd_pci_restore(struct device *dev)#define hcd_pci_suspend NULL#define hcd_pci_freeze NULL#define hcd_pci_suspend_noirq NULL +#define hcd_pci_poweroff NULL#define hcd_pci_poweroff_late NULL#define hcd_pci_resume_noirq NULL#define hcd_pci_resume NULL@@ -639,7 +648,7 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = { .freeze_noirq = check_root_hub_suspended, .thaw_noirq = NULL, .thaw = hcd_pci_resume, - .poweroff = hcd_pci_suspend, + .poweroff = hcd_pci_poweroff,
Quoted 8 lines
drivers/usb/core/hcd-pci.c const struct dev_pm_ops usb_hcd_pci_pm_ops = {
Quoted 4 lines
drivers/usb/core/hcd-pci.c +0
-1.poweroff_late = hcd_pci_poweroff_late, .poweroff_noirq = hcd_pci_suspend_noirq, .restore_noirq = hcd_pci_resume_noirq, --I would defer this patch until you know what exactly
suspend_common()will do forPMSG_POWEROFFbecause it may just be simpler to checksystem_state==SYSTEM_POWER_OFFin it internally.
OK - in that case would you just take the first 3 for 6.19?
Rafael J. Wysocki
maintainerRe: [PATCH v9 4/4] USB: Pass PMSG_POWEROFF event to suspend_common()
Quoted 85 lines · Mario Limonciello (AMD) (kernel.org)
Quoted 72 lines · Rafael J. Wysocki
Quoted 70 lines · Mario Limonciello (AMD)
suspend_common()passes a PM message indicating what type of event is occurring.PMSG_POWEROFFis intended to be used when hibernate callbacks were utilized for turning off the system.Add a new callback
hcd_pci_poweroff()which will determine if target state is power off and passPMSG_POWEROFFas the message.
suspend_common()doesn't do any special handling with this case at the moment, so there are no functional changes in this patch.Signed-off-by Mario Limonciello (AMD) <[email protected]>---
v9:
* Reword commit message (Bjorn)
v8:
* DropSYSTEM_HALTcase
v7:
* Reword commit mesasge
v6:
* Fix LKP robot issue withoutCONFIG_PM_SLEEP
v5:
* New patch
v4:
* https://lore.kernel.org/linux-pci/[email protected]/--- drivers/usb/core/hcd-pci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)drivers/usb/core/hcd-pci.c +10
-1@@ -6,6 +6,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/pm.h> #include <linux/usb.h> #include <linux/usb/hcd.h> @@ -531,6 +532,13 @@ static int hcd_pci_freeze(struct device *dev)return suspend_common (dev,PMSG_FREEZE ); } +static int hcd_pci_poweroff (struct device *dev) +{ +if (system_state ==SYSTEM_POWER_OFF ) +return suspend_common (dev,PMSG_POWEROFF ); +return suspend_common (dev,PMSG_SUSPEND ); +} +static int hcd_pci_suspend_noirq (struct device *dev) {struct pci_dev *pci_dev =to_pci_dev (dev);@@ -602,6 +610,7 @@ static int hcd_pci_restore(struct device *dev)#define hcd_pci_suspend NULL#define hcd_pci_freeze NULL#define hcd_pci_suspend_noirq NULL +#define hcd_pci_poweroff NULL#define hcd_pci_poweroff_late NULL#define hcd_pci_resume_noirq NULL#define hcd_pci_resume NULL@@ -639,7 +648,7 @@ const struct dev_pm_ops usb_hcd_pci_pm_ops = { .freeze_noirq = check_root_hub_suspended, .thaw_noirq = NULL, .thaw = hcd_pci_resume, - .poweroff = hcd_pci_suspend, + .poweroff = hcd_pci_poweroff,Quoted 8 lines
drivers/usb/core/hcd-pci.c const struct dev_pm_ops usb_hcd_pci_pm_ops = {
Quoted 4 lines
drivers/usb/core/hcd-pci.c +0
-1.poweroff_late = hcd_pci_poweroff_late, .poweroff_noirq = hcd_pci_suspend_noirq, .restore_noirq = hcd_pci_resume_noirq, --I would defer this patch until you know what exactly
suspend_common()will do forPMSG_POWEROFFbecause it may just be simpler to checksystem_state==SYSTEM_POWER_OFFin it internally.
Quoted 1 line
OK - in that case would you just take the first 3 for 6.19?
I still need to go through them once again, but overall that's the plan.