Linux ACPI
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM <linux-pm@vger.kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	Linux ACPI <linux-acpi@vger.kernel.org>,
	Linux PCI <linux-pci@vger.kernel.org>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	Mika Westerberg <mika.westerberg@linux.intel.com>
Subject: [PATCH v2 7/9] PM: sleep: Add strict_midlayer flag to struct dev_pm_info
Date: Thu, 26 Jun 2025 20:09:19 +0200	[thread overview]
Message-ID: <3311786.5fSG56mABF@rjwysocki.net> (raw)
In-Reply-To: <5015172.GXAFRqVoOG@rjwysocki.net>

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Add a new flag, called strict_midlayer, to struct dev_pm_info, along
with a helper function for changing its value, to allow middle layer
code that provides proper callbacks for device suspend/resume during
system-wide PM transitions to let pm_runtime_force_suspend() and
and pm_runtime_force_resume() know that they should only invoke runtime
PM callbacks coming from the device's driver.

Namely, if this flag is set, pm_runtime_force_suspend() and
and pm_runtime_force_resume() will invoke runtime PM callbacks
provided by the device's driver directly with the assumption that
they have been called via a middle layer callback for device suspend
or resume, respectively.

For instance, acpi_general_pm_domain provides specific
callback functions for system suspend, acpi_subsys_suspend(),
acpi_subsys_suspend_late() and acpi_subsys_suspend_noirq(), and
it does not expect its runtime suspend callback function,
acpi_subsys_runtime_suspend(), to be invoked at any point during
system suspend. In particular, it does not expect that function
to be called from within any of the system suspend callback functions
mentioned above which would happen if a device driver collaborating
with acpi_general_pm_domain used pm_runtime_force_suspend() as its
callback function for any system suspend phase later than "prepare".

The new flag allows this expectation of acpi_general_pm_domain to
be formally expressed, which is going to be done subsequently.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

v1 -> v2:
   * Rename dev_pm_strict_midlayer() to dev_pm_set_strict_midlayer().
   * Add dev_pm_strict_midlayer_is_set() and use it in get_callback()
     because pm_runtime_force_suspend() can be used in driver remove
     callbacks and so it needs to work with CONFIG_PM_SLEEP unset.

---
 drivers/base/power/runtime.c |   21 +++++++++++++++++++--
 include/linux/device.h       |   16 ++++++++++++++++
 include/linux/pm.h           |    1 +
 3 files changed, 36 insertions(+), 2 deletions(-)

--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1958,6 +1958,23 @@
 	pm_request_idle(link->supplier);
 }
 
+static pm_callback_t get_callback(struct device *dev, size_t cb_offset)
+{
+	/*
+	 * Setting power.strict_midlayer means that the middle layer
+	 * code does not want its runtime PM callbacks to be invoked via
+	 * pm_runtime_force_suspend() and pm_runtime_force_resume(), so
+	 * return a direct pointer to the driver callback in that case.
+	 */
+	if (dev_pm_strict_midlayer_is_set(dev))
+		return __rpm_get_driver_callback(dev, cb_offset);
+
+	return __rpm_get_callback(dev, cb_offset);
+}
+
+#define GET_CALLBACK(dev, callback) \
+		get_callback(dev, offsetof(struct dev_pm_ops, callback))
+
 /**
  * pm_runtime_force_suspend - Force a device into suspend state if needed.
  * @dev: Device to suspend.
@@ -1984,7 +2001,7 @@
 	if (pm_runtime_status_suspended(dev) || dev->power.needs_force_resume)
 		return 0;
 
-	callback = RPM_GET_CALLBACK(dev, runtime_suspend);
+	callback = GET_CALLBACK(dev, runtime_suspend);
 
 	dev_pm_enable_wake_irq_check(dev, true);
 	ret = callback ? callback(dev) : 0;
@@ -2046,7 +2063,7 @@
 	    pm_runtime_status_suspended(dev)))
 		goto out;
 
-	callback = RPM_GET_CALLBACK(dev, runtime_resume);
+	callback = GET_CALLBACK(dev, runtime_resume);
 
 	dev_pm_disable_wake_irq_check(dev, false);
 	ret = callback ? callback(dev) : 0;
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -879,6 +879,22 @@
 #endif
 }
 
+static inline void dev_pm_set_strict_midlayer(struct device *dev, bool val)
+{
+#ifdef CONFIG_PM_SLEEP
+	dev->power.strict_midlayer = val;
+#endif
+}
+
+static inline bool dev_pm_strict_midlayer_is_set(struct device *dev)
+{
+#ifdef CONFIG_PM_SLEEP
+	return dev->power.strict_midlayer;
+#else
+	return false;
+#endif
+}
+
 static inline void device_lock(struct device *dev)
 {
 	mutex_lock(&dev->mutex);
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -683,6 +683,7 @@
 	bool			smart_suspend:1;	/* Owned by the PM core */
 	bool			must_resume:1;		/* Owned by the PM core */
 	bool			may_skip_resume:1;	/* Set by subsystems */
+	bool			strict_midlayer:1;
 #else
 	bool			should_wakeup:1;
 #endif




  parent reply	other threads:[~2025-06-26 18:15 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-26 17:56 [PATCH v2 0/9] PM: Reconcile different driver options for runtime PM integration with system sleep Rafael J. Wysocki
2025-06-26 17:57 ` [PATCH v2 1/9] PM: Use true/false as power.needs_force_resume values Rafael J. Wysocki
2025-06-26 17:58 ` [PATCH v2 2/9] PM: runtime: Clear power.needs_force_resume in pm_runtime_reinit() Rafael J. Wysocki
2025-06-26 18:01 ` [PATCH v2 3/9] PM: Move two sleep-related functions under CONFIG_PM_SLEEP Rafael J. Wysocki
2025-06-26 18:03 ` [PATCH v2 4/9] PM: Check power.needs_force_resume in pm_runtime_force_suspend() Rafael J. Wysocki
2025-06-27 10:52   ` Rafael J. Wysocki
2025-06-27 11:14     ` Rafael J. Wysocki
2025-06-26 18:04 ` [PATCH v2 5/9] PM: Make pm_runtime_force_resume() work with DPM_FLAG_SMART_SUSPEND Rafael J. Wysocki
2025-06-26 18:06 ` [PATCH v2 6/9] PM: runtime: Introduce __rpm_get_driver_callback() Rafael J. Wysocki
2025-06-26 18:09 ` Rafael J. Wysocki [this message]
2025-06-26 18:12 ` [PATCH v2 8/9] ACPI: PM: Set/clear power.strict_midlayer in prepare/complete Rafael J. Wysocki
2025-06-26 18:15 ` [PATCH v2 9/9] PCI: PM: Set power.strict_midlayer in pci_pm_init() Rafael J. Wysocki
2025-06-26 20:59   ` Bjorn Helgaas
2025-06-27 10:11     ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3311786.5fSG56mABF@rjwysocki.net \
    --to=rjw@rjwysocki.net \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox