linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: Linux PM list <linux-pm@vger.kernel.org>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	Aaron Lu <aaron.lu@intel.com>,
	ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>
Subject: [RFC][PATCH 1/3] PM / sleep: Flag to speed up suspend-resume of runtime-suspended devices
Date: Thu, 08 May 2014 01:29:47 +0200	[thread overview]
Message-ID: <2703563.1xTcfTGG98@vostro.rjw.lan> (raw)
In-Reply-To: <2333255.ofrK1CRRL4@vostro.rjw.lan>

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

Currently, some subsystems (e.g. PCI and the ACPI PM domain) have to
resume all runtime-suspended devices during system suspend, mostly
because those devices may need to be reprogrammed due to different
wakeup settings for system sleep and for runtime PM.

For some devices, though, it's OK to remain in runtime suspend 
throughout a complete system suspend/resume cycle (if the device was in
runtime suspend at the start of the cycle).  We would like to do this
whenever possible, to avoid the overhead of extra power-up and power-down
events.

However, problems may arise because the device's descendants may require
it to be at full power at various points during the cycle.  Therefore the
most straightforward way to do this safely is if the device and all its
descendants can remain runtime suspended until the resume stage of system
resume.

To this end, introduce dev->power.leave_runtime_suspended.
If a subsystem or driver sets this flag during the ->prepare() callback,
and if the flag is set in all of the device's descendants, and if the
device is still in runtime suspend at the beginning of the ->suspend()
callback, that callback is allowed to return 0 without clearing
power.leave_runtime_suspended and without changing the state of the
device, unless the current state of the device is not appropriate for
the upcoming system sleep state (for example, the device is supposed to
wake up the system from that state and its current wakeup settings are
not suitable for that).  Then, the PM core will not invoke the device's
->suspend_late(), ->suspend_irq(), ->resume_irq(), ->resume_early(), or
->resume() callbacks.  Instead, it will invoke ->runtime_resume() during
the device resume stage of system resume.

By leaving this flag set after ->suspend(), a driver or subsystem tells
the PM core that the device is runtime suspended, it is in a suitable
state for system suspend (for example, the wakeup setting does not
need to be changed), and it does not need to return to full
power until the resume stage.

Changelog based on an Alan Stern's description of the idea
(http://marc.info/?l=linux-pm&m=139940466625569&w=2).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/base/power/main.c    |   31 ++++++++++++++++++++++++-------
 drivers/base/power/runtime.c |   10 ++++++++++
 include/linux/pm.h           |    3 +++
 include/linux/pm_runtime.h   |   16 ++++++++++++++++
 kernel/power/Kconfig         |    4 ++++
 5 files changed, 57 insertions(+), 7 deletions(-)

Index: linux-pm/kernel/power/Kconfig
===================================================================
--- linux-pm.orig/kernel/power/Kconfig
+++ linux-pm/kernel/power/Kconfig
@@ -147,6 +147,10 @@ config PM
 	def_bool y
 	depends on PM_SLEEP || PM_RUNTIME
 
+config PM_BOTH
+	def_bool y
+	depends on PM_SLEEP && PM_RUNTIME
+
 config PM_DEBUG
 	bool "Power Management Debug Support"
 	depends on PM
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -583,6 +583,9 @@ struct dev_pm_info {
 	unsigned long		suspended_jiffies;
 	unsigned long		accounting_timestamp;
 #endif
+#ifdef CONFIG_PM_BOTH
+	bool			leave_runtime_suspended:1;
+#endif
 	struct pm_subsys_data	*subsys_data;  /* Owned by the subsystem. */
 	void (*set_latency_tolerance)(struct device *, s32);
 	struct dev_pm_qos	*qos;
Index: linux-pm/include/linux/pm_runtime.h
===================================================================
--- linux-pm.orig/include/linux/pm_runtime.h
+++ linux-pm/include/linux/pm_runtime.h
@@ -264,4 +264,20 @@ static inline void pm_runtime_dont_use_a
 	__pm_runtime_use_autosuspend(dev, false);
 }
 
+#ifdef CONFIG_PM_BOTH
+static inline void __set_leave_runtime_suspended(struct device *dev, bool val)
+{
+	dev->power.leave_runtime_suspended = val;
+}
+extern void pm_set_leave_runtime_suspended(struct device *dev, bool val);
+static inline bool pm_leave_runtime_suspended(struct device *dev)
+{
+	return dev->power.leave_runtime_suspended;
+}
+#else
+static inline void __set_leave_runtime_suspended(struct device *dev, bool val) {}
+static inline void pm_set_leave_runtime_suspended(struct device *dev, bool val) {}
+static inline bool pm_leave_runtime_suspended(struct device *dev) { return false; }
+#endif
+
 #endif
Index: linux-pm/drivers/base/power/runtime.c
===================================================================
--- linux-pm.orig/drivers/base/power/runtime.c
+++ linux-pm/drivers/base/power/runtime.c
@@ -732,6 +732,7 @@ static int rpm_resume(struct device *dev
 	}
  skip_parent:
 
+	__set_leave_runtime_suspended(dev, false);
 	if (dev->power.no_callbacks)
 		goto no_callback;	/* Assume success. */
 
@@ -1485,3 +1486,12 @@ out:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(pm_runtime_force_resume);
+
+#ifdef CONFIG_PM_BOTH
+void pm_set_leave_runtime_suspended(struct device *dev, bool val)
+{
+	spin_lock_irq(&dev->power.lock);
+	__set_leave_runtime_suspended(dev, val);
+	spin_unlock_irq(&dev->power.lock);
+}
+#endif
Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -479,7 +479,7 @@ static int device_resume_noirq(struct de
 	TRACE_DEVICE(dev);
 	TRACE_RESUME(0);
 
-	if (dev->power.syscore)
+	if (dev->power.syscore || pm_leave_runtime_suspended(dev))
 		goto Out;
 
 	if (!dev->power.is_noirq_suspended)
@@ -605,7 +605,7 @@ static int device_resume_early(struct de
 	TRACE_DEVICE(dev);
 	TRACE_RESUME(0);
 
-	if (dev->power.syscore)
+	if (dev->power.syscore || pm_leave_runtime_suspended(dev))
 		goto Out;
 
 	if (!dev->power.is_late_suspended)
@@ -735,6 +735,11 @@ static int device_resume(struct device *
 	if (dev->power.syscore)
 		goto Complete;
 
+	if (pm_leave_runtime_suspended(dev)) {
+		pm_runtime_resume(dev);
+		goto Complete;
+	}
+
 	dpm_wait(dev->parent, async);
 	dpm_watchdog_set(&wd, dev);
 	device_lock(dev);
@@ -1007,7 +1012,7 @@ static int __device_suspend_noirq(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore)
+	if (dev->power.syscore || pm_leave_runtime_suspended(dev))
 		goto Complete;
 
 	dpm_wait_for_children(dev, async);
@@ -1146,7 +1151,7 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore)
+	if (dev->power.syscore || pm_leave_runtime_suspended(dev))
 		goto Complete;
 
 	dpm_wait_for_children(dev, async);
@@ -1382,10 +1387,21 @@ static int __device_suspend(struct devic
 
  End:
 	if (!error) {
+		struct device *parent = dev->parent;
+
 		dev->power.is_suspended = true;
-		if (dev->power.wakeup_path
-		    && dev->parent && !dev->parent->power.ignore_children)
-			dev->parent->power.wakeup_path = true;
+		if (parent) {
+			spin_lock_irq(&parent->power.lock);
+
+			if (dev->power.wakeup_path
+			    && !parent->power.ignore_children)
+				parent->power.wakeup_path = true;
+
+			if (!pm_leave_runtime_suspended(dev))
+				__set_leave_runtime_suspended(parent, false);
+
+			spin_unlock_irq(&parent->power.lock);
+		}
 	}
 
 	device_unlock(dev);
@@ -1553,6 +1569,7 @@ int dpm_prepare(pm_message_t state)
 		struct device *dev = to_device(dpm_list.next);
 
 		get_device(dev);
+		pm_set_leave_runtime_suspended(dev, false);
 		mutex_unlock(&dpm_list_mtx);
 
 		error = device_prepare(dev, state);


  reply	other threads:[~2014-05-07 23:17 UTC|newest]

Thread overview: 78+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-14 23:12 [RFC][PATCH 0/3] PM: Mechanism to avoid resuming runtime-suspended devices during system suspend Rafael J. Wysocki
2014-01-14 23:13 ` [RFC][PATCH 1/3] PM / sleep: Flag to avoid executing suspend callbacks for devices Rafael J. Wysocki
2014-01-14 23:14 ` [RFC][PATCH 2/3] PM / runtime: Routine for checking device status during system suspend Rafael J. Wysocki
2014-01-16 13:32   ` Mika Westerberg
2014-01-16 16:07     ` [Update][RFC][PATCH " Rafael J. Wysocki
2014-01-14 23:16 ` [RFC][PATCH 3/3] ACPI / PM: Avoid resuming devices in ACPI PM domain " Rafael J. Wysocki
2014-01-15 13:57   ` [Update][RFC][PATCH " Rafael J. Wysocki
2014-02-16 23:49 ` [RFC][PATCH 0/3] PM: Mechanism to avoid resuming runtime-suspended devices " Rafael J. Wysocki
2014-02-16 23:50   ` [PATCH 1/3] PM / sleep: New flag to speed up suspend-resume of suspended devices Rafael J. Wysocki
2014-02-18 12:59     ` Ulf Hansson
2014-02-18 13:25       ` Rafael J. Wysocki
2014-02-19 17:01     ` Alan Stern
2014-02-20  1:23       ` Rafael J. Wysocki
2014-02-20  1:42         ` Rafael J. Wysocki
2014-02-20 17:03         ` Alan Stern
2014-02-24  0:00           ` Rafael J. Wysocki
2014-02-24 19:36             ` Alan Stern
2014-02-25  0:07               ` Rafael J. Wysocki
2014-02-25 17:08                 ` Alan Stern
2014-02-25 23:56                   ` Rafael J. Wysocki
2014-02-26 16:49                     ` Alan Stern
2014-02-26 21:44                       ` Rafael J. Wysocki
2014-02-26 22:17                         ` Alan Stern
2014-02-26 23:13                           ` Rafael J. Wysocki
2014-02-27 15:02                             ` Alan Stern
2014-04-24 22:36                               ` [RFC][PATCH 0/3] PM: Mechanism to avoid resuming runtime-suspended devices during system suspend, v2 Rafael J. Wysocki
2014-04-24 22:37                                 ` [RFC][PATCH 1/3] PM / sleep: Flags to speed up suspend-resume of runtime-suspended devices Rafael J. Wysocki
2014-05-01 21:39                                   ` Alan Stern
2014-05-01 23:15                                     ` Rafael J. Wysocki
2014-05-01 23:36                                       ` Rafael J. Wysocki
2014-05-02  0:04                                         ` Rafael J. Wysocki
2014-05-02 15:41                                           ` Rafael J. Wysocki
2014-05-02 18:44                                             ` Alan Stern
2014-05-05  0:09                                               ` Rafael J. Wysocki
2014-05-05 15:46                                                 ` Alan Stern
2014-05-06  1:31                                                   ` Rafael J. Wysocki
2014-05-06 19:31                                                     ` Alan Stern
2014-05-07  0:36                                                       ` Rafael J. Wysocki
2014-05-07 15:43                                                         ` Alan Stern
2014-05-07 23:27                                                           ` [RFC][PATCH 0/3] (was: Re: [RFC][PATCH 1/3] PM / sleep: Flags to speed up suspend-resume of runtime-suspended devices) Rafael J. Wysocki
2014-05-07 23:29                                                             ` Rafael J. Wysocki [this message]
2014-05-08  7:49                                                               ` [RFC][PATCH 1/3] PM / sleep: Flag to speed up suspend-resume of runtime-suspended devices Ulf Hansson
2014-05-08 10:53                                                                 ` Rafael J. Wysocki
2014-05-08 10:59                                                                   ` Ulf Hansson
2014-05-08 11:44                                                                     ` Rafael J. Wysocki
2014-05-08 12:25                                                                       ` Ulf Hansson
2014-05-08 20:02                                                                         ` Rafael J. Wysocki
2014-05-08 14:36                                                                     ` Alan Stern
2014-05-08 14:57                                                               ` Alan Stern
2014-05-08 20:17                                                                 ` Rafael J. Wysocki
2014-05-08 21:03                                                                   ` Rafael J. Wysocki
2014-05-08 21:20                                                                     ` Alan Stern
2014-05-08 21:42                                                                       ` Rafael J. Wysocki
2014-05-08 21:50                                                                         ` Rafael J. Wysocki
2014-05-08 22:28                                                                           ` [RFC][PATCH 0/3] (was: Re: PM / sleep: Flag to speed up suspend-resume of runtime-suspended devices) Rafael J. Wysocki
2014-05-08 22:41                                                                             ` [RFC][PATCH 1/3] PM / sleep: Flag to speed up suspend-resume of runtime-suspended devices Rafael J. Wysocki
2014-05-09  7:23                                                                               ` Ulf Hansson
2014-05-09 11:33                                                                                 ` Rafael J. Wysocki
2014-05-08 22:41                                                                             ` [RFC][PATCH 2/3] PM / runtime: Routine for checking device status during system suspend Rafael J. Wysocki
2014-05-08 22:42                                                                             ` [RFC][PATCH 3/3] ACPI / PM: Avoid resuming devices in ACPI PM domain " Rafael J. Wysocki
2014-05-09  1:52                                                                           ` [RFC][PATCH 1/3] PM / sleep: Flag to speed up suspend-resume of runtime-suspended devices Alan Stern
2014-05-09 22:49                                                                             ` Rafael J. Wysocki
2014-05-11 16:46                                                                               ` Alan Stern
2014-05-13  0:51                                                                                 ` Rafael J. Wysocki
2014-05-08 21:08                                                                   ` Alan Stern
2014-05-09 22:48                                                               ` Kevin Hilman
2014-05-10  1:38                                                                 ` Rafael J. Wysocki
2014-05-12 16:33                                                                   ` Kevin Hilman
2014-05-07 23:31                                                             ` [Resend][PATCH 2/3] PM / runtime: Routine for checking device status during system suspend Rafael J. Wysocki
2014-05-07 23:33                                                             ` [RFC][PATCH 3/3] ACPI / PM: Avoid resuming devices in ACPI PM domain " Rafael J. Wysocki
2014-05-08 14:59                                                               ` Alan Stern
2014-05-08 19:40                                                                 ` Rafael J. Wysocki
2014-05-02 16:12                                         ` [RFC][PATCH 1/3] PM / sleep: Flags to speed up suspend-resume of runtime-suspended devices Alan Stern
2014-04-24 22:39                                 ` [RFC][PATCH 2/3][Resend] PM / runtime: Routine for checking device status during system suspend Rafael J. Wysocki
2014-04-25 11:28                                   ` Ulf Hansson
2014-04-24 22:40                                 ` [RFC][PATCH 3/3] ACPI / PM: Avoid resuming devices in ACPI PM domain " Rafael J. Wysocki
2014-02-16 23:51   ` [PATCH 2/3][Resend] PM / runtime: Routine for checking device status " Rafael J. Wysocki
2014-02-16 23:52   ` [PATCH 3/3] ACPI / PM: Avoid resuming devices in ACPI PM domain " 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=2703563.1xTcfTGG98@vostro.rjw.lan \
    --to=rjw@rjwysocki.net \
    --cc=aaron.lu@intel.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=stern@rowland.harvard.edu \
    /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;
as well as URLs for NNTP newsgroup(s).