[PATCH v4 2/4] PM: hibernate: add pm_hibernation_snapshot_done() helper

Haowen Tu <[email protected]>
Newsgroups org.kernel.vger.linux-pm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-media,org.kernel.vger.linux-usb
Message-ID <ac2ab0e03a93ef9b92b556d09cbcec58dcb73c87.1785226280.git.tuhaowen@uniontech.com>
Some subsystem resume callbacks do not receive the PM event and
therefore cannot distinguish the PMSG_THAW phase after snapshot creation
from the PMSG_RESTORE phase.

Export pm_hibernation_snapshot_done() so a driver can query whether the
hibernation snapshot has been created and is still available.  The helper
only exposes the PM state; callers remain responsible for ensuring that
any device-specific behavior is safe, including subsequent poweroff or
shutdown handling.

The helper returns !!in_suspend.  This variable is set before
swsusp_arch_suspend(), cleared before the snapshot memory is released,
and marked __nosavedata, so it remains clear on the restore path.

Acked-by: Rafael J. Wysocki (Intel) <[email protected]>
Signed-off-by: Haowen Tu <[email protected]>
---
 include/linux/suspend.h  |  2 ++
 kernel/power/hibernate.c | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index b02876f1ae38..2cebbec3e2f7 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -393,6 +393,7 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
 extern int hibernate(void);
 extern bool system_entering_hibernation(void);
 extern bool hibernation_available(void);
+bool pm_hibernation_snapshot_done(void);
 asmlinkage int swsusp_save(void);
 extern struct pbe *restore_pblist;
 int pfn_is_nosave(unsigned long pfn);
@@ -412,6 +413,7 @@ static inline void hibernation_set_ops(const struct platform_hibernation_ops *op
 static inline int hibernate(void) { return -ENOSYS; }
 static inline bool system_entering_hibernation(void) { return false; }
 static inline bool hibernation_available(void) { return false; }
+static inline bool pm_hibernation_snapshot_done(void) { return false; }
 
 static inline int hibernate_quiet_exec(int (*func)(void *data), void *data) {
 	return -ENOTSUPP;
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 6d3e637c5a02..045d29f55011 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -113,6 +113,18 @@ bool hibernation_available(void)
 		!secretmem_active() && !cxl_mem_active();
 }
 
+/**
+ * pm_hibernation_snapshot_done - check if a hibernation snapshot is available
+ *
+ * Return: %true if a hibernation snapshot has been taken and has not been
+ *         released yet.
+ */
+bool pm_hibernation_snapshot_done(void)
+{
+	return !!in_suspend;
+}
+EXPORT_SYMBOL_GPL(pm_hibernation_snapshot_done);
+
 /**
  * hibernation_set_ops - Set the global hibernate operations.
  * @ops: Hibernation operations to use in subsequent hibernation transitions.
-- 
2.20.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.