mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux PM <linux-pm@vger.kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>,
	Alan Stern <stern@rowland.harvard.edu>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Linux ACPI <linux-acpi@vger.kernel.org>,
	Linux PCI <linux-pci@vger.kernel.org>,
	Linux Documentation <linux-doc@vger.kernel.org>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Kevin Hilman <khilman@kernel.org>
Subject: [PATCH v2 1/6] PM / core: Add LEAVE_SUSPENDED driver flag
Date: Wed, 08 Nov 2017 14:25:35 +0100	[thread overview]
Message-ID: <2932219.eEdIVn6WWf@aspire.rjw.lan> (raw)
In-Reply-To: <6330680.LdxjlP4uri@aspire.rjw.lan>

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

Define and document a new driver flag, DPM_FLAG_LEAVE_SUSPENDED, to
instruct the PM core and middle-layer (bus type, PM domain, etc.)
code that it is desirable to leave the device in runtime suspend
after system-wide transitions to the working state (for example,
the device may be slow to resume and it may be better to avoid
resuming it right away).

Generally, the middle-layer code involved in the handling of the
device is expected to indicate to the PM core whether or not the
device may be left in suspend with the help of the device's
power.may_skip_resume status bit.  That has to happen in the "noirq"
phase of the preceding system suspend (or analogous) transition.
The middle layer is then responsible for handling the device as
appropriate in its "noirq" resume callback which is executed
regardless of whether or not the device may be left suspended, but
the other resume callbacks (except for ->complete) will be skipped
automatically by the core if the device really can be left in
suspend.

The additional power.must_resume status bit introduced for the
implementation of this mechanisn is used internally by the PM core
to track the requirement to resume the device (which may depend on
its children etc).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/driver-api/pm/devices.rst |   24 ++++++++++-
 drivers/base/power/main.c               |   65 +++++++++++++++++++++++++++++---
 include/linux/pm.h                      |   14 +++++-
 3 files changed, 93 insertions(+), 10 deletions(-)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -559,6 +559,7 @@ struct pm_subsys_data {
  * NEVER_SKIP: Do not skip system suspend/resume callbacks for the device.
  * SMART_PREPARE: Check the return value of the driver's ->prepare callback.
  * SMART_SUSPEND: No need to resume the device from runtime suspend.
+ * LEAVE_SUSPENDED: Avoid resuming the device during system resume if possible.
  *
  * Setting SMART_PREPARE instructs bus types and PM domains which may want
  * system suspend/resume callbacks to be skipped for the device to return 0 from
@@ -572,10 +573,14 @@ struct pm_subsys_data {
  * necessary from the driver's perspective.  It also may cause them to skip
  * invocations of the ->suspend_late and ->suspend_noirq callbacks provided by
  * the driver if they decide to leave the device in runtime suspend.
+ *
+ * Setting LEAVE_SUSPENDED informs the PM core and middle-layer code that the
+ * driver prefers the device to be left in runtime suspend after system resume.
  */
-#define DPM_FLAG_NEVER_SKIP	BIT(0)
-#define DPM_FLAG_SMART_PREPARE	BIT(1)
-#define DPM_FLAG_SMART_SUSPEND	BIT(2)
+#define DPM_FLAG_NEVER_SKIP		BIT(0)
+#define DPM_FLAG_SMART_PREPARE		BIT(1)
+#define DPM_FLAG_SMART_SUSPEND		BIT(2)
+#define DPM_FLAG_LEAVE_SUSPENDED	BIT(3)
 
 struct dev_pm_info {
 	pm_message_t		power_state;
@@ -597,6 +602,8 @@ struct dev_pm_info {
 	bool			wakeup_path:1;
 	bool			syscore:1;
 	bool			no_pm_callbacks:1;	/* Owned by the PM core */
+	unsigned int		must_resume:1;	/* Owned by the PM core */
+	unsigned int		may_skip_resume:1;	/* Set by subsystems */
 #else
 	unsigned int		should_wakeup:1;
 #endif
@@ -765,6 +772,7 @@ extern int pm_generic_poweroff_late(stru
 extern int pm_generic_poweroff(struct device *dev);
 extern void pm_generic_complete(struct device *dev);
 
+extern bool dev_pm_may_skip_resume(struct device *dev);
 extern bool dev_pm_smart_suspend_and_suspended(struct device *dev);
 
 #else /* !CONFIG_PM_SLEEP */
Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -528,6 +528,18 @@ static void dpm_watchdog_clear(struct dp
 /*------------------------- Resume routines -------------------------*/
 
 /**
+ * dev_pm_may_skip_resume - System-wide device resume optimization check.
+ * @dev: Target device.
+ *
+ * Checks whether or not the device may be left in suspend after a system-wide
+ * transition to the working state.
+ */
+bool dev_pm_may_skip_resume(struct device *dev)
+{
+	return !dev->power.must_resume && pm_transition.event != PM_EVENT_RESTORE;
+}
+
+/**
  * device_resume_noirq - Execute a "noirq resume" callback for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
@@ -575,6 +587,12 @@ static int device_resume_noirq(struct de
 	error = dpm_run_callback(callback, dev, state, info);
 	dev->power.is_noirq_suspended = false;
 
+	if (dev_pm_may_skip_resume(dev)) {
+		pm_runtime_set_suspended(dev);
+		dev->power.is_late_suspended = false;
+		dev->power.is_suspended = false;
+	}
+
  Out:
 	complete_all(&dev->power.completion);
 	TRACE_RESUME(error);
@@ -1076,6 +1094,22 @@ static pm_message_t resume_event(pm_mess
 	return PMSG_ON;
 }
 
+static void dpm_superior_set_must_resume(struct device *dev)
+{
+	struct device_link *link;
+	int idx;
+
+	if (dev->parent)
+		dev->parent->power.must_resume = true;
+
+	idx = device_links_read_lock();
+
+	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node)
+		link->supplier->power.must_resume = true;
+
+	device_links_read_unlock(idx);
+}
+
 /**
  * __device_suspend_noirq - Execute a "noirq suspend" callback for given device.
  * @dev: Device to handle.
@@ -1127,10 +1161,27 @@ static int __device_suspend_noirq(struct
 	}
 
 	error = dpm_run_callback(callback, dev, state, info);
-	if (!error)
-		dev->power.is_noirq_suspended = true;
-	else
+	if (error) {
 		async_error = error;
+		goto Complete;
+	}
+
+	dev->power.is_noirq_suspended = true;
+
+	if (dev_pm_test_driver_flags(dev, DPM_FLAG_LEAVE_SUSPENDED)) {
+		/*
+		 * The only safe strategy here is to require that if the device
+		 * may not be left in suspend, resume callbacks must be invoked
+		 * for it.
+		 */
+		dev->power.must_resume = dev->power.must_resume ||
+					!dev->power.may_skip_resume;
+	} else {
+		dev->power.must_resume = true;
+	}
+
+	if (dev->power.must_resume)
+		dpm_superior_set_must_resume(dev);
 
 Complete:
 	complete_all(&dev->power.completion);
@@ -1487,6 +1538,9 @@ static int __device_suspend(struct devic
 		dev->power.direct_complete = false;
 	}
 
+	dev->power.may_skip_resume = false;
+	dev->power.must_resume = false;
+
 	dpm_watchdog_set(&wd, dev);
 	device_lock(dev);
 
@@ -1652,8 +1706,9 @@ static int device_prepare(struct device
 	if (dev->power.syscore)
 		return 0;
 
-	WARN_ON(dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND) &&
-		!pm_runtime_enabled(dev));
+	WARN_ON(!pm_runtime_enabled(dev) &&
+		dev_pm_test_driver_flags(dev, DPM_FLAG_SMART_SUSPEND |
+					      DPM_FLAG_LEAVE_SUSPENDED));
 
 	/*
 	 * If a device's parent goes into runtime suspend at the wrong time,
Index: linux-pm/Documentation/driver-api/pm/devices.rst
===================================================================
--- linux-pm.orig/Documentation/driver-api/pm/devices.rst
+++ linux-pm/Documentation/driver-api/pm/devices.rst
@@ -788,6 +788,26 @@ must reflect the "active" status for run
 
 During system-wide resume from a sleep state it's easiest to put devices into
 the full-power state, as explained in :file:`Documentation/power/runtime_pm.txt`.
-Refer to that document for more information regarding this particular issue as
+[Refer to that document for more information regarding this particular issue as
 well as for information on the device runtime power management framework in
-general.
+general.]
+
+However, it may be desirable to leave some devices in runtime suspend after
+system transitions to the working state and device drivers can use the
+``DPM_FLAG_LEAVE_SUSPENDED`` flag to indicate to the PM core (and middle-layer
+code) that this is the case.  Whether or not the devices will actually be left
+in suspend may depend on their state before the given system suspend-resume
+cycle and on the type of the system transition under way.  In particular,
+devices are not left suspended if that transition is a restore from hibernation,
+as device states are not guaranteed to be reflected by the information stored in
+the hibernation image in that case.
+
+The middle-layer code involved in the handling of the device has to indicate to
+the PM core if the device may be left in suspend with the help of its
+:c:member:`power.may_skip_resume` status bit.  That has to happen in the "noirq"
+phase of the preceding system-wide suspend (or analogous) transition.  The
+middle layer is then responsible for handling the device as appropriate in its
+"noirq" resume callback, which is executed regardless of whether or not the
+device may be left suspended, but the other resume callbacks (except for
+``->complete``) will be skipped automatically by the PM core if the device
+really can be left in suspend.

  reply	other threads:[~2017-11-08 13:53 UTC|newest]

Thread overview: 135+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-16  1:12 [PATCH 0/12] PM / sleep: Driver flags for system suspend/resume Rafael J. Wysocki
2017-10-16  1:29 ` [PATCH 01/12] PM / core: Add NEVER_SKIP and SMART_PREPARE driver flags Rafael J. Wysocki
2017-10-16  5:34   ` Lukas Wunner
2017-10-16 22:03     ` Rafael J. Wysocki
2017-10-16  6:28   ` Greg Kroah-Hartman
2017-10-16 22:05     ` Rafael J. Wysocki
2017-10-17  7:15       ` Greg Kroah-Hartman
2017-10-17 15:26         ` Rafael J. Wysocki
2017-10-18  6:56           ` Greg Kroah-Hartman
2017-10-16  6:31   ` Greg Kroah-Hartman
2017-10-16 22:07     ` Rafael J. Wysocki
2017-10-17 13:26       ` Greg Kroah-Hartman
2017-10-16 20:16   ` Alan Stern
2017-10-16 22:11     ` Rafael J. Wysocki
2017-10-18 23:17   ` [Update][PATCH v2 " Rafael J. Wysocki
2017-10-19  7:33     ` Greg Kroah-Hartman
2017-10-20 11:11       ` Rafael J. Wysocki
2017-10-20 11:35         ` Greg Kroah-Hartman
2017-10-20 11:28           ` Rafael J. Wysocki
2017-10-23 16:37     ` Ulf Hansson
2017-10-23 20:41       ` Rafael J. Wysocki
2017-10-16  1:29 ` [PATCH 02/12] PCI / PM: Use the NEVER_SKIP driver flag Rafael J. Wysocki
2017-10-23 16:40   ` Ulf Hansson
2017-10-16  1:29 ` [PATCH 03/12] PM: i2c-designware-platdrv: Use DPM_FLAG_SMART_PREPARE Rafael J. Wysocki
2017-10-23 16:57   ` Ulf Hansson
2017-10-16  1:29 ` [PATCH 04/12] PM / core: Add SMART_SUSPEND driver flag Rafael J. Wysocki
2017-10-23 19:01   ` Ulf Hansson
2017-10-24  5:22   ` Ulf Hansson
2017-10-24  8:55     ` Rafael J. Wysocki
2017-10-16  1:29 ` [PATCH 05/12] PCI / PM: Drop unnecessary invocations of pcibios_pm_ops callbacks Rafael J. Wysocki
2017-10-23 19:06   ` Ulf Hansson
2017-10-16  1:29 ` [PATCH 06/12] PCI / PM: Take SMART_SUSPEND driver flag into account Rafael J. Wysocki
2017-10-16  1:29 ` [PATCH 07/12] ACPI / LPSS: Consolidate runtime PM and system sleep handling Rafael J. Wysocki
2017-10-23 19:09   ` Ulf Hansson
2017-10-16  1:30 ` [PATCH 08/12] ACPI / PM: Take SMART_SUSPEND driver flag into account Rafael J. Wysocki
2017-10-16  1:30 ` [PATCH 09/12] PM / mfd: intel-lpss: Use DPM_FLAG_SMART_SUSPEND Rafael J. Wysocki
2017-10-31 15:09   ` Lee Jones
2017-10-31 16:28     ` Rafael J. Wysocki
2017-11-01  9:28       ` Lee Jones
2017-11-01 20:26         ` Rafael J. Wysocki
2017-11-08 11:08           ` Lee Jones
2017-10-16  1:30 ` [PATCH 10/12] PM / core: Add LEAVE_SUSPENDED driver flag Rafael J. Wysocki
2017-10-23 19:38   ` Ulf Hansson
2017-10-16  1:31 ` [PATCH 11/12] PM: i2c-designware-platdrv: Optimize power management Rafael J. Wysocki
2017-10-26 20:41   ` Wolfram Sang
2017-10-26 21:14     ` Rafael J. Wysocki
2017-10-16  1:32 ` [PATCH 12/12] PM / core: Add AVOID_RPM driver flag Rafael J. Wysocki
2017-10-17 15:33   ` Andy Shevchenko
2017-10-17 15:59     ` Rafael J. Wysocki
2017-10-17 16:25       ` Andy Shevchenko
2017-10-16  7:08 ` [PATCH 0/12] PM / sleep: Driver flags for system suspend/resume Greg Kroah-Hartman
2017-10-16 21:50   ` Rafael J. Wysocki
2017-10-17  8:36 ` Ulf Hansson
2017-10-17 15:25   ` Rafael J. Wysocki
2017-10-17 19:41     ` Ulf Hansson
2017-10-17 20:12       ` Alan Stern
2017-10-17 23:07         ` Rafael J. Wysocki
2017-10-18  0:39       ` Rafael J. Wysocki
2017-10-18 10:24         ` Rafael J. Wysocki
2017-10-18 12:34           ` Ulf Hansson
2017-10-18 21:54             ` Rafael J. Wysocki
2017-10-18 11:57         ` Ulf Hansson
2017-10-18 13:00           ` Rafael J. Wysocki
2017-10-18 14:11             ` Ulf Hansson
2017-10-18 19:45               ` Grygorii Strashko
2017-10-18 21:48                 ` Rafael J. Wysocki
2017-10-19  8:33                   ` Ulf Hansson
2017-10-19 17:21                     ` Grygorii Strashko
2017-10-19 18:04                       ` Ulf Hansson
2017-10-19 18:11                         ` Ulf Hansson
2017-10-19 21:31                           ` Grygorii Strashko
2017-10-20  6:05                             ` Ulf Hansson
2017-10-18 22:12               ` Rafael J. Wysocki
2017-10-19 12:21                 ` Ulf Hansson
2017-10-19 18:01                   ` Ulf Hansson
2017-10-20  1:19                   ` Rafael J. Wysocki
2017-10-20  5:57                     ` Ulf Hansson
2017-10-20 20:46 ` Bjorn Helgaas
2017-10-21  1:04   ` Rafael J. Wysocki
2017-10-27 22:11 ` [PATCH v2 0/6] PM / sleep: Driver flags for system suspend/resume (part 1) Rafael J. Wysocki
2017-10-27 22:17   ` [PATCH v2 1/6] PM / core: Add NEVER_SKIP and SMART_PREPARE driver flags Rafael J. Wysocki
2017-11-06  8:07     ` Ulf Hansson
2017-10-27 22:19   ` [PATCH v2 2/6] PCI / PM: Use the NEVER_SKIP driver flag Rafael J. Wysocki
2017-10-27 22:22   ` [PATCH v2 3/6] PM / core: Add SMART_SUSPEND " Rafael J. Wysocki
2017-11-06  8:09     ` Ulf Hansson
2017-11-06 11:23       ` Rafael J. Wysocki
2017-10-27 22:23   ` [PATCH v2 4/6] PCI / PM: Drop unnecessary invocations of pcibios_pm_ops callbacks Rafael J. Wysocki
2017-10-27 22:27   ` [PATCH v2 5/6] PCI / PM: Take SMART_SUSPEND driver flag into account Rafael J. Wysocki
2017-10-31 22:48     ` Bjorn Helgaas
2017-10-27 22:30   ` [PATCH v2 6/6] ACPI " Rafael J. Wysocki
2017-11-08  0:41   ` [PATCH v2 0/6] PM / sleep: Driver flags for system suspend/resume (part 2) Rafael J. Wysocki
2017-11-08 13:25     ` Rafael J. Wysocki [this message]
2017-11-10  9:09       ` [PATCH v2 1/6] PM / core: Add LEAVE_SUSPENDED driver flag Ulf Hansson
2017-11-10 23:45         ` Rafael J. Wysocki
2017-11-11  0:41           ` Rafael J. Wysocki
2017-11-11  1:36           ` Rafael J. Wysocki
2017-11-14 16:07           ` Ulf Hansson
2017-11-15  1:48             ` Rafael J. Wysocki
2017-11-16 10:18               ` Ulf Hansson
2017-11-08 13:28     ` [PATCH v2 2/6] PCI / PM: Support for " Rafael J. Wysocki
2017-11-08 20:38       ` Bjorn Helgaas
2017-11-08 21:09         ` Rafael J. Wysocki
2017-11-08 13:34     ` [PATCH v2 3/6] ACPI / PM: Support for LEAVE_SUSPENDED driver flag in ACPI PM domain Rafael J. Wysocki
2017-11-08 13:37     ` [PATCH v2 4/6] PM / core: Add helpers for subsystem callback selection Rafael J. Wysocki
2017-11-08 13:38     ` [PATCH v2 5/6] PM / core: Direct handling of DPM_FLAG_LEAVE_SUSPENDED Rafael J. Wysocki
2017-11-08 13:39     ` [PATCH v2 6/6] PM / core: DPM_FLAG_SMART_SUSPEND optimization Rafael J. Wysocki
2017-11-12  0:34     ` [PATCH v3 0/6] PM / sleep: Driver flags for system suspend/resume (part 2) Rafael J. Wysocki
2017-11-12  0:37       ` [PATCH v3 1/6] PM / core: Add LEAVE_SUSPENDED driver flag Rafael J. Wysocki
2017-11-16 15:10         ` Ulf Hansson
2017-11-16 23:07           ` Rafael J. Wysocki
2017-11-17  6:11             ` Ulf Hansson
2017-11-17 13:18               ` Rafael J. Wysocki
2017-11-17 13:49                 ` Ulf Hansson
2017-11-17 14:31                   ` Rafael J. Wysocki
2017-11-17 15:57                     ` Ulf Hansson
2017-11-17 12:45             ` Rafael J. Wysocki
2017-11-12  0:40       ` [PATCH v3 2/6] PCI / PM: Support for " Rafael J. Wysocki
2017-11-12  0:40       ` [PATCH v3 3/6] ACPI / PM: Support for LEAVE_SUSPENDED driver flag in ACPI PM domain Rafael J. Wysocki
2017-11-12  0:42       ` [PATCH v3 4/6] PM / core: Add helpers for subsystem callback selection Rafael J. Wysocki
2017-11-15  7:43         ` Ulf Hansson
2017-11-15 17:55           ` Rafael J. Wysocki
2017-11-12  0:43       ` [PATCH v3 5/6] PM / core: Direct handling of DPM_FLAG_LEAVE_SUSPENDED Rafael J. Wysocki
2017-11-12  0:44       ` [PATCH v3 6/6] PM / core: DPM_FLAG_SMART_SUSPEND optimization Rafael J. Wysocki
2017-11-18 14:27       ` [PATCH v4 0/6] PM / sleep: Driver flags for system suspend/resume (part 2) Rafael J. Wysocki
2017-11-18 14:31         ` [PATCH v4 1/6] PM / core: Add LEAVE_SUSPENDED driver flag Rafael J. Wysocki
2017-11-20 12:25           ` Ulf Hansson
2017-11-21  0:16             ` Rafael J. Wysocki
2017-11-18 14:33         ` [PATCH v4 2/6] PCI / PM: Support for " Rafael J. Wysocki
2017-11-18 14:35         ` [PATCH v4 3/6] ACPI / PM: Support for LEAVE_SUSPENDED driver flag in ACPI PM domain Rafael J. Wysocki
2017-11-18 14:37         ` [PATCH v4 4/6] PM / core: Add helpers for subsystem callback selection Rafael J. Wysocki
2017-11-18 14:41         ` [PATCH v4 5/6] PM / core: Direct handling of DPM_FLAG_LEAVE_SUSPENDED Rafael J. Wysocki
2017-11-20 13:42           ` Ulf Hansson
2017-11-22  1:10             ` Rafael J. Wysocki
2017-11-22  1:28               ` Rafael J. Wysocki
2017-11-18 14:44         ` [PATCH v4 6/6] PM / core: DPM_FLAG_SMART_SUSPEND optimization 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=2932219.eEdIVn6WWf@aspire.rjw.lan \
    --to=rjw@rjwysocki.net \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=bhelgaas@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=khilman@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-doc@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=stern@rowland.harvard.edu \
    --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

Powered by JetHome