All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] PM / ACPI / i2c: Deploy runtime PM centric path for system sleep
@ 2017-08-23 14:42 ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
isn't well optimized for system sleep.

What makes this driver particularly interesting is because it's a cross-SoC
driver, which sometimes means there is an ACPI PM domain attached to the i2c
device and sometimes not. The driver is being used on both x86 and ARM.

In principle, to optimize the system sleep support in i2c driver, this series
enables the proven runtime PM centric path for the i2c driver. However, to do
that the ACPI PM domain also have to collaborate and understand this behaviour.
Therefore a number of changes, patch 1 to patch 7, makes the needed changes to
the ACPI PM domain. In patch8 and patch 9, the i2c driver gets optimized and is
converted to the runtime PM centric path for system sleep.

It shall be noted, the behaviour of the ACPI PM domain should remain intact,
still taking benefit of using the direct_complete path during system sleep,
except for those drivers that explicitly request it not to (via a new ACPI API
added in this series).

This series has been tested on an ARM64 Hikey board, which isn't having the
i2c device attached to the ACPI PM domain. This means that the ACPI changes
needs to be tested on some relevant Intel SoCs and it's greatly appreciated
is someone could help out with this, so is of course review comments.

Some news in v2:
	- The v1 contained a fix for the i2c driver, this has been sent
	separately [1] and picked up for fixes by Wolfram for v4.13-rcs. However
	the fix has not yet reached Linus' tree. The changes on i2c driver
	are based upon that change.
	- To simplify for testers, I have published a branch [2] based upon
	Rafael's pm tree and linux-next branch, which also includes the above
	patch.
	- Rephrased the coverletter to clarify the intent of this series.
	- Addressed review comments from v1.

[1]
http://patchwork.ozlabs.org/patch/799803/

[2]
git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git acpi_pm_i2c_rpm_path_v2

Kind regards
Ulf Hansson


Ulf Hansson (9):
  PM / ACPI: Restore acpi_subsys_complete()
  PM / Sleep: Remove pm_complete_with_resume_check()
  PM / ACPI: Split code validating need for runtime resume in
    ->prepare()
  PM / ACPI: Split acpi_lpss_suspend_late|resume_early()
  PM / ACPI: Provide option to disable direct_complete for ACPI devices
  PM / ACPI: Enable the runtime PM centric approach for system sleep
  PM / ACPI: Avoid runtime resuming device in
    acpi_subsys_suspend|freeze()
  i2c: designware: Don't resume device in the ->complete() callback
  i2c: designware: Deploy the runtime PM centric approach for system
    sleep

 drivers/acpi/acpi_lpss.c                    |  81 +++++++++----
 drivers/acpi/device_pm.c                    | 169 ++++++++++++++++++++++++----
 drivers/base/power/generic_ops.c            |  23 ----
 drivers/i2c/busses/i2c-designware-platdrv.c |  35 +-----
 include/acpi/acpi_bus.h                     |   1 +
 include/linux/acpi.h                        |   4 +
 include/linux/pm.h                          |   1 -
 7 files changed, 218 insertions(+), 96 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 0/9] PM / ACPI / i2c: Deploy runtime PM centric path for system sleep
@ 2017-08-23 14:42 ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
isn't well optimized for system sleep.

What makes this driver particularly interesting is because it's a cross-SoC
driver, which sometimes means there is an ACPI PM domain attached to the i2c
device and sometimes not. The driver is being used on both x86 and ARM.

In principle, to optimize the system sleep support in i2c driver, this series
enables the proven runtime PM centric path for the i2c driver. However, to do
that the ACPI PM domain also have to collaborate and understand this behaviour.
Therefore a number of changes, patch 1 to patch 7, makes the needed changes to
the ACPI PM domain. In patch8 and patch 9, the i2c driver gets optimized and is
converted to the runtime PM centric path for system sleep.

It shall be noted, the behaviour of the ACPI PM domain should remain intact,
still taking benefit of using the direct_complete path during system sleep,
except for those drivers that explicitly request it not to (via a new ACPI API
added in this series).

This series has been tested on an ARM64 Hikey board, which isn't having the
i2c device attached to the ACPI PM domain. This means that the ACPI changes
needs to be tested on some relevant Intel SoCs and it's greatly appreciated
is someone could help out with this, so is of course review comments.

Some news in v2:
	- The v1 contained a fix for the i2c driver, this has been sent
	separately [1] and picked up for fixes by Wolfram for v4.13-rcs. However
	the fix has not yet reached Linus' tree. The changes on i2c driver
	are based upon that change.
	- To simplify for testers, I have published a branch [2] based upon
	Rafael's pm tree and linux-next branch, which also includes the above
	patch.
	- Rephrased the coverletter to clarify the intent of this series.
	- Addressed review comments from v1.

[1]
http://patchwork.ozlabs.org/patch/799803/

[2]
git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git acpi_pm_i2c_rpm_path_v2

Kind regards
Ulf Hansson


Ulf Hansson (9):
  PM / ACPI: Restore acpi_subsys_complete()
  PM / Sleep: Remove pm_complete_with_resume_check()
  PM / ACPI: Split code validating need for runtime resume in
    ->prepare()
  PM / ACPI: Split acpi_lpss_suspend_late|resume_early()
  PM / ACPI: Provide option to disable direct_complete for ACPI devices
  PM / ACPI: Enable the runtime PM centric approach for system sleep
  PM / ACPI: Avoid runtime resuming device in
    acpi_subsys_suspend|freeze()
  i2c: designware: Don't resume device in the ->complete() callback
  i2c: designware: Deploy the runtime PM centric approach for system
    sleep

 drivers/acpi/acpi_lpss.c                    |  81 +++++++++----
 drivers/acpi/device_pm.c                    | 169 ++++++++++++++++++++++++----
 drivers/base/power/generic_ops.c            |  23 ----
 drivers/i2c/busses/i2c-designware-platdrv.c |  35 +-----
 include/acpi/acpi_bus.h                     |   1 +
 include/linux/acpi.h                        |   4 +
 include/linux/pm.h                          |   1 -
 7 files changed, 218 insertions(+), 96 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 1/9] PM / ACPI: Restore acpi_subsys_complete()
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

The commit 58a1fbbb2ee8 ("PM / PCI / ACPI: Kick devices that might have
been reset by firmware"), made PCI's and ACPI's ->complete() callbacks to
be assigned to a new API called pm_complete_with_resume_check(), which was
introduced in the same change.

Later it turned out that using pm_complete_with_resume_check() isn't good
enough for PCI, as it needs additional PCI specific checks, before deciding
whether runtime resuming the device is needed when running the ->complete()
callback.

This leaves ACPI being the only user of pm_complete_with_resume_check().
Therefore let's restore ACPI's acpi_subsys_complete(), which was dropped in
commit 58a1fbbb2ee8 ("PM / PCI / ACPI: Kick devices that might have been
reset by firmware").

This enables us to remove the pm_complete_with_resume_check() API in a
following change, but it also enables ACPI to add more ACPI specific checks
in acpi_subsys_complete() if it turns out that is needed.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- None.

---
 drivers/acpi/acpi_lpss.c |  2 +-
 drivers/acpi/device_pm.c | 19 ++++++++++++++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 032ae44..0c84d15 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -894,7 +894,7 @@ static struct dev_pm_domain acpi_lpss_pm_domain = {
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM_SLEEP
 		.prepare = acpi_subsys_prepare,
-		.complete = pm_complete_with_resume_check,
+		.complete = acpi_subsys_complete,
 		.suspend = acpi_subsys_suspend,
 		.suspend_late = acpi_lpss_suspend_late,
 		.resume_early = acpi_lpss_resume_early,
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index fbcc73f..632f214 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1020,6 +1020,23 @@ int acpi_subsys_prepare(struct device *dev)
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
 /**
+ * acpi_subsys_complete - Finalize device's resume during system resume.
+ * @dev: Device to handle.
+ */
+void acpi_subsys_complete(struct device *dev)
+{
+	pm_generic_complete(dev);
+	/*
+	 * If the device had been runtime-suspended before the system went into
+	 * the sleep state it is going out of and it has never been resumed till
+	 * now, resume it in case the firmware powered it up.
+	 */
+	if (dev->power.direct_complete && pm_resume_via_firmware())
+		pm_request_resume(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_complete);
+
+/**
  * acpi_subsys_suspend - Run the device driver's suspend callback.
  * @dev: Device to handle.
  *
@@ -1087,7 +1104,7 @@ static struct dev_pm_domain acpi_general_pm_domain = {
 		.runtime_resume = acpi_subsys_runtime_resume,
 #ifdef CONFIG_PM_SLEEP
 		.prepare = acpi_subsys_prepare,
-		.complete = pm_complete_with_resume_check,
+		.complete = acpi_subsys_complete,
 		.suspend = acpi_subsys_suspend,
 		.suspend_late = acpi_subsys_suspend_late,
 		.resume_early = acpi_subsys_resume_early,
-- 
2.7.4


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 1/9] PM / ACPI: Restore acpi_subsys_complete()
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

The commit 58a1fbbb2ee8 ("PM / PCI / ACPI: Kick devices that might have
been reset by firmware"), made PCI's and ACPI's ->complete() callbacks to
be assigned to a new API called pm_complete_with_resume_check(), which was
introduced in the same change.

Later it turned out that using pm_complete_with_resume_check() isn't good
enough for PCI, as it needs additional PCI specific checks, before deciding
whether runtime resuming the device is needed when running the ->complete()
callback.

This leaves ACPI being the only user of pm_complete_with_resume_check().
Therefore let's restore ACPI's acpi_subsys_complete(), which was dropped in
commit 58a1fbbb2ee8 ("PM / PCI / ACPI: Kick devices that might have been
reset by firmware").

This enables us to remove the pm_complete_with_resume_check() API in a
following change, but it also enables ACPI to add more ACPI specific checks
in acpi_subsys_complete() if it turns out that is needed.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- None.

---
 drivers/acpi/acpi_lpss.c |  2 +-
 drivers/acpi/device_pm.c | 19 ++++++++++++++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 032ae44..0c84d15 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -894,7 +894,7 @@ static struct dev_pm_domain acpi_lpss_pm_domain = {
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM_SLEEP
 		.prepare = acpi_subsys_prepare,
-		.complete = pm_complete_with_resume_check,
+		.complete = acpi_subsys_complete,
 		.suspend = acpi_subsys_suspend,
 		.suspend_late = acpi_lpss_suspend_late,
 		.resume_early = acpi_lpss_resume_early,
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index fbcc73f..632f214 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1020,6 +1020,23 @@ int acpi_subsys_prepare(struct device *dev)
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
 /**
+ * acpi_subsys_complete - Finalize device's resume during system resume.
+ * @dev: Device to handle.
+ */
+void acpi_subsys_complete(struct device *dev)
+{
+	pm_generic_complete(dev);
+	/*
+	 * If the device had been runtime-suspended before the system went into
+	 * the sleep state it is going out of and it has never been resumed till
+	 * now, resume it in case the firmware powered it up.
+	 */
+	if (dev->power.direct_complete && pm_resume_via_firmware())
+		pm_request_resume(dev);
+}
+EXPORT_SYMBOL_GPL(acpi_subsys_complete);
+
+/**
  * acpi_subsys_suspend - Run the device driver's suspend callback.
  * @dev: Device to handle.
  *
@@ -1087,7 +1104,7 @@ static struct dev_pm_domain acpi_general_pm_domain = {
 		.runtime_resume = acpi_subsys_runtime_resume,
 #ifdef CONFIG_PM_SLEEP
 		.prepare = acpi_subsys_prepare,
-		.complete = pm_complete_with_resume_check,
+		.complete = acpi_subsys_complete,
 		.suspend = acpi_subsys_suspend,
 		.suspend_late = acpi_subsys_suspend_late,
 		.resume_early = acpi_subsys_resume_early,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 2/9] PM / Sleep: Remove pm_complete_with_resume_check()
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

According to recent changes for ACPI, the are longer any users of
pm_complete_with_resume_check(), thus let's drop it.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- None.

---
 drivers/base/power/generic_ops.c | 23 -----------------------
 include/linux/pm.h               |  1 -
 2 files changed, 24 deletions(-)

diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 07c3c4a..b2ed606 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -9,7 +9,6 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/export.h>
-#include <linux/suspend.h>
 
 #ifdef CONFIG_PM
 /**
@@ -298,26 +297,4 @@ void pm_generic_complete(struct device *dev)
 	if (drv && drv->pm && drv->pm->complete)
 		drv->pm->complete(dev);
 }
-
-/**
- * pm_complete_with_resume_check - Complete a device power transition.
- * @dev: Device to handle.
- *
- * Complete a device power transition during a system-wide power transition and
- * optionally schedule a runtime resume of the device if the system resume in
- * progress has been initated by the platform firmware and the device had its
- * power.direct_complete flag set.
- */
-void pm_complete_with_resume_check(struct device *dev)
-{
-	pm_generic_complete(dev);
-	/*
-	 * If the device had been runtime-suspended before the system went into
-	 * the sleep state it is going out of and it has never been resumed till
-	 * now, resume it in case the firmware powered it up.
-	 */
-	if (dev->power.direct_complete && pm_resume_via_firmware())
-		pm_request_resume(dev);
-}
-EXPORT_SYMBOL_GPL(pm_complete_with_resume_check);
 #endif /* CONFIG_PM_SLEEP */
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 47ded8a..a0ceecc 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -736,7 +736,6 @@ extern int pm_generic_poweroff_noirq(struct device *dev);
 extern int pm_generic_poweroff_late(struct device *dev);
 extern int pm_generic_poweroff(struct device *dev);
 extern void pm_generic_complete(struct device *dev);
-extern void pm_complete_with_resume_check(struct device *dev);
 
 #else /* !CONFIG_PM_SLEEP */
 
-- 
2.7.4


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 2/9] PM / Sleep: Remove pm_complete_with_resume_check()
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

According to recent changes for ACPI, the are longer any users of
pm_complete_with_resume_check(), thus let's drop it.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- None.

---
 drivers/base/power/generic_ops.c | 23 -----------------------
 include/linux/pm.h               |  1 -
 2 files changed, 24 deletions(-)

diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c
index 07c3c4a..b2ed606 100644
--- a/drivers/base/power/generic_ops.c
+++ b/drivers/base/power/generic_ops.c
@@ -9,7 +9,6 @@
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/export.h>
-#include <linux/suspend.h>
 
 #ifdef CONFIG_PM
 /**
@@ -298,26 +297,4 @@ void pm_generic_complete(struct device *dev)
 	if (drv && drv->pm && drv->pm->complete)
 		drv->pm->complete(dev);
 }
-
-/**
- * pm_complete_with_resume_check - Complete a device power transition.
- * @dev: Device to handle.
- *
- * Complete a device power transition during a system-wide power transition and
- * optionally schedule a runtime resume of the device if the system resume in
- * progress has been initated by the platform firmware and the device had its
- * power.direct_complete flag set.
- */
-void pm_complete_with_resume_check(struct device *dev)
-{
-	pm_generic_complete(dev);
-	/*
-	 * If the device had been runtime-suspended before the system went into
-	 * the sleep state it is going out of and it has never been resumed till
-	 * now, resume it in case the firmware powered it up.
-	 */
-	if (dev->power.direct_complete && pm_resume_via_firmware())
-		pm_request_resume(dev);
-}
-EXPORT_SYMBOL_GPL(pm_complete_with_resume_check);
 #endif /* CONFIG_PM_SLEEP */
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 47ded8a..a0ceecc 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -736,7 +736,6 @@ extern int pm_generic_poweroff_noirq(struct device *dev);
 extern int pm_generic_poweroff_late(struct device *dev);
 extern int pm_generic_poweroff(struct device *dev);
 extern void pm_generic_complete(struct device *dev);
-extern void pm_complete_with_resume_check(struct device *dev);
 
 #else /* !CONFIG_PM_SLEEP */
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 3/9] PM / ACPI: Split code validating need for runtime resume in ->prepare()
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

Move the code dealing with validation of whether runtime resuming the
device is needed during system suspend.

In this way it becomes more clear for what circumstances ACPI is prevented
from trying the direct_complete path.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Updated return expression for acpi_dev_needs_resume().

---
 drivers/acpi/device_pm.c | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 632f214..5181057 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -989,6 +989,27 @@ int acpi_dev_resume_early(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 
+static bool acpi_dev_needs_resume(struct device *dev, struct acpi_device *adev)
+{
+	u32 sys_target = acpi_target_system_state();
+	int ret, state;
+
+	if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
+		return true;
+
+	if (sys_target == ACPI_STATE_S0)
+		return false;
+
+	if (adev->power.flags.dsw_present)
+		return true;
+
+	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
+	if (ret)
+		return true;
+
+	return state != adev->power.state;
+}
+
 /**
  * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
  * @dev: Device to prepare.
@@ -996,26 +1017,16 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 int acpi_subsys_prepare(struct device *dev)
 {
 	struct acpi_device *adev = ACPI_COMPANION(dev);
-	u32 sys_target;
-	int ret, state;
+	int ret;
 
 	ret = pm_generic_prepare(dev);
 	if (ret < 0)
 		return ret;
 
-	if (!adev || !pm_runtime_suspended(dev)
-	    || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
-		return 0;
-
-	sys_target = acpi_target_system_state();
-	if (sys_target == ACPI_STATE_S0)
-		return 1;
-
-	if (adev->power.flags.dsw_present)
+	if (!adev || !pm_runtime_suspended(dev))
 		return 0;
 
-	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
-	return !ret && state == adev->power.state;
+	return !acpi_dev_needs_resume(dev, adev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 3/9] PM / ACPI: Split code validating need for runtime resume in ->prepare()
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Move the code dealing with validation of whether runtime resuming the
device is needed during system suspend.

In this way it becomes more clear for what circumstances ACPI is prevented
from trying the direct_complete path.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Updated return expression for acpi_dev_needs_resume().

---
 drivers/acpi/device_pm.c | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 632f214..5181057 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -989,6 +989,27 @@ int acpi_dev_resume_early(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 
+static bool acpi_dev_needs_resume(struct device *dev, struct acpi_device *adev)
+{
+	u32 sys_target = acpi_target_system_state();
+	int ret, state;
+
+	if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
+		return true;
+
+	if (sys_target == ACPI_STATE_S0)
+		return false;
+
+	if (adev->power.flags.dsw_present)
+		return true;
+
+	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
+	if (ret)
+		return true;
+
+	return state != adev->power.state;
+}
+
 /**
  * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
  * @dev: Device to prepare.
@@ -996,26 +1017,16 @@ EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 int acpi_subsys_prepare(struct device *dev)
 {
 	struct acpi_device *adev = ACPI_COMPANION(dev);
-	u32 sys_target;
-	int ret, state;
+	int ret;
 
 	ret = pm_generic_prepare(dev);
 	if (ret < 0)
 		return ret;
 
-	if (!adev || !pm_runtime_suspended(dev)
-	    || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
-		return 0;
-
-	sys_target = acpi_target_system_state();
-	if (sys_target == ACPI_STATE_S0)
-		return 1;
-
-	if (adev->power.flags.dsw_present)
+	if (!adev || !pm_runtime_suspended(dev))
 		return 0;
 
-	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
-	return !ret && state == adev->power.state;
+	return !acpi_dev_needs_resume(dev, adev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 4/9] PM / ACPI: Split acpi_lpss_suspend_late|resume_early()
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

Move the code which is special to ACPI LPSS into separate functions. This
may clarify the code a bit, but the main purpose of this change, is instead
to prepare for additional changes on top. Ideally the following changes
should then become easier to review.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- None.

---
 drivers/acpi/acpi_lpss.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 0c84d15..e726173 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -717,22 +717,28 @@ static void acpi_lpss_dismiss(struct device *dev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int acpi_lpss_suspend_late(struct device *dev)
+static int lpss_suspend_late(struct device *dev)
 {
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+
+	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
+		acpi_lpss_save_ctx(dev, pdata);
+
+	return acpi_dev_suspend_late(dev);
+}
+
+static int acpi_lpss_suspend_late(struct device *dev)
+{
 	int ret;
 
 	ret = pm_generic_suspend_late(dev);
 	if (ret)
 		return ret;
 
-	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
-		acpi_lpss_save_ctx(dev, pdata);
-
-	return acpi_dev_suspend_late(dev);
+	return lpss_suspend_late(dev);
 }
 
-static int acpi_lpss_resume_early(struct device *dev)
+static int lpss_resume_early(struct device *dev)
 {
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
 	int ret;
@@ -746,6 +752,17 @@ static int acpi_lpss_resume_early(struct device *dev)
 	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
 		acpi_lpss_restore_ctx(dev, pdata);
 
+	return 0;
+}
+
+static int acpi_lpss_resume_early(struct device *dev)
+{
+	int ret;
+
+	ret = lpss_resume_early(dev);
+	if (ret)
+		return ret;
+
 	return pm_generic_resume_early(dev);
 }
 #endif /* CONFIG_PM_SLEEP */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 4/9] PM / ACPI: Split acpi_lpss_suspend_late|resume_early()
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Move the code which is special to ACPI LPSS into separate functions. This
may clarify the code a bit, but the main purpose of this change, is instead
to prepare for additional changes on top. Ideally the following changes
should then become easier to review.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- None.

---
 drivers/acpi/acpi_lpss.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 0c84d15..e726173 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -717,22 +717,28 @@ static void acpi_lpss_dismiss(struct device *dev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int acpi_lpss_suspend_late(struct device *dev)
+static int lpss_suspend_late(struct device *dev)
 {
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+
+	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
+		acpi_lpss_save_ctx(dev, pdata);
+
+	return acpi_dev_suspend_late(dev);
+}
+
+static int acpi_lpss_suspend_late(struct device *dev)
+{
 	int ret;
 
 	ret = pm_generic_suspend_late(dev);
 	if (ret)
 		return ret;
 
-	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
-		acpi_lpss_save_ctx(dev, pdata);
-
-	return acpi_dev_suspend_late(dev);
+	return lpss_suspend_late(dev);
 }
 
-static int acpi_lpss_resume_early(struct device *dev)
+static int lpss_resume_early(struct device *dev)
 {
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
 	int ret;
@@ -746,6 +752,17 @@ static int acpi_lpss_resume_early(struct device *dev)
 	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
 		acpi_lpss_restore_ctx(dev, pdata);
 
+	return 0;
+}
+
+static int acpi_lpss_resume_early(struct device *dev)
+{
+	int ret;
+
+	ret = lpss_resume_early(dev);
+	if (ret)
+		return ret;
+
 	return pm_generic_resume_early(dev);
 }
 #endif /* CONFIG_PM_SLEEP */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

In some cases a driver for an ACPI device needs to be able to prevent the
ACPI PM domain from using the direct_complete path during system sleep.

One typical case is when the driver for the device needs its device to stay
runtime enabled, during the __device_suspend phase. This isn't the case
when the direct_complete path is being executed by the PM core, as it then
disables runtime PM for the device in __device_suspend(). Any following
attempts to runtime resume the device after that point, just fails.

A workaround to this problem is to let the driver runtime resume its device
from its ->prepare() callback, as that would prevent the direct_complete
path from being executed. However, that may often be a waste, especially if
it turned out that no one really needed the device.

For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
drivers to inform the ACPI PM domain to change its default behaviour during
system sleep, and thus control whether it may use the direct_complete path
or not.

Typically a driver should call acpi_dev_disable_direct_comlete() during
->probe() and acpi_dev_enable_direct_complete() in ->remove().

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Moved the no_direct_complete flag to the struct acpi_device_power.

---
 drivers/acpi/device_pm.c | 38 +++++++++++++++++++++++++++++++++++++-
 include/acpi/acpi_bus.h  |  1 +
 include/linux/acpi.h     |  4 ++++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 5181057..f7bf596 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -933,6 +933,41 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
 
 #ifdef CONFIG_PM_SLEEP
 /**
+ * acpi_dev_disable_direct_complete - Disable the direct_complete path for ACPI.
+ * @dev: Device to disable the path for.
+ *
+ * Per default the ACPI PM domain tries to use the direct_complete path for its
+ * devices during system sleep. This function allows a user, typically a driver
+ * during probe, to disable the direct_complete path from being used by ACPI.
+ */
+void acpi_dev_disable_direct_complete(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev)
+		adev->power.no_direct_complete = true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_disable_direct_complete);
+
+/**
+ * acpi_dev_enable_direct_complete - Enable the direct_complete path for ACPI.
+ * @dev: Device to enable the path for.
+ *
+ * Enable the direct_complete path to be used during system suspend for the ACPI
+ * PM domain, which is the default option. Typically a driver that disabled the
+ * path during ->probe(), must call this function during ->remove() to re-enable
+ * the direct_complete path to be used by ACPI.
+ */
+void acpi_dev_enable_direct_complete(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev)
+		adev->power.no_direct_complete = false;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_enable_direct_complete);
+
+/**
  * acpi_dev_suspend_late - Put device into a low-power state using ACPI.
  * @dev: Device to put into a low-power state.
  *
@@ -1023,7 +1058,8 @@ int acpi_subsys_prepare(struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	if (!adev || !pm_runtime_suspended(dev))
+	if (!adev || adev->power.no_direct_complete ||
+	    !pm_runtime_suspended(dev))
 		return 0;
 
 	return !acpi_dev_needs_resume(dev, adev);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index dedf9d7..bdec5f2 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -285,6 +285,7 @@ struct acpi_device_power_state {
 
 struct acpi_device_power {
 	int state;		/* Current state */
+	bool no_direct_complete;
 	struct acpi_device_power_flags flags;
 	struct acpi_device_power_state states[ACPI_D_STATE_COUNT];	/* Power states (D0-D3Cold) */
 };
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index c1a5213..ec33c41 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -867,6 +867,8 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
 #endif
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
+void acpi_dev_disable_direct_complete(struct device *dev);
+void acpi_dev_enable_direct_complete(struct device *dev);
 int acpi_dev_suspend_late(struct device *dev);
 int acpi_dev_resume_early(struct device *dev);
 int acpi_subsys_prepare(struct device *dev);
@@ -876,6 +878,8 @@ int acpi_subsys_resume_early(struct device *dev);
 int acpi_subsys_suspend(struct device *dev);
 int acpi_subsys_freeze(struct device *dev);
 #else
+static inline void acpi_dev_disable_direct_complete(struct device *dev) {}
+static inline void acpi_dev_enable_direct_complete(struct device *dev) {}
 static inline int acpi_dev_suspend_late(struct device *dev) { return 0; }
 static inline int acpi_dev_resume_early(struct device *dev) { return 0; }
 static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
-- 
2.7.4


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

In some cases a driver for an ACPI device needs to be able to prevent the
ACPI PM domain from using the direct_complete path during system sleep.

One typical case is when the driver for the device needs its device to stay
runtime enabled, during the __device_suspend phase. This isn't the case
when the direct_complete path is being executed by the PM core, as it then
disables runtime PM for the device in __device_suspend(). Any following
attempts to runtime resume the device after that point, just fails.

A workaround to this problem is to let the driver runtime resume its device
from its ->prepare() callback, as that would prevent the direct_complete
path from being executed. However, that may often be a waste, especially if
it turned out that no one really needed the device.

For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
drivers to inform the ACPI PM domain to change its default behaviour during
system sleep, and thus control whether it may use the direct_complete path
or not.

Typically a driver should call acpi_dev_disable_direct_comlete() during
->probe() and acpi_dev_enable_direct_complete() in ->remove().

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Moved the no_direct_complete flag to the struct acpi_device_power.

---
 drivers/acpi/device_pm.c | 38 +++++++++++++++++++++++++++++++++++++-
 include/acpi/acpi_bus.h  |  1 +
 include/linux/acpi.h     |  4 ++++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 5181057..f7bf596 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -933,6 +933,41 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
 
 #ifdef CONFIG_PM_SLEEP
 /**
+ * acpi_dev_disable_direct_complete - Disable the direct_complete path for ACPI.
+ * @dev: Device to disable the path for.
+ *
+ * Per default the ACPI PM domain tries to use the direct_complete path for its
+ * devices during system sleep. This function allows a user, typically a driver
+ * during probe, to disable the direct_complete path from being used by ACPI.
+ */
+void acpi_dev_disable_direct_complete(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev)
+		adev->power.no_direct_complete = true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_disable_direct_complete);
+
+/**
+ * acpi_dev_enable_direct_complete - Enable the direct_complete path for ACPI.
+ * @dev: Device to enable the path for.
+ *
+ * Enable the direct_complete path to be used during system suspend for the ACPI
+ * PM domain, which is the default option. Typically a driver that disabled the
+ * path during ->probe(), must call this function during ->remove() to re-enable
+ * the direct_complete path to be used by ACPI.
+ */
+void acpi_dev_enable_direct_complete(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev)
+		adev->power.no_direct_complete = false;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_enable_direct_complete);
+
+/**
  * acpi_dev_suspend_late - Put device into a low-power state using ACPI.
  * @dev: Device to put into a low-power state.
  *
@@ -1023,7 +1058,8 @@ int acpi_subsys_prepare(struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	if (!adev || !pm_runtime_suspended(dev))
+	if (!adev || adev->power.no_direct_complete ||
+	    !pm_runtime_suspended(dev))
 		return 0;
 
 	return !acpi_dev_needs_resume(dev, adev);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index dedf9d7..bdec5f2 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -285,6 +285,7 @@ struct acpi_device_power_state {
 
 struct acpi_device_power {
 	int state;		/* Current state */
+	bool no_direct_complete;
 	struct acpi_device_power_flags flags;
 	struct acpi_device_power_state states[ACPI_D_STATE_COUNT];	/* Power states (D0-D3Cold) */
 };
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index c1a5213..ec33c41 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -867,6 +867,8 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on)
 #endif
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PM_SLEEP)
+void acpi_dev_disable_direct_complete(struct device *dev);
+void acpi_dev_enable_direct_complete(struct device *dev);
 int acpi_dev_suspend_late(struct device *dev);
 int acpi_dev_resume_early(struct device *dev);
 int acpi_subsys_prepare(struct device *dev);
@@ -876,6 +878,8 @@ int acpi_subsys_resume_early(struct device *dev);
 int acpi_subsys_suspend(struct device *dev);
 int acpi_subsys_freeze(struct device *dev);
 #else
+static inline void acpi_dev_disable_direct_complete(struct device *dev) {}
+static inline void acpi_dev_enable_direct_complete(struct device *dev) {}
 static inline int acpi_dev_suspend_late(struct device *dev) { return 0; }
 static inline int acpi_dev_resume_early(struct device *dev) { return 0; }
 static inline int acpi_subsys_prepare(struct device *dev) { return 0; }
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 6/9] PM / ACPI: Enable the runtime PM centric approach for system sleep
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

This change extends the interpretation of the ACPI's no_direct_complete
flag to be used to enable the so called runtime PM centric approach, for
devices being attached to the ACPI PM domain.

The principle behind the runtime PM centric approach is to re-use the
runtime PM callbacks to implement system sleep for drivers/subsystems.
Moreover, using the runtime PM centric approach gives an optimized
behaviour around avoiding to wake up a device from its low power state
during system sleep, unless really needed.

To deploy the runtime PM centric approach for a subsystem/driver, the
following adaptations needs to be made.

First, the runtime PM callbacks may be called when runtime PM has been
disabled for the device. This serves as an indication for the callbacks to
understand they are running in the system sleep sequence, instead of in the
regular runtime PM path. In some cases, a callback needs to take different
actions depending in what path it is being executed in, as is the case for
the ACPI PM domain.

In particular for the ACPI PM domain's ->runtime_suspend|resume()
callbacks, when those finds runtime PM being disabled for the device, it
instead executes the same operations as normally being run when
->suspend_late() and ->resume_early() callbacks are invoked during system
sleep.

Second, at the PM domain level, it is expected that the driver for the
device makes use of pm_runtime_force_suspend|resume(), to re-use the
runtime PM callbacks to put the device into low power state and to wake it
up when needed during system sleep.

For the ACPI PM domain's ->suspend_late() and ->resume_early() callbacks,
it means bypassing the operations putting the device into low power state
and the operations that wakes it up. Instead it shall invoke only the lower
level ->suspend_late() and ->resume_early() callbacks for the driver, if
present.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Rebased.
	- Updated header for acpi_enable|disable_no_direct_complete().

---
 drivers/acpi/acpi_lpss.c | 58 +++++++++++++++++++++++++++++++---------------
 drivers/acpi/device_pm.c | 60 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 93 insertions(+), 25 deletions(-)

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index e726173..f0d1141 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -729,10 +729,11 @@ static int lpss_suspend_late(struct device *dev)
 
 static int acpi_lpss_suspend_late(struct device *dev)
 {
+	struct acpi_device *adev = ACPI_COMPANION(dev);
 	int ret;
 
 	ret = pm_generic_suspend_late(dev);
-	if (ret)
+	if (ret || adev->power.no_direct_complete)
 		return ret;
 
 	return lpss_suspend_late(dev);
@@ -757,13 +758,23 @@ static int lpss_resume_early(struct device *dev)
 
 static int acpi_lpss_resume_early(struct device *dev)
 {
-	int ret;
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret = 0;
 
-	ret = lpss_resume_early(dev);
-	if (ret)
-		return ret;
+	if (!adev->power.no_direct_complete)
+		ret = lpss_resume_early(dev);
 
-	return pm_generic_resume_early(dev);
+	return ret ? ret : pm_generic_resume_early(dev);
+}
+#else
+static inline int lpss_suspend_late(struct device *dev)
+{
+	return 0;
+}
+
+static inline int lpss_resume_early(struct device *dev)
+{
+	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
 
@@ -861,6 +872,9 @@ static int acpi_lpss_runtime_suspend(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (!pm_runtime_enabled(dev))
+		return lpss_suspend_late(dev);
+
 	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
 		acpi_lpss_save_ctx(dev, pdata);
 
@@ -882,21 +896,29 @@ static int acpi_lpss_runtime_resume(struct device *dev)
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
 	int ret;
 
-	/*
-	 * This call is kept first to be in symmetry with
-	 * acpi_lpss_runtime_suspend() one.
-	 */
-	if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available())
-		lpss_iosf_exit_d3_state();
+	if (pm_runtime_enabled(dev)) {
+		/*
+		 * This call is kept first to be in symmetry with
+		 * acpi_lpss_runtime_suspend() one.
+		 */
+		if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON &&
+		    iosf_mbi_available())
+			lpss_iosf_exit_d3_state();
 
-	ret = acpi_dev_runtime_resume(dev);
-	if (ret)
-		return ret;
+		ret = acpi_dev_runtime_resume(dev);
+		if (ret)
+			return ret;
 
-	acpi_lpss_d3_to_d0_delay(pdata);
+		acpi_lpss_d3_to_d0_delay(pdata);
 
-	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
-		acpi_lpss_restore_ctx(dev, pdata);
+		if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
+			acpi_lpss_restore_ctx(dev, pdata);
+
+	} else {
+		ret = lpss_resume_early(dev);
+		if (ret)
+			return ret;
+	}
 
 	return pm_generic_runtime_resume(dev);
 }
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index f7bf596..b595968 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -913,7 +913,14 @@ EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
 int acpi_subsys_runtime_suspend(struct device *dev)
 {
 	int ret = pm_generic_runtime_suspend(dev);
-	return ret ? ret : acpi_dev_runtime_suspend(dev);
+
+	if (ret)
+		return ret;
+
+	if (!pm_runtime_enabled(dev))
+		return acpi_dev_suspend_late(dev);
+
+	return acpi_dev_runtime_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend);
 
@@ -926,7 +933,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend);
  */
 int acpi_subsys_runtime_resume(struct device *dev)
 {
-	int ret = acpi_dev_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret = 0;
+
+	if (!adev)
+		return 0;
+
+	if (!pm_runtime_enabled(dev))
+		ret = acpi_dev_resume_early(dev);
+	else
+		ret = acpi_dev_runtime_resume(dev);
+
 	return ret ? ret : pm_generic_runtime_resume(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
@@ -939,6 +956,10 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
  * Per default the ACPI PM domain tries to use the direct_complete path for its
  * devices during system sleep. This function allows a user, typically a driver
  * during probe, to disable the direct_complete path from being used by ACPI.
+ * Moreover, the ACPI PM domain expects and depends on that such driver deploys
+ * the runtime PM centric path for system sleep. In other words, the driver must
+ * make use of the pm_runtime_force_suspend|resume() helpers when implementing
+ * system sleep.
  */
 void acpi_dev_disable_direct_complete(struct device *dev)
 {
@@ -1072,13 +1093,21 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  */
 void acpi_subsys_complete(struct device *dev)
 {
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return;
+
 	pm_generic_complete(dev);
 	/*
 	 * If the device had been runtime-suspended before the system went into
 	 * the sleep state it is going out of and it has never been resumed till
-	 * now, resume it in case the firmware powered it up.
+	 * now, resume it in case the firmware powered it up. Also resume it in
+	 * case no_direct_complete is set for the device, to be sure the device
+	 * are managed correctly when firmware has powered it up.
 	 */
-	if (dev->power.direct_complete && pm_resume_via_firmware())
+	if ((dev->power.direct_complete || adev->power.no_direct_complete) &&
+	    pm_resume_via_firmware())
 		pm_request_resume(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_complete);
@@ -1106,8 +1135,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
  */
 int acpi_subsys_suspend_late(struct device *dev)
 {
-	int ret = pm_generic_suspend_late(dev);
-	return ret ? ret : acpi_dev_suspend_late(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	if (!adev)
+		return 0;
+
+	ret = pm_generic_suspend_late(dev);
+	if (ret || adev->power.no_direct_complete)
+		return ret;
+
+	return acpi_dev_suspend_late(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
 
@@ -1121,7 +1159,15 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
  */
 int acpi_subsys_resume_early(struct device *dev)
 {
-	int ret = acpi_dev_resume_early(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret = 0;
+
+	if (!adev)
+		return 0;
+
+	if (!adev->power.no_direct_complete)
+		ret = acpi_dev_resume_early(dev);
+
 	return ret ? ret : pm_generic_resume_early(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 6/9] PM / ACPI: Enable the runtime PM centric approach for system sleep
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

This change extends the interpretation of the ACPI's no_direct_complete
flag to be used to enable the so called runtime PM centric approach, for
devices being attached to the ACPI PM domain.

The principle behind the runtime PM centric approach is to re-use the
runtime PM callbacks to implement system sleep for drivers/subsystems.
Moreover, using the runtime PM centric approach gives an optimized
behaviour around avoiding to wake up a device from its low power state
during system sleep, unless really needed.

To deploy the runtime PM centric approach for a subsystem/driver, the
following adaptations needs to be made.

First, the runtime PM callbacks may be called when runtime PM has been
disabled for the device. This serves as an indication for the callbacks to
understand they are running in the system sleep sequence, instead of in the
regular runtime PM path. In some cases, a callback needs to take different
actions depending in what path it is being executed in, as is the case for
the ACPI PM domain.

In particular for the ACPI PM domain's ->runtime_suspend|resume()
callbacks, when those finds runtime PM being disabled for the device, it
instead executes the same operations as normally being run when
->suspend_late() and ->resume_early() callbacks are invoked during system
sleep.

Second, at the PM domain level, it is expected that the driver for the
device makes use of pm_runtime_force_suspend|resume(), to re-use the
runtime PM callbacks to put the device into low power state and to wake it
up when needed during system sleep.

For the ACPI PM domain's ->suspend_late() and ->resume_early() callbacks,
it means bypassing the operations putting the device into low power state
and the operations that wakes it up. Instead it shall invoke only the lower
level ->suspend_late() and ->resume_early() callbacks for the driver, if
present.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Rebased.
	- Updated header for acpi_enable|disable_no_direct_complete().

---
 drivers/acpi/acpi_lpss.c | 58 +++++++++++++++++++++++++++++++---------------
 drivers/acpi/device_pm.c | 60 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 93 insertions(+), 25 deletions(-)

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index e726173..f0d1141 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -729,10 +729,11 @@ static int lpss_suspend_late(struct device *dev)
 
 static int acpi_lpss_suspend_late(struct device *dev)
 {
+	struct acpi_device *adev = ACPI_COMPANION(dev);
 	int ret;
 
 	ret = pm_generic_suspend_late(dev);
-	if (ret)
+	if (ret || adev->power.no_direct_complete)
 		return ret;
 
 	return lpss_suspend_late(dev);
@@ -757,13 +758,23 @@ static int lpss_resume_early(struct device *dev)
 
 static int acpi_lpss_resume_early(struct device *dev)
 {
-	int ret;
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret = 0;
 
-	ret = lpss_resume_early(dev);
-	if (ret)
-		return ret;
+	if (!adev->power.no_direct_complete)
+		ret = lpss_resume_early(dev);
 
-	return pm_generic_resume_early(dev);
+	return ret ? ret : pm_generic_resume_early(dev);
+}
+#else
+static inline int lpss_suspend_late(struct device *dev)
+{
+	return 0;
+}
+
+static inline int lpss_resume_early(struct device *dev)
+{
+	return 0;
 }
 #endif /* CONFIG_PM_SLEEP */
 
@@ -861,6 +872,9 @@ static int acpi_lpss_runtime_suspend(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (!pm_runtime_enabled(dev))
+		return lpss_suspend_late(dev);
+
 	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
 		acpi_lpss_save_ctx(dev, pdata);
 
@@ -882,21 +896,29 @@ static int acpi_lpss_runtime_resume(struct device *dev)
 	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
 	int ret;
 
-	/*
-	 * This call is kept first to be in symmetry with
-	 * acpi_lpss_runtime_suspend() one.
-	 */
-	if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON && iosf_mbi_available())
-		lpss_iosf_exit_d3_state();
+	if (pm_runtime_enabled(dev)) {
+		/*
+		 * This call is kept first to be in symmetry with
+		 * acpi_lpss_runtime_suspend() one.
+		 */
+		if (lpss_quirks & LPSS_QUIRK_ALWAYS_POWER_ON &&
+		    iosf_mbi_available())
+			lpss_iosf_exit_d3_state();
 
-	ret = acpi_dev_runtime_resume(dev);
-	if (ret)
-		return ret;
+		ret = acpi_dev_runtime_resume(dev);
+		if (ret)
+			return ret;
 
-	acpi_lpss_d3_to_d0_delay(pdata);
+		acpi_lpss_d3_to_d0_delay(pdata);
 
-	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
-		acpi_lpss_restore_ctx(dev, pdata);
+		if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
+			acpi_lpss_restore_ctx(dev, pdata);
+
+	} else {
+		ret = lpss_resume_early(dev);
+		if (ret)
+			return ret;
+	}
 
 	return pm_generic_runtime_resume(dev);
 }
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index f7bf596..b595968 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -913,7 +913,14 @@ EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
 int acpi_subsys_runtime_suspend(struct device *dev)
 {
 	int ret = pm_generic_runtime_suspend(dev);
-	return ret ? ret : acpi_dev_runtime_suspend(dev);
+
+	if (ret)
+		return ret;
+
+	if (!pm_runtime_enabled(dev))
+		return acpi_dev_suspend_late(dev);
+
+	return acpi_dev_runtime_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend);
 
@@ -926,7 +933,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend);
  */
 int acpi_subsys_runtime_resume(struct device *dev)
 {
-	int ret = acpi_dev_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret = 0;
+
+	if (!adev)
+		return 0;
+
+	if (!pm_runtime_enabled(dev))
+		ret = acpi_dev_resume_early(dev);
+	else
+		ret = acpi_dev_runtime_resume(dev);
+
 	return ret ? ret : pm_generic_runtime_resume(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
@@ -939,6 +956,10 @@ EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
  * Per default the ACPI PM domain tries to use the direct_complete path for its
  * devices during system sleep. This function allows a user, typically a driver
  * during probe, to disable the direct_complete path from being used by ACPI.
+ * Moreover, the ACPI PM domain expects and depends on that such driver deploys
+ * the runtime PM centric path for system sleep. In other words, the driver must
+ * make use of the pm_runtime_force_suspend|resume() helpers when implementing
+ * system sleep.
  */
 void acpi_dev_disable_direct_complete(struct device *dev)
 {
@@ -1072,13 +1093,21 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  */
 void acpi_subsys_complete(struct device *dev)
 {
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return;
+
 	pm_generic_complete(dev);
 	/*
 	 * If the device had been runtime-suspended before the system went into
 	 * the sleep state it is going out of and it has never been resumed till
-	 * now, resume it in case the firmware powered it up.
+	 * now, resume it in case the firmware powered it up. Also resume it in
+	 * case no_direct_complete is set for the device, to be sure the device
+	 * are managed correctly when firmware has powered it up.
 	 */
-	if (dev->power.direct_complete && pm_resume_via_firmware())
+	if ((dev->power.direct_complete || adev->power.no_direct_complete) &&
+	    pm_resume_via_firmware())
 		pm_request_resume(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_complete);
@@ -1106,8 +1135,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
  */
 int acpi_subsys_suspend_late(struct device *dev)
 {
-	int ret = pm_generic_suspend_late(dev);
-	return ret ? ret : acpi_dev_suspend_late(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	if (!adev)
+		return 0;
+
+	ret = pm_generic_suspend_late(dev);
+	if (ret || adev->power.no_direct_complete)
+		return ret;
+
+	return acpi_dev_suspend_late(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
 
@@ -1121,7 +1159,15 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
  */
 int acpi_subsys_resume_early(struct device *dev)
 {
-	int ret = acpi_dev_resume_early(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret = 0;
+
+	if (!adev)
+		return 0;
+
+	if (!adev->power.no_direct_complete)
+		ret = acpi_dev_resume_early(dev);
+
 	return ret ? ret : pm_generic_resume_early(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 7/9] PM / ACPI: Avoid runtime resuming device in acpi_subsys_suspend|freeze()
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

In the case when the no_direct_complete flag is set for the ACPI device, we
can under some conditions during system sleep, avoid runtime resuming the
device in acpi_subsys_suspend|freeze(). This means we can decrease the time
needed for the device to enter its system sleep state, but also that we can
avoid to waste power.

More precisely, calling acpi_dev_needs_resume() from the
acpi_subsys_suspend|freeze() in cases when the no_direct_complete flag has
been set for the device, tells us if a runtime resume of the device is
needed. Thus it may allow us to avoid it.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Clarified changelog.
	- Improved comments is code.
	- Rebased.
	- Improved change to avoid open-coding.

---
 drivers/acpi/device_pm.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index b595968..5dd23de 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1117,11 +1117,19 @@ EXPORT_SYMBOL_GPL(acpi_subsys_complete);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks. However, try to avoid it when no_direct_complete
+ * is set.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return 0;
+
+	if (!adev->power.no_direct_complete || acpi_dev_needs_resume(dev, adev))
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
@@ -1178,13 +1186,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
  */
 int acpi_subsys_freeze(struct device *dev)
 {
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return 0;
+
 	/*
 	 * This used to be done in acpi_subsys_prepare() for all devices and
 	 * some drivers may depend on it, so do it here.  Ideally, however,
 	 * runtime-suspended devices should not be touched during freeze/thaw
-	 * transitions.
+	 * transitions. In case the no_direct_complete is set, try to avoid it.
 	 */
-	pm_runtime_resume(dev);
+	if (!adev->power.no_direct_complete || acpi_dev_needs_resume(dev, adev))
+		pm_runtime_resume(dev);
+
 	return pm_generic_freeze(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_freeze);
-- 
2.7.4


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 7/9] PM / ACPI: Avoid runtime resuming device in acpi_subsys_suspend|freeze()
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

In the case when the no_direct_complete flag is set for the ACPI device, we
can under some conditions during system sleep, avoid runtime resuming the
device in acpi_subsys_suspend|freeze(). This means we can decrease the time
needed for the device to enter its system sleep state, but also that we can
avoid to waste power.

More precisely, calling acpi_dev_needs_resume() from the
acpi_subsys_suspend|freeze() in cases when the no_direct_complete flag has
been set for the device, tells us if a runtime resume of the device is
needed. Thus it may allow us to avoid it.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Clarified changelog.
	- Improved comments is code.
	- Rebased.
	- Improved change to avoid open-coding.

---
 drivers/acpi/device_pm.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index b595968..5dd23de 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -1117,11 +1117,19 @@ EXPORT_SYMBOL_GPL(acpi_subsys_complete);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks. However, try to avoid it when no_direct_complete
+ * is set.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return 0;
+
+	if (!adev->power.no_direct_complete || acpi_dev_needs_resume(dev, adev))
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
@@ -1178,13 +1186,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
  */
 int acpi_subsys_freeze(struct device *dev)
 {
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return 0;
+
 	/*
 	 * This used to be done in acpi_subsys_prepare() for all devices and
 	 * some drivers may depend on it, so do it here.  Ideally, however,
 	 * runtime-suspended devices should not be touched during freeze/thaw
-	 * transitions.
+	 * transitions. In case the no_direct_complete is set, try to avoid it.
 	 */
-	pm_runtime_resume(dev);
+	if (!adev->power.no_direct_complete || acpi_dev_needs_resume(dev, adev))
+		pm_runtime_resume(dev);
+
 	return pm_generic_freeze(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_freeze);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 8/9] i2c: designware: Don't resume device in the ->complete() callback
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

In case the PM core is able to use the direct_complete path during system
sleep for the i2c device, the device is runtime resumed in the ->complete()
callback. For ACPI platforms this is needed to synchronize the power state
of the device, while for non-ACPI platforms this is a waste.

To better deal with this, let's drop the ->complete() callback from the
i2c-dw-plat driver altogether, thus avoiding the runtime resume of the
device.

This change still plays well for the ACPI case, because the ACPI PM
domain's ->complete() callback, assigned to acpi_subsys_complete(), already
deals with runtime resuming the device in case it's needed.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- New patch.

---
 drivers/i2c/busses/i2c-designware-platdrv.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 441afc7..fc6b99f 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -418,15 +418,8 @@ static int dw_i2c_plat_prepare(struct device *dev)
 {
 	return pm_runtime_suspended(dev);
 }
-
-static void dw_i2c_plat_complete(struct device *dev)
-{
-	if (dev->power.direct_complete)
-		pm_request_resume(dev);
-}
 #else
 #define dw_i2c_plat_prepare	NULL
-#define dw_i2c_plat_complete	NULL
 #endif
 
 #ifdef CONFIG_PM
@@ -462,7 +455,6 @@ static int dw_i2c_plat_suspend(struct device *dev)
 
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
 	.prepare = dw_i2c_plat_prepare,
-	.complete = dw_i2c_plat_complete,
 	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend,
 			   dw_i2c_plat_resume,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 8/9] i2c: designware: Don't resume device in the ->complete() callback
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

In case the PM core is able to use the direct_complete path during system
sleep for the i2c device, the device is runtime resumed in the ->complete()
callback. For ACPI platforms this is needed to synchronize the power state
of the device, while for non-ACPI platforms this is a waste.

To better deal with this, let's drop the ->complete() callback from the
i2c-dw-plat driver altogether, thus avoiding the runtime resume of the
device.

This change still plays well for the ACPI case, because the ACPI PM
domain's ->complete() callback, assigned to acpi_subsys_complete(), already
deals with runtime resuming the device in case it's needed.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- New patch.

---
 drivers/i2c/busses/i2c-designware-platdrv.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 441afc7..fc6b99f 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -418,15 +418,8 @@ static int dw_i2c_plat_prepare(struct device *dev)
 {
 	return pm_runtime_suspended(dev);
 }
-
-static void dw_i2c_plat_complete(struct device *dev)
-{
-	if (dev->power.direct_complete)
-		pm_request_resume(dev);
-}
 #else
 #define dw_i2c_plat_prepare	NULL
-#define dw_i2c_plat_complete	NULL
 #endif
 
 #ifdef CONFIG_PM
@@ -462,7 +455,6 @@ static int dw_i2c_plat_suspend(struct device *dev)
 
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
 	.prepare = dw_i2c_plat_prepare,
-	.complete = dw_i2c_plat_complete,
 	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend,
 			   dw_i2c_plat_resume,
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 9/9] i2c: designware: Deploy the runtime PM centric approach for system sleep
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-23 14:42   ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: Wolfram Sang, Rafael J . Wysocki, Len Brown, linux-acpi, linux-pm
  Cc: Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Ulf Hansson

Currently the device is runtime resumed in the i2c-dw-plat driver's
->suspend() callback, which is needed to manage system sleep properly.

The particular reason for the runtime resume is because the PM core may
unset the direct_complete flag for a parent device, in case its child
device are being system suspended before. This leads to that the
i2c-dw-plat driver's ->suspend() callback can be invoked when the device is
runtime suspended.

Runtime resuming the device in this scenario may be unnecessary, in case
when the device is already in its proper lower power state for system
sleep. This behaviour increases the time it takes to put the device into
low power state, but means also a waste of power.

Let's fix the behaviour by deploying the runtime PM centric path for system
sleep, via assigning the pm_runtime_force_suspend|resume() helpers as the
system sleep callbacks for the i2c-dw-plat driver.

To deploy this, we must also make sure that the direct_complete path isn't
used for the device. Therefore we drop the ->prepare() callback from the
i2c-dw-plat driver and we inform the ACPI PM domain to not try out the
direct_complete path for the device, as that is the default behaviour for
the ACPI PM domain.

Along with the runtime PM centric path, we also get some additional
improvements of the behaviour during system sleep. More precisely:

*)
In case the device is/gets runtime resumed before the device_suspend()
phase is entered, the PM core doesn't run the direct_complete path for the
device during system sleep. During system resume, this lead to that the
device will always be brought back to full power when the i2c-dw-plat
driver's ->resume() callback is invoked. This may not be necessary, thus
increasing the resume time for the device and wasting power.

In the runtime PM centric path, the pm_runtime_force_resume() helper takes
better care, as it resumes the device only in case it's really needed.
Normally this means it can be postponed to be dealt with via regular calls
to runtime PM (pm_runtime_get*()) instead. In other words, the device
remains in its low power state until someone request a new i2c transfer,
whenever that may be.

**)
In case the device is runtime suspended when the ->prepare() callback is
invoked, the direct_complete path is tried by the PM core. If it succeeds,
this leads to disabling runtime PM for the device in the device_suspend()
phase. That is a problem in cases when others may need the device to be
operational, as to be able send i2c transfers during the entire
device_suspend() phase.

By using the runtime PM centric path, we postpones runtime PM to be
disabled for the device by the PM core to the regular device_suspend_late()
phase.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Rebased.
	- Clarify changelog.

---
 drivers/i2c/busses/i2c-designware-platdrv.c | 27 ++++++---------------------
 1 file changed, 6 insertions(+), 21 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index fc6b99f..e0cbf5e 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -372,6 +372,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
 	if (ret)
 		goto exit_probe;
 
+	acpi_dev_disable_direct_complete(&pdev->dev);
 	return ret;
 
 exit_probe:
@@ -387,6 +388,7 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
 {
 	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
 
+	acpi_dev_enable_direct_complete(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
 	i2c_del_adapter(&dev->adapter);
@@ -413,15 +415,6 @@ static const struct of_device_id dw_i2c_of_match[] = {
 MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
 #endif
 
-#ifdef CONFIG_PM_SLEEP
-static int dw_i2c_plat_prepare(struct device *dev)
-{
-	return pm_runtime_suspended(dev);
-}
-#else
-#define dw_i2c_plat_prepare	NULL
-#endif
-
 #ifdef CONFIG_PM
 static int dw_i2c_plat_runtime_suspend(struct device *dev)
 {
@@ -434,7 +427,7 @@ static int dw_i2c_plat_runtime_suspend(struct device *dev)
 	return 0;
 }
 
-static int dw_i2c_plat_resume(struct device *dev)
+static int dw_i2c_plat_runtime_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
@@ -445,19 +438,11 @@ static int dw_i2c_plat_resume(struct device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int dw_i2c_plat_suspend(struct device *dev)
-{
-	pm_runtime_resume(dev);
-	return dw_i2c_plat_runtime_suspend(dev);
-}
-#endif
-
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
-	.prepare = dw_i2c_plat_prepare,
-	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend,
-			   dw_i2c_plat_resume,
+			   dw_i2c_plat_runtime_resume,
 			   NULL)
 };
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 9/9] i2c: designware: Deploy the runtime PM centric approach for system sleep
@ 2017-08-23 14:42   ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-23 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

Currently the device is runtime resumed in the i2c-dw-plat driver's
->suspend() callback, which is needed to manage system sleep properly.

The particular reason for the runtime resume is because the PM core may
unset the direct_complete flag for a parent device, in case its child
device are being system suspended before. This leads to that the
i2c-dw-plat driver's ->suspend() callback can be invoked when the device is
runtime suspended.

Runtime resuming the device in this scenario may be unnecessary, in case
when the device is already in its proper lower power state for system
sleep. This behaviour increases the time it takes to put the device into
low power state, but means also a waste of power.

Let's fix the behaviour by deploying the runtime PM centric path for system
sleep, via assigning the pm_runtime_force_suspend|resume() helpers as the
system sleep callbacks for the i2c-dw-plat driver.

To deploy this, we must also make sure that the direct_complete path isn't
used for the device. Therefore we drop the ->prepare() callback from the
i2c-dw-plat driver and we inform the ACPI PM domain to not try out the
direct_complete path for the device, as that is the default behaviour for
the ACPI PM domain.

Along with the runtime PM centric path, we also get some additional
improvements of the behaviour during system sleep. More precisely:

*)
In case the device is/gets runtime resumed before the device_suspend()
phase is entered, the PM core doesn't run the direct_complete path for the
device during system sleep. During system resume, this lead to that the
device will always be brought back to full power when the i2c-dw-plat
driver's ->resume() callback is invoked. This may not be necessary, thus
increasing the resume time for the device and wasting power.

In the runtime PM centric path, the pm_runtime_force_resume() helper takes
better care, as it resumes the device only in case it's really needed.
Normally this means it can be postponed to be dealt with via regular calls
to runtime PM (pm_runtime_get*()) instead. In other words, the device
remains in its low power state until someone request a new i2c transfer,
whenever that may be.

**)
In case the device is runtime suspended when the ->prepare() callback is
invoked, the direct_complete path is tried by the PM core. If it succeeds,
this leads to disabling runtime PM for the device in the device_suspend()
phase. That is a problem in cases when others may need the device to be
operational, as to be able send i2c transfers during the entire
device_suspend() phase.

By using the runtime PM centric path, we postpones runtime PM to be
disabled for the device by the PM core to the regular device_suspend_late()
phase.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
---

Changes in v2:
	- Rebased.
	- Clarify changelog.

---
 drivers/i2c/busses/i2c-designware-platdrv.c | 27 ++++++---------------------
 1 file changed, 6 insertions(+), 21 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index fc6b99f..e0cbf5e 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -372,6 +372,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
 	if (ret)
 		goto exit_probe;
 
+	acpi_dev_disable_direct_complete(&pdev->dev);
 	return ret;
 
 exit_probe:
@@ -387,6 +388,7 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
 {
 	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
 
+	acpi_dev_enable_direct_complete(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
 	i2c_del_adapter(&dev->adapter);
@@ -413,15 +415,6 @@ static const struct of_device_id dw_i2c_of_match[] = {
 MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
 #endif
 
-#ifdef CONFIG_PM_SLEEP
-static int dw_i2c_plat_prepare(struct device *dev)
-{
-	return pm_runtime_suspended(dev);
-}
-#else
-#define dw_i2c_plat_prepare	NULL
-#endif
-
 #ifdef CONFIG_PM
 static int dw_i2c_plat_runtime_suspend(struct device *dev)
 {
@@ -434,7 +427,7 @@ static int dw_i2c_plat_runtime_suspend(struct device *dev)
 	return 0;
 }
 
-static int dw_i2c_plat_resume(struct device *dev)
+static int dw_i2c_plat_runtime_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
@@ -445,19 +438,11 @@ static int dw_i2c_plat_resume(struct device *dev)
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int dw_i2c_plat_suspend(struct device *dev)
-{
-	pm_runtime_resume(dev);
-	return dw_i2c_plat_runtime_suspend(dev);
-}
-#endif
-
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
-	.prepare = dw_i2c_plat_prepare,
-	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend,
-			   dw_i2c_plat_resume,
+			   dw_i2c_plat_runtime_resume,
 			   NULL)
 };
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 1/9] PM / ACPI: Restore acpi_subsys_complete()
  2017-08-23 14:42   ` Ulf Hansson
@ 2017-08-23 22:41     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-23 22:41 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Rafael J . Wysocki, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> The commit 58a1fbbb2ee8 ("PM / PCI / ACPI: Kick devices that might have
> been reset by firmware"), made PCI's and ACPI's ->complete() callbacks to
> be assigned to a new API called pm_complete_with_resume_check(), which was
> introduced in the same change.
>
> Later it turned out that using pm_complete_with_resume_check() isn't good
> enough for PCI, as it needs additional PCI specific checks, before deciding
> whether runtime resuming the device is needed when running the ->complete()
> callback.
>
> This leaves ACPI being the only user of pm_complete_with_resume_check().

I would say "the ACPI PM domain" instead of just "ACPI" here, because
in fact this is only about the ACPI PM domain.

This more-or-less applies to all of the changelogs in this series and
to some comments added by it too: please be specific that it is *only*
about the ACPI PM domain.

The patch itself is fine.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 1/9] PM / ACPI: Restore acpi_subsys_complete()
@ 2017-08-23 22:41     ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-23 22:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> The commit 58a1fbbb2ee8 ("PM / PCI / ACPI: Kick devices that might have
> been reset by firmware"), made PCI's and ACPI's ->complete() callbacks to
> be assigned to a new API called pm_complete_with_resume_check(), which was
> introduced in the same change.
>
> Later it turned out that using pm_complete_with_resume_check() isn't good
> enough for PCI, as it needs additional PCI specific checks, before deciding
> whether runtime resuming the device is needed when running the ->complete()
> callback.
>
> This leaves ACPI being the only user of pm_complete_with_resume_check().

I would say "the ACPI PM domain" instead of just "ACPI" here, because
in fact this is only about the ACPI PM domain.

This more-or-less applies to all of the changelogs in this series and
to some comments added by it too: please be specific that it is *only*
about the ACPI PM domain.

The patch itself is fine.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-23 14:42   ` Ulf Hansson
@ 2017-08-23 23:39     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-23 23:39 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Rafael J . Wysocki, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> In some cases a driver for an ACPI device needs to be able to prevent the
> ACPI PM domain from using the direct_complete path during system sleep.
>
> One typical case is when the driver for the device needs its device to stay
> runtime enabled, during the __device_suspend phase. This isn't the case
> when the direct_complete path is being executed by the PM core, as it then
> disables runtime PM for the device in __device_suspend(). Any following
> attempts to runtime resume the device after that point, just fails.

OK, that is a problem.

> A workaround to this problem is to let the driver runtime resume its device
> from its ->prepare() callback, as that would prevent the direct_complete
> path from being executed. However, that may often be a waste, especially if
> it turned out that no one really needed the device.
>
> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> drivers to inform the ACPI PM domain to change its default behaviour during
> system sleep, and thus control whether it may use the direct_complete path
> or not.

But I'm not sure this is the right place to address it as it very well
may affect a PCI device too.

Also, this is about the device and not about its ACPI companion
object, so putting the flag in there is somewhat unclean, so to speak.

It looks like we need a flag in dev_pm_info saying something along the
lines of "my system suspend callback can deal with runtime PM" that
will cause the direct_complete update to occur in
__device_suspend_late() instead of __device_suspend().

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-23 23:39     ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-23 23:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> In some cases a driver for an ACPI device needs to be able to prevent the
> ACPI PM domain from using the direct_complete path during system sleep.
>
> One typical case is when the driver for the device needs its device to stay
> runtime enabled, during the __device_suspend phase. This isn't the case
> when the direct_complete path is being executed by the PM core, as it then
> disables runtime PM for the device in __device_suspend(). Any following
> attempts to runtime resume the device after that point, just fails.

OK, that is a problem.

> A workaround to this problem is to let the driver runtime resume its device
> from its ->prepare() callback, as that would prevent the direct_complete
> path from being executed. However, that may often be a waste, especially if
> it turned out that no one really needed the device.
>
> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> drivers to inform the ACPI PM domain to change its default behaviour during
> system sleep, and thus control whether it may use the direct_complete path
> or not.

But I'm not sure this is the right place to address it as it very well
may affect a PCI device too.

Also, this is about the device and not about its ACPI companion
object, so putting the flag in there is somewhat unclean, so to speak.

It looks like we need a flag in dev_pm_info saying something along the
lines of "my system suspend callback can deal with runtime PM" that
will cause the direct_complete update to occur in
__device_suspend_late() instead of __device_suspend().

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-23 23:39     ` Rafael J. Wysocki
@ 2017-08-24  0:13       ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24  0:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Thursday, August 24, 2017 1:39:44 AM CEST Rafael J. Wysocki wrote:
> On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > In some cases a driver for an ACPI device needs to be able to prevent the
> > ACPI PM domain from using the direct_complete path during system sleep.
> >
> > One typical case is when the driver for the device needs its device to stay
> > runtime enabled, during the __device_suspend phase. This isn't the case
> > when the direct_complete path is being executed by the PM core, as it then
> > disables runtime PM for the device in __device_suspend(). Any following
> > attempts to runtime resume the device after that point, just fails.
> 
> OK, that is a problem.
> 
> > A workaround to this problem is to let the driver runtime resume its device
> > from its ->prepare() callback, as that would prevent the direct_complete
> > path from being executed. However, that may often be a waste, especially if
> > it turned out that no one really needed the device.
> >
> > For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> > drivers to inform the ACPI PM domain to change its default behaviour during
> > system sleep, and thus control whether it may use the direct_complete path
> > or not.
> 
> But I'm not sure this is the right place to address it as it very well
> may affect a PCI device too.
> 
> Also, this is about the device and not about its ACPI companion
> object, so putting the flag in there is somewhat unclean, so to speak.
> 
> It looks like we need a flag in dev_pm_info saying something along the
> lines of "my system suspend callback can deal with runtime PM" that
> will cause the direct_complete update to occur in
> __device_suspend_late() instead of __device_suspend().

IOW, something like the patch below.

It actually should work with the ACPI PM domain code as is except that it
will cause the device to be runtime resumed every time during suspend.

But acpi_subsys_suspend() can be changed to avoid resuming the device if
power.force_suspend is set.

---
 drivers/base/power/main.c |   11 +++++++++--
 include/linux/pm.h        |    1 +
 2 files changed, 10 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete && !dev->power.force_suspend) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -554,6 +554,7 @@ struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
 	unsigned int		async_suspend:1;
+	unsigned int		force_suspend:1;
 	bool			in_dpm_list:1;	/* Owned by the PM core */
 	bool			is_prepared:1;	/* Owned by the PM core */
 	bool			is_suspended:1;	/* Ditto */

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24  0:13       ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24  0:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, August 24, 2017 1:39:44 AM CEST Rafael J. Wysocki wrote:
> On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > In some cases a driver for an ACPI device needs to be able to prevent the
> > ACPI PM domain from using the direct_complete path during system sleep.
> >
> > One typical case is when the driver for the device needs its device to stay
> > runtime enabled, during the __device_suspend phase. This isn't the case
> > when the direct_complete path is being executed by the PM core, as it then
> > disables runtime PM for the device in __device_suspend(). Any following
> > attempts to runtime resume the device after that point, just fails.
> 
> OK, that is a problem.
> 
> > A workaround to this problem is to let the driver runtime resume its device
> > from its ->prepare() callback, as that would prevent the direct_complete
> > path from being executed. However, that may often be a waste, especially if
> > it turned out that no one really needed the device.
> >
> > For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> > drivers to inform the ACPI PM domain to change its default behaviour during
> > system sleep, and thus control whether it may use the direct_complete path
> > or not.
> 
> But I'm not sure this is the right place to address it as it very well
> may affect a PCI device too.
> 
> Also, this is about the device and not about its ACPI companion
> object, so putting the flag in there is somewhat unclean, so to speak.
> 
> It looks like we need a flag in dev_pm_info saying something along the
> lines of "my system suspend callback can deal with runtime PM" that
> will cause the direct_complete update to occur in
> __device_suspend_late() instead of __device_suspend().

IOW, something like the patch below.

It actually should work with the ACPI PM domain code as is except that it
will cause the device to be runtime resumed every time during suspend.

But acpi_subsys_suspend() can be changed to avoid resuming the device if
power.force_suspend is set.

---
 drivers/base/power/main.c |   11 +++++++++--
 include/linux/pm.h        |    1 +
 2 files changed, 10 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete && !dev->power.force_suspend) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -554,6 +554,7 @@ struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
 	unsigned int		async_suspend:1;
+	unsigned int		force_suspend:1;
 	bool			in_dpm_list:1;	/* Owned by the PM core */
 	bool			is_prepared:1;	/* Owned by the PM core */
 	bool			is_suspended:1;	/* Ditto */

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24  0:13       ` Rafael J. Wysocki
@ 2017-08-24  0:20         ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24  0:20 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Thursday, August 24, 2017 2:13:55 AM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 1:39:44 AM CEST Rafael J. Wysocki wrote:
> > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > In some cases a driver for an ACPI device needs to be able to prevent the
> > > ACPI PM domain from using the direct_complete path during system sleep.
> > >
> > > One typical case is when the driver for the device needs its device to stay
> > > runtime enabled, during the __device_suspend phase. This isn't the case
> > > when the direct_complete path is being executed by the PM core, as it then
> > > disables runtime PM for the device in __device_suspend(). Any following
> > > attempts to runtime resume the device after that point, just fails.
> > 
> > OK, that is a problem.
> > 
> > > A workaround to this problem is to let the driver runtime resume its device
> > > from its ->prepare() callback, as that would prevent the direct_complete
> > > path from being executed. However, that may often be a waste, especially if
> > > it turned out that no one really needed the device.
> > >
> > > For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> > > drivers to inform the ACPI PM domain to change its default behaviour during
> > > system sleep, and thus control whether it may use the direct_complete path
> > > or not.
> > 
> > But I'm not sure this is the right place to address it as it very well
> > may affect a PCI device too.
> > 
> > Also, this is about the device and not about its ACPI companion
> > object, so putting the flag in there is somewhat unclean, so to speak.
> > 
> > It looks like we need a flag in dev_pm_info saying something along the
> > lines of "my system suspend callback can deal with runtime PM" that
> > will cause the direct_complete update to occur in
> > __device_suspend_late() instead of __device_suspend().
> 
> IOW, something like the patch below.
> 
> It actually should work with the ACPI PM domain code as is except that it
> will cause the device to be runtime resumed every time during suspend.
> 
> But acpi_subsys_suspend() can be changed to avoid resuming the device if
> power.force_suspend is set.

Or better yet, if power.direct_complete is not set, because that means the
device needs to be resumed anyway.

And if power.direct_complete is set at that point, power.force_suspend has to
be set too.

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24  0:20         ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24  0:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, August 24, 2017 2:13:55 AM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 1:39:44 AM CEST Rafael J. Wysocki wrote:
> > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > In some cases a driver for an ACPI device needs to be able to prevent the
> > > ACPI PM domain from using the direct_complete path during system sleep.
> > >
> > > One typical case is when the driver for the device needs its device to stay
> > > runtime enabled, during the __device_suspend phase. This isn't the case
> > > when the direct_complete path is being executed by the PM core, as it then
> > > disables runtime PM for the device in __device_suspend(). Any following
> > > attempts to runtime resume the device after that point, just fails.
> > 
> > OK, that is a problem.
> > 
> > > A workaround to this problem is to let the driver runtime resume its device
> > > from its ->prepare() callback, as that would prevent the direct_complete
> > > path from being executed. However, that may often be a waste, especially if
> > > it turned out that no one really needed the device.
> > >
> > > For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> > > drivers to inform the ACPI PM domain to change its default behaviour during
> > > system sleep, and thus control whether it may use the direct_complete path
> > > or not.
> > 
> > But I'm not sure this is the right place to address it as it very well
> > may affect a PCI device too.
> > 
> > Also, this is about the device and not about its ACPI companion
> > object, so putting the flag in there is somewhat unclean, so to speak.
> > 
> > It looks like we need a flag in dev_pm_info saying something along the
> > lines of "my system suspend callback can deal with runtime PM" that
> > will cause the direct_complete update to occur in
> > __device_suspend_late() instead of __device_suspend().
> 
> IOW, something like the patch below.
> 
> It actually should work with the ACPI PM domain code as is except that it
> will cause the device to be runtime resumed every time during suspend.
> 
> But acpi_subsys_suspend() can be changed to avoid resuming the device if
> power.force_suspend is set.

Or better yet, if power.direct_complete is not set, because that means the
device needs to be resumed anyway.

And if power.direct_complete is set at that point, power.force_suspend has to
be set too.

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24  0:20         ` Rafael J. Wysocki
@ 2017-08-24  1:03           ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24  1:03 UTC (permalink / raw)
  To: Ulf Hansson; +Cc: Rafael J. Wysocki

On Thursday, August 24, 2017 2:20:00 AM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 2:13:55 AM CEST Rafael J. Wysocki wrote:
> > On Thursday, August 24, 2017 1:39:44 AM CEST Rafael J. Wysocki wrote:
> > > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > > In some cases a driver for an ACPI device needs to be able to prevent the
> > > > ACPI PM domain from using the direct_complete path during system sleep.
> > > >
> > > > One typical case is when the driver for the device needs its device to stay
> > > > runtime enabled, during the __device_suspend phase. This isn't the case
> > > > when the direct_complete path is being executed by the PM core, as it then
> > > > disables runtime PM for the device in __device_suspend(). Any following
> > > > attempts to runtime resume the device after that point, just fails.
> > > 
> > > OK, that is a problem.
> > > 
> > > > A workaround to this problem is to let the driver runtime resume its device
> > > > from its ->prepare() callback, as that would prevent the direct_complete
> > > > path from being executed. However, that may often be a waste, especially if
> > > > it turned out that no one really needed the device.
> > > >
> > > > For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> > > > drivers to inform the ACPI PM domain to change its default behaviour during
> > > > system sleep, and thus control whether it may use the direct_complete path
> > > > or not.
> > > 
> > > But I'm not sure this is the right place to address it as it very well
> > > may affect a PCI device too.
> > > 
> > > Also, this is about the device and not about its ACPI companion
> > > object, so putting the flag in there is somewhat unclean, so to speak.
> > > 
> > > It looks like we need a flag in dev_pm_info saying something along the
> > > lines of "my system suspend callback can deal with runtime PM" that
> > > will cause the direct_complete update to occur in
> > > __device_suspend_late() instead of __device_suspend().
> > 
> > IOW, something like the patch below.
> > 
> > It actually should work with the ACPI PM domain code as is except that it
> > will cause the device to be runtime resumed every time during suspend.
> > 
> > But acpi_subsys_suspend() can be changed to avoid resuming the device if
> > power.force_suspend is set.
> 
> Or better yet, if power.direct_complete is not set, because that means the
> device needs to be resumed anyway.
> 
> And if power.direct_complete is set at that point, power.force_suspend has to
> be set too.

Overall, like below, and of course drivers that ser power.force_suspend need to
be able to deal with devices that have been runtime resumed during
__device_suspend().

---
 drivers/acpi/device_pm.c  |    8 ++++++++
 drivers/base/power/main.c |   11 +++++++++--
 include/linux/pm.h        |    1 +
 3 files changed, 18 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete && !dev->power.force_suspend) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -554,6 +554,7 @@ struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
 	unsigned int		async_suspend:1;
+	unsigned int		force_suspend:1;
 	bool			in_dpm_list:1;	/* Owned by the PM core */
 	bool			is_prepared:1;	/* Owned by the PM core */
 	bool			is_suspended:1;	/* Ditto */
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  *
  * Follow PCI and resume devices suspended at run time before running their
  * system suspend callbacks.
+ *
+ * If the power.direct_complete flag is set for the device, though, skip all
+ * that, because the device doesn't need to be resumed then and if it is
+ * resumed via runtime PM, the core will notice that and will carry out the
+ * late suspend for it.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
+	if (dev->power.direct_complete)
+		return 0;
+
 	pm_runtime_resume(dev);
 	return pm_generic_suspend(dev);
 }

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24  1:03           ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24  1:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, August 24, 2017 2:20:00 AM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 2:13:55 AM CEST Rafael J. Wysocki wrote:
> > On Thursday, August 24, 2017 1:39:44 AM CEST Rafael J. Wysocki wrote:
> > > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> > > > In some cases a driver for an ACPI device needs to be able to prevent the
> > > > ACPI PM domain from using the direct_complete path during system sleep.
> > > >
> > > > One typical case is when the driver for the device needs its device to stay
> > > > runtime enabled, during the __device_suspend phase. This isn't the case
> > > > when the direct_complete path is being executed by the PM core, as it then
> > > > disables runtime PM for the device in __device_suspend(). Any following
> > > > attempts to runtime resume the device after that point, just fails.
> > > 
> > > OK, that is a problem.
> > > 
> > > > A workaround to this problem is to let the driver runtime resume its device
> > > > from its ->prepare() callback, as that would prevent the direct_complete
> > > > path from being executed. However, that may often be a waste, especially if
> > > > it turned out that no one really needed the device.
> > > >
> > > > For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> > > > drivers to inform the ACPI PM domain to change its default behaviour during
> > > > system sleep, and thus control whether it may use the direct_complete path
> > > > or not.
> > > 
> > > But I'm not sure this is the right place to address it as it very well
> > > may affect a PCI device too.
> > > 
> > > Also, this is about the device and not about its ACPI companion
> > > object, so putting the flag in there is somewhat unclean, so to speak.
> > > 
> > > It looks like we need a flag in dev_pm_info saying something along the
> > > lines of "my system suspend callback can deal with runtime PM" that
> > > will cause the direct_complete update to occur in
> > > __device_suspend_late() instead of __device_suspend().
> > 
> > IOW, something like the patch below.
> > 
> > It actually should work with the ACPI PM domain code as is except that it
> > will cause the device to be runtime resumed every time during suspend.
> > 
> > But acpi_subsys_suspend() can be changed to avoid resuming the device if
> > power.force_suspend is set.
> 
> Or better yet, if power.direct_complete is not set, because that means the
> device needs to be resumed anyway.
> 
> And if power.direct_complete is set at that point, power.force_suspend has to
> be set too.

Overall, like below, and of course drivers that ser power.force_suspend need to
be able to deal with devices that have been runtime resumed during
__device_suspend().

---
 drivers/acpi/device_pm.c  |    8 ++++++++
 drivers/base/power/main.c |   11 +++++++++--
 include/linux/pm.h        |    1 +
 3 files changed, 18 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete && !dev->power.force_suspend) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -554,6 +554,7 @@ struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
 	unsigned int		async_suspend:1;
+	unsigned int		force_suspend:1;
 	bool			in_dpm_list:1;	/* Owned by the PM core */
 	bool			is_prepared:1;	/* Owned by the PM core */
 	bool			is_suspended:1;	/* Ditto */
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  *
  * Follow PCI and resume devices suspended at run time before running their
  * system suspend callbacks.
+ *
+ * If the power.direct_complete flag is set for the device, though, skip all
+ * that, because the device doesn't need to be resumed then and if it is
+ * resumed via runtime PM, the core will notice that and will carry out the
+ * late suspend for it.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
+	if (dev->power.direct_complete)
+		return 0;
+
 	pm_runtime_resume(dev);
 	return pm_generic_suspend(dev);
 }

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-23 23:39     ` Rafael J. Wysocki
@ 2017-08-24  8:19       ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-24  8:19 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Wolfram Sang, Rafael J . Wysocki, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On 24 August 2017 at 01:39, Rafael J. Wysocki <rafael@kernel.org> wrote:
> On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> In some cases a driver for an ACPI device needs to be able to prevent the
>> ACPI PM domain from using the direct_complete path during system sleep.
>>
>> One typical case is when the driver for the device needs its device to stay
>> runtime enabled, during the __device_suspend phase. This isn't the case
>> when the direct_complete path is being executed by the PM core, as it then
>> disables runtime PM for the device in __device_suspend(). Any following
>> attempts to runtime resume the device after that point, just fails.
>
> OK, that is a problem.
>
>> A workaround to this problem is to let the driver runtime resume its device
>> from its ->prepare() callback, as that would prevent the direct_complete
>> path from being executed. However, that may often be a waste, especially if
>> it turned out that no one really needed the device.
>>
>> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
>> drivers to inform the ACPI PM domain to change its default behaviour during
>> system sleep, and thus control whether it may use the direct_complete path
>> or not.
>
> But I'm not sure this is the right place to address it as it very well
> may affect a PCI device too.
>
> Also, this is about the device and not about its ACPI companion
> object, so putting the flag in there is somewhat unclean, so to speak.
>
> It looks like we need a flag in dev_pm_info saying something along the
> lines of "my system suspend callback can deal with runtime PM" that
> will cause the direct_complete update to occur in
> __device_suspend_late() instead of __device_suspend().

I realize that in the end this turns out to be a comparison between
the runtime PM centric path and the direct_complete path while
implementing system sleep. In patch 9, there is some more explanation
around this, however if you like I can elaborate even more about
this!?

Regarding making changes to the PM core and adding more flags to the
dev_pm_info etc, I am not sure we really want that. Isn't it already
complex enough?

My point is, that I am trying to improve the behavior of the ACPI PM
domain by enabling the runtime PM centric path for it, and even if
there is something similar that could be done for PCI, I don't think
we should need involvement by the PM core.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24  8:19       ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-24  8:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 24 August 2017 at 01:39, Rafael J. Wysocki <rafael@kernel.org> wrote:
> On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> In some cases a driver for an ACPI device needs to be able to prevent the
>> ACPI PM domain from using the direct_complete path during system sleep.
>>
>> One typical case is when the driver for the device needs its device to stay
>> runtime enabled, during the __device_suspend phase. This isn't the case
>> when the direct_complete path is being executed by the PM core, as it then
>> disables runtime PM for the device in __device_suspend(). Any following
>> attempts to runtime resume the device after that point, just fails.
>
> OK, that is a problem.
>
>> A workaround to this problem is to let the driver runtime resume its device
>> from its ->prepare() callback, as that would prevent the direct_complete
>> path from being executed. However, that may often be a waste, especially if
>> it turned out that no one really needed the device.
>>
>> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
>> drivers to inform the ACPI PM domain to change its default behaviour during
>> system sleep, and thus control whether it may use the direct_complete path
>> or not.
>
> But I'm not sure this is the right place to address it as it very well
> may affect a PCI device too.
>
> Also, this is about the device and not about its ACPI companion
> object, so putting the flag in there is somewhat unclean, so to speak.
>
> It looks like we need a flag in dev_pm_info saying something along the
> lines of "my system suspend callback can deal with runtime PM" that
> will cause the direct_complete update to occur in
> __device_suspend_late() instead of __device_suspend().

I realize that in the end this turns out to be a comparison between
the runtime PM centric path and the direct_complete path while
implementing system sleep. In patch 9, there is some more explanation
around this, however if you like I can elaborate even more about
this!?

Regarding making changes to the PM core and adding more flags to the
dev_pm_info etc, I am not sure we really want that. Isn't it already
complex enough?

My point is, that I am trying to improve the behavior of the ACPI PM
domain by enabling the runtime PM centric path for it, and even if
there is something similar that could be done for PCI, I don't think
we should need involvement by the PM core.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24  1:03           ` Rafael J. Wysocki
@ 2017-08-24  9:15             ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-24  9:15 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

[...]

>> >
>> > It actually should work with the ACPI PM domain code as is except that it
>> > will cause the device to be runtime resumed every time during suspend.
>> >
>> > But acpi_subsys_suspend() can be changed to avoid resuming the device if
>> > power.force_suspend is set.
>>
>> Or better yet, if power.direct_complete is not set, because that means the
>> device needs to be resumed anyway.
>>
>> And if power.direct_complete is set at that point, power.force_suspend has to
>> be set too.

I believe I understand your goal here. You want to consider if it is
possible to extend the behavior of the direct_complete path, instead
of enabling the runtime PM centric path for the ACPI PM domain, to
accomplish the same optimizations.

I think the answer to that, is that it simply can't. See more
information about why further down below.

>
> Overall, like below, and of course drivers that ser power.force_suspend need to
> be able to deal with devices that have been runtime resumed during
> __device_suspend().

The a concern I see with this approach, is that is going to be too
complex to understand.

We have already seen how the i2c-designware-driver was screwed up when
it was trying to take advantage of the optimizations provided by the
current direct_complete path. I think we should be careful when
considering making it even more complex.

In the runtime PM centric path, driver authors can easily deploy
system sleep support. In some cases it may even consists of only two
lines of code. As can be shown in patch9 for the i2c driver.

Just to be clear, that doesn't mean that I think the direct_complete
path isn't useful. Especially it is a good match for the ACPI PM
domain, as it can easily affect all its devices, without having to
care much about the behavior of the drivers.

>
> ---
>  drivers/acpi/device_pm.c  |    8 ++++++++
>  drivers/base/power/main.c |   11 +++++++++--
>  include/linux/pm.h        |    1 +
>  3 files changed, 18 insertions(+), 2 deletions(-)
>
> Index: linux-pm/drivers/base/power/main.c
> ===================================================================
> --- linux-pm.orig/drivers/base/power/main.c
> +++ linux-pm/drivers/base/power/main.c
> @@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
>                 goto Complete;
>         }
>
> -       if (dev->power.syscore || dev->power.direct_complete)
> +       if (dev->power.syscore)
>                 goto Complete;
>
> +       if (dev->power.direct_complete) {
> +               if (pm_runtime_status_suspended(dev))
> +                       goto Complete;
> +
> +               dev->power.direct_complete = false;
> +       }
> +
>         if (dev->pm_domain) {
>                 info = "late power domain ";
>                 callback = pm_late_early_op(&dev->pm_domain->ops, state);
> @@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
>         if (dev->power.syscore)
>                 goto Complete;
>
> -       if (dev->power.direct_complete) {
> +       if (dev->power.direct_complete && !dev->power.force_suspend) {
>                 if (pm_runtime_status_suspended(dev)) {
>                         pm_runtime_disable(dev);
>                         if (pm_runtime_status_suspended(dev))
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -554,6 +554,7 @@ struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
>         unsigned int            async_suspend:1;
> +       unsigned int            force_suspend:1;
>         bool                    in_dpm_list:1;  /* Owned by the PM core */
>         bool                    is_prepared:1;  /* Owned by the PM core */
>         bool                    is_suspended:1; /* Ditto */
> Index: linux-pm/drivers/acpi/device_pm.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/device_pm.c
> +++ linux-pm/drivers/acpi/device_pm.c
> @@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>   *
>   * Follow PCI and resume devices suspended at run time before running their
>   * system suspend callbacks.
> + *
> + * If the power.direct_complete flag is set for the device, though, skip all
> + * that, because the device doesn't need to be resumed then and if it is
> + * resumed via runtime PM, the core will notice that and will carry out the
> + * late suspend for it.
>   */
>  int acpi_subsys_suspend(struct device *dev)
>  {
> +       if (dev->power.direct_complete)
> +               return 0;
> +
>         pm_runtime_resume(dev);
>         return pm_generic_suspend(dev);
>  }
>

The above change would offer an improvement, however there are more
benefits from the runtime PM centric path that it doesn't cover. The
below is pasted from the changelog for patch9 (I will make sure to
fold in this in the changelog for $subject patch next version).

In case the device is/gets runtime resumed before the device_suspend()
phase is entered, the PM core doesn't run the direct_complete path for
the device during system sleep. During system resume, this lead to
that the device will always be brought back to full power when the
i2c-dw-plat driver's ->resume() callback is invoked. This may not be
necessary, thus increasing the resume time for the device and wasting
power.

In the runtime PM centric path, the pm_runtime_force_resume() helper
takes better care, as it resumes the device only in case it's really
needed. Normally this means it can be postponed to be dealt with via
regular calls to runtime PM (pm_runtime_get*()) instead. In other
words, the device remains in its low power state until someone request
a new i2c transfer, whenever that may be.

As far as I can think of, the direct_complete path can't be adjusted
to support this. Or can it?

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24  9:15             ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-24  9:15 UTC (permalink / raw)
  To: linux-arm-kernel

[...]

>> >
>> > It actually should work with the ACPI PM domain code as is except that it
>> > will cause the device to be runtime resumed every time during suspend.
>> >
>> > But acpi_subsys_suspend() can be changed to avoid resuming the device if
>> > power.force_suspend is set.
>>
>> Or better yet, if power.direct_complete is not set, because that means the
>> device needs to be resumed anyway.
>>
>> And if power.direct_complete is set at that point, power.force_suspend has to
>> be set too.

I believe I understand your goal here. You want to consider if it is
possible to extend the behavior of the direct_complete path, instead
of enabling the runtime PM centric path for the ACPI PM domain, to
accomplish the same optimizations.

I think the answer to that, is that it simply can't. See more
information about why further down below.

>
> Overall, like below, and of course drivers that ser power.force_suspend need to
> be able to deal with devices that have been runtime resumed during
> __device_suspend().

The a concern I see with this approach, is that is going to be too
complex to understand.

We have already seen how the i2c-designware-driver was screwed up when
it was trying to take advantage of the optimizations provided by the
current direct_complete path. I think we should be careful when
considering making it even more complex.

In the runtime PM centric path, driver authors can easily deploy
system sleep support. In some cases it may even consists of only two
lines of code. As can be shown in patch9 for the i2c driver.

Just to be clear, that doesn't mean that I think the direct_complete
path isn't useful. Especially it is a good match for the ACPI PM
domain, as it can easily affect all its devices, without having to
care much about the behavior of the drivers.

>
> ---
>  drivers/acpi/device_pm.c  |    8 ++++++++
>  drivers/base/power/main.c |   11 +++++++++--
>  include/linux/pm.h        |    1 +
>  3 files changed, 18 insertions(+), 2 deletions(-)
>
> Index: linux-pm/drivers/base/power/main.c
> ===================================================================
> --- linux-pm.orig/drivers/base/power/main.c
> +++ linux-pm/drivers/base/power/main.c
> @@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
>                 goto Complete;
>         }
>
> -       if (dev->power.syscore || dev->power.direct_complete)
> +       if (dev->power.syscore)
>                 goto Complete;
>
> +       if (dev->power.direct_complete) {
> +               if (pm_runtime_status_suspended(dev))
> +                       goto Complete;
> +
> +               dev->power.direct_complete = false;
> +       }
> +
>         if (dev->pm_domain) {
>                 info = "late power domain ";
>                 callback = pm_late_early_op(&dev->pm_domain->ops, state);
> @@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
>         if (dev->power.syscore)
>                 goto Complete;
>
> -       if (dev->power.direct_complete) {
> +       if (dev->power.direct_complete && !dev->power.force_suspend) {
>                 if (pm_runtime_status_suspended(dev)) {
>                         pm_runtime_disable(dev);
>                         if (pm_runtime_status_suspended(dev))
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -554,6 +554,7 @@ struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
>         unsigned int            async_suspend:1;
> +       unsigned int            force_suspend:1;
>         bool                    in_dpm_list:1;  /* Owned by the PM core */
>         bool                    is_prepared:1;  /* Owned by the PM core */
>         bool                    is_suspended:1; /* Ditto */
> Index: linux-pm/drivers/acpi/device_pm.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/device_pm.c
> +++ linux-pm/drivers/acpi/device_pm.c
> @@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>   *
>   * Follow PCI and resume devices suspended at run time before running their
>   * system suspend callbacks.
> + *
> + * If the power.direct_complete flag is set for the device, though, skip all
> + * that, because the device doesn't need to be resumed then and if it is
> + * resumed via runtime PM, the core will notice that and will carry out the
> + * late suspend for it.
>   */
>  int acpi_subsys_suspend(struct device *dev)
>  {
> +       if (dev->power.direct_complete)
> +               return 0;
> +
>         pm_runtime_resume(dev);
>         return pm_generic_suspend(dev);
>  }
>

The above change would offer an improvement, however there are more
benefits from the runtime PM centric path that it doesn't cover. The
below is pasted from the changelog for patch9 (I will make sure to
fold in this in the changelog for $subject patch next version).

In case the device is/gets runtime resumed before the device_suspend()
phase is entered, the PM core doesn't run the direct_complete path for
the device during system sleep. During system resume, this lead to
that the device will always be brought back to full power when the
i2c-dw-plat driver's ->resume() callback is invoked. This may not be
necessary, thus increasing the resume time for the device and wasting
power.

In the runtime PM centric path, the pm_runtime_force_resume() helper
takes better care, as it resumes the device only in case it's really
needed. Normally this means it can be postponed to be dealt with via
regular calls to runtime PM (pm_runtime_get*()) instead. In other
words, the device remains in its low power state until someone request
a new i2c transfer, whenever that may be.

As far as I can think of, the direct_complete path can't be adjusted
to support this. Or can it?

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24  8:19       ` Ulf Hansson
@ 2017-08-24 14:57         ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24 14:57 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Thursday, August 24, 2017 10:19:43 AM CEST Ulf Hansson wrote:
> On 24 August 2017 at 01:39, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >> In some cases a driver for an ACPI device needs to be able to prevent the
> >> ACPI PM domain from using the direct_complete path during system sleep.
> >>
> >> One typical case is when the driver for the device needs its device to stay
> >> runtime enabled, during the __device_suspend phase. This isn't the case
> >> when the direct_complete path is being executed by the PM core, as it then
> >> disables runtime PM for the device in __device_suspend(). Any following
> >> attempts to runtime resume the device after that point, just fails.
> >
> > OK, that is a problem.
> >
> >> A workaround to this problem is to let the driver runtime resume its device
> >> from its ->prepare() callback, as that would prevent the direct_complete
> >> path from being executed. However, that may often be a waste, especially if
> >> it turned out that no one really needed the device.
> >>
> >> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> >> drivers to inform the ACPI PM domain to change its default behaviour during
> >> system sleep, and thus control whether it may use the direct_complete path
> >> or not.
> >
> > But I'm not sure this is the right place to address it as it very well
> > may affect a PCI device too.
> >
> > Also, this is about the device and not about its ACPI companion
> > object, so putting the flag in there is somewhat unclean, so to speak.
> >
> > It looks like we need a flag in dev_pm_info saying something along the
> > lines of "my system suspend callback can deal with runtime PM" that
> > will cause the direct_complete update to occur in
> > __device_suspend_late() instead of __device_suspend().
> 
> I realize that in the end this turns out to be a comparison between
> the runtime PM centric path and the direct_complete path while
> implementing system sleep. In patch 9, there is some more explanation
> around this, however if you like I can elaborate even more about
> this!?
> 
> Regarding making changes to the PM core and adding more flags to the
> dev_pm_info etc, I am not sure we really want that. Isn't it already
> complex enough?

Maybe it is.

> My point is, that I am trying to improve the behavior of the ACPI PM
> domain by enabling the runtime PM centric path for it, and even if
> there is something similar that could be done for PCI, I don't think
> we should need involvement by the PM core.

Well, this generally simply doesn't work.

The whole "runtime PM centric approach" idea is generally fine by me,
but the fact today is that there are drivers not ready for it.  Which
is why there is the direct_complete thing (it may be regarded as a
sort-of workaround for the unreadiness of drivers if you will).

Now, buy adding the no_direct_complete flag just to the ACPI PM domain
you basically overlook the fact that this potentially affects the parents
of the devices in question by preventing direct_complete from being set
for them.  And those parents may not be in the ACPI PM domain in principle,
so the problem needs to be addressed in the core.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24 14:57         ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, August 24, 2017 10:19:43 AM CEST Ulf Hansson wrote:
> On 24 August 2017 at 01:39, Rafael J. Wysocki <rafael@kernel.org> wrote:
> > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >> In some cases a driver for an ACPI device needs to be able to prevent the
> >> ACPI PM domain from using the direct_complete path during system sleep.
> >>
> >> One typical case is when the driver for the device needs its device to stay
> >> runtime enabled, during the __device_suspend phase. This isn't the case
> >> when the direct_complete path is being executed by the PM core, as it then
> >> disables runtime PM for the device in __device_suspend(). Any following
> >> attempts to runtime resume the device after that point, just fails.
> >
> > OK, that is a problem.
> >
> >> A workaround to this problem is to let the driver runtime resume its device
> >> from its ->prepare() callback, as that would prevent the direct_complete
> >> path from being executed. However, that may often be a waste, especially if
> >> it turned out that no one really needed the device.
> >>
> >> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
> >> drivers to inform the ACPI PM domain to change its default behaviour during
> >> system sleep, and thus control whether it may use the direct_complete path
> >> or not.
> >
> > But I'm not sure this is the right place to address it as it very well
> > may affect a PCI device too.
> >
> > Also, this is about the device and not about its ACPI companion
> > object, so putting the flag in there is somewhat unclean, so to speak.
> >
> > It looks like we need a flag in dev_pm_info saying something along the
> > lines of "my system suspend callback can deal with runtime PM" that
> > will cause the direct_complete update to occur in
> > __device_suspend_late() instead of __device_suspend().
> 
> I realize that in the end this turns out to be a comparison between
> the runtime PM centric path and the direct_complete path while
> implementing system sleep. In patch 9, there is some more explanation
> around this, however if you like I can elaborate even more about
> this!?
> 
> Regarding making changes to the PM core and adding more flags to the
> dev_pm_info etc, I am not sure we really want that. Isn't it already
> complex enough?

Maybe it is.

> My point is, that I am trying to improve the behavior of the ACPI PM
> domain by enabling the runtime PM centric path for it, and even if
> there is something similar that could be done for PCI, I don't think
> we should need involvement by the PM core.

Well, this generally simply doesn't work.

The whole "runtime PM centric approach" idea is generally fine by me,
but the fact today is that there are drivers not ready for it.  Which
is why there is the direct_complete thing (it may be regarded as a
sort-of workaround for the unreadiness of drivers if you will).

Now, buy adding the no_direct_complete flag just to the ACPI PM domain
you basically overlook the fact that this potentially affects the parents
of the devices in question by preventing direct_complete from being set
for them.  And those parents may not be in the ACPI PM domain in principle,
so the problem needs to be addressed in the core.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24  9:15             ` Ulf Hansson
@ 2017-08-24 16:35               ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24 16:35 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> [...]
> 
> >> >
> >> > It actually should work with the ACPI PM domain code as is except that it
> >> > will cause the device to be runtime resumed every time during suspend.
> >> >
> >> > But acpi_subsys_suspend() can be changed to avoid resuming the device if
> >> > power.force_suspend is set.
> >>
> >> Or better yet, if power.direct_complete is not set, because that means the
> >> device needs to be resumed anyway.
> >>
> >> And if power.direct_complete is set at that point, power.force_suspend has to
> >> be set too.
> 
> I believe I understand your goal here. You want to consider if it is
> possible to extend the behavior of the direct_complete path, instead
> of enabling the runtime PM centric path for the ACPI PM domain, to
> accomplish the same optimizations.

This isn't really "instead of", but rather "in addition to".

> I think the answer to that, is that it simply can't. See more
> information about why further down below.
> 
> >
> > Overall, like below, and of course drivers that ser power.force_suspend need to
> > be able to deal with devices that have been runtime resumed during
> > __device_suspend().
> 
> The a concern I see with this approach, is that is going to be too
> complex to understand.

That is a valid concern, but then your approach with using an extra flag
just for the ACPI PM domain isn't particularly straightforward either IMO.

> We have already seen how the i2c-designware-driver was screwed up when
> it was trying to take advantage of the optimizations provided by the
> current direct_complete path. I think we should be careful when
> considering making it even more complex.

OK, but this applies to your series as well, as it is adding a new flag too,
just not in the core. :-)

> In the runtime PM centric path, driver authors can easily deploy
> system sleep support. In some cases it may even consists of only two
> lines of code. As can be shown in patch9 for the i2c driver.

That still requires the new flag to be set if the ACPI PM is in use AFAICS,
which then will prevent the entire hierarchy above the device from having
direct_complete set.

> Just to be clear, that doesn't mean that I think the direct_complete
> path isn't useful. Especially it is a good match for the ACPI PM
> domain, as it can easily affect all its devices, without having to
> care much about the behavior of the drivers.

OK

[cut]

> 
> The above change would offer an improvement, however there are more
> benefits from the runtime PM centric path that it doesn't cover.

The idea, though, is not to make it instead of, but in addition to the
runtime PM centric path.

So a driver using the runtime PM centric (or rather runtime PM aware)
callbacks can set power.force_suspend and benefit from having direct_complete
set conditional on whether or not the device is runtime resumed before the
late suspend.

If device_complete remains set in __device_suspend_late(), no system
suspend/resume callbacks will be invoked from that point on.  If it isn't
set, pm_runtime_force_suspend() should work just fine and then
pm_runtime_force_resume() should do the right thing on the way back.

All boils down to (a) setting a flag and (b) using the right callbacks
for system suspend which is the case with your patches either.

> The below is pasted from the changelog for patch9 (I will make sure to
> fold in this in the changelog for $subject patch next version).
> 
> In case the device is/gets runtime resumed before the device_suspend()
> phase is entered, the PM core doesn't run the direct_complete path for
> the device during system sleep. During system resume, this lead to
> that the device will always be brought back to full power when the
> i2c-dw-plat driver's ->resume() callback is invoked. This may not be
> necessary, thus increasing the resume time for the device and wasting
> power.

Well, I guess that depends on what is there in its resume callbacks.

> In the runtime PM centric path, the pm_runtime_force_resume() helper
> takes better care, as it resumes the device only in case it's really
> needed. Normally this means it can be postponed to be dealt with via
> regular calls to runtime PM (pm_runtime_get*()) instead. In other
> words, the device remains in its low power state until someone request
> a new i2c transfer, whenever that may be.
> 
> As far as I can think of, the direct_complete path can't be adjusted
> to support this. Or can it?

It surely can, it's just software. :-)  The question is how complicated that
is going to be in the end, however.

So the patch I sent didn't address the dependency issue, but it allows the
core to deal with the issue which is a core issue, not an ACPI PM domain
issue, because the core disables runtime PM for devices with direct_complete
set, not the ACPI PM domain or PCI etc.

[BTW, it is not entirely clear to me why it ever is necessary to runtime resume
a device with direct_complete set after __device_suspend(), because it can only
have direct_complete set at that point if all of the hierarchy below it has
this flag set too and so runtime PM has to be disabled for all of those
devices as well.]

It can be made slightly better by adding a piece to avoid clearing the
parent's direct_complete if it had the new flag set, so below is a new
version (with the new flag renamed to safe_suspend which seemed better to
me).

Of course, having safe_suspend set will still cause the parent's
direct_complete to be cleared unless the parent has safe_suspend set too,
but that's better than not allowing the parent to use direct_complete at all.

---
 drivers/acpi/device_pm.c  |    8 ++++++++
 drivers/base/power/main.c |   15 ++++++++++++---
 include/linux/pm.h        |    1 +
 3 files changed, 21 insertions(+), 3 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete && !dev->power.safe_suspend) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
@@ -1549,7 +1556,9 @@ static int __device_suspend(struct devic
 		if (parent) {
 			spin_lock_irq(&parent->power.lock);
 
-			dev->parent->power.direct_complete = false;
+			if (!dev->parent->power.safe_suspend)
+				dev->parent->power.direct_complete = false;
+
 			if (dev->power.wakeup_path
 			    && !dev->parent->power.ignore_children)
 				dev->parent->power.wakeup_path = true;
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -554,6 +554,7 @@ struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
 	unsigned int		async_suspend:1;
+	unsigned int		safe_suspend:1;
 	bool			in_dpm_list:1;	/* Owned by the PM core */
 	bool			is_prepared:1;	/* Owned by the PM core */
 	bool			is_suspended:1;	/* Ditto */
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  *
  * Follow PCI and resume devices suspended at run time before running their
  * system suspend callbacks.
+ *
+ * If the power.direct_complete flag is set for the device, though, skip all
+ * that, because the device doesn't need to be resumed then and if it is
+ * resumed via runtime PM, the core will notice that and will carry out the
+ * late suspend for it.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
+	if (dev->power.direct_complete)
+		return 0;
+
 	pm_runtime_resume(dev);
 	return pm_generic_suspend(dev);
 }


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24 16:35               ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24 16:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> [...]
> 
> >> >
> >> > It actually should work with the ACPI PM domain code as is except that it
> >> > will cause the device to be runtime resumed every time during suspend.
> >> >
> >> > But acpi_subsys_suspend() can be changed to avoid resuming the device if
> >> > power.force_suspend is set.
> >>
> >> Or better yet, if power.direct_complete is not set, because that means the
> >> device needs to be resumed anyway.
> >>
> >> And if power.direct_complete is set at that point, power.force_suspend has to
> >> be set too.
> 
> I believe I understand your goal here. You want to consider if it is
> possible to extend the behavior of the direct_complete path, instead
> of enabling the runtime PM centric path for the ACPI PM domain, to
> accomplish the same optimizations.

This isn't really "instead of", but rather "in addition to".

> I think the answer to that, is that it simply can't. See more
> information about why further down below.
> 
> >
> > Overall, like below, and of course drivers that ser power.force_suspend need to
> > be able to deal with devices that have been runtime resumed during
> > __device_suspend().
> 
> The a concern I see with this approach, is that is going to be too
> complex to understand.

That is a valid concern, but then your approach with using an extra flag
just for the ACPI PM domain isn't particularly straightforward either IMO.

> We have already seen how the i2c-designware-driver was screwed up when
> it was trying to take advantage of the optimizations provided by the
> current direct_complete path. I think we should be careful when
> considering making it even more complex.

OK, but this applies to your series as well, as it is adding a new flag too,
just not in the core. :-)

> In the runtime PM centric path, driver authors can easily deploy
> system sleep support. In some cases it may even consists of only two
> lines of code. As can be shown in patch9 for the i2c driver.

That still requires the new flag to be set if the ACPI PM is in use AFAICS,
which then will prevent the entire hierarchy above the device from having
direct_complete set.

> Just to be clear, that doesn't mean that I think the direct_complete
> path isn't useful. Especially it is a good match for the ACPI PM
> domain, as it can easily affect all its devices, without having to
> care much about the behavior of the drivers.

OK

[cut]

> 
> The above change would offer an improvement, however there are more
> benefits from the runtime PM centric path that it doesn't cover.

The idea, though, is not to make it instead of, but in addition to the
runtime PM centric path.

So a driver using the runtime PM centric (or rather runtime PM aware)
callbacks can set power.force_suspend and benefit from having direct_complete
set conditional on whether or not the device is runtime resumed before the
late suspend.

If device_complete remains set in __device_suspend_late(), no system
suspend/resume callbacks will be invoked from that point on.  If it isn't
set, pm_runtime_force_suspend() should work just fine and then
pm_runtime_force_resume() should do the right thing on the way back.

All boils down to (a) setting a flag and (b) using the right callbacks
for system suspend which is the case with your patches either.

> The below is pasted from the changelog for patch9 (I will make sure to
> fold in this in the changelog for $subject patch next version).
> 
> In case the device is/gets runtime resumed before the device_suspend()
> phase is entered, the PM core doesn't run the direct_complete path for
> the device during system sleep. During system resume, this lead to
> that the device will always be brought back to full power when the
> i2c-dw-plat driver's ->resume() callback is invoked. This may not be
> necessary, thus increasing the resume time for the device and wasting
> power.

Well, I guess that depends on what is there in its resume callbacks.

> In the runtime PM centric path, the pm_runtime_force_resume() helper
> takes better care, as it resumes the device only in case it's really
> needed. Normally this means it can be postponed to be dealt with via
> regular calls to runtime PM (pm_runtime_get*()) instead. In other
> words, the device remains in its low power state until someone request
> a new i2c transfer, whenever that may be.
> 
> As far as I can think of, the direct_complete path can't be adjusted
> to support this. Or can it?

It surely can, it's just software. :-)  The question is how complicated that
is going to be in the end, however.

So the patch I sent didn't address the dependency issue, but it allows the
core to deal with the issue which is a core issue, not an ACPI PM domain
issue, because the core disables runtime PM for devices with direct_complete
set, not the ACPI PM domain or PCI etc.

[BTW, it is not entirely clear to me why it ever is necessary to runtime resume
a device with direct_complete set after __device_suspend(), because it can only
have direct_complete set at that point if all of the hierarchy below it has
this flag set too and so runtime PM has to be disabled for all of those
devices as well.]

It can be made slightly better by adding a piece to avoid clearing the
parent's direct_complete if it had the new flag set, so below is a new
version (with the new flag renamed to safe_suspend which seemed better to
me).

Of course, having safe_suspend set will still cause the parent's
direct_complete to be cleared unless the parent has safe_suspend set too,
but that's better than not allowing the parent to use direct_complete at all.

---
 drivers/acpi/device_pm.c  |    8 ++++++++
 drivers/base/power/main.c |   15 ++++++++++++---
 include/linux/pm.h        |    1 +
 3 files changed, 21 insertions(+), 3 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete && !dev->power.safe_suspend) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
@@ -1549,7 +1556,9 @@ static int __device_suspend(struct devic
 		if (parent) {
 			spin_lock_irq(&parent->power.lock);
 
-			dev->parent->power.direct_complete = false;
+			if (!dev->parent->power.safe_suspend)
+				dev->parent->power.direct_complete = false;
+
 			if (dev->power.wakeup_path
 			    && !dev->parent->power.ignore_children)
 				dev->parent->power.wakeup_path = true;
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -554,6 +554,7 @@ struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
 	unsigned int		async_suspend:1;
+	unsigned int		safe_suspend:1;
 	bool			in_dpm_list:1;	/* Owned by the PM core */
 	bool			is_prepared:1;	/* Owned by the PM core */
 	bool			is_suspended:1;	/* Ditto */
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  *
  * Follow PCI and resume devices suspended at run time before running their
  * system suspend callbacks.
+ *
+ * If the power.direct_complete flag is set for the device, though, skip all
+ * that, because the device doesn't need to be resumed then and if it is
+ * resumed via runtime PM, the core will notice that and will carry out the
+ * late suspend for it.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
+	if (dev->power.direct_complete)
+		return 0;
+
 	pm_runtime_resume(dev);
 	return pm_generic_suspend(dev);
 }

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24 16:35               ` Rafael J. Wysocki
@ 2017-08-24 21:50                 ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24 21:50 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:

[cut]

> [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> a device with direct_complete set after __device_suspend(), because it can only
> have direct_complete set at that point if all of the hierarchy below it has
> this flag set too and so runtime PM has to be disabled for all of those
> devices as well.]

Which makes me realize that we should take a step back and look at what
problems there are.

First, there are devices (I know about two examples so far and both are PCI)
that may need to be runtime resumed during system suspend for reasons other
than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
to be a way to indicate that from the driver side.

However, it still may be valuable to check the power-related conditions for
leaving the device in runtime suspend over system suspend/resume in case
it actually doesn't need to be runtime resumed during system suspend after
all.  That's what the majority of my patch was about.

The second problem is that the ACPI PM domain (and the PCI bus type)
runtime resumes all devices unconditionally in its ->suspend callback,
even though that may not be necessary for some devices.  Therefore there
needs to be a way to indicate that too.  That still would be good to
have *regardless* of the direct_complete mechanism, because the direct_complete
flag may not be set very often due to dependencies and then the
resume-during-suspend will take place unnecessarily.

Accordingly, it looks like we need a "no need to resume me" flag in the first
place.  That would indicate to interested pieces of code that, from the
driver perspective, the device doesn't need to be runtime resumed before
invoking its system suspend callbacks.  This should be clear enough to everyone
IMO.

[Note that if that flag is set for all devices, we may drop it along with
direct_complete, but before that happens both are needed.]

To address the first issue I would add something like the flag in the patches
I sent (but without the ACPI PM domain part which should be covered by the
"no need to resume me" flag above), because that allows the device's ->suspend
callback to run in principle and the driver may use that callback even to
runtime resume the device if that's what it wants to do.  So something like
"run my ->suspend callback even though I might stay in runtime suspend".

I would probably add driver_flags to dev_pm_info for that to set at the probe
time (and I would make the core clear that on driver removal).

The complexity concern is there, but honestly I don't see a better way at
this point.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-24 21:50                 ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-24 21:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:

[cut]

> [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> a device with direct_complete set after __device_suspend(), because it can only
> have direct_complete set at that point if all of the hierarchy below it has
> this flag set too and so runtime PM has to be disabled for all of those
> devices as well.]

Which makes me realize that we should take a step back and look at what
problems there are.

First, there are devices (I know about two examples so far and both are PCI)
that may need to be runtime resumed during system suspend for reasons other
than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
to be a way to indicate that from the driver side.

However, it still may be valuable to check the power-related conditions for
leaving the device in runtime suspend over system suspend/resume in case
it actually doesn't need to be runtime resumed during system suspend after
all.  That's what the majority of my patch was about.

The second problem is that the ACPI PM domain (and the PCI bus type)
runtime resumes all devices unconditionally in its ->suspend callback,
even though that may not be necessary for some devices.  Therefore there
needs to be a way to indicate that too.  That still would be good to
have *regardless* of the direct_complete mechanism, because the direct_complete
flag may not be set very often due to dependencies and then the
resume-during-suspend will take place unnecessarily.

Accordingly, it looks like we need a "no need to resume me" flag in the first
place.  That would indicate to interested pieces of code that, from the
driver perspective, the device doesn't need to be runtime resumed before
invoking its system suspend callbacks.  This should be clear enough to everyone
IMO.

[Note that if that flag is set for all devices, we may drop it along with
direct_complete, but before that happens both are needed.]

To address the first issue I would add something like the flag in the patches
I sent (but without the ACPI PM domain part which should be covered by the
"no need to resume me" flag above), because that allows the device's ->suspend
callback to run in principle and the driver may use that callback even to
runtime resume the device if that's what it wants to do.  So something like
"run my ->suspend callback even though I might stay in runtime suspend".

I would probably add driver_flags to dev_pm_info for that to set at the probe
time (and I would make the core clear that on driver removal).

The complexity concern is there, but honestly I don't see a better way at
this point.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24 14:57         ` Rafael J. Wysocki
@ 2017-08-25  9:04           ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-25  9:04 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On 24 August 2017 at 16:57, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Thursday, August 24, 2017 10:19:43 AM CEST Ulf Hansson wrote:
>> On 24 August 2017 at 01:39, Rafael J. Wysocki <rafael@kernel.org> wrote:
>> > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> >> In some cases a driver for an ACPI device needs to be able to prevent the
>> >> ACPI PM domain from using the direct_complete path during system sleep.
>> >>
>> >> One typical case is when the driver for the device needs its device to stay
>> >> runtime enabled, during the __device_suspend phase. This isn't the case
>> >> when the direct_complete path is being executed by the PM core, as it then
>> >> disables runtime PM for the device in __device_suspend(). Any following
>> >> attempts to runtime resume the device after that point, just fails.
>> >
>> > OK, that is a problem.
>> >
>> >> A workaround to this problem is to let the driver runtime resume its device
>> >> from its ->prepare() callback, as that would prevent the direct_complete
>> >> path from being executed. However, that may often be a waste, especially if
>> >> it turned out that no one really needed the device.
>> >>
>> >> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
>> >> drivers to inform the ACPI PM domain to change its default behaviour during
>> >> system sleep, and thus control whether it may use the direct_complete path
>> >> or not.
>> >
>> > But I'm not sure this is the right place to address it as it very well
>> > may affect a PCI device too.
>> >
>> > Also, this is about the device and not about its ACPI companion
>> > object, so putting the flag in there is somewhat unclean, so to speak.
>> >
>> > It looks like we need a flag in dev_pm_info saying something along the
>> > lines of "my system suspend callback can deal with runtime PM" that
>> > will cause the direct_complete update to occur in
>> > __device_suspend_late() instead of __device_suspend().
>>
>> I realize that in the end this turns out to be a comparison between
>> the runtime PM centric path and the direct_complete path while
>> implementing system sleep. In patch 9, there is some more explanation
>> around this, however if you like I can elaborate even more about
>> this!?
>>
>> Regarding making changes to the PM core and adding more flags to the
>> dev_pm_info etc, I am not sure we really want that. Isn't it already
>> complex enough?
>
> Maybe it is.
>
>> My point is, that I am trying to improve the behavior of the ACPI PM
>> domain by enabling the runtime PM centric path for it, and even if
>> there is something similar that could be done for PCI, I don't think
>> we should need involvement by the PM core.
>
> Well, this generally simply doesn't work.
>
> The whole "runtime PM centric approach" idea is generally fine by me,
> but the fact today is that there are drivers not ready for it.  Which
> is why there is the direct_complete thing (it may be regarded as a
> sort-of workaround for the unreadiness of drivers if you will).

This is how I see it:

The runtime PM centric path is being widely deployed, however it takes
time to convert drivers.

The direct_complete path offers a great intermediate step for the ACPI
PM domain as it affects all its devices - while we wait for further
optimizations being deployed using the runtime PM centric path.

>
> Now, buy adding the no_direct_complete flag just to the ACPI PM domain
> you basically overlook the fact that this potentially affects the parents
> of the devices in question by preventing direct_complete from being set
> for them.  And those parents may not be in the ACPI PM domain in principle,
> so the problem needs to be addressed in the core.

Okay, let's move the flag to the dev_pm* structures, to not limit this
to the ACPI PM domain.

However in the current approach taken in this series, as it's coded as
opt-in to use for drivers, I am questioning how big of a problem
parent devices not being able to use the direct_complete path could
be!?
Couldn't it be good enough to just adopt the behavior of the ACPI PM
domain and more or less leave the core out of it - at least for now!?

I am also thinking, that for those parent devices that potentially may
suffer from not be able to use the direct_complete path, those can be
fixed by deploying the runtime PM centric path in their
subsystems/drivers. That would even mean that the parent devices get
the additional benefits that the runtime PM centric path offers. So,
in the end we would end up having a better optimized solution than we
had before.

What do you think?

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-25  9:04           ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-25  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 24 August 2017 at 16:57, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Thursday, August 24, 2017 10:19:43 AM CEST Ulf Hansson wrote:
>> On 24 August 2017 at 01:39, Rafael J. Wysocki <rafael@kernel.org> wrote:
>> > On Wed, Aug 23, 2017 at 4:42 PM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> >> In some cases a driver for an ACPI device needs to be able to prevent the
>> >> ACPI PM domain from using the direct_complete path during system sleep.
>> >>
>> >> One typical case is when the driver for the device needs its device to stay
>> >> runtime enabled, during the __device_suspend phase. This isn't the case
>> >> when the direct_complete path is being executed by the PM core, as it then
>> >> disables runtime PM for the device in __device_suspend(). Any following
>> >> attempts to runtime resume the device after that point, just fails.
>> >
>> > OK, that is a problem.
>> >
>> >> A workaround to this problem is to let the driver runtime resume its device
>> >> from its ->prepare() callback, as that would prevent the direct_complete
>> >> path from being executed. However, that may often be a waste, especially if
>> >> it turned out that no one really needed the device.
>> >>
>> >> For this reason, invent acpi_dev_disable|enable_direct_complete(), to allow
>> >> drivers to inform the ACPI PM domain to change its default behaviour during
>> >> system sleep, and thus control whether it may use the direct_complete path
>> >> or not.
>> >
>> > But I'm not sure this is the right place to address it as it very well
>> > may affect a PCI device too.
>> >
>> > Also, this is about the device and not about its ACPI companion
>> > object, so putting the flag in there is somewhat unclean, so to speak.
>> >
>> > It looks like we need a flag in dev_pm_info saying something along the
>> > lines of "my system suspend callback can deal with runtime PM" that
>> > will cause the direct_complete update to occur in
>> > __device_suspend_late() instead of __device_suspend().
>>
>> I realize that in the end this turns out to be a comparison between
>> the runtime PM centric path and the direct_complete path while
>> implementing system sleep. In patch 9, there is some more explanation
>> around this, however if you like I can elaborate even more about
>> this!?
>>
>> Regarding making changes to the PM core and adding more flags to the
>> dev_pm_info etc, I am not sure we really want that. Isn't it already
>> complex enough?
>
> Maybe it is.
>
>> My point is, that I am trying to improve the behavior of the ACPI PM
>> domain by enabling the runtime PM centric path for it, and even if
>> there is something similar that could be done for PCI, I don't think
>> we should need involvement by the PM core.
>
> Well, this generally simply doesn't work.
>
> The whole "runtime PM centric approach" idea is generally fine by me,
> but the fact today is that there are drivers not ready for it.  Which
> is why there is the direct_complete thing (it may be regarded as a
> sort-of workaround for the unreadiness of drivers if you will).

This is how I see it:

The runtime PM centric path is being widely deployed, however it takes
time to convert drivers.

The direct_complete path offers a great intermediate step for the ACPI
PM domain as it affects all its devices - while we wait for further
optimizations being deployed using the runtime PM centric path.

>
> Now, buy adding the no_direct_complete flag just to the ACPI PM domain
> you basically overlook the fact that this potentially affects the parents
> of the devices in question by preventing direct_complete from being set
> for them.  And those parents may not be in the ACPI PM domain in principle,
> so the problem needs to be addressed in the core.

Okay, let's move the flag to the dev_pm* structures, to not limit this
to the ACPI PM domain.

However in the current approach taken in this series, as it's coded as
opt-in to use for drivers, I am questioning how big of a problem
parent devices not being able to use the direct_complete path could
be!?
Couldn't it be good enough to just adopt the behavior of the ACPI PM
domain and more or less leave the core out of it - at least for now!?

I am also thinking, that for those parent devices that potentially may
suffer from not be able to use the direct_complete path, those can be
fixed by deploying the runtime PM centric path in their
subsystems/drivers. That would even mean that the parent devices get
the additional benefits that the runtime PM centric path offers. So,
in the end we would end up having a better optimized solution than we
had before.

What do you think?

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24 16:35               ` Rafael J. Wysocki
@ 2017-08-25  9:28                 ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-25  9:28 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

[...]

>>
>> The above change would offer an improvement, however there are more
>> benefits from the runtime PM centric path that it doesn't cover.
>
> The idea, though, is not to make it instead of, but in addition to the
> runtime PM centric path.
>
> So a driver using the runtime PM centric (or rather runtime PM aware)
> callbacks can set power.force_suspend and benefit from having direct_complete
> set conditional on whether or not the device is runtime resumed before the
> late suspend.
>
> If device_complete remains set in __device_suspend_late(), no system
> suspend/resume callbacks will be invoked from that point on.  If it isn't
> set, pm_runtime_force_suspend() should work just fine and then
> pm_runtime_force_resume() should do the right thing on the way back.
>
> All boils down to (a) setting a flag and (b) using the right callbacks
> for system suspend which is the case with your patches either.

You make it sound simple. :-)

I try to get inspired of your ideas and see what I can come up with.
However, I really want us to avoid making it more difficult to
understand the behavior of the core, so I probably look start changing
the ACPI PM domain first, then trying to adopt the behavior of the
core on top of those changes. Does that sound reasonable to you?

>
>> The below is pasted from the changelog for patch9 (I will make sure to
>> fold in this in the changelog for $subject patch next version).
>>
>> In case the device is/gets runtime resumed before the device_suspend()
>> phase is entered, the PM core doesn't run the direct_complete path for
>> the device during system sleep. During system resume, this lead to
>> that the device will always be brought back to full power when the
>> i2c-dw-plat driver's ->resume() callback is invoked. This may not be
>> necessary, thus increasing the resume time for the device and wasting
>> power.
>
> Well, I guess that depends on what is there in its resume callbacks.
>
>> In the runtime PM centric path, the pm_runtime_force_resume() helper
>> takes better care, as it resumes the device only in case it's really
>> needed. Normally this means it can be postponed to be dealt with via
>> regular calls to runtime PM (pm_runtime_get*()) instead. In other
>> words, the device remains in its low power state until someone request
>> a new i2c transfer, whenever that may be.
>>
>> As far as I can think of, the direct_complete path can't be adjusted
>> to support this. Or can it?
>
> It surely can, it's just software. :-)  The question is how complicated that
> is going to be in the end, however.
>
> So the patch I sent didn't address the dependency issue, but it allows the
> core to deal with the issue which is a core issue, not an ACPI PM domain
> issue, because the core disables runtime PM for devices with direct_complete
> set, not the ACPI PM domain or PCI etc.
>
> [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> a device with direct_complete set after __device_suspend(), because it can only
> have direct_complete set at that point if all of the hierarchy below it has
> this flag set too and so runtime PM has to be disabled for all of those
> devices as well.]
>
> It can be made slightly better by adding a piece to avoid clearing the
> parent's direct_complete if it had the new flag set, so below is a new
> version (with the new flag renamed to safe_suspend which seemed better to
> me).
>
> Of course, having safe_suspend set will still cause the parent's
> direct_complete to be cleared unless the parent has safe_suspend set too,
> but that's better than not allowing the parent to use direct_complete at all.

Well, as I replied in the earlier response, deploying the runtime PM
centric path also for the parent, offers additional optimizations
while comparing to try to make the direct_complete path still to work.

We could also pick that approach, which would mean additional
arguments of moving drivers to the runtime PM centric path, of course
only where it makes sense.

>
> ---
>  drivers/acpi/device_pm.c  |    8 ++++++++
>  drivers/base/power/main.c |   15 ++++++++++++---
>  include/linux/pm.h        |    1 +
>  3 files changed, 21 insertions(+), 3 deletions(-)
>
> Index: linux-pm/drivers/base/power/main.c
> ===================================================================
> --- linux-pm.orig/drivers/base/power/main.c
> +++ linux-pm/drivers/base/power/main.c
> @@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
>                 goto Complete;
>         }
>
> -       if (dev->power.syscore || dev->power.direct_complete)
> +       if (dev->power.syscore)
>                 goto Complete;
>
> +       if (dev->power.direct_complete) {
> +               if (pm_runtime_status_suspended(dev))
> +                       goto Complete;
> +
> +               dev->power.direct_complete = false;
> +       }
> +
>         if (dev->pm_domain) {
>                 info = "late power domain ";
>                 callback = pm_late_early_op(&dev->pm_domain->ops, state);
> @@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
>         if (dev->power.syscore)
>                 goto Complete;
>
> -       if (dev->power.direct_complete) {
> +       if (dev->power.direct_complete && !dev->power.safe_suspend) {
>                 if (pm_runtime_status_suspended(dev)) {
>                         pm_runtime_disable(dev);
>                         if (pm_runtime_status_suspended(dev))
> @@ -1549,7 +1556,9 @@ static int __device_suspend(struct devic
>                 if (parent) {
>                         spin_lock_irq(&parent->power.lock);
>
> -                       dev->parent->power.direct_complete = false;
> +                       if (!dev->parent->power.safe_suspend)
> +                               dev->parent->power.direct_complete = false;
> +
>                         if (dev->power.wakeup_path
>                             && !dev->parent->power.ignore_children)
>                                 dev->parent->power.wakeup_path = true;
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -554,6 +554,7 @@ struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
>         unsigned int            async_suspend:1;
> +       unsigned int            safe_suspend:1;
>         bool                    in_dpm_list:1;  /* Owned by the PM core */
>         bool                    is_prepared:1;  /* Owned by the PM core */
>         bool                    is_suspended:1; /* Ditto */
> Index: linux-pm/drivers/acpi/device_pm.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/device_pm.c
> +++ linux-pm/drivers/acpi/device_pm.c
> @@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>   *
>   * Follow PCI and resume devices suspended at run time before running their
>   * system suspend callbacks.
> + *
> + * If the power.direct_complete flag is set for the device, though, skip all
> + * that, because the device doesn't need to be resumed then and if it is
> + * resumed via runtime PM, the core will notice that and will carry out the
> + * late suspend for it.
>   */
>  int acpi_subsys_suspend(struct device *dev)
>  {
> +       if (dev->power.direct_complete)
> +               return 0;
> +
>         pm_runtime_resume(dev);
>         return pm_generic_suspend(dev);
>  }
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-25  9:28                 ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-25  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

[...]

>>
>> The above change would offer an improvement, however there are more
>> benefits from the runtime PM centric path that it doesn't cover.
>
> The idea, though, is not to make it instead of, but in addition to the
> runtime PM centric path.
>
> So a driver using the runtime PM centric (or rather runtime PM aware)
> callbacks can set power.force_suspend and benefit from having direct_complete
> set conditional on whether or not the device is runtime resumed before the
> late suspend.
>
> If device_complete remains set in __device_suspend_late(), no system
> suspend/resume callbacks will be invoked from that point on.  If it isn't
> set, pm_runtime_force_suspend() should work just fine and then
> pm_runtime_force_resume() should do the right thing on the way back.
>
> All boils down to (a) setting a flag and (b) using the right callbacks
> for system suspend which is the case with your patches either.

You make it sound simple. :-)

I try to get inspired of your ideas and see what I can come up with.
However, I really want us to avoid making it more difficult to
understand the behavior of the core, so I probably look start changing
the ACPI PM domain first, then trying to adopt the behavior of the
core on top of those changes. Does that sound reasonable to you?

>
>> The below is pasted from the changelog for patch9 (I will make sure to
>> fold in this in the changelog for $subject patch next version).
>>
>> In case the device is/gets runtime resumed before the device_suspend()
>> phase is entered, the PM core doesn't run the direct_complete path for
>> the device during system sleep. During system resume, this lead to
>> that the device will always be brought back to full power when the
>> i2c-dw-plat driver's ->resume() callback is invoked. This may not be
>> necessary, thus increasing the resume time for the device and wasting
>> power.
>
> Well, I guess that depends on what is there in its resume callbacks.
>
>> In the runtime PM centric path, the pm_runtime_force_resume() helper
>> takes better care, as it resumes the device only in case it's really
>> needed. Normally this means it can be postponed to be dealt with via
>> regular calls to runtime PM (pm_runtime_get*()) instead. In other
>> words, the device remains in its low power state until someone request
>> a new i2c transfer, whenever that may be.
>>
>> As far as I can think of, the direct_complete path can't be adjusted
>> to support this. Or can it?
>
> It surely can, it's just software. :-)  The question is how complicated that
> is going to be in the end, however.
>
> So the patch I sent didn't address the dependency issue, but it allows the
> core to deal with the issue which is a core issue, not an ACPI PM domain
> issue, because the core disables runtime PM for devices with direct_complete
> set, not the ACPI PM domain or PCI etc.
>
> [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> a device with direct_complete set after __device_suspend(), because it can only
> have direct_complete set at that point if all of the hierarchy below it has
> this flag set too and so runtime PM has to be disabled for all of those
> devices as well.]
>
> It can be made slightly better by adding a piece to avoid clearing the
> parent's direct_complete if it had the new flag set, so below is a new
> version (with the new flag renamed to safe_suspend which seemed better to
> me).
>
> Of course, having safe_suspend set will still cause the parent's
> direct_complete to be cleared unless the parent has safe_suspend set too,
> but that's better than not allowing the parent to use direct_complete at all.

Well, as I replied in the earlier response, deploying the runtime PM
centric path also for the parent, offers additional optimizations
while comparing to try to make the direct_complete path still to work.

We could also pick that approach, which would mean additional
arguments of moving drivers to the runtime PM centric path, of course
only where it makes sense.

>
> ---
>  drivers/acpi/device_pm.c  |    8 ++++++++
>  drivers/base/power/main.c |   15 ++++++++++++---
>  include/linux/pm.h        |    1 +
>  3 files changed, 21 insertions(+), 3 deletions(-)
>
> Index: linux-pm/drivers/base/power/main.c
> ===================================================================
> --- linux-pm.orig/drivers/base/power/main.c
> +++ linux-pm/drivers/base/power/main.c
> @@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
>                 goto Complete;
>         }
>
> -       if (dev->power.syscore || dev->power.direct_complete)
> +       if (dev->power.syscore)
>                 goto Complete;
>
> +       if (dev->power.direct_complete) {
> +               if (pm_runtime_status_suspended(dev))
> +                       goto Complete;
> +
> +               dev->power.direct_complete = false;
> +       }
> +
>         if (dev->pm_domain) {
>                 info = "late power domain ";
>                 callback = pm_late_early_op(&dev->pm_domain->ops, state);
> @@ -1482,7 +1489,7 @@ static int __device_suspend(struct devic
>         if (dev->power.syscore)
>                 goto Complete;
>
> -       if (dev->power.direct_complete) {
> +       if (dev->power.direct_complete && !dev->power.safe_suspend) {
>                 if (pm_runtime_status_suspended(dev)) {
>                         pm_runtime_disable(dev);
>                         if (pm_runtime_status_suspended(dev))
> @@ -1549,7 +1556,9 @@ static int __device_suspend(struct devic
>                 if (parent) {
>                         spin_lock_irq(&parent->power.lock);
>
> -                       dev->parent->power.direct_complete = false;
> +                       if (!dev->parent->power.safe_suspend)
> +                               dev->parent->power.direct_complete = false;
> +
>                         if (dev->power.wakeup_path
>                             && !dev->parent->power.ignore_children)
>                                 dev->parent->power.wakeup_path = true;
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -554,6 +554,7 @@ struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
>         unsigned int            async_suspend:1;
> +       unsigned int            safe_suspend:1;
>         bool                    in_dpm_list:1;  /* Owned by the PM core */
>         bool                    is_prepared:1;  /* Owned by the PM core */
>         bool                    is_suspended:1; /* Ditto */
> Index: linux-pm/drivers/acpi/device_pm.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/device_pm.c
> +++ linux-pm/drivers/acpi/device_pm.c
> @@ -1025,9 +1025,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>   *
>   * Follow PCI and resume devices suspended at run time before running their
>   * system suspend callbacks.
> + *
> + * If the power.direct_complete flag is set for the device, though, skip all
> + * that, because the device doesn't need to be resumed then and if it is
> + * resumed via runtime PM, the core will notice that and will carry out the
> + * late suspend for it.
>   */
>  int acpi_subsys_suspend(struct device *dev)
>  {
> +       if (dev->power.direct_complete)
> +               return 0;
> +
>         pm_runtime_resume(dev);
>         return pm_generic_suspend(dev);
>  }
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-25  9:28                 ` Ulf Hansson
@ 2017-08-25 12:23                   ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-25 12:23 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Friday, August 25, 2017 11:28:25 AM CEST Ulf Hansson wrote:
> [...]
> 
> >>
> >> The above change would offer an improvement, however there are more
> >> benefits from the runtime PM centric path that it doesn't cover.
> >
> > The idea, though, is not to make it instead of, but in addition to the
> > runtime PM centric path.
> >
> > So a driver using the runtime PM centric (or rather runtime PM aware)
> > callbacks can set power.force_suspend and benefit from having direct_complete
> > set conditional on whether or not the device is runtime resumed before the
> > late suspend.
> >
> > If device_complete remains set in __device_suspend_late(), no system
> > suspend/resume callbacks will be invoked from that point on.  If it isn't
> > set, pm_runtime_force_suspend() should work just fine and then
> > pm_runtime_force_resume() should do the right thing on the way back.
> >
> > All boils down to (a) setting a flag and (b) using the right callbacks
> > for system suspend which is the case with your patches either.
> 
> You make it sound simple. :-)
> 
> I try to get inspired of your ideas and see what I can come up with.
> However, I really want us to avoid making it more difficult to
> understand the behavior of the core, so I probably look start changing
> the ACPI PM domain first, then trying to adopt the behavior of the
> core on top of those changes. Does that sound reasonable to you?

Well, I don't think we need to change the ACPI PM domain at all. :-)

However, let me contiune in a reply to

https://marc.info/?l=linux-arm-kernel&m=150361200030186&w=2

for more complete context.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-25 12:23                   ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-25 12:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday, August 25, 2017 11:28:25 AM CEST Ulf Hansson wrote:
> [...]
> 
> >>
> >> The above change would offer an improvement, however there are more
> >> benefits from the runtime PM centric path that it doesn't cover.
> >
> > The idea, though, is not to make it instead of, but in addition to the
> > runtime PM centric path.
> >
> > So a driver using the runtime PM centric (or rather runtime PM aware)
> > callbacks can set power.force_suspend and benefit from having direct_complete
> > set conditional on whether or not the device is runtime resumed before the
> > late suspend.
> >
> > If device_complete remains set in __device_suspend_late(), no system
> > suspend/resume callbacks will be invoked from that point on.  If it isn't
> > set, pm_runtime_force_suspend() should work just fine and then
> > pm_runtime_force_resume() should do the right thing on the way back.
> >
> > All boils down to (a) setting a flag and (b) using the right callbacks
> > for system suspend which is the case with your patches either.
> 
> You make it sound simple. :-)
> 
> I try to get inspired of your ideas and see what I can come up with.
> However, I really want us to avoid making it more difficult to
> understand the behavior of the core, so I probably look start changing
> the ACPI PM domain first, then trying to adopt the behavior of the
> core on top of those changes. Does that sound reasonable to you?

Well, I don't think we need to change the ACPI PM domain at all. :-)

However, let me contiune in a reply to

https://marc.info/?l=linux-arm-kernel&m=150361200030186&w=2

for more complete context.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-24 21:50                 ` Rafael J. Wysocki
@ 2017-08-25 13:42                   ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-25 13:42 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> 
> [cut]
> 
> > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> > a device with direct_complete set after __device_suspend(), because it can only
> > have direct_complete set at that point if all of the hierarchy below it has
> > this flag set too and so runtime PM has to be disabled for all of those
> > devices as well.]
> 
> Which makes me realize that we should take a step back and look at what
> problems there are.
> 
> First, there are devices (I know about two examples so far and both are PCI)
> that may need to be runtime resumed during system suspend for reasons other
> than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
> to be a way to indicate that from the driver side.
> 
> However, it still may be valuable to check the power-related conditions for
> leaving the device in runtime suspend over system suspend/resume in case
> it actually doesn't need to be runtime resumed during system suspend after
> all.  That's what the majority of my patch was about.
> 
> The second problem is that the ACPI PM domain (and the PCI bus type)
> runtime resumes all devices unconditionally in its ->suspend callback,
> even though that may not be necessary for some devices.  Therefore there
> needs to be a way to indicate that too.  That still would be good to
> have *regardless* of the direct_complete mechanism, because the direct_complete
> flag may not be set very often due to dependencies and then the
> resume-during-suspend will take place unnecessarily.
> 
> Accordingly, it looks like we need a "no need to resume me" flag in the first
> place.  That would indicate to interested pieces of code that, from the
> driver perspective, the device doesn't need to be runtime resumed before
> invoking its system suspend callbacks.  This should be clear enough to everyone
> IMO.
> 
> [Note that if that flag is set for all devices, we may drop it along with
> direct_complete, but before that happens both are needed.]

I think we are in agreement that direct_complete will not be necessary any
more when all drivers/bus types/PM domains and so on can do the "safe
suspend", but we're not there yet. :-)

> To address the first issue I would add something like the flag in the patches
> I sent (but without the ACPI PM domain part which should be covered by the
> "no need to resume me" flag above), because that allows the device's ->suspend
> callback to run in principle and the driver may use that callback even to
> runtime resume the device if that's what it wants to do.  So something like
> "run my ->suspend callback even though I might stay in runtime suspend".
> 
> I would probably add driver_flags to dev_pm_info for that to set at the probe
> time (and I would make the core clear that on driver removal).
> 
> The complexity concern is there, but honestly I don't see a better way at
> this point.

So below is a prototype patch.  It still is missing a documentation update, but
other than that it should be complete unless I missed something.

The way it works is that the SAFE_SUSPEND flag is not looked at by the core
at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
to take it into account in the future.  That is what causes the "runtime resume
during system suspend" to be skipped.

In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
the decision on whether or not to use direct_complete to be deferred to the
__device_suspend_late() time.  If you set it for a PCI device, the effect is
equivalent to "no direct_complete".  If you set it for a device in the ACPI
PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
set, the effect is equivalent to "no direct_complete" too, but if it is set,
the core may still try to use direct_complete for the device, but it will
make the decision on it in __device_suspend_late() and then it will not invoke
the ->suspend_late callback for the device if it is still runtime suspended.
[Note that you cannot runtime resume and runtime suspend again a device during
system suspend, so if it is runtime suspended in __device_suspend_late(), it
has been runtime suspend all the way since device_prepare().]

So say you point the ->suspend_late and ->resume_early callbacks of
the designware i2c driver to pm_runtime_force_suspend() and
pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
and ALWAYS_SUSPEND flags for the device.

If system suspend is started and the device is not runtime suspended,
direct_complete is not set for it and everything works as usual, so say
the device is runtime suspended in device_prepare().  Then, the ACPI PM
domain checks the other conditions for leaving it in runtime suspend and
returns either 0 or a positive number from acpi_subsys_prepare().

If 0 is returned, direct_complete is not set by the core and
acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
that the device need not be runtime resumed, so it invokes the driver's
->suspend callback (which is not present, so it doesn't do anything).
Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
and it calls pm_runtime_force_suspend(), which executes the driver's
->runtime_suspend() callback, and then (if successful) calls
acpi_dev_suspend_late() to put the device into a low-power state.  The
resume path is a reverse of the above in this case.  So far, so good.

If acpi_subsys_prepare() returns a positive number, the core sets
direct_complete for the device.  Next, in __device_suspend(), it sees
direct_complete set and checks the ALWAYS_SUSPEND flag.  It is set,
so the runtime PM disabling part is skipped.  acpi_subsys_suspend()
is called, it checks SAFE_SUSPEND and skips the runtime resume of the
device.  Now, the device can stay runtime suspended or it may be runtime
resumed in the meantime.

First, say it stays runtime suspended.  __device_suspend_late() is called
for it, sees direct_complete set and sees that the device is runtime
suspended, so it just returns with direct_complete set.  The resume path
will be skipped entirely for the device, so it remains runtime suspended
all the way throughout the system suspend and resume.  Still OK.

Now, say the device has been runtime resumed between __device_suspend()
and __device_suspend_late().  The latter will see direct_complete set
and will see that the device is not runtime suspended any more, so it
will clear direct_complete and call acpi_subsys_suspend_late().  That,
in turn, will call pm_runtime_force_suspend(), which will see that
the device is not runtime suspended, so it will call the driver's
->runtime_suspend() callback.  Next,  acpi_dev_suspend_late() will be
called to put the device into a low-power state.  From that point on
everything is equivalent to the case in which acpi_subsys_prepare()
returned 0.

---
 drivers/acpi/device_pm.c  |    7 +++++--
 drivers/base/dd.c         |    2 ++
 drivers/base/power/main.c |   21 +++++++++++++++++----
 include/linux/pm.h        |   32 ++++++++++++++++++++++++++++++++
 4 files changed, 56 insertions(+), 6 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1437,7 +1444,10 @@ static void dpm_clear_suppliers_direct_c
 
 	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) {
 		spin_lock_irq(&link->supplier->power.lock);
-		link->supplier->power.direct_complete = false;
+
+		if (!(link->supplier->power.driver_flags & DPM_FLAG_ALWAYS_SUSPEND))
+			link->supplier->power.direct_complete = false;
+
 		spin_unlock_irq(&link->supplier->power.lock);
 	}
 
@@ -1482,7 +1492,8 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete &&
+	    !(dev->power.driver_flags & DPM_FLAG_ALWAYS_SUSPEND)) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
@@ -1549,7 +1560,9 @@ static int __device_suspend(struct devic
 		if (parent) {
 			spin_lock_irq(&parent->power.lock);
 
-			dev->parent->power.direct_complete = false;
+			if (!(dev->parent->power.driver_flags & DPM_FLAG_ALWAYS_SUSPEND))
+				dev->parent->power.direct_complete = false;
+
 			if (dev->power.wakeup_path
 			    && !dev->parent->power.ignore_children)
 				dev->parent->power.wakeup_path = true;
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -550,6 +550,37 @@ struct pm_subsys_data {
 #endif
 };
 
+/*
+ * Driver flags to control system suspend/resume behavior.
+ *
+ * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
+ * ALWAYS_SUSPEND: Invoke ->suspend callback regardless of runtime PM status.
+ *
+ * These flags can be set by device drivers at the probe time.  They need not be
+ * cleared by the drivers as the driver core will take care of that.
+ *
+ * Setting SAFE_SUSPEND instructs bus types and PM domains that may want to
+ * runtime resume the device upfront during system suspend that doing so is not
+ * necessary from the driver's perspective, because its ->suspend callback can
+ * cope with a runtime suspended device (or is not present at all).
+ *
+ * Setting ALWAYS_SUSPEND instructs the PM core to always invoke the top-level
+ * ->suspend callback for the device during system suspend even though it may
+ * be runtime suspended at that point and might be left alone in principle.
+ * That is required for some devices that need to be prepared for system
+ * suspend in a special way which only is known to their drivers.  However,
+ * setting ALWAYS_SUSPEND may also affect the devices parent and its parent and
+ * so on, as it may cause those devices to be runtime resumed upfront during
+ * system suspend unless SAFE_SUSPEND is set for them.
+ *
+ * Moreover, some bus types and PM domains have a policy to runtime resume all
+ * devices upfront in their ->suspend callbacks, so if ALWAYS_SUSPEND is set and
+ * SAFE_SUSPEND is not set for a device belonging to one of them, the device
+ * will be runtime resumed upfront every time during system suspend.
+ */
+#define DPM_FLAG_SAFE_SUSPEND	BIT(0)
+#define DPM_FLAG_ALWAYS_SUSPEND	BIT(1)
+
 struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
@@ -561,6 +592,7 @@ struct dev_pm_info {
 	bool			is_late_suspended:1;
 	bool			early_init:1;	/* Owned by the PM core */
 	bool			direct_complete:1;	/* Owned by the PM core */
+	unsigned int		driver_flags;
 	spinlock_t		lock;
 #ifdef CONFIG_PM_SLEEP
 	struct list_head	entry;
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -1024,11 +1024,14 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
+ * set for them.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	if (!(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND))
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
Index: linux-pm/drivers/base/dd.c
===================================================================
--- linux-pm.orig/drivers/base/dd.c
+++ linux-pm/drivers/base/dd.c
@@ -436,6 +436,7 @@ pinctrl_bind_failed:
 	if (dev->pm_domain && dev->pm_domain->dismiss)
 		dev->pm_domain->dismiss(dev);
 	pm_runtime_reinit(dev);
+	dev->power.driver_flags = 0;
 
 	switch (ret) {
 	case -EPROBE_DEFER:
@@ -841,6 +842,7 @@ static void __device_release_driver(stru
 		if (dev->pm_domain && dev->pm_domain->dismiss)
 			dev->pm_domain->dismiss(dev);
 		pm_runtime_reinit(dev);
+		dev->power.driver_flags = 0;
 
 		klist_remove(&dev->p->knode_driver);
 		device_pm_check_callbacks(dev);

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-25 13:42                   ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-25 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> 
> [cut]
> 
> > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> > a device with direct_complete set after __device_suspend(), because it can only
> > have direct_complete set at that point if all of the hierarchy below it has
> > this flag set too and so runtime PM has to be disabled for all of those
> > devices as well.]
> 
> Which makes me realize that we should take a step back and look at what
> problems there are.
> 
> First, there are devices (I know about two examples so far and both are PCI)
> that may need to be runtime resumed during system suspend for reasons other
> than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
> to be a way to indicate that from the driver side.
> 
> However, it still may be valuable to check the power-related conditions for
> leaving the device in runtime suspend over system suspend/resume in case
> it actually doesn't need to be runtime resumed during system suspend after
> all.  That's what the majority of my patch was about.
> 
> The second problem is that the ACPI PM domain (and the PCI bus type)
> runtime resumes all devices unconditionally in its ->suspend callback,
> even though that may not be necessary for some devices.  Therefore there
> needs to be a way to indicate that too.  That still would be good to
> have *regardless* of the direct_complete mechanism, because the direct_complete
> flag may not be set very often due to dependencies and then the
> resume-during-suspend will take place unnecessarily.
> 
> Accordingly, it looks like we need a "no need to resume me" flag in the first
> place.  That would indicate to interested pieces of code that, from the
> driver perspective, the device doesn't need to be runtime resumed before
> invoking its system suspend callbacks.  This should be clear enough to everyone
> IMO.
> 
> [Note that if that flag is set for all devices, we may drop it along with
> direct_complete, but before that happens both are needed.]

I think we are in agreement that direct_complete will not be necessary any
more when all drivers/bus types/PM domains and so on can do the "safe
suspend", but we're not there yet. :-)

> To address the first issue I would add something like the flag in the patches
> I sent (but without the ACPI PM domain part which should be covered by the
> "no need to resume me" flag above), because that allows the device's ->suspend
> callback to run in principle and the driver may use that callback even to
> runtime resume the device if that's what it wants to do.  So something like
> "run my ->suspend callback even though I might stay in runtime suspend".
> 
> I would probably add driver_flags to dev_pm_info for that to set at the probe
> time (and I would make the core clear that on driver removal).
> 
> The complexity concern is there, but honestly I don't see a better way at
> this point.

So below is a prototype patch.  It still is missing a documentation update, but
other than that it should be complete unless I missed something.

The way it works is that the SAFE_SUSPEND flag is not looked at by the core
at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
to take it into account in the future.  That is what causes the "runtime resume
during system suspend" to be skipped.

In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
the decision on whether or not to use direct_complete to be deferred to the
__device_suspend_late() time.  If you set it for a PCI device, the effect is
equivalent to "no direct_complete".  If you set it for a device in the ACPI
PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
set, the effect is equivalent to "no direct_complete" too, but if it is set,
the core may still try to use direct_complete for the device, but it will
make the decision on it in __device_suspend_late() and then it will not invoke
the ->suspend_late callback for the device if it is still runtime suspended.
[Note that you cannot runtime resume and runtime suspend again a device during
system suspend, so if it is runtime suspended in __device_suspend_late(), it
has been runtime suspend all the way since device_prepare().]

So say you point the ->suspend_late and ->resume_early callbacks of
the designware i2c driver to pm_runtime_force_suspend() and
pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
and ALWAYS_SUSPEND flags for the device.

If system suspend is started and the device is not runtime suspended,
direct_complete is not set for it and everything works as usual, so say
the device is runtime suspended in device_prepare().  Then, the ACPI PM
domain checks the other conditions for leaving it in runtime suspend and
returns either 0 or a positive number from acpi_subsys_prepare().

If 0 is returned, direct_complete is not set by the core and
acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
that the device need not be runtime resumed, so it invokes the driver's
->suspend callback (which is not present, so it doesn't do anything).
Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
and it calls pm_runtime_force_suspend(), which executes the driver's
->runtime_suspend() callback, and then (if successful) calls
acpi_dev_suspend_late() to put the device into a low-power state.  The
resume path is a reverse of the above in this case.  So far, so good.

If acpi_subsys_prepare() returns a positive number, the core sets
direct_complete for the device.  Next, in __device_suspend(), it sees
direct_complete set and checks the ALWAYS_SUSPEND flag.  It is set,
so the runtime PM disabling part is skipped.  acpi_subsys_suspend()
is called, it checks SAFE_SUSPEND and skips the runtime resume of the
device.  Now, the device can stay runtime suspended or it may be runtime
resumed in the meantime.

First, say it stays runtime suspended.  __device_suspend_late() is called
for it, sees direct_complete set and sees that the device is runtime
suspended, so it just returns with direct_complete set.  The resume path
will be skipped entirely for the device, so it remains runtime suspended
all the way throughout the system suspend and resume.  Still OK.

Now, say the device has been runtime resumed between __device_suspend()
and __device_suspend_late().  The latter will see direct_complete set
and will see that the device is not runtime suspended any more, so it
will clear direct_complete and call acpi_subsys_suspend_late().  That,
in turn, will call pm_runtime_force_suspend(), which will see that
the device is not runtime suspended, so it will call the driver's
->runtime_suspend() callback.  Next,  acpi_dev_suspend_late() will be
called to put the device into a low-power state.  From that point on
everything is equivalent to the case in which acpi_subsys_prepare()
returned 0.

---
 drivers/acpi/device_pm.c  |    7 +++++--
 drivers/base/dd.c         |    2 ++
 drivers/base/power/main.c |   21 +++++++++++++++++----
 include/linux/pm.h        |   32 ++++++++++++++++++++++++++++++++
 4 files changed, 56 insertions(+), 6 deletions(-)

Index: linux-pm/drivers/base/power/main.c
===================================================================
--- linux-pm.orig/drivers/base/power/main.c
+++ linux-pm/drivers/base/power/main.c
@@ -1271,9 +1271,16 @@ static int __device_suspend_late(struct
 		goto Complete;
 	}
 
-	if (dev->power.syscore || dev->power.direct_complete)
+	if (dev->power.syscore)
 		goto Complete;
 
+	if (dev->power.direct_complete) {
+		if (pm_runtime_status_suspended(dev))
+			goto Complete;
+
+		dev->power.direct_complete = false;
+	}
+
 	if (dev->pm_domain) {
 		info = "late power domain ";
 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
@@ -1437,7 +1444,10 @@ static void dpm_clear_suppliers_direct_c
 
 	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node) {
 		spin_lock_irq(&link->supplier->power.lock);
-		link->supplier->power.direct_complete = false;
+
+		if (!(link->supplier->power.driver_flags & DPM_FLAG_ALWAYS_SUSPEND))
+			link->supplier->power.direct_complete = false;
+
 		spin_unlock_irq(&link->supplier->power.lock);
 	}
 
@@ -1482,7 +1492,8 @@ static int __device_suspend(struct devic
 	if (dev->power.syscore)
 		goto Complete;
 
-	if (dev->power.direct_complete) {
+	if (dev->power.direct_complete &&
+	    !(dev->power.driver_flags & DPM_FLAG_ALWAYS_SUSPEND)) {
 		if (pm_runtime_status_suspended(dev)) {
 			pm_runtime_disable(dev);
 			if (pm_runtime_status_suspended(dev))
@@ -1549,7 +1560,9 @@ static int __device_suspend(struct devic
 		if (parent) {
 			spin_lock_irq(&parent->power.lock);
 
-			dev->parent->power.direct_complete = false;
+			if (!(dev->parent->power.driver_flags & DPM_FLAG_ALWAYS_SUSPEND))
+				dev->parent->power.direct_complete = false;
+
 			if (dev->power.wakeup_path
 			    && !dev->parent->power.ignore_children)
 				dev->parent->power.wakeup_path = true;
Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -550,6 +550,37 @@ struct pm_subsys_data {
 #endif
 };
 
+/*
+ * Driver flags to control system suspend/resume behavior.
+ *
+ * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
+ * ALWAYS_SUSPEND: Invoke ->suspend callback regardless of runtime PM status.
+ *
+ * These flags can be set by device drivers at the probe time.  They need not be
+ * cleared by the drivers as the driver core will take care of that.
+ *
+ * Setting SAFE_SUSPEND instructs bus types and PM domains that may want to
+ * runtime resume the device upfront during system suspend that doing so is not
+ * necessary from the driver's perspective, because its ->suspend callback can
+ * cope with a runtime suspended device (or is not present at all).
+ *
+ * Setting ALWAYS_SUSPEND instructs the PM core to always invoke the top-level
+ * ->suspend callback for the device during system suspend even though it may
+ * be runtime suspended at that point and might be left alone in principle.
+ * That is required for some devices that need to be prepared for system
+ * suspend in a special way which only is known to their drivers.  However,
+ * setting ALWAYS_SUSPEND may also affect the devices parent and its parent and
+ * so on, as it may cause those devices to be runtime resumed upfront during
+ * system suspend unless SAFE_SUSPEND is set for them.
+ *
+ * Moreover, some bus types and PM domains have a policy to runtime resume all
+ * devices upfront in their ->suspend callbacks, so if ALWAYS_SUSPEND is set and
+ * SAFE_SUSPEND is not set for a device belonging to one of them, the device
+ * will be runtime resumed upfront every time during system suspend.
+ */
+#define DPM_FLAG_SAFE_SUSPEND	BIT(0)
+#define DPM_FLAG_ALWAYS_SUSPEND	BIT(1)
+
 struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
@@ -561,6 +592,7 @@ struct dev_pm_info {
 	bool			is_late_suspended:1;
 	bool			early_init:1;	/* Owned by the PM core */
 	bool			direct_complete:1;	/* Owned by the PM core */
+	unsigned int		driver_flags;
 	spinlock_t		lock;
 #ifdef CONFIG_PM_SLEEP
 	struct list_head	entry;
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -1024,11 +1024,14 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
+ * set for them.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	if (!(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND))
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
Index: linux-pm/drivers/base/dd.c
===================================================================
--- linux-pm.orig/drivers/base/dd.c
+++ linux-pm/drivers/base/dd.c
@@ -436,6 +436,7 @@ pinctrl_bind_failed:
 	if (dev->pm_domain && dev->pm_domain->dismiss)
 		dev->pm_domain->dismiss(dev);
 	pm_runtime_reinit(dev);
+	dev->power.driver_flags = 0;
 
 	switch (ret) {
 	case -EPROBE_DEFER:
@@ -841,6 +842,7 @@ static void __device_release_driver(stru
 		if (dev->pm_domain && dev->pm_domain->dismiss)
 			dev->pm_domain->dismiss(dev);
 		pm_runtime_reinit(dev);
+		dev->power.driver_flags = 0;
 
 		klist_remove(&dev->p->knode_driver);
 		device_pm_check_callbacks(dev);

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 0/9] PM / ACPI / i2c: Deploy runtime PM centric path for system sleep
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-25 14:10   ` Jarkko Nikula
  -1 siblings, 0 replies; 94+ messages in thread
From: Jarkko Nikula @ 2017-08-25 14:10 UTC (permalink / raw)
  To: Ulf Hansson, Wolfram Sang, Rafael J . Wysocki, Len Brown,
	linux-acpi, linux-pm
  Cc: Kevin Hilman, Andy Shevchenko, Mika Westerberg, Jisheng Zhang,
	John Stultz, Guodong Xu, Sumit Semwal, Haojian Zhuang,
	linux-arm-kernel, linux-i2c

On 08/23/2017 05:42 PM, Ulf Hansson wrote:
> This series has been tested on an ARM64 Hikey board, which isn't having the
> i2c device attached to the ACPI PM domain. This means that the ACPI changes
> needs to be tested on some relevant Intel SoCs and it's greatly appreciated
> is someone could help out with this, so is of course review comments.
> 
I tested this set on both platforms using drivers/acpi/acpi_lpss.c and 
drivers/mfd/intel-lpss.c and didn't see any issues.

I guess tested-by is not needed yet as details are cooking in ACPI part 
of the set.

-- 
Jarkko

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 0/9] PM / ACPI / i2c: Deploy runtime PM centric path for system sleep
@ 2017-08-25 14:10   ` Jarkko Nikula
  0 siblings, 0 replies; 94+ messages in thread
From: Jarkko Nikula @ 2017-08-25 14:10 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/23/2017 05:42 PM, Ulf Hansson wrote:
> This series has been tested on an ARM64 Hikey board, which isn't having the
> i2c device attached to the ACPI PM domain. This means that the ACPI changes
> needs to be tested on some relevant Intel SoCs and it's greatly appreciated
> is someone could help out with this, so is of course review comments.
> 
I tested this set on both platforms using drivers/acpi/acpi_lpss.c and 
drivers/mfd/intel-lpss.c and didn't see any issues.

I guess tested-by is not needed yet as details are cooking in ACPI part 
of the set.

-- 
Jarkko

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-25 13:42                   ` Rafael J. Wysocki
@ 2017-08-28  1:30                     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28  1:30 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> > 
> > [cut]
> > 
> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> > > a device with direct_complete set after __device_suspend(), because it can only
> > > have direct_complete set at that point if all of the hierarchy below it has
> > > this flag set too and so runtime PM has to be disabled for all of those
> > > devices as well.]
> > 
> > Which makes me realize that we should take a step back and look at what
> > problems there are.
> > 
> > First, there are devices (I know about two examples so far and both are PCI)
> > that may need to be runtime resumed during system suspend for reasons other
> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
> > to be a way to indicate that from the driver side.
> > 
> > However, it still may be valuable to check the power-related conditions for
> > leaving the device in runtime suspend over system suspend/resume in case
> > it actually doesn't need to be runtime resumed during system suspend after
> > all.  That's what the majority of my patch was about.
> > 
> > The second problem is that the ACPI PM domain (and the PCI bus type)
> > runtime resumes all devices unconditionally in its ->suspend callback,
> > even though that may not be necessary for some devices.  Therefore there
> > needs to be a way to indicate that too.  That still would be good to
> > have *regardless* of the direct_complete mechanism, because the direct_complete
> > flag may not be set very often due to dependencies and then the
> > resume-during-suspend will take place unnecessarily.
> > 
> > Accordingly, it looks like we need a "no need to resume me" flag in the first
> > place.  That would indicate to interested pieces of code that, from the
> > driver perspective, the device doesn't need to be runtime resumed before
> > invoking its system suspend callbacks.  This should be clear enough to everyone
> > IMO.
> > 
> > [Note that if that flag is set for all devices, we may drop it along with
> > direct_complete, but before that happens both are needed.]
> 
> I think we are in agreement that direct_complete will not be necessary any
> more when all drivers/bus types/PM domains and so on can do the "safe
> suspend", but we're not there yet. :-)
> 
> > To address the first issue I would add something like the flag in the patches
> > I sent (but without the ACPI PM domain part which should be covered by the
> > "no need to resume me" flag above), because that allows the device's ->suspend
> > callback to run in principle and the driver may use that callback even to
> > runtime resume the device if that's what it wants to do.  So something like
> > "run my ->suspend callback even though I might stay in runtime suspend".
> > 
> > I would probably add driver_flags to dev_pm_info for that to set at the probe
> > time (and I would make the core clear that on driver removal).
> > 
> > The complexity concern is there, but honestly I don't see a better way at
> > this point.
> 
> So below is a prototype patch.  It still is missing a documentation update, but
> other than that it should be complete unless I missed something.
> 
> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
> to take it into account in the future.  That is what causes the "runtime resume
> during system suspend" to be skipped.
> 
> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
> the decision on whether or not to use direct_complete to be deferred to the
> __device_suspend_late() time.  If you set it for a PCI device, the effect is
> equivalent to "no direct_complete".  If you set it for a device in the ACPI
> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
> set, the effect is equivalent to "no direct_complete" too, but if it is set,
> the core may still try to use direct_complete for the device, but it will
> make the decision on it in __device_suspend_late() and then it will not invoke
> the ->suspend_late callback for the device if it is still runtime suspended.
> [Note that you cannot runtime resume and runtime suspend again a device during
> system suspend, so if it is runtime suspended in __device_suspend_late(), it
> has been runtime suspend all the way since device_prepare().]
> 
> So say you point the ->suspend_late and ->resume_early callbacks of
> the designware i2c driver to pm_runtime_force_suspend() and
> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
> and ALWAYS_SUSPEND flags for the device.
> 
> If system suspend is started and the device is not runtime suspended,
> direct_complete is not set for it and everything works as usual, so say
> the device is runtime suspended in device_prepare().  Then, the ACPI PM
> domain checks the other conditions for leaving it in runtime suspend and
> returns either 0 or a positive number from acpi_subsys_prepare().
> 
> If 0 is returned, direct_complete is not set by the core and
> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
> that the device need not be runtime resumed, so it invokes the driver's
> ->suspend callback (which is not present, so it doesn't do anything).
> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
> and it calls pm_runtime_force_suspend(), which executes the driver's
> ->runtime_suspend() callback, and then (if successful) calls
> acpi_dev_suspend_late() to put the device into a low-power state.  The
> resume path is a reverse of the above in this case.  So far, so good.

Well, not really, because if the device remains runtime suspended,
->runtime_suspend() will not be called by pm_runtime_force_suspend() and
acpi_dev_suspend_late() should not be called then.

So more changes in the ACPI PM domain are needed after all.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-28  1:30                     ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28  1:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> > 
> > [cut]
> > 
> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> > > a device with direct_complete set after __device_suspend(), because it can only
> > > have direct_complete set at that point if all of the hierarchy below it has
> > > this flag set too and so runtime PM has to be disabled for all of those
> > > devices as well.]
> > 
> > Which makes me realize that we should take a step back and look at what
> > problems there are.
> > 
> > First, there are devices (I know about two examples so far and both are PCI)
> > that may need to be runtime resumed during system suspend for reasons other
> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
> > to be a way to indicate that from the driver side.
> > 
> > However, it still may be valuable to check the power-related conditions for
> > leaving the device in runtime suspend over system suspend/resume in case
> > it actually doesn't need to be runtime resumed during system suspend after
> > all.  That's what the majority of my patch was about.
> > 
> > The second problem is that the ACPI PM domain (and the PCI bus type)
> > runtime resumes all devices unconditionally in its ->suspend callback,
> > even though that may not be necessary for some devices.  Therefore there
> > needs to be a way to indicate that too.  That still would be good to
> > have *regardless* of the direct_complete mechanism, because the direct_complete
> > flag may not be set very often due to dependencies and then the
> > resume-during-suspend will take place unnecessarily.
> > 
> > Accordingly, it looks like we need a "no need to resume me" flag in the first
> > place.  That would indicate to interested pieces of code that, from the
> > driver perspective, the device doesn't need to be runtime resumed before
> > invoking its system suspend callbacks.  This should be clear enough to everyone
> > IMO.
> > 
> > [Note that if that flag is set for all devices, we may drop it along with
> > direct_complete, but before that happens both are needed.]
> 
> I think we are in agreement that direct_complete will not be necessary any
> more when all drivers/bus types/PM domains and so on can do the "safe
> suspend", but we're not there yet. :-)
> 
> > To address the first issue I would add something like the flag in the patches
> > I sent (but without the ACPI PM domain part which should be covered by the
> > "no need to resume me" flag above), because that allows the device's ->suspend
> > callback to run in principle and the driver may use that callback even to
> > runtime resume the device if that's what it wants to do.  So something like
> > "run my ->suspend callback even though I might stay in runtime suspend".
> > 
> > I would probably add driver_flags to dev_pm_info for that to set at the probe
> > time (and I would make the core clear that on driver removal).
> > 
> > The complexity concern is there, but honestly I don't see a better way at
> > this point.
> 
> So below is a prototype patch.  It still is missing a documentation update, but
> other than that it should be complete unless I missed something.
> 
> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
> to take it into account in the future.  That is what causes the "runtime resume
> during system suspend" to be skipped.
> 
> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
> the decision on whether or not to use direct_complete to be deferred to the
> __device_suspend_late() time.  If you set it for a PCI device, the effect is
> equivalent to "no direct_complete".  If you set it for a device in the ACPI
> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
> set, the effect is equivalent to "no direct_complete" too, but if it is set,
> the core may still try to use direct_complete for the device, but it will
> make the decision on it in __device_suspend_late() and then it will not invoke
> the ->suspend_late callback for the device if it is still runtime suspended.
> [Note that you cannot runtime resume and runtime suspend again a device during
> system suspend, so if it is runtime suspended in __device_suspend_late(), it
> has been runtime suspend all the way since device_prepare().]
> 
> So say you point the ->suspend_late and ->resume_early callbacks of
> the designware i2c driver to pm_runtime_force_suspend() and
> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
> and ALWAYS_SUSPEND flags for the device.
> 
> If system suspend is started and the device is not runtime suspended,
> direct_complete is not set for it and everything works as usual, so say
> the device is runtime suspended in device_prepare().  Then, the ACPI PM
> domain checks the other conditions for leaving it in runtime suspend and
> returns either 0 or a positive number from acpi_subsys_prepare().
> 
> If 0 is returned, direct_complete is not set by the core and
> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
> that the device need not be runtime resumed, so it invokes the driver's
> ->suspend callback (which is not present, so it doesn't do anything).
> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
> and it calls pm_runtime_force_suspend(), which executes the driver's
> ->runtime_suspend() callback, and then (if successful) calls
> acpi_dev_suspend_late() to put the device into a low-power state.  The
> resume path is a reverse of the above in this case.  So far, so good.

Well, not really, because if the device remains runtime suspended,
->runtime_suspend() will not be called by pm_runtime_force_suspend() and
acpi_dev_suspend_late() should not be called then.

So more changes in the ACPI PM domain are needed after all.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-28  1:30                     ` Rafael J. Wysocki
@ 2017-08-28  8:31                       ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-28  8:31 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
>> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
>> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
>> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
>> >
>> > [cut]
>> >
>> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
>> > > a device with direct_complete set after __device_suspend(), because it can only
>> > > have direct_complete set at that point if all of the hierarchy below it has
>> > > this flag set too and so runtime PM has to be disabled for all of those
>> > > devices as well.]
>> >
>> > Which makes me realize that we should take a step back and look at what
>> > problems there are.
>> >
>> > First, there are devices (I know about two examples so far and both are PCI)
>> > that may need to be runtime resumed during system suspend for reasons other
>> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
>> > to be a way to indicate that from the driver side.
>> >
>> > However, it still may be valuable to check the power-related conditions for
>> > leaving the device in runtime suspend over system suspend/resume in case
>> > it actually doesn't need to be runtime resumed during system suspend after
>> > all.  That's what the majority of my patch was about.
>> >
>> > The second problem is that the ACPI PM domain (and the PCI bus type)
>> > runtime resumes all devices unconditionally in its ->suspend callback,
>> > even though that may not be necessary for some devices.  Therefore there
>> > needs to be a way to indicate that too.  That still would be good to
>> > have *regardless* of the direct_complete mechanism, because the direct_complete
>> > flag may not be set very often due to dependencies and then the
>> > resume-during-suspend will take place unnecessarily.
>> >
>> > Accordingly, it looks like we need a "no need to resume me" flag in the first
>> > place.  That would indicate to interested pieces of code that, from the
>> > driver perspective, the device doesn't need to be runtime resumed before
>> > invoking its system suspend callbacks.  This should be clear enough to everyone
>> > IMO.
>> >
>> > [Note that if that flag is set for all devices, we may drop it along with
>> > direct_complete, but before that happens both are needed.]
>>
>> I think we are in agreement that direct_complete will not be necessary any
>> more when all drivers/bus types/PM domains and so on can do the "safe
>> suspend", but we're not there yet. :-)
>>
>> > To address the first issue I would add something like the flag in the patches
>> > I sent (but without the ACPI PM domain part which should be covered by the
>> > "no need to resume me" flag above), because that allows the device's ->suspend
>> > callback to run in principle and the driver may use that callback even to
>> > runtime resume the device if that's what it wants to do.  So something like
>> > "run my ->suspend callback even though I might stay in runtime suspend".
>> >
>> > I would probably add driver_flags to dev_pm_info for that to set at the probe
>> > time (and I would make the core clear that on driver removal).
>> >
>> > The complexity concern is there, but honestly I don't see a better way at
>> > this point.
>>
>> So below is a prototype patch.  It still is missing a documentation update, but
>> other than that it should be complete unless I missed something.
>>
>> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
>> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
>> to take it into account in the future.  That is what causes the "runtime resume
>> during system suspend" to be skipped.
>>
>> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
>> the decision on whether or not to use direct_complete to be deferred to the
>> __device_suspend_late() time.  If you set it for a PCI device, the effect is
>> equivalent to "no direct_complete".  If you set it for a device in the ACPI
>> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
>> set, the effect is equivalent to "no direct_complete" too, but if it is set,
>> the core may still try to use direct_complete for the device, but it will
>> make the decision on it in __device_suspend_late() and then it will not invoke
>> the ->suspend_late callback for the device if it is still runtime suspended.
>> [Note that you cannot runtime resume and runtime suspend again a device during
>> system suspend, so if it is runtime suspended in __device_suspend_late(), it
>> has been runtime suspend all the way since device_prepare().]
>>
>> So say you point the ->suspend_late and ->resume_early callbacks of
>> the designware i2c driver to pm_runtime_force_suspend() and
>> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
>> and ALWAYS_SUSPEND flags for the device.
>>
>> If system suspend is started and the device is not runtime suspended,
>> direct_complete is not set for it and everything works as usual, so say
>> the device is runtime suspended in device_prepare().  Then, the ACPI PM
>> domain checks the other conditions for leaving it in runtime suspend and
>> returns either 0 or a positive number from acpi_subsys_prepare().
>>
>> If 0 is returned, direct_complete is not set by the core and
>> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
>> that the device need not be runtime resumed, so it invokes the driver's
>> ->suspend callback (which is not present, so it doesn't do anything).
>> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
>> and it calls pm_runtime_force_suspend(), which executes the driver's
>> ->runtime_suspend() callback, and then (if successful) calls
>> acpi_dev_suspend_late() to put the device into a low-power state.  The
>> resume path is a reverse of the above in this case.  So far, so good.
>
> Well, not really, because if the device remains runtime suspended,
> ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> acpi_dev_suspend_late() should not be called then.
>
> So more changes in the ACPI PM domain are needed after all.

Yes, that's what I thought as well.

Anyway, let me cook a new version of the series - trying to address
the first bits you have pointed out. Then we can continue with
fine-tuning on top, addressing further optimizations of the ACPI PM
domain.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-28  8:31                       ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-28  8:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
>> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
>> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
>> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
>> >
>> > [cut]
>> >
>> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
>> > > a device with direct_complete set after __device_suspend(), because it can only
>> > > have direct_complete set at that point if all of the hierarchy below it has
>> > > this flag set too and so runtime PM has to be disabled for all of those
>> > > devices as well.]
>> >
>> > Which makes me realize that we should take a step back and look at what
>> > problems there are.
>> >
>> > First, there are devices (I know about two examples so far and both are PCI)
>> > that may need to be runtime resumed during system suspend for reasons other
>> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
>> > to be a way to indicate that from the driver side.
>> >
>> > However, it still may be valuable to check the power-related conditions for
>> > leaving the device in runtime suspend over system suspend/resume in case
>> > it actually doesn't need to be runtime resumed during system suspend after
>> > all.  That's what the majority of my patch was about.
>> >
>> > The second problem is that the ACPI PM domain (and the PCI bus type)
>> > runtime resumes all devices unconditionally in its ->suspend callback,
>> > even though that may not be necessary for some devices.  Therefore there
>> > needs to be a way to indicate that too.  That still would be good to
>> > have *regardless* of the direct_complete mechanism, because the direct_complete
>> > flag may not be set very often due to dependencies and then the
>> > resume-during-suspend will take place unnecessarily.
>> >
>> > Accordingly, it looks like we need a "no need to resume me" flag in the first
>> > place.  That would indicate to interested pieces of code that, from the
>> > driver perspective, the device doesn't need to be runtime resumed before
>> > invoking its system suspend callbacks.  This should be clear enough to everyone
>> > IMO.
>> >
>> > [Note that if that flag is set for all devices, we may drop it along with
>> > direct_complete, but before that happens both are needed.]
>>
>> I think we are in agreement that direct_complete will not be necessary any
>> more when all drivers/bus types/PM domains and so on can do the "safe
>> suspend", but we're not there yet. :-)
>>
>> > To address the first issue I would add something like the flag in the patches
>> > I sent (but without the ACPI PM domain part which should be covered by the
>> > "no need to resume me" flag above), because that allows the device's ->suspend
>> > callback to run in principle and the driver may use that callback even to
>> > runtime resume the device if that's what it wants to do.  So something like
>> > "run my ->suspend callback even though I might stay in runtime suspend".
>> >
>> > I would probably add driver_flags to dev_pm_info for that to set at the probe
>> > time (and I would make the core clear that on driver removal).
>> >
>> > The complexity concern is there, but honestly I don't see a better way at
>> > this point.
>>
>> So below is a prototype patch.  It still is missing a documentation update, but
>> other than that it should be complete unless I missed something.
>>
>> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
>> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
>> to take it into account in the future.  That is what causes the "runtime resume
>> during system suspend" to be skipped.
>>
>> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
>> the decision on whether or not to use direct_complete to be deferred to the
>> __device_suspend_late() time.  If you set it for a PCI device, the effect is
>> equivalent to "no direct_complete".  If you set it for a device in the ACPI
>> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
>> set, the effect is equivalent to "no direct_complete" too, but if it is set,
>> the core may still try to use direct_complete for the device, but it will
>> make the decision on it in __device_suspend_late() and then it will not invoke
>> the ->suspend_late callback for the device if it is still runtime suspended.
>> [Note that you cannot runtime resume and runtime suspend again a device during
>> system suspend, so if it is runtime suspended in __device_suspend_late(), it
>> has been runtime suspend all the way since device_prepare().]
>>
>> So say you point the ->suspend_late and ->resume_early callbacks of
>> the designware i2c driver to pm_runtime_force_suspend() and
>> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
>> and ALWAYS_SUSPEND flags for the device.
>>
>> If system suspend is started and the device is not runtime suspended,
>> direct_complete is not set for it and everything works as usual, so say
>> the device is runtime suspended in device_prepare().  Then, the ACPI PM
>> domain checks the other conditions for leaving it in runtime suspend and
>> returns either 0 or a positive number from acpi_subsys_prepare().
>>
>> If 0 is returned, direct_complete is not set by the core and
>> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
>> that the device need not be runtime resumed, so it invokes the driver's
>> ->suspend callback (which is not present, so it doesn't do anything).
>> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
>> and it calls pm_runtime_force_suspend(), which executes the driver's
>> ->runtime_suspend() callback, and then (if successful) calls
>> acpi_dev_suspend_late() to put the device into a low-power state.  The
>> resume path is a reverse of the above in this case.  So far, so good.
>
> Well, not really, because if the device remains runtime suspended,
> ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> acpi_dev_suspend_late() should not be called then.
>
> So more changes in the ACPI PM domain are needed after all.

Yes, that's what I thought as well.

Anyway, let me cook a new version of the series - trying to address
the first bits you have pointed out. Then we can continue with
fine-tuning on top, addressing further optimizations of the ACPI PM
domain.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-28  8:31                       ` Ulf Hansson
@ 2017-08-28 12:39                         ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28 12:39 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> >> >
> >> > [cut]
> >> >
> >> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> >> > > a device with direct_complete set after __device_suspend(), because it can only
> >> > > have direct_complete set at that point if all of the hierarchy below it has
> >> > > this flag set too and so runtime PM has to be disabled for all of those
> >> > > devices as well.]
> >> >
> >> > Which makes me realize that we should take a step back and look at what
> >> > problems there are.
> >> >
> >> > First, there are devices (I know about two examples so far and both are PCI)
> >> > that may need to be runtime resumed during system suspend for reasons other
> >> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
> >> > to be a way to indicate that from the driver side.
> >> >
> >> > However, it still may be valuable to check the power-related conditions for
> >> > leaving the device in runtime suspend over system suspend/resume in case
> >> > it actually doesn't need to be runtime resumed during system suspend after
> >> > all.  That's what the majority of my patch was about.
> >> >
> >> > The second problem is that the ACPI PM domain (and the PCI bus type)
> >> > runtime resumes all devices unconditionally in its ->suspend callback,
> >> > even though that may not be necessary for some devices.  Therefore there
> >> > needs to be a way to indicate that too.  That still would be good to
> >> > have *regardless* of the direct_complete mechanism, because the direct_complete
> >> > flag may not be set very often due to dependencies and then the
> >> > resume-during-suspend will take place unnecessarily.
> >> >
> >> > Accordingly, it looks like we need a "no need to resume me" flag in the first
> >> > place.  That would indicate to interested pieces of code that, from the
> >> > driver perspective, the device doesn't need to be runtime resumed before
> >> > invoking its system suspend callbacks.  This should be clear enough to everyone
> >> > IMO.
> >> >
> >> > [Note that if that flag is set for all devices, we may drop it along with
> >> > direct_complete, but before that happens both are needed.]
> >>
> >> I think we are in agreement that direct_complete will not be necessary any
> >> more when all drivers/bus types/PM domains and so on can do the "safe
> >> suspend", but we're not there yet. :-)
> >>
> >> > To address the first issue I would add something like the flag in the patches
> >> > I sent (but without the ACPI PM domain part which should be covered by the
> >> > "no need to resume me" flag above), because that allows the device's ->suspend
> >> > callback to run in principle and the driver may use that callback even to
> >> > runtime resume the device if that's what it wants to do.  So something like
> >> > "run my ->suspend callback even though I might stay in runtime suspend".
> >> >
> >> > I would probably add driver_flags to dev_pm_info for that to set at the probe
> >> > time (and I would make the core clear that on driver removal).
> >> >
> >> > The complexity concern is there, but honestly I don't see a better way at
> >> > this point.
> >>
> >> So below is a prototype patch.  It still is missing a documentation update, but
> >> other than that it should be complete unless I missed something.
> >>
> >> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
> >> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
> >> to take it into account in the future.  That is what causes the "runtime resume
> >> during system suspend" to be skipped.
> >>
> >> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
> >> the decision on whether or not to use direct_complete to be deferred to the
> >> __device_suspend_late() time.  If you set it for a PCI device, the effect is
> >> equivalent to "no direct_complete".  If you set it for a device in the ACPI
> >> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
> >> set, the effect is equivalent to "no direct_complete" too, but if it is set,
> >> the core may still try to use direct_complete for the device, but it will
> >> make the decision on it in __device_suspend_late() and then it will not invoke
> >> the ->suspend_late callback for the device if it is still runtime suspended.
> >> [Note that you cannot runtime resume and runtime suspend again a device during
> >> system suspend, so if it is runtime suspended in __device_suspend_late(), it
> >> has been runtime suspend all the way since device_prepare().]
> >>
> >> So say you point the ->suspend_late and ->resume_early callbacks of
> >> the designware i2c driver to pm_runtime_force_suspend() and
> >> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
> >> and ALWAYS_SUSPEND flags for the device.
> >>
> >> If system suspend is started and the device is not runtime suspended,
> >> direct_complete is not set for it and everything works as usual, so say
> >> the device is runtime suspended in device_prepare().  Then, the ACPI PM
> >> domain checks the other conditions for leaving it in runtime suspend and
> >> returns either 0 or a positive number from acpi_subsys_prepare().
> >>
> >> If 0 is returned, direct_complete is not set by the core and
> >> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
> >> that the device need not be runtime resumed, so it invokes the driver's
> >> ->suspend callback (which is not present, so it doesn't do anything).
> >> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
> >> and it calls pm_runtime_force_suspend(), which executes the driver's
> >> ->runtime_suspend() callback, and then (if successful) calls
> >> acpi_dev_suspend_late() to put the device into a low-power state.  The
> >> resume path is a reverse of the above in this case.  So far, so good.
> >
> > Well, not really, because if the device remains runtime suspended,
> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> > acpi_dev_suspend_late() should not be called then.
> >
> > So more changes in the ACPI PM domain are needed after all.
> 
> Yes, that's what I thought as well.
> 
> Anyway, let me cook a new version of the series - trying to address
> the first bits you have pointed out. Then we can continue with
> fine-tuning on top, addressing further optimizations of the ACPI PM
> domain.

Actually, please hold on and let me show you what I would like to do
first.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-28 12:39                         ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28 12:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> >> >
> >> > [cut]
> >> >
> >> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
> >> > > a device with direct_complete set after __device_suspend(), because it can only
> >> > > have direct_complete set at that point if all of the hierarchy below it has
> >> > > this flag set too and so runtime PM has to be disabled for all of those
> >> > > devices as well.]
> >> >
> >> > Which makes me realize that we should take a step back and look at what
> >> > problems there are.
> >> >
> >> > First, there are devices (I know about two examples so far and both are PCI)
> >> > that may need to be runtime resumed during system suspend for reasons other
> >> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
> >> > to be a way to indicate that from the driver side.
> >> >
> >> > However, it still may be valuable to check the power-related conditions for
> >> > leaving the device in runtime suspend over system suspend/resume in case
> >> > it actually doesn't need to be runtime resumed during system suspend after
> >> > all.  That's what the majority of my patch was about.
> >> >
> >> > The second problem is that the ACPI PM domain (and the PCI bus type)
> >> > runtime resumes all devices unconditionally in its ->suspend callback,
> >> > even though that may not be necessary for some devices.  Therefore there
> >> > needs to be a way to indicate that too.  That still would be good to
> >> > have *regardless* of the direct_complete mechanism, because the direct_complete
> >> > flag may not be set very often due to dependencies and then the
> >> > resume-during-suspend will take place unnecessarily.
> >> >
> >> > Accordingly, it looks like we need a "no need to resume me" flag in the first
> >> > place.  That would indicate to interested pieces of code that, from the
> >> > driver perspective, the device doesn't need to be runtime resumed before
> >> > invoking its system suspend callbacks.  This should be clear enough to everyone
> >> > IMO.
> >> >
> >> > [Note that if that flag is set for all devices, we may drop it along with
> >> > direct_complete, but before that happens both are needed.]
> >>
> >> I think we are in agreement that direct_complete will not be necessary any
> >> more when all drivers/bus types/PM domains and so on can do the "safe
> >> suspend", but we're not there yet. :-)
> >>
> >> > To address the first issue I would add something like the flag in the patches
> >> > I sent (but without the ACPI PM domain part which should be covered by the
> >> > "no need to resume me" flag above), because that allows the device's ->suspend
> >> > callback to run in principle and the driver may use that callback even to
> >> > runtime resume the device if that's what it wants to do.  So something like
> >> > "run my ->suspend callback even though I might stay in runtime suspend".
> >> >
> >> > I would probably add driver_flags to dev_pm_info for that to set at the probe
> >> > time (and I would make the core clear that on driver removal).
> >> >
> >> > The complexity concern is there, but honestly I don't see a better way at
> >> > this point.
> >>
> >> So below is a prototype patch.  It still is missing a documentation update, but
> >> other than that it should be complete unless I missed something.
> >>
> >> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
> >> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
> >> to take it into account in the future.  That is what causes the "runtime resume
> >> during system suspend" to be skipped.
> >>
> >> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
> >> the decision on whether or not to use direct_complete to be deferred to the
> >> __device_suspend_late() time.  If you set it for a PCI device, the effect is
> >> equivalent to "no direct_complete".  If you set it for a device in the ACPI
> >> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
> >> set, the effect is equivalent to "no direct_complete" too, but if it is set,
> >> the core may still try to use direct_complete for the device, but it will
> >> make the decision on it in __device_suspend_late() and then it will not invoke
> >> the ->suspend_late callback for the device if it is still runtime suspended.
> >> [Note that you cannot runtime resume and runtime suspend again a device during
> >> system suspend, so if it is runtime suspended in __device_suspend_late(), it
> >> has been runtime suspend all the way since device_prepare().]
> >>
> >> So say you point the ->suspend_late and ->resume_early callbacks of
> >> the designware i2c driver to pm_runtime_force_suspend() and
> >> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
> >> and ALWAYS_SUSPEND flags for the device.
> >>
> >> If system suspend is started and the device is not runtime suspended,
> >> direct_complete is not set for it and everything works as usual, so say
> >> the device is runtime suspended in device_prepare().  Then, the ACPI PM
> >> domain checks the other conditions for leaving it in runtime suspend and
> >> returns either 0 or a positive number from acpi_subsys_prepare().
> >>
> >> If 0 is returned, direct_complete is not set by the core and
> >> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
> >> that the device need not be runtime resumed, so it invokes the driver's
> >> ->suspend callback (which is not present, so it doesn't do anything).
> >> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
> >> and it calls pm_runtime_force_suspend(), which executes the driver's
> >> ->runtime_suspend() callback, and then (if successful) calls
> >> acpi_dev_suspend_late() to put the device into a low-power state.  The
> >> resume path is a reverse of the above in this case.  So far, so good.
> >
> > Well, not really, because if the device remains runtime suspended,
> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> > acpi_dev_suspend_late() should not be called then.
> >
> > So more changes in the ACPI PM domain are needed after all.
> 
> Yes, that's what I thought as well.
> 
> Anyway, let me cook a new version of the series - trying to address
> the first bits you have pointed out. Then we can continue with
> fine-tuning on top, addressing further optimizations of the ACPI PM
> domain.

Actually, please hold on and let me show you what I would like to do
first.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-28 12:39                         ` Rafael J. Wysocki
@ 2017-08-28 12:54                           ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-28 12:54 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
>> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
>> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
>> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
>> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
>> >> >
>> >> > [cut]
>> >> >
>> >> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
>> >> > > a device with direct_complete set after __device_suspend(), because it can only
>> >> > > have direct_complete set at that point if all of the hierarchy below it has
>> >> > > this flag set too and so runtime PM has to be disabled for all of those
>> >> > > devices as well.]
>> >> >
>> >> > Which makes me realize that we should take a step back and look at what
>> >> > problems there are.
>> >> >
>> >> > First, there are devices (I know about two examples so far and both are PCI)
>> >> > that may need to be runtime resumed during system suspend for reasons other
>> >> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
>> >> > to be a way to indicate that from the driver side.
>> >> >
>> >> > However, it still may be valuable to check the power-related conditions for
>> >> > leaving the device in runtime suspend over system suspend/resume in case
>> >> > it actually doesn't need to be runtime resumed during system suspend after
>> >> > all.  That's what the majority of my patch was about.
>> >> >
>> >> > The second problem is that the ACPI PM domain (and the PCI bus type)
>> >> > runtime resumes all devices unconditionally in its ->suspend callback,
>> >> > even though that may not be necessary for some devices.  Therefore there
>> >> > needs to be a way to indicate that too.  That still would be good to
>> >> > have *regardless* of the direct_complete mechanism, because the direct_complete
>> >> > flag may not be set very often due to dependencies and then the
>> >> > resume-during-suspend will take place unnecessarily.
>> >> >
>> >> > Accordingly, it looks like we need a "no need to resume me" flag in the first
>> >> > place.  That would indicate to interested pieces of code that, from the
>> >> > driver perspective, the device doesn't need to be runtime resumed before
>> >> > invoking its system suspend callbacks.  This should be clear enough to everyone
>> >> > IMO.
>> >> >
>> >> > [Note that if that flag is set for all devices, we may drop it along with
>> >> > direct_complete, but before that happens both are needed.]
>> >>
>> >> I think we are in agreement that direct_complete will not be necessary any
>> >> more when all drivers/bus types/PM domains and so on can do the "safe
>> >> suspend", but we're not there yet. :-)
>> >>
>> >> > To address the first issue I would add something like the flag in the patches
>> >> > I sent (but without the ACPI PM domain part which should be covered by the
>> >> > "no need to resume me" flag above), because that allows the device's ->suspend
>> >> > callback to run in principle and the driver may use that callback even to
>> >> > runtime resume the device if that's what it wants to do.  So something like
>> >> > "run my ->suspend callback even though I might stay in runtime suspend".
>> >> >
>> >> > I would probably add driver_flags to dev_pm_info for that to set at the probe
>> >> > time (and I would make the core clear that on driver removal).
>> >> >
>> >> > The complexity concern is there, but honestly I don't see a better way at
>> >> > this point.
>> >>
>> >> So below is a prototype patch.  It still is missing a documentation update, but
>> >> other than that it should be complete unless I missed something.
>> >>
>> >> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
>> >> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
>> >> to take it into account in the future.  That is what causes the "runtime resume
>> >> during system suspend" to be skipped.
>> >>
>> >> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
>> >> the decision on whether or not to use direct_complete to be deferred to the
>> >> __device_suspend_late() time.  If you set it for a PCI device, the effect is
>> >> equivalent to "no direct_complete".  If you set it for a device in the ACPI
>> >> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
>> >> set, the effect is equivalent to "no direct_complete" too, but if it is set,
>> >> the core may still try to use direct_complete for the device, but it will
>> >> make the decision on it in __device_suspend_late() and then it will not invoke
>> >> the ->suspend_late callback for the device if it is still runtime suspended.
>> >> [Note that you cannot runtime resume and runtime suspend again a device during
>> >> system suspend, so if it is runtime suspended in __device_suspend_late(), it
>> >> has been runtime suspend all the way since device_prepare().]
>> >>
>> >> So say you point the ->suspend_late and ->resume_early callbacks of
>> >> the designware i2c driver to pm_runtime_force_suspend() and
>> >> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
>> >> and ALWAYS_SUSPEND flags for the device.
>> >>
>> >> If system suspend is started and the device is not runtime suspended,
>> >> direct_complete is not set for it and everything works as usual, so say
>> >> the device is runtime suspended in device_prepare().  Then, the ACPI PM
>> >> domain checks the other conditions for leaving it in runtime suspend and
>> >> returns either 0 or a positive number from acpi_subsys_prepare().
>> >>
>> >> If 0 is returned, direct_complete is not set by the core and
>> >> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
>> >> that the device need not be runtime resumed, so it invokes the driver's
>> >> ->suspend callback (which is not present, so it doesn't do anything).
>> >> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
>> >> and it calls pm_runtime_force_suspend(), which executes the driver's
>> >> ->runtime_suspend() callback, and then (if successful) calls
>> >> acpi_dev_suspend_late() to put the device into a low-power state.  The
>> >> resume path is a reverse of the above in this case.  So far, so good.
>> >
>> > Well, not really, because if the device remains runtime suspended,
>> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
>> > acpi_dev_suspend_late() should not be called then.
>> >
>> > So more changes in the ACPI PM domain are needed after all.
>>
>> Yes, that's what I thought as well.
>>
>> Anyway, let me cook a new version of the series - trying to address
>> the first bits you have pointed out. Then we can continue with
>> fine-tuning on top, addressing further optimizations of the ACPI PM
>> domain.
>
> Actually, please hold on and let me show you what I would like to do
> first.

Hmm.

I think I have almost done the work for the ACPI PM domain already.
It's just a matter of minor tweaks to the changes in patch 6 and 7
(and of course to get them into a shape that you prefer) and then
dropping patch 5 altogether.

Wouldn't it be better if you build upon my changes?

Anyway, if you have strong opinion of driving this, I am fine stepping aside.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-28 12:54                           ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-28 12:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
>> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
>> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
>> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
>> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
>> >> >
>> >> > [cut]
>> >> >
>> >> > > [BTW, it is not entirely clear to me why it ever is necessary to runtime resume
>> >> > > a device with direct_complete set after __device_suspend(), because it can only
>> >> > > have direct_complete set at that point if all of the hierarchy below it has
>> >> > > this flag set too and so runtime PM has to be disabled for all of those
>> >> > > devices as well.]
>> >> >
>> >> > Which makes me realize that we should take a step back and look at what
>> >> > problems there are.
>> >> >
>> >> > First, there are devices (I know about two examples so far and both are PCI)
>> >> > that may need to be runtime resumed during system suspend for reasons other
>> >> > than the ones checked by the ACPI PM domain (or the PCI bus type).  There needs
>> >> > to be a way to indicate that from the driver side.
>> >> >
>> >> > However, it still may be valuable to check the power-related conditions for
>> >> > leaving the device in runtime suspend over system suspend/resume in case
>> >> > it actually doesn't need to be runtime resumed during system suspend after
>> >> > all.  That's what the majority of my patch was about.
>> >> >
>> >> > The second problem is that the ACPI PM domain (and the PCI bus type)
>> >> > runtime resumes all devices unconditionally in its ->suspend callback,
>> >> > even though that may not be necessary for some devices.  Therefore there
>> >> > needs to be a way to indicate that too.  That still would be good to
>> >> > have *regardless* of the direct_complete mechanism, because the direct_complete
>> >> > flag may not be set very often due to dependencies and then the
>> >> > resume-during-suspend will take place unnecessarily.
>> >> >
>> >> > Accordingly, it looks like we need a "no need to resume me" flag in the first
>> >> > place.  That would indicate to interested pieces of code that, from the
>> >> > driver perspective, the device doesn't need to be runtime resumed before
>> >> > invoking its system suspend callbacks.  This should be clear enough to everyone
>> >> > IMO.
>> >> >
>> >> > [Note that if that flag is set for all devices, we may drop it along with
>> >> > direct_complete, but before that happens both are needed.]
>> >>
>> >> I think we are in agreement that direct_complete will not be necessary any
>> >> more when all drivers/bus types/PM domains and so on can do the "safe
>> >> suspend", but we're not there yet. :-)
>> >>
>> >> > To address the first issue I would add something like the flag in the patches
>> >> > I sent (but without the ACPI PM domain part which should be covered by the
>> >> > "no need to resume me" flag above), because that allows the device's ->suspend
>> >> > callback to run in principle and the driver may use that callback even to
>> >> > runtime resume the device if that's what it wants to do.  So something like
>> >> > "run my ->suspend callback even though I might stay in runtime suspend".
>> >> >
>> >> > I would probably add driver_flags to dev_pm_info for that to set at the probe
>> >> > time (and I would make the core clear that on driver removal).
>> >> >
>> >> > The complexity concern is there, but honestly I don't see a better way at
>> >> > this point.
>> >>
>> >> So below is a prototype patch.  It still is missing a documentation update, but
>> >> other than that it should be complete unless I missed something.
>> >>
>> >> The way it works is that the SAFE_SUSPEND flag is not looked at by the core
>> >> at all.  The ACPI PM domain looks at it and the PCI bus type can be modified
>> >> to take it into account in the future.  That is what causes the "runtime resume
>> >> during system suspend" to be skipped.
>> >>
>> >> In turn, the ALWAYS_SUSPEND flag is only looked at by the core and it causes
>> >> the decision on whether or not to use direct_complete to be deferred to the
>> >> __device_suspend_late() time.  If you set it for a PCI device, the effect is
>> >> equivalent to "no direct_complete".  If you set it for a device in the ACPI
>> >> PM domain, that depends on whether or not SAFE_SUSPEND is set.  If it isn't
>> >> set, the effect is equivalent to "no direct_complete" too, but if it is set,
>> >> the core may still try to use direct_complete for the device, but it will
>> >> make the decision on it in __device_suspend_late() and then it will not invoke
>> >> the ->suspend_late callback for the device if it is still runtime suspended.
>> >> [Note that you cannot runtime resume and runtime suspend again a device during
>> >> system suspend, so if it is runtime suspended in __device_suspend_late(), it
>> >> has been runtime suspend all the way since device_prepare().]
>> >>
>> >> So say you point the ->suspend_late and ->resume_early callbacks of
>> >> the designware i2c driver to pm_runtime_force_suspend() and
>> >> pm_runtime_force_resume(), respectively, and set both the SAFE_SUSPEND
>> >> and ALWAYS_SUSPEND flags for the device.
>> >>
>> >> If system suspend is started and the device is not runtime suspended,
>> >> direct_complete is not set for it and everything works as usual, so say
>> >> the device is runtime suspended in device_prepare().  Then, the ACPI PM
>> >> domain checks the other conditions for leaving it in runtime suspend and
>> >> returns either 0 or a positive number from acpi_subsys_prepare().
>> >>
>> >> If 0 is returned, direct_complete is not set by the core and
>> >> acpi_subsys_suspend() is called.  It checks the SAFE_SUSPEND flag and sees
>> >> that the device need not be runtime resumed, so it invokes the driver's
>> >> ->suspend callback (which is not present, so it doesn't do anything).
>> >> Next, in __device_suspend_late(), acpi_subsys_suspend_late() is invoked
>> >> and it calls pm_runtime_force_suspend(), which executes the driver's
>> >> ->runtime_suspend() callback, and then (if successful) calls
>> >> acpi_dev_suspend_late() to put the device into a low-power state.  The
>> >> resume path is a reverse of the above in this case.  So far, so good.
>> >
>> > Well, not really, because if the device remains runtime suspended,
>> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
>> > acpi_dev_suspend_late() should not be called then.
>> >
>> > So more changes in the ACPI PM domain are needed after all.
>>
>> Yes, that's what I thought as well.
>>
>> Anyway, let me cook a new version of the series - trying to address
>> the first bits you have pointed out. Then we can continue with
>> fine-tuning on top, addressing further optimizations of the ACPI PM
>> domain.
>
> Actually, please hold on and let me show you what I would like to do
> first.

Hmm.

I think I have almost done the work for the ACPI PM domain already.
It's just a matter of minor tweaks to the changes in patch 6 and 7
(and of course to get them into a shape that you prefer) and then
dropping patch 5 altogether.

Wouldn't it be better if you build upon my changes?

Anyway, if you have strong opinion of driving this, I am fine stepping aside.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-28 12:54                           ` Ulf Hansson
@ 2017-08-28 13:40                             ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28 13:40 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Monday, August 28, 2017 2:54:40 PM CEST Ulf Hansson wrote:
> On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
> >> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> >> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> >> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> >> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> >> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:

[cut]

> >> >
> >> > Well, not really, because if the device remains runtime suspended,
> >> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> >> > acpi_dev_suspend_late() should not be called then.
> >> >
> >> > So more changes in the ACPI PM domain are needed after all.
> >>
> >> Yes, that's what I thought as well.
> >>
> >> Anyway, let me cook a new version of the series - trying to address
> >> the first bits you have pointed out. Then we can continue with
> >> fine-tuning on top, addressing further optimizations of the ACPI PM
> >> domain.
> >
> > Actually, please hold on and let me show you what I would like to do
> > first.
> 
> Hmm.
> 
> I think I have almost done the work for the ACPI PM domain already.
> It's just a matter of minor tweaks to the changes in patch 6 and 7
> (and of course to get them into a shape that you prefer) and then
> dropping patch 5 altogether.
> 
> Wouldn't it be better if you build upon my changes?
> 
> Anyway, if you have strong opinion of driving this, I am fine stepping aside.

OK, so see below. :-)

If what you want is to make the i2c designware driver use _force_suspend() and
_force_resume(), then to me this is only tangentially related to direct_complete
and can be done without messing up with that one.

So the problem is not when direct_complete is set (becasue the driver's and
PM domain's callbacks will not be invoked then even), but when it is not set.
If direct_complete is not set, the ACPI PM domain resumes the device in
acpi_subsys_suspend(), because it doesn't know two things: (a) why direct_complete
is not set and (b) whether or not the drivers PM callbacks can cope with a
runtime suspended device.  These two things are separate, so they need to
be addressed separately.

For (b) I'd like to use the SAFE_SUSPEND flag from my previous patch.

As far as (a) is concerned, there are two possible reasons for not setting
direct_complete.  First, it may be necessary to change the power state of the
device and in that case the device *should* be resumed in acpi_subsys_suspend().
Second, direct_complete may not be set for the device's children and in that
case acpi_subsys_suspend() may not care as long as SAFE_SUSPEND is set.

So the ACPI PM domain needs to distinguish these two cases and for that reason
it has to track whether or not the power state of the device needs to be updated
which is what the (untested) patch below does, but of course it doesn't
cover the LPSS.

---
 Documentation/driver-api/pm/devices.rst     |    7 ++
 drivers/acpi/device_pm.c                    |   72 +++++++++++++++++++++-------
 drivers/base/dd.c                           |    2 
 drivers/i2c/busses/i2c-designware-platdrv.c |    4 +
 include/acpi/acpi_bus.h                     |    1 
 include/linux/pm.h                          |   16 ++++++
 6 files changed, 83 insertions(+), 19 deletions(-)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -550,6 +550,21 @@ struct pm_subsys_data {
 #endif
 };
 
+/*
+ * Driver flags to control system suspend/resume behavior.
+ *
+ * These flags can be set by device drivers at the probe time.  They need not be
+ * cleared by the drivers as the driver core will take care of that.
+ *
+ * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
+ *
+ * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
+ * runtime resume the device upfront during system suspend that doing so is not
+ * necessary from the driver's perspective, because the system suspend callbacks
+ * provided by it can cope with a runtime suspended device.
+ */
+#define DPM_FLAG_SAFE_SUSPEND	BIT(0)
+
 struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
@@ -561,6 +576,7 @@ struct dev_pm_info {
 	bool			is_late_suspended:1;
 	bool			early_init:1;	/* Owned by the PM core */
 	bool			direct_complete:1;	/* Owned by the PM core */
+	unsigned int		driver_flags;
 	spinlock_t		lock;
 #ifdef CONFIG_PM_SLEEP
 	struct list_head	entry;
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -899,6 +899,7 @@ int acpi_dev_runtime_resume(struct devic
 
 	error = acpi_dev_pm_full_power(adev);
 	acpi_device_wakeup_disable(adev);
+	adev->power.update_state = true;
 	return error;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
@@ -989,33 +990,47 @@ int acpi_dev_resume_early(struct device
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 
-/**
- * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
- * @dev: Device to prepare.
- */
-int acpi_subsys_prepare(struct device *dev)
+static bool acpi_dev_state_update_needed(struct device *dev)
 {
 	struct acpi_device *adev = ACPI_COMPANION(dev);
 	u32 sys_target;
 	int ret, state;
 
-	ret = pm_generic_prepare(dev);
-	if (ret < 0)
-		return ret;
+	if (!adev || !pm_runtime_suspended(dev))
+		return true;
 
-	if (!adev || !pm_runtime_suspended(dev)
-	    || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
-		return 0;
+	if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
+		return true;
 
 	sys_target = acpi_target_system_state();
 	if (sys_target == ACPI_STATE_S0)
-		return 1;
+		return false;
 
 	if (adev->power.flags.dsw_present)
-		return 0;
+		return true;
 
 	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
-	return !ret && state == adev->power.state;
+	if (ret)
+		return true;
+
+	return state != adev->power.state;
+}
+
+/**
+ * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
+ * @dev: Device to prepare.
+ */
+int acpi_subsys_prepare(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	ret = pm_generic_prepare(dev);
+	if (ret < 0)
+		return ret;
+
+	adev->power.update_state = acpi_dev_state_update_needed(dev);
+	return !adev->power.update_state;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
@@ -1024,11 +1039,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
+ * set for them.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return 0;
+
+	if (adev->power.update_state ||
+	    !(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND))
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
@@ -1042,8 +1066,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
  */
 int acpi_subsys_suspend_late(struct device *dev)
 {
-	int ret = pm_generic_suspend_late(dev);
-	return ret ? ret : acpi_dev_suspend_late(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	if (!adev)
+		return 0;
+
+	ret = pm_generic_suspend_late(dev);
+	if (ret)
+		return ret;
+
+	if (adev->power.update_state)
+		return acpi_dev_suspend_late(dev);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
 
Index: linux-pm/drivers/base/dd.c
===================================================================
--- linux-pm.orig/drivers/base/dd.c
+++ linux-pm/drivers/base/dd.c
@@ -436,6 +436,7 @@ pinctrl_bind_failed:
 	if (dev->pm_domain && dev->pm_domain->dismiss)
 		dev->pm_domain->dismiss(dev);
 	pm_runtime_reinit(dev);
+	dev->power.driver_flags = 0;
 
 	switch (ret) {
 	case -EPROBE_DEFER:
@@ -841,6 +842,7 @@ static void __device_release_driver(stru
 		if (dev->pm_domain && dev->pm_domain->dismiss)
 			dev->pm_domain->dismiss(dev);
 		pm_runtime_reinit(dev);
+		dev->power.driver_flags = 0;
 
 		klist_remove(&dev->p->knode_driver);
 		device_pm_check_callbacks(dev);
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
@@ -729,6 +729,13 @@ state temporarily, for example so that i
 disabled.  This all depends on the hardware and the design of the subsystem and
 device driver in question.
 
+Some bus types and PM domains have a policy to runtime resume all
+devices upfront in their ``->suspend`` callbacks, but that may not be really
+necessary if the system suspend-resume callbacks provided by the device's
+driver can cope with a runtime-suspended device.  The driver can indicate that
+by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
+probe time.
+
 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
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -287,6 +287,7 @@ struct acpi_device_power {
 	int state;		/* Current state */
 	struct acpi_device_power_flags flags;
 	struct acpi_device_power_state states[ACPI_D_STATE_COUNT];	/* Power states (D0-D3Cold) */
+	bool update_state;
 };
 
 /* Performance Management */
Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
===================================================================
--- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
+++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
 	if (dev->pm_disabled) {
 		pm_runtime_forbid(&pdev->dev);
 	} else {
+		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
 		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
 		pm_runtime_use_autosuspend(&pdev->dev);
 		pm_runtime_set_active(&pdev->dev);
@@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
 	.prepare = dw_i2c_plat_prepare,
 	.complete = dw_i2c_plat_complete,
-	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
 };
 


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-28 13:40                             ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28 13:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, August 28, 2017 2:54:40 PM CEST Ulf Hansson wrote:
> On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
> >> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> >> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> >> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> >> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> >> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:

[cut]

> >> >
> >> > Well, not really, because if the device remains runtime suspended,
> >> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> >> > acpi_dev_suspend_late() should not be called then.
> >> >
> >> > So more changes in the ACPI PM domain are needed after all.
> >>
> >> Yes, that's what I thought as well.
> >>
> >> Anyway, let me cook a new version of the series - trying to address
> >> the first bits you have pointed out. Then we can continue with
> >> fine-tuning on top, addressing further optimizations of the ACPI PM
> >> domain.
> >
> > Actually, please hold on and let me show you what I would like to do
> > first.
> 
> Hmm.
> 
> I think I have almost done the work for the ACPI PM domain already.
> It's just a matter of minor tweaks to the changes in patch 6 and 7
> (and of course to get them into a shape that you prefer) and then
> dropping patch 5 altogether.
> 
> Wouldn't it be better if you build upon my changes?
> 
> Anyway, if you have strong opinion of driving this, I am fine stepping aside.

OK, so see below. :-)

If what you want is to make the i2c designware driver use _force_suspend() and
_force_resume(), then to me this is only tangentially related to direct_complete
and can be done without messing up with that one.

So the problem is not when direct_complete is set (becasue the driver's and
PM domain's callbacks will not be invoked then even), but when it is not set.
If direct_complete is not set, the ACPI PM domain resumes the device in
acpi_subsys_suspend(), because it doesn't know two things: (a) why direct_complete
is not set and (b) whether or not the drivers PM callbacks can cope with a
runtime suspended device.  These two things are separate, so they need to
be addressed separately.

For (b) I'd like to use the SAFE_SUSPEND flag from my previous patch.

As far as (a) is concerned, there are two possible reasons for not setting
direct_complete.  First, it may be necessary to change the power state of the
device and in that case the device *should* be resumed in acpi_subsys_suspend().
Second, direct_complete may not be set for the device's children and in that
case acpi_subsys_suspend() may not care as long as SAFE_SUSPEND is set.

So the ACPI PM domain needs to distinguish these two cases and for that reason
it has to track whether or not the power state of the device needs to be updated
which is what the (untested) patch below does, but of course it doesn't
cover the LPSS.

---
 Documentation/driver-api/pm/devices.rst     |    7 ++
 drivers/acpi/device_pm.c                    |   72 +++++++++++++++++++++-------
 drivers/base/dd.c                           |    2 
 drivers/i2c/busses/i2c-designware-platdrv.c |    4 +
 include/acpi/acpi_bus.h                     |    1 
 include/linux/pm.h                          |   16 ++++++
 6 files changed, 83 insertions(+), 19 deletions(-)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -550,6 +550,21 @@ struct pm_subsys_data {
 #endif
 };
 
+/*
+ * Driver flags to control system suspend/resume behavior.
+ *
+ * These flags can be set by device drivers at the probe time.  They need not be
+ * cleared by the drivers as the driver core will take care of that.
+ *
+ * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
+ *
+ * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
+ * runtime resume the device upfront during system suspend that doing so is not
+ * necessary from the driver's perspective, because the system suspend callbacks
+ * provided by it can cope with a runtime suspended device.
+ */
+#define DPM_FLAG_SAFE_SUSPEND	BIT(0)
+
 struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
@@ -561,6 +576,7 @@ struct dev_pm_info {
 	bool			is_late_suspended:1;
 	bool			early_init:1;	/* Owned by the PM core */
 	bool			direct_complete:1;	/* Owned by the PM core */
+	unsigned int		driver_flags;
 	spinlock_t		lock;
 #ifdef CONFIG_PM_SLEEP
 	struct list_head	entry;
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -899,6 +899,7 @@ int acpi_dev_runtime_resume(struct devic
 
 	error = acpi_dev_pm_full_power(adev);
 	acpi_device_wakeup_disable(adev);
+	adev->power.update_state = true;
 	return error;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
@@ -989,33 +990,47 @@ int acpi_dev_resume_early(struct device
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 
-/**
- * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
- * @dev: Device to prepare.
- */
-int acpi_subsys_prepare(struct device *dev)
+static bool acpi_dev_state_update_needed(struct device *dev)
 {
 	struct acpi_device *adev = ACPI_COMPANION(dev);
 	u32 sys_target;
 	int ret, state;
 
-	ret = pm_generic_prepare(dev);
-	if (ret < 0)
-		return ret;
+	if (!adev || !pm_runtime_suspended(dev))
+		return true;
 
-	if (!adev || !pm_runtime_suspended(dev)
-	    || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
-		return 0;
+	if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
+		return true;
 
 	sys_target = acpi_target_system_state();
 	if (sys_target == ACPI_STATE_S0)
-		return 1;
+		return false;
 
 	if (adev->power.flags.dsw_present)
-		return 0;
+		return true;
 
 	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
-	return !ret && state == adev->power.state;
+	if (ret)
+		return true;
+
+	return state != adev->power.state;
+}
+
+/**
+ * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
+ * @dev: Device to prepare.
+ */
+int acpi_subsys_prepare(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	ret = pm_generic_prepare(dev);
+	if (ret < 0)
+		return ret;
+
+	adev->power.update_state = acpi_dev_state_update_needed(dev);
+	return !adev->power.update_state;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
@@ -1024,11 +1039,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
+ * set for them.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (!adev)
+		return 0;
+
+	if (adev->power.update_state ||
+	    !(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND))
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
@@ -1042,8 +1066,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
  */
 int acpi_subsys_suspend_late(struct device *dev)
 {
-	int ret = pm_generic_suspend_late(dev);
-	return ret ? ret : acpi_dev_suspend_late(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	if (!adev)
+		return 0;
+
+	ret = pm_generic_suspend_late(dev);
+	if (ret)
+		return ret;
+
+	if (adev->power.update_state)
+		return acpi_dev_suspend_late(dev);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
 
Index: linux-pm/drivers/base/dd.c
===================================================================
--- linux-pm.orig/drivers/base/dd.c
+++ linux-pm/drivers/base/dd.c
@@ -436,6 +436,7 @@ pinctrl_bind_failed:
 	if (dev->pm_domain && dev->pm_domain->dismiss)
 		dev->pm_domain->dismiss(dev);
 	pm_runtime_reinit(dev);
+	dev->power.driver_flags = 0;
 
 	switch (ret) {
 	case -EPROBE_DEFER:
@@ -841,6 +842,7 @@ static void __device_release_driver(stru
 		if (dev->pm_domain && dev->pm_domain->dismiss)
 			dev->pm_domain->dismiss(dev);
 		pm_runtime_reinit(dev);
+		dev->power.driver_flags = 0;
 
 		klist_remove(&dev->p->knode_driver);
 		device_pm_check_callbacks(dev);
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
@@ -729,6 +729,13 @@ state temporarily, for example so that i
 disabled.  This all depends on the hardware and the design of the subsystem and
 device driver in question.
 
+Some bus types and PM domains have a policy to runtime resume all
+devices upfront in their ``->suspend`` callbacks, but that may not be really
+necessary if the system suspend-resume callbacks provided by the device's
+driver can cope with a runtime-suspended device.  The driver can indicate that
+by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
+probe time.
+
 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
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -287,6 +287,7 @@ struct acpi_device_power {
 	int state;		/* Current state */
 	struct acpi_device_power_flags flags;
 	struct acpi_device_power_state states[ACPI_D_STATE_COUNT];	/* Power states (D0-D3Cold) */
+	bool update_state;
 };
 
 /* Performance Management */
Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
===================================================================
--- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
+++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
 	if (dev->pm_disabled) {
 		pm_runtime_forbid(&pdev->dev);
 	} else {
+		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
 		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
 		pm_runtime_use_autosuspend(&pdev->dev);
 		pm_runtime_set_active(&pdev->dev);
@@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
 	.prepare = dw_i2c_plat_prepare,
 	.complete = dw_i2c_plat_complete,
-	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
 };
 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-28 13:40                             ` Rafael J. Wysocki
@ 2017-08-28 14:24                               ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-28 14:24 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On 28 August 2017 at 15:40, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Monday, August 28, 2017 2:54:40 PM CEST Ulf Hansson wrote:
>> On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> > On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
>> >> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> >> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
>> >> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
>> >> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
>> >> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
>
> [cut]
>
>> >> >
>> >> > Well, not really, because if the device remains runtime suspended,
>> >> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
>> >> > acpi_dev_suspend_late() should not be called then.
>> >> >
>> >> > So more changes in the ACPI PM domain are needed after all.
>> >>
>> >> Yes, that's what I thought as well.
>> >>
>> >> Anyway, let me cook a new version of the series - trying to address
>> >> the first bits you have pointed out. Then we can continue with
>> >> fine-tuning on top, addressing further optimizations of the ACPI PM
>> >> domain.
>> >
>> > Actually, please hold on and let me show you what I would like to do
>> > first.
>>
>> Hmm.
>>
>> I think I have almost done the work for the ACPI PM domain already.
>> It's just a matter of minor tweaks to the changes in patch 6 and 7
>> (and of course to get them into a shape that you prefer) and then
>> dropping patch 5 altogether.
>>
>> Wouldn't it be better if you build upon my changes?
>>
>> Anyway, if you have strong opinion of driving this, I am fine stepping aside.
>
> OK, so see below. :-)
>
> If what you want is to make the i2c designware driver use _force_suspend() and
> _force_resume(), then to me this is only tangentially related to direct_complete
> and can be done without messing up with that one.
>
> So the problem is not when direct_complete is set (becasue the driver's and
> PM domain's callbacks will not be invoked then even), but when it is not set.

For i2c designware driver case - then you are right! Although, that's
because the i2c designware driver has nothing else to do than to call
pm_runtime_force_suspend|resume() from the late suspend and early
resume callbacks.

However, for other drivers this isn't the case. A driver may have some
additional things to cope with during system sleep, besides making
sure to call pm_runtime_force_suspend|resume().

Then as I stated earlier, it would be of great value if we could
remain having runtime PM enabled during the entire device_suspend()
phase. I am not sure how you intend to address that, or perhaps you
did in some of those earlier patches you posted.

In my re-spinned series (not posted yet), I am still addressing both
issues above, but also not preventing the direct_complete path for
parent/suppliers when the runtime PM centric path is used.

> If direct_complete is not set, the ACPI PM domain resumes the device in
> acpi_subsys_suspend(), because it doesn't know two things: (a) why direct_complete
> is not set and (b) whether or not the drivers PM callbacks can cope with a
> runtime suspended device.  These two things are separate, so they need to
> be addressed separately.

Yes.

>
> For (b) I'd like to use the SAFE_SUSPEND flag from my previous patch.

Seems like a reasonable approach.

>
> As far as (a) is concerned, there are two possible reasons for not setting
> direct_complete.  First, it may be necessary to change the power state of the
> device and in that case the device *should* be resumed in acpi_subsys_suspend().
> Second, direct_complete may not be set for the device's children and in that
> case acpi_subsys_suspend() may not care as long as SAFE_SUSPEND is set.

Okay!

>
> So the ACPI PM domain needs to distinguish these two cases and for that reason
> it has to track whether or not the power state of the device needs to be updated
> which is what the (untested) patch below does, but of course it doesn't
> cover the LPSS.
>
> ---
>  Documentation/driver-api/pm/devices.rst     |    7 ++
>  drivers/acpi/device_pm.c                    |   72 +++++++++++++++++++++-------
>  drivers/base/dd.c                           |    2
>  drivers/i2c/busses/i2c-designware-platdrv.c |    4 +
>  include/acpi/acpi_bus.h                     |    1
>  include/linux/pm.h                          |   16 ++++++
>  6 files changed, 83 insertions(+), 19 deletions(-)
>
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -550,6 +550,21 @@ struct pm_subsys_data {
>  #endif
>  };
>
> +/*
> + * Driver flags to control system suspend/resume behavior.
> + *
> + * These flags can be set by device drivers at the probe time.  They need not be
> + * cleared by the drivers as the driver core will take care of that.
> + *
> + * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
> + *
> + * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
> + * runtime resume the device upfront during system suspend that doing so is not
> + * necessary from the driver's perspective, because the system suspend callbacks
> + * provided by it can cope with a runtime suspended device.
> + */
> +#define DPM_FLAG_SAFE_SUSPEND  BIT(0)
> +
>  struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
> @@ -561,6 +576,7 @@ struct dev_pm_info {
>         bool                    is_late_suspended:1;
>         bool                    early_init:1;   /* Owned by the PM core */
>         bool                    direct_complete:1;      /* Owned by the PM core */
> +       unsigned int            driver_flags;
>         spinlock_t              lock;
>  #ifdef CONFIG_PM_SLEEP
>         struct list_head        entry;
> Index: linux-pm/drivers/acpi/device_pm.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/device_pm.c
> +++ linux-pm/drivers/acpi/device_pm.c
> @@ -899,6 +899,7 @@ int acpi_dev_runtime_resume(struct devic
>
>         error = acpi_dev_pm_full_power(adev);
>         acpi_device_wakeup_disable(adev);
> +       adev->power.update_state = true;
>         return error;
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
> @@ -989,33 +990,47 @@ int acpi_dev_resume_early(struct device
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
>
> -/**
> - * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
> - * @dev: Device to prepare.
> - */
> -int acpi_subsys_prepare(struct device *dev)
> +static bool acpi_dev_state_update_needed(struct device *dev)
>  {
>         struct acpi_device *adev = ACPI_COMPANION(dev);
>         u32 sys_target;
>         int ret, state;
>
> -       ret = pm_generic_prepare(dev);
> -       if (ret < 0)
> -               return ret;
> +       if (!adev || !pm_runtime_suspended(dev))
> +               return true;
>
> -       if (!adev || !pm_runtime_suspended(dev)
> -           || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
> -               return 0;
> +       if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
> +               return true;
>
>         sys_target = acpi_target_system_state();
>         if (sys_target == ACPI_STATE_S0)
> -               return 1;
> +               return false;
>
>         if (adev->power.flags.dsw_present)
> -               return 0;
> +               return true;
>
>         ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
> -       return !ret && state == adev->power.state;
> +       if (ret)
> +               return true;
> +
> +       return state != adev->power.state;
> +}
> +
> +/**
> + * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
> + * @dev: Device to prepare.
> + */
> +int acpi_subsys_prepare(struct device *dev)
> +{
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
> +       int ret;
> +
> +       ret = pm_generic_prepare(dev);
> +       if (ret < 0)
> +               return ret;
> +
> +       adev->power.update_state = acpi_dev_state_update_needed(dev);
> +       return !adev->power.update_state;
>  }
>  EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>
> @@ -1024,11 +1039,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>   * @dev: Device to handle.
>   *
>   * Follow PCI and resume devices suspended at run time before running their
> - * system suspend callbacks.
> + * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
> + * set for them.
>   */
>  int acpi_subsys_suspend(struct device *dev)
>  {
> -       pm_runtime_resume(dev);
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
> +
> +       if (!adev)
> +               return 0;
> +
> +       if (adev->power.update_state ||
> +           !(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND))
> +               pm_runtime_resume(dev);
> +
>         return pm_generic_suspend(dev);
>  }
>  EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
> @@ -1042,8 +1066,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
>   */
>  int acpi_subsys_suspend_late(struct device *dev)
>  {
> -       int ret = pm_generic_suspend_late(dev);
> -       return ret ? ret : acpi_dev_suspend_late(dev);
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
> +       int ret;
> +
> +       if (!adev)
> +               return 0;
> +
> +       ret = pm_generic_suspend_late(dev);
> +       if (ret)
> +               return ret;
> +
> +       if (adev->power.update_state)
> +               return acpi_dev_suspend_late(dev);
> +
> +       return 0;
>  }
>  EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
>
> Index: linux-pm/drivers/base/dd.c
> ===================================================================
> --- linux-pm.orig/drivers/base/dd.c
> +++ linux-pm/drivers/base/dd.c
> @@ -436,6 +436,7 @@ pinctrl_bind_failed:
>         if (dev->pm_domain && dev->pm_domain->dismiss)
>                 dev->pm_domain->dismiss(dev);
>         pm_runtime_reinit(dev);
> +       dev->power.driver_flags = 0;
>
>         switch (ret) {
>         case -EPROBE_DEFER:
> @@ -841,6 +842,7 @@ static void __device_release_driver(stru
>                 if (dev->pm_domain && dev->pm_domain->dismiss)
>                         dev->pm_domain->dismiss(dev);
>                 pm_runtime_reinit(dev);
> +               dev->power.driver_flags = 0;
>
>                 klist_remove(&dev->p->knode_driver);
>                 device_pm_check_callbacks(dev);
> 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
> @@ -729,6 +729,13 @@ state temporarily, for example so that i
>  disabled.  This all depends on the hardware and the design of the subsystem and
>  device driver in question.
>
> +Some bus types and PM domains have a policy to runtime resume all
> +devices upfront in their ``->suspend`` callbacks, but that may not be really
> +necessary if the system suspend-resume callbacks provided by the device's
> +driver can cope with a runtime-suspended device.  The driver can indicate that
> +by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
> +probe time.
> +
>  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
> Index: linux-pm/include/acpi/acpi_bus.h
> ===================================================================
> --- linux-pm.orig/include/acpi/acpi_bus.h
> +++ linux-pm/include/acpi/acpi_bus.h
> @@ -287,6 +287,7 @@ struct acpi_device_power {
>         int state;              /* Current state */
>         struct acpi_device_power_flags flags;
>         struct acpi_device_power_state states[ACPI_D_STATE_COUNT];      /* Power states (D0-D3Cold) */
> +       bool update_state;
>  };
>
>  /* Performance Management */
> Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> ===================================================================
> --- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
>         if (dev->pm_disabled) {
>                 pm_runtime_forbid(&pdev->dev);
>         } else {
> +               dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
>                 pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
>                 pm_runtime_use_autosuspend(&pdev->dev);
>                 pm_runtime_set_active(&pdev->dev);
> @@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
>  static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
>         .prepare = dw_i2c_plat_prepare,
>         .complete = dw_i2c_plat_complete,
> -       SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
> +       SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +                                    pm_runtime_force_resume)
>         SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
>  };
>
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-28 14:24                               ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-28 14:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 28 August 2017 at 15:40, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Monday, August 28, 2017 2:54:40 PM CEST Ulf Hansson wrote:
>> On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> > On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
>> >> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
>> >> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
>> >> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
>> >> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
>> >> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
>
> [cut]
>
>> >> >
>> >> > Well, not really, because if the device remains runtime suspended,
>> >> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
>> >> > acpi_dev_suspend_late() should not be called then.
>> >> >
>> >> > So more changes in the ACPI PM domain are needed after all.
>> >>
>> >> Yes, that's what I thought as well.
>> >>
>> >> Anyway, let me cook a new version of the series - trying to address
>> >> the first bits you have pointed out. Then we can continue with
>> >> fine-tuning on top, addressing further optimizations of the ACPI PM
>> >> domain.
>> >
>> > Actually, please hold on and let me show you what I would like to do
>> > first.
>>
>> Hmm.
>>
>> I think I have almost done the work for the ACPI PM domain already.
>> It's just a matter of minor tweaks to the changes in patch 6 and 7
>> (and of course to get them into a shape that you prefer) and then
>> dropping patch 5 altogether.
>>
>> Wouldn't it be better if you build upon my changes?
>>
>> Anyway, if you have strong opinion of driving this, I am fine stepping aside.
>
> OK, so see below. :-)
>
> If what you want is to make the i2c designware driver use _force_suspend() and
> _force_resume(), then to me this is only tangentially related to direct_complete
> and can be done without messing up with that one.
>
> So the problem is not when direct_complete is set (becasue the driver's and
> PM domain's callbacks will not be invoked then even), but when it is not set.

For i2c designware driver case - then you are right! Although, that's
because the i2c designware driver has nothing else to do than to call
pm_runtime_force_suspend|resume() from the late suspend and early
resume callbacks.

However, for other drivers this isn't the case. A driver may have some
additional things to cope with during system sleep, besides making
sure to call pm_runtime_force_suspend|resume().

Then as I stated earlier, it would be of great value if we could
remain having runtime PM enabled during the entire device_suspend()
phase. I am not sure how you intend to address that, or perhaps you
did in some of those earlier patches you posted.

In my re-spinned series (not posted yet), I am still addressing both
issues above, but also not preventing the direct_complete path for
parent/suppliers when the runtime PM centric path is used.

> If direct_complete is not set, the ACPI PM domain resumes the device in
> acpi_subsys_suspend(), because it doesn't know two things: (a) why direct_complete
> is not set and (b) whether or not the drivers PM callbacks can cope with a
> runtime suspended device.  These two things are separate, so they need to
> be addressed separately.

Yes.

>
> For (b) I'd like to use the SAFE_SUSPEND flag from my previous patch.

Seems like a reasonable approach.

>
> As far as (a) is concerned, there are two possible reasons for not setting
> direct_complete.  First, it may be necessary to change the power state of the
> device and in that case the device *should* be resumed in acpi_subsys_suspend().
> Second, direct_complete may not be set for the device's children and in that
> case acpi_subsys_suspend() may not care as long as SAFE_SUSPEND is set.

Okay!

>
> So the ACPI PM domain needs to distinguish these two cases and for that reason
> it has to track whether or not the power state of the device needs to be updated
> which is what the (untested) patch below does, but of course it doesn't
> cover the LPSS.
>
> ---
>  Documentation/driver-api/pm/devices.rst     |    7 ++
>  drivers/acpi/device_pm.c                    |   72 +++++++++++++++++++++-------
>  drivers/base/dd.c                           |    2
>  drivers/i2c/busses/i2c-designware-platdrv.c |    4 +
>  include/acpi/acpi_bus.h                     |    1
>  include/linux/pm.h                          |   16 ++++++
>  6 files changed, 83 insertions(+), 19 deletions(-)
>
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -550,6 +550,21 @@ struct pm_subsys_data {
>  #endif
>  };
>
> +/*
> + * Driver flags to control system suspend/resume behavior.
> + *
> + * These flags can be set by device drivers at the probe time.  They need not be
> + * cleared by the drivers as the driver core will take care of that.
> + *
> + * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
> + *
> + * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
> + * runtime resume the device upfront during system suspend that doing so is not
> + * necessary from the driver's perspective, because the system suspend callbacks
> + * provided by it can cope with a runtime suspended device.
> + */
> +#define DPM_FLAG_SAFE_SUSPEND  BIT(0)
> +
>  struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
> @@ -561,6 +576,7 @@ struct dev_pm_info {
>         bool                    is_late_suspended:1;
>         bool                    early_init:1;   /* Owned by the PM core */
>         bool                    direct_complete:1;      /* Owned by the PM core */
> +       unsigned int            driver_flags;
>         spinlock_t              lock;
>  #ifdef CONFIG_PM_SLEEP
>         struct list_head        entry;
> Index: linux-pm/drivers/acpi/device_pm.c
> ===================================================================
> --- linux-pm.orig/drivers/acpi/device_pm.c
> +++ linux-pm/drivers/acpi/device_pm.c
> @@ -899,6 +899,7 @@ int acpi_dev_runtime_resume(struct devic
>
>         error = acpi_dev_pm_full_power(adev);
>         acpi_device_wakeup_disable(adev);
> +       adev->power.update_state = true;
>         return error;
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
> @@ -989,33 +990,47 @@ int acpi_dev_resume_early(struct device
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
>
> -/**
> - * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
> - * @dev: Device to prepare.
> - */
> -int acpi_subsys_prepare(struct device *dev)
> +static bool acpi_dev_state_update_needed(struct device *dev)
>  {
>         struct acpi_device *adev = ACPI_COMPANION(dev);
>         u32 sys_target;
>         int ret, state;
>
> -       ret = pm_generic_prepare(dev);
> -       if (ret < 0)
> -               return ret;
> +       if (!adev || !pm_runtime_suspended(dev))
> +               return true;
>
> -       if (!adev || !pm_runtime_suspended(dev)
> -           || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
> -               return 0;
> +       if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
> +               return true;
>
>         sys_target = acpi_target_system_state();
>         if (sys_target == ACPI_STATE_S0)
> -               return 1;
> +               return false;
>
>         if (adev->power.flags.dsw_present)
> -               return 0;
> +               return true;
>
>         ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
> -       return !ret && state == adev->power.state;
> +       if (ret)
> +               return true;
> +
> +       return state != adev->power.state;
> +}
> +
> +/**
> + * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
> + * @dev: Device to prepare.
> + */
> +int acpi_subsys_prepare(struct device *dev)
> +{
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
> +       int ret;
> +
> +       ret = pm_generic_prepare(dev);
> +       if (ret < 0)
> +               return ret;
> +
> +       adev->power.update_state = acpi_dev_state_update_needed(dev);
> +       return !adev->power.update_state;
>  }
>  EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>
> @@ -1024,11 +1039,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
>   * @dev: Device to handle.
>   *
>   * Follow PCI and resume devices suspended at run time before running their
> - * system suspend callbacks.
> + * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
> + * set for them.
>   */
>  int acpi_subsys_suspend(struct device *dev)
>  {
> -       pm_runtime_resume(dev);
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
> +
> +       if (!adev)
> +               return 0;
> +
> +       if (adev->power.update_state ||
> +           !(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND))
> +               pm_runtime_resume(dev);
> +
>         return pm_generic_suspend(dev);
>  }
>  EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
> @@ -1042,8 +1066,20 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
>   */
>  int acpi_subsys_suspend_late(struct device *dev)
>  {
> -       int ret = pm_generic_suspend_late(dev);
> -       return ret ? ret : acpi_dev_suspend_late(dev);
> +       struct acpi_device *adev = ACPI_COMPANION(dev);
> +       int ret;
> +
> +       if (!adev)
> +               return 0;
> +
> +       ret = pm_generic_suspend_late(dev);
> +       if (ret)
> +               return ret;
> +
> +       if (adev->power.update_state)
> +               return acpi_dev_suspend_late(dev);
> +
> +       return 0;
>  }
>  EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
>
> Index: linux-pm/drivers/base/dd.c
> ===================================================================
> --- linux-pm.orig/drivers/base/dd.c
> +++ linux-pm/drivers/base/dd.c
> @@ -436,6 +436,7 @@ pinctrl_bind_failed:
>         if (dev->pm_domain && dev->pm_domain->dismiss)
>                 dev->pm_domain->dismiss(dev);
>         pm_runtime_reinit(dev);
> +       dev->power.driver_flags = 0;
>
>         switch (ret) {
>         case -EPROBE_DEFER:
> @@ -841,6 +842,7 @@ static void __device_release_driver(stru
>                 if (dev->pm_domain && dev->pm_domain->dismiss)
>                         dev->pm_domain->dismiss(dev);
>                 pm_runtime_reinit(dev);
> +               dev->power.driver_flags = 0;
>
>                 klist_remove(&dev->p->knode_driver);
>                 device_pm_check_callbacks(dev);
> 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
> @@ -729,6 +729,13 @@ state temporarily, for example so that i
>  disabled.  This all depends on the hardware and the design of the subsystem and
>  device driver in question.
>
> +Some bus types and PM domains have a policy to runtime resume all
> +devices upfront in their ``->suspend`` callbacks, but that may not be really
> +necessary if the system suspend-resume callbacks provided by the device's
> +driver can cope with a runtime-suspended device.  The driver can indicate that
> +by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
> +probe time.
> +
>  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
> Index: linux-pm/include/acpi/acpi_bus.h
> ===================================================================
> --- linux-pm.orig/include/acpi/acpi_bus.h
> +++ linux-pm/include/acpi/acpi_bus.h
> @@ -287,6 +287,7 @@ struct acpi_device_power {
>         int state;              /* Current state */
>         struct acpi_device_power_flags flags;
>         struct acpi_device_power_state states[ACPI_D_STATE_COUNT];      /* Power states (D0-D3Cold) */
> +       bool update_state;
>  };
>
>  /* Performance Management */
> Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> ===================================================================
> --- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
>         if (dev->pm_disabled) {
>                 pm_runtime_forbid(&pdev->dev);
>         } else {
> +               dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
>                 pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
>                 pm_runtime_use_autosuspend(&pdev->dev);
>                 pm_runtime_set_active(&pdev->dev);
> @@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
>  static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
>         .prepare = dw_i2c_plat_prepare,
>         .complete = dw_i2c_plat_complete,
> -       SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
> +       SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +                                    pm_runtime_force_resume)
>         SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
>  };
>
>

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
  2017-08-28 14:24                               ` Ulf Hansson
@ 2017-08-28 21:14                                 ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28 21:14 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, Linux PM, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c

On Monday, August 28, 2017 4:24:51 PM CEST Ulf Hansson wrote:
> On 28 August 2017 at 15:40, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Monday, August 28, 2017 2:54:40 PM CEST Ulf Hansson wrote:
> >> On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> >> > On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
> >> >> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> >> >> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> >> >> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> >> >> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> >> >> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> >
> > [cut]
> >
> >> >> >
> >> >> > Well, not really, because if the device remains runtime suspended,
> >> >> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> >> >> > acpi_dev_suspend_late() should not be called then.
> >> >> >
> >> >> > So more changes in the ACPI PM domain are needed after all.
> >> >>
> >> >> Yes, that's what I thought as well.
> >> >>
> >> >> Anyway, let me cook a new version of the series - trying to address
> >> >> the first bits you have pointed out. Then we can continue with
> >> >> fine-tuning on top, addressing further optimizations of the ACPI PM
> >> >> domain.
> >> >
> >> > Actually, please hold on and let me show you what I would like to do
> >> > first.
> >>
> >> Hmm.
> >>
> >> I think I have almost done the work for the ACPI PM domain already.
> >> It's just a matter of minor tweaks to the changes in patch 6 and 7
> >> (and of course to get them into a shape that you prefer) and then
> >> dropping patch 5 altogether.
> >>
> >> Wouldn't it be better if you build upon my changes?
> >>
> >> Anyway, if you have strong opinion of driving this, I am fine stepping aside.
> >
> > OK, so see below. :-)
> >
> > If what you want is to make the i2c designware driver use _force_suspend() and
> > _force_resume(), then to me this is only tangentially related to direct_complete
> > and can be done without messing up with that one.
> >
> > So the problem is not when direct_complete is set (becasue the driver's and
> > PM domain's callbacks will not be invoked then even), but when it is not set.
> 
> For i2c designware driver case - then you are right! Although, that's
> because the i2c designware driver has nothing else to do than to call
> pm_runtime_force_suspend|resume() from the late suspend and early
> resume callbacks.
> 
> However, for other drivers this isn't the case. A driver may have some
> additional things to cope with during system sleep, besides making
> sure to call pm_runtime_force_suspend|resume().

Sure enough, but I'm seeing that as a separate issue.

> Then as I stated earlier, it would be of great value if we could
> remain having runtime PM enabled during the entire device_suspend()
> phase. I am not sure how you intend to address that, or perhaps you
> did in some of those earlier patches you posted.

I did, but I'd prefer to get back to that later.

If the issues occurring when direct_complete is not set are addressed first,
disabling direct_complete for the devices that cannot use it should be
straightforward.

> In my re-spinned series (not posted yet), I am still addressing both
> issues above, but also not preventing the direct_complete path for
> parent/suppliers when the runtime PM centric path is used.
> 
> > If direct_complete is not set, the ACPI PM domain resumes the device in
> > acpi_subsys_suspend(), because it doesn't know two things: (a) why direct_complete
> > is not set and (b) whether or not the drivers PM callbacks can cope with a
> > runtime suspended device.  These two things are separate, so they need to
> > be addressed separately.
> 
> Yes.
> 
> >
> > For (b) I'd like to use the SAFE_SUSPEND flag from my previous patch.
> 
> Seems like a reasonable approach.
> 
> >
> > As far as (a) is concerned, there are two possible reasons for not setting
> > direct_complete.  First, it may be necessary to change the power state of the
> > device and in that case the device *should* be resumed in acpi_subsys_suspend().
> > Second, direct_complete may not be set for the device's children and in that
> > case acpi_subsys_suspend() may not care as long as SAFE_SUSPEND is set.
> 
> Okay!

Good. :-)

Let me split the patch into a more manageable series, then, clean it up a bit
and add the LPSS coverage to the ACPI part.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices
@ 2017-08-28 21:14                                 ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-28 21:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday, August 28, 2017 4:24:51 PM CEST Ulf Hansson wrote:
> On 28 August 2017 at 15:40, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Monday, August 28, 2017 2:54:40 PM CEST Ulf Hansson wrote:
> >> On 28 August 2017 at 14:39, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> >> > On Monday, August 28, 2017 10:31:44 AM CEST Ulf Hansson wrote:
> >> >> On 28 August 2017 at 03:30, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> >> >> > On Friday, August 25, 2017 3:42:35 PM CEST Rafael J. Wysocki wrote:
> >> >> >> On Thursday, August 24, 2017 11:50:40 PM CEST Rafael J. Wysocki wrote:
> >> >> >> > On Thursday, August 24, 2017 6:35:49 PM CEST Rafael J. Wysocki wrote:
> >> >> >> > > On Thursday, August 24, 2017 11:15:26 AM CEST Ulf Hansson wrote:
> >
> > [cut]
> >
> >> >> >
> >> >> > Well, not really, because if the device remains runtime suspended,
> >> >> > ->runtime_suspend() will not be called by pm_runtime_force_suspend() and
> >> >> > acpi_dev_suspend_late() should not be called then.
> >> >> >
> >> >> > So more changes in the ACPI PM domain are needed after all.
> >> >>
> >> >> Yes, that's what I thought as well.
> >> >>
> >> >> Anyway, let me cook a new version of the series - trying to address
> >> >> the first bits you have pointed out. Then we can continue with
> >> >> fine-tuning on top, addressing further optimizations of the ACPI PM
> >> >> domain.
> >> >
> >> > Actually, please hold on and let me show you what I would like to do
> >> > first.
> >>
> >> Hmm.
> >>
> >> I think I have almost done the work for the ACPI PM domain already.
> >> It's just a matter of minor tweaks to the changes in patch 6 and 7
> >> (and of course to get them into a shape that you prefer) and then
> >> dropping patch 5 altogether.
> >>
> >> Wouldn't it be better if you build upon my changes?
> >>
> >> Anyway, if you have strong opinion of driving this, I am fine stepping aside.
> >
> > OK, so see below. :-)
> >
> > If what you want is to make the i2c designware driver use _force_suspend() and
> > _force_resume(), then to me this is only tangentially related to direct_complete
> > and can be done without messing up with that one.
> >
> > So the problem is not when direct_complete is set (becasue the driver's and
> > PM domain's callbacks will not be invoked then even), but when it is not set.
> 
> For i2c designware driver case - then you are right! Although, that's
> because the i2c designware driver has nothing else to do than to call
> pm_runtime_force_suspend|resume() from the late suspend and early
> resume callbacks.
> 
> However, for other drivers this isn't the case. A driver may have some
> additional things to cope with during system sleep, besides making
> sure to call pm_runtime_force_suspend|resume().

Sure enough, but I'm seeing that as a separate issue.

> Then as I stated earlier, it would be of great value if we could
> remain having runtime PM enabled during the entire device_suspend()
> phase. I am not sure how you intend to address that, or perhaps you
> did in some of those earlier patches you posted.

I did, but I'd prefer to get back to that later.

If the issues occurring when direct_complete is not set are addressed first,
disabling direct_complete for the devices that cannot use it should be
straightforward.

> In my re-spinned series (not posted yet), I am still addressing both
> issues above, but also not preventing the direct_complete path for
> parent/suppliers when the runtime PM centric path is used.
> 
> > If direct_complete is not set, the ACPI PM domain resumes the device in
> > acpi_subsys_suspend(), because it doesn't know two things: (a) why direct_complete
> > is not set and (b) whether or not the drivers PM callbacks can cope with a
> > runtime suspended device.  These two things are separate, so they need to
> > be addressed separately.
> 
> Yes.
> 
> >
> > For (b) I'd like to use the SAFE_SUSPEND flag from my previous patch.
> 
> Seems like a reasonable approach.
> 
> >
> > As far as (a) is concerned, there are two possible reasons for not setting
> > direct_complete.  First, it may be necessary to change the power state of the
> > device and in that case the device *should* be resumed in acpi_subsys_suspend().
> > Second, direct_complete may not be set for the device's children and in that
> > case acpi_subsys_suspend() may not care as long as SAFE_SUSPEND is set.
> 
> Okay!

Good. :-)

Let me split the patch into a more manageable series, then, clean it up a bit
and add the LPSS coverage to the ACPI part.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-23 14:42 ` Ulf Hansson
@ 2017-08-29  0:18   ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:18 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Len Brown, linux-acpi, linux-pm, Kevin Hilman,
	Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jisheng Zhang,
	John Stultz, Guodong Xu, Sumit Semwal, Haojian Zhuang,
	linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> isn't well optimized for system sleep.
> 
> What makes this driver particularly interesting is because it's a cross-SoC
> driver, which sometimes means there is an ACPI PM domain attached to the i2c
> device and sometimes not. The driver is being used on both x86 and ARM.
> 
> In principle, to optimize the system sleep support in i2c driver, this series
> enables the proven runtime PM centric path for the i2c driver. However, to do
> that the ACPI PM domain also have to collaborate and understand this behaviour.
> Therefore a number of changes, patch 1 to patch 7, makes the needed changes to
> the ACPI PM domain. In patch8 and patch 9, the i2c driver gets optimized and is
> converted to the runtime PM centric path for system sleep.
> 
> It shall be noted, the behaviour of the ACPI PM domain should remain intact,
> still taking benefit of using the direct_complete path during system sleep,
> except for those drivers that explicitly request it not to (via a new ACPI API
> added in this series).

The following is my take on this (untested so far).

Basically, the point is to allow i2c-designware-platdrv to point its late
suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
and pm_runtime_force_resume() which then will do the right thing regardless of
whether or not the device is runtime suspended when system suspend starts.

However, for this to work, the ACPI PM domain (and the LPSS driver which also
has to work with i2c-designware-platdrv) must do the right thing regardless of
whether or not the device is runtime suspended when system suspend starts too.

The primary problem with that is that acpi_subsys_suspend() has to decide
whether or not to runtime resume the device and then
acpi_subsys_suspend_late/resume_early() (and their counterparts in the ACPI
LPSS driver) need to know whether or not to run acpi_dev_suspend_late/resume_early(), respectively.

In order to make that decision, acpi_subsys_suspend() needs to know (a) if
the power state of the device has to be updated (in which case the device
should be runtime resumed) and (b) if the driver's callbacks that will be
run subsequently can cope with a runtime suspended device.  The former can
be figured out from the check done in acpi_subsys_prepare() (but its result
needs to be saved), but the latter is only known to the driver, so it needs a
way to tell the code above it about that.  Hence, the SAFE_SUSPEND flag
introduced by the first patch.

The second patch simply reworks the ACPI PM domain and the ACPI LPSS driver
to do all the checks etc as needed.

The third one finally updates i2c-designware-platdrv.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29  0:18   ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> isn't well optimized for system sleep.
> 
> What makes this driver particularly interesting is because it's a cross-SoC
> driver, which sometimes means there is an ACPI PM domain attached to the i2c
> device and sometimes not. The driver is being used on both x86 and ARM.
> 
> In principle, to optimize the system sleep support in i2c driver, this series
> enables the proven runtime PM centric path for the i2c driver. However, to do
> that the ACPI PM domain also have to collaborate and understand this behaviour.
> Therefore a number of changes, patch 1 to patch 7, makes the needed changes to
> the ACPI PM domain. In patch8 and patch 9, the i2c driver gets optimized and is
> converted to the runtime PM centric path for system sleep.
> 
> It shall be noted, the behaviour of the ACPI PM domain should remain intact,
> still taking benefit of using the direct_complete path during system sleep,
> except for those drivers that explicitly request it not to (via a new ACPI API
> added in this series).

The following is my take on this (untested so far).

Basically, the point is to allow i2c-designware-platdrv to point its late
suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
and pm_runtime_force_resume() which then will do the right thing regardless of
whether or not the device is runtime suspended when system suspend starts.

However, for this to work, the ACPI PM domain (and the LPSS driver which also
has to work with i2c-designware-platdrv) must do the right thing regardless of
whether or not the device is runtime suspended when system suspend starts too.

The primary problem with that is that acpi_subsys_suspend() has to decide
whether or not to runtime resume the device and then
acpi_subsys_suspend_late/resume_early() (and their counterparts in the ACPI
LPSS driver) need to know whether or not to run acpi_dev_suspend_late/resume_early(), respectively.

In order to make that decision, acpi_subsys_suspend() needs to know (a) if
the power state of the device has to be updated (in which case the device
should be runtime resumed) and (b) if the driver's callbacks that will be
run subsequently can cope with a runtime suspended device.  The former can
be figured out from the check done in acpi_subsys_prepare() (but its result
needs to be saved), but the latter is only known to the driver, so it needs a
way to tell the code above it about that.  Hence, the SAFE_SUSPEND flag
introduced by the first patch.

The second patch simply reworks the ACPI PM domain and the ACPI LPSS driver
to do all the checks etc as needed.

The third one finally updates i2c-designware-platdrv.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 1/3] PM / core: Add SAFE_SUSPEND driver flag
  2017-08-29  0:18   ` Rafael J. Wysocki
@ 2017-08-29  0:20     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:20 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Len Brown, linux-acpi, linux-pm, Kevin Hilman,
	Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jisheng Zhang,
	John Stultz, Guodong Xu, Sumit Semwal, Haojian Zhuang,
	linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

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

Add a driver_flags field to struct dev_pm_info for flags that can be
set by device drivers at the probe time to inform the PM core and/or
bus types, PM domains and so on on the capabilities and/or
preferences of device drivers.  It is anticipated that more than one
flag of this kind will be necessary going forward.

Define and document a SAFE_SUSPEND flag to instruct bus types and PM
domains that the system suspend callbacks provided by the driver can
cope with runtime suspended devices, so from the driver's perspective
it should be safe to leave devices in runtime suspend during system
suspend.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 Documentation/driver-api/pm/devices.rst |    7 +++++++
 drivers/base/dd.c                       |    2 ++
 include/linux/pm.h                      |   16 ++++++++++++++++
 3 files changed, 25 insertions(+)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -550,6 +550,21 @@ struct pm_subsys_data {
 #endif
 };
 
+/*
+ * Driver flags to control system suspend/resume behavior.
+ *
+ * These flags can be set by device drivers at the probe time.  They need not be
+ * cleared by the drivers as the driver core will take care of that.
+ *
+ * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
+ *
+ * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
+ * runtime resume the device upfront during system suspend that doing so is not
+ * necessary from the driver's perspective, because the system suspend callbacks
+ * provided by it can cope with a runtime suspended device.
+ */
+#define DPM_FLAG_SAFE_SUSPEND	BIT(0)
+
 struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
@@ -561,6 +576,7 @@ struct dev_pm_info {
 	bool			is_late_suspended:1;
 	bool			early_init:1;	/* Owned by the PM core */
 	bool			direct_complete:1;	/* Owned by the PM core */
+	unsigned int		driver_flags;
 	spinlock_t		lock;
 #ifdef CONFIG_PM_SLEEP
 	struct list_head	entry;
Index: linux-pm/drivers/base/dd.c
===================================================================
--- linux-pm.orig/drivers/base/dd.c
+++ linux-pm/drivers/base/dd.c
@@ -436,6 +436,7 @@ pinctrl_bind_failed:
 	if (dev->pm_domain && dev->pm_domain->dismiss)
 		dev->pm_domain->dismiss(dev);
 	pm_runtime_reinit(dev);
+	dev->power.driver_flags = 0;
 
 	switch (ret) {
 	case -EPROBE_DEFER:
@@ -841,6 +842,7 @@ static void __device_release_driver(stru
 		if (dev->pm_domain && dev->pm_domain->dismiss)
 			dev->pm_domain->dismiss(dev);
 		pm_runtime_reinit(dev);
+		dev->power.driver_flags = 0;
 
 		klist_remove(&dev->p->knode_driver);
 		device_pm_check_callbacks(dev);
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
@@ -729,6 +729,13 @@ state temporarily, for example so that i
 disabled.  This all depends on the hardware and the design of the subsystem and
 device driver in question.
 
+Some bus types and PM domains have a policy to runtime resume all
+devices upfront in their ``->suspend`` callbacks, but that may not be really
+necessary if the system suspend-resume callbacks provided by the device's
+driver can cope with a runtime-suspended device.  The driver can indicate that
+by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
+probe time.
+
 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

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 1/3] PM / core: Add SAFE_SUSPEND driver flag
@ 2017-08-29  0:20     ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:20 UTC (permalink / raw)
  To: linux-arm-kernel

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

Add a driver_flags field to struct dev_pm_info for flags that can be
set by device drivers at the probe time to inform the PM core and/or
bus types, PM domains and so on on the capabilities and/or
preferences of device drivers.  It is anticipated that more than one
flag of this kind will be necessary going forward.

Define and document a SAFE_SUSPEND flag to instruct bus types and PM
domains that the system suspend callbacks provided by the driver can
cope with runtime suspended devices, so from the driver's perspective
it should be safe to leave devices in runtime suspend during system
suspend.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 Documentation/driver-api/pm/devices.rst |    7 +++++++
 drivers/base/dd.c                       |    2 ++
 include/linux/pm.h                      |   16 ++++++++++++++++
 3 files changed, 25 insertions(+)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -550,6 +550,21 @@ struct pm_subsys_data {
 #endif
 };
 
+/*
+ * Driver flags to control system suspend/resume behavior.
+ *
+ * These flags can be set by device drivers at the probe time.  They need not be
+ * cleared by the drivers as the driver core will take care of that.
+ *
+ * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
+ *
+ * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
+ * runtime resume the device upfront during system suspend that doing so is not
+ * necessary from the driver's perspective, because the system suspend callbacks
+ * provided by it can cope with a runtime suspended device.
+ */
+#define DPM_FLAG_SAFE_SUSPEND	BIT(0)
+
 struct dev_pm_info {
 	pm_message_t		power_state;
 	unsigned int		can_wakeup:1;
@@ -561,6 +576,7 @@ struct dev_pm_info {
 	bool			is_late_suspended:1;
 	bool			early_init:1;	/* Owned by the PM core */
 	bool			direct_complete:1;	/* Owned by the PM core */
+	unsigned int		driver_flags;
 	spinlock_t		lock;
 #ifdef CONFIG_PM_SLEEP
 	struct list_head	entry;
Index: linux-pm/drivers/base/dd.c
===================================================================
--- linux-pm.orig/drivers/base/dd.c
+++ linux-pm/drivers/base/dd.c
@@ -436,6 +436,7 @@ pinctrl_bind_failed:
 	if (dev->pm_domain && dev->pm_domain->dismiss)
 		dev->pm_domain->dismiss(dev);
 	pm_runtime_reinit(dev);
+	dev->power.driver_flags = 0;
 
 	switch (ret) {
 	case -EPROBE_DEFER:
@@ -841,6 +842,7 @@ static void __device_release_driver(stru
 		if (dev->pm_domain && dev->pm_domain->dismiss)
 			dev->pm_domain->dismiss(dev);
 		pm_runtime_reinit(dev);
+		dev->power.driver_flags = 0;
 
 		klist_remove(&dev->p->knode_driver);
 		device_pm_check_callbacks(dev);
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
@@ -729,6 +729,13 @@ state temporarily, for example so that i
 disabled.  This all depends on the hardware and the design of the subsystem and
 device driver in question.
 
+Some bus types and PM domains have a policy to runtime resume all
+devices upfront in their ``->suspend`` callbacks, but that may not be really
+necessary if the system suspend-resume callbacks provided by the device's
+driver can cope with a runtime-suspended device.  The driver can indicate that
+by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
+probe time.
+
 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

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 2/3] PM / ACPI: Use SAFE_SUSPEND in the generic ACPI PM domain
  2017-08-29  0:18   ` Rafael J. Wysocki
@ 2017-08-29  0:59     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:59 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Len Brown, linux-acpi, linux-pm, Kevin Hilman,
	Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jisheng Zhang,
	John Stultz, Guodong Xu, Sumit Semwal, Haojian Zhuang,
	linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: [PATCH] PM / ACPI: Use SAFE_SUSPEND in the generic ACPI PM domain

Make the generic ACPI PM domain and the ACPI LPSS driver take the
SAFE_SUSPEND driver flag into consideration when deciding whether
or not to runtime resume devices during system suspend.

Namely, if the flag is set, acpi_subsys_suspend() will not attempt
to runtime resume the device unless acpi_subsys_prepare() has found
that the power state of the device has to be updated.  Accordingly,
acpi_subsys_suspend_late(), acpi_subsys_resume_late(),
acpi_lpss_suspend_late(), and acpi_lpss_resume_late() will only
try to update the power state of the device and its wakeup settings
if the device has been runtime resumed beforehand.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_lpss.c |   20 ++++++----
 drivers/acpi/device_pm.c |   90 ++++++++++++++++++++++++++++++++++++-----------
 include/acpi/acpi_bus.h  |    1 
 3 files changed, 84 insertions(+), 27 deletions(-)

Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -287,6 +287,7 @@ struct acpi_device_power {
 	int state;		/* Current state */
 	struct acpi_device_power_flags flags;
 	struct acpi_device_power_state states[ACPI_D_STATE_COUNT];	/* Power states (D0-D3Cold) */
+	bool update_state;
 };
 
 /* Performance Management */
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -899,6 +899,7 @@ int acpi_dev_runtime_resume(struct devic
 
 	error = acpi_dev_pm_full_power(adev);
 	acpi_device_wakeup_disable(adev);
+	adev->power.update_state = true;
 	return error;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
@@ -989,33 +990,47 @@ int acpi_dev_resume_early(struct device
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 
-/**
- * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
- * @dev: Device to prepare.
- */
-int acpi_subsys_prepare(struct device *dev)
+static bool acpi_dev_state_update_needed(struct device *dev)
 {
 	struct acpi_device *adev = ACPI_COMPANION(dev);
 	u32 sys_target;
 	int ret, state;
 
-	ret = pm_generic_prepare(dev);
-	if (ret < 0)
-		return ret;
+	if (!pm_runtime_suspended(dev))
+		return true;
 
-	if (!adev || !pm_runtime_suspended(dev)
-	    || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
-		return 0;
+	if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
+		return true;
 
 	sys_target = acpi_target_system_state();
 	if (sys_target == ACPI_STATE_S0)
-		return 1;
+		return false;
 
 	if (adev->power.flags.dsw_present)
-		return 0;
+		return true;
 
 	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
-	return !ret && state == adev->power.state;
+	if (ret)
+		return true;
+
+	return state != adev->power.state;
+}
+
+/**
+ * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
+ * @dev: Device to prepare.
+ */
+int acpi_subsys_prepare(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	ret = pm_generic_prepare(dev);
+	if (ret < 0 || !adev)
+		return ret;
+
+	adev->power.update_state = acpi_dev_state_update_needed(dev);
+	return !adev->power.update_state;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
@@ -1024,11 +1039,30 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
+ * set for them.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	bool resume = !(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND);
+
+	if (adev) {
+		/* The device may have resumed in the meantime. */
+		if (pm_runtime_suspended(dev)) {
+			resume = resume || adev->power.update_state;
+		} else {
+			/*
+			 * Work around a super-theoretical race between runtime
+			 * resume and acpi_dev_state_update_needed().
+			 */
+			adev->power.update_state = true;
+			resume = false;
+		}
+	}
+	if (resume)
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
@@ -1042,8 +1076,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
  */
 int acpi_subsys_suspend_late(struct device *dev)
 {
-	int ret = pm_generic_suspend_late(dev);
-	return ret ? ret : acpi_dev_suspend_late(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	ret = pm_generic_suspend_late(dev);
+	if (ret)
+		return ret;
+
+	if (adev && adev->power.update_state)
+		return acpi_dev_suspend_late(dev);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
 
@@ -1057,8 +1100,15 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_la
  */
 int acpi_subsys_resume_early(struct device *dev)
 {
-	int ret = acpi_dev_resume_early(dev);
-	return ret ? ret : pm_generic_resume_early(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev && adev->power.update_state) {
+		int ret = acpi_dev_resume_early(dev);
+		if (ret)
+			return ret;
+	}
+
+	return pm_generic_resume_early(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
 
Index: linux-pm/drivers/acpi/acpi_lpss.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpi_lpss.c
+++ linux-pm/drivers/acpi/acpi_lpss.c
@@ -719,7 +719,8 @@ static void acpi_lpss_dismiss(struct dev
 #ifdef CONFIG_PM_SLEEP
 static int acpi_lpss_suspend_late(struct device *dev)
 {
-	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct lpss_private_data *pdata = acpi_driver_data(adev);
 	int ret;
 
 	ret = pm_generic_suspend_late(dev);
@@ -729,17 +730,22 @@ static int acpi_lpss_suspend_late(struct
 	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
 		acpi_lpss_save_ctx(dev, pdata);
 
-	return acpi_dev_suspend_late(dev);
+	if (adev->power.update_state)
+		return acpi_dev_suspend_late(dev);
+
+	return 0;
 }
 
 static int acpi_lpss_resume_early(struct device *dev)
 {
-	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
-	int ret;
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct lpss_private_data *pdata = acpi_driver_data(adev);
 
-	ret = acpi_dev_resume_early(dev);
-	if (ret)
-		return ret;
+	if (adev->power.update_state) {
+		int ret = acpi_dev_resume_early(dev);
+		if (ret)
+			return ret;
+	}
 
 	acpi_lpss_d3_to_d0_delay(pdata);
 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 2/3] PM / ACPI: Use SAFE_SUSPEND in the generic ACPI PM domain
@ 2017-08-29  0:59     ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: [PATCH] PM / ACPI: Use SAFE_SUSPEND in the generic ACPI PM domain

Make the generic ACPI PM domain and the ACPI LPSS driver take the
SAFE_SUSPEND driver flag into consideration when deciding whether
or not to runtime resume devices during system suspend.

Namely, if the flag is set, acpi_subsys_suspend() will not attempt
to runtime resume the device unless acpi_subsys_prepare() has found
that the power state of the device has to be updated.  Accordingly,
acpi_subsys_suspend_late(), acpi_subsys_resume_late(),
acpi_lpss_suspend_late(), and acpi_lpss_resume_late() will only
try to update the power state of the device and its wakeup settings
if the device has been runtime resumed beforehand.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_lpss.c |   20 ++++++----
 drivers/acpi/device_pm.c |   90 ++++++++++++++++++++++++++++++++++++-----------
 include/acpi/acpi_bus.h  |    1 
 3 files changed, 84 insertions(+), 27 deletions(-)

Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -287,6 +287,7 @@ struct acpi_device_power {
 	int state;		/* Current state */
 	struct acpi_device_power_flags flags;
 	struct acpi_device_power_state states[ACPI_D_STATE_COUNT];	/* Power states (D0-D3Cold) */
+	bool update_state;
 };
 
 /* Performance Management */
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -899,6 +899,7 @@ int acpi_dev_runtime_resume(struct devic
 
 	error = acpi_dev_pm_full_power(adev);
 	acpi_device_wakeup_disable(adev);
+	adev->power.update_state = true;
 	return error;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume);
@@ -989,33 +990,47 @@ int acpi_dev_resume_early(struct device
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resume_early);
 
-/**
- * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
- * @dev: Device to prepare.
- */
-int acpi_subsys_prepare(struct device *dev)
+static bool acpi_dev_state_update_needed(struct device *dev)
 {
 	struct acpi_device *adev = ACPI_COMPANION(dev);
 	u32 sys_target;
 	int ret, state;
 
-	ret = pm_generic_prepare(dev);
-	if (ret < 0)
-		return ret;
+	if (!pm_runtime_suspended(dev))
+		return true;
 
-	if (!adev || !pm_runtime_suspended(dev)
-	    || device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
-		return 0;
+	if (device_may_wakeup(dev) != !!adev->wakeup.prepare_count)
+		return true;
 
 	sys_target = acpi_target_system_state();
 	if (sys_target == ACPI_STATE_S0)
-		return 1;
+		return false;
 
 	if (adev->power.flags.dsw_present)
-		return 0;
+		return true;
 
 	ret = acpi_dev_pm_get_state(dev, adev, sys_target, NULL, &state);
-	return !ret && state == adev->power.state;
+	if (ret)
+		return true;
+
+	return state != adev->power.state;
+}
+
+/**
+ * acpi_subsys_prepare - Prepare device for system transition to a sleep state.
+ * @dev: Device to prepare.
+ */
+int acpi_subsys_prepare(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	ret = pm_generic_prepare(dev);
+	if (ret < 0 || !adev)
+		return ret;
+
+	adev->power.update_state = acpi_dev_state_update_needed(dev);
+	return !adev->power.update_state;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
 
@@ -1024,11 +1039,30 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
  * @dev: Device to handle.
  *
  * Follow PCI and resume devices suspended at run time before running their
- * system suspend callbacks.
+ * system suspend callbacks, unless the DPM_FLAG_SAFE_SUSPEND driver flag is
+ * set for them.
  */
 int acpi_subsys_suspend(struct device *dev)
 {
-	pm_runtime_resume(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	bool resume = !(dev->power.driver_flags & DPM_FLAG_SAFE_SUSPEND);
+
+	if (adev) {
+		/* The device may have resumed in the meantime. */
+		if (pm_runtime_suspended(dev)) {
+			resume = resume || adev->power.update_state;
+		} else {
+			/*
+			 * Work around a super-theoretical race between runtime
+			 * resume and acpi_dev_state_update_needed().
+			 */
+			adev->power.update_state = true;
+			resume = false;
+		}
+	}
+	if (resume)
+		pm_runtime_resume(dev);
+
 	return pm_generic_suspend(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
@@ -1042,8 +1076,17 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend);
  */
 int acpi_subsys_suspend_late(struct device *dev)
 {
-	int ret = pm_generic_suspend_late(dev);
-	return ret ? ret : acpi_dev_suspend_late(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	int ret;
+
+	ret = pm_generic_suspend_late(dev);
+	if (ret)
+		return ret;
+
+	if (adev && adev->power.update_state)
+		return acpi_dev_suspend_late(dev);
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late);
 
@@ -1057,8 +1100,15 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_la
  */
 int acpi_subsys_resume_early(struct device *dev)
 {
-	int ret = acpi_dev_resume_early(dev);
-	return ret ? ret : pm_generic_resume_early(dev);
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev && adev->power.update_state) {
+		int ret = acpi_dev_resume_early(dev);
+		if (ret)
+			return ret;
+	}
+
+	return pm_generic_resume_early(dev);
 }
 EXPORT_SYMBOL_GPL(acpi_subsys_resume_early);
 
Index: linux-pm/drivers/acpi/acpi_lpss.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpi_lpss.c
+++ linux-pm/drivers/acpi/acpi_lpss.c
@@ -719,7 +719,8 @@ static void acpi_lpss_dismiss(struct dev
 #ifdef CONFIG_PM_SLEEP
 static int acpi_lpss_suspend_late(struct device *dev)
 {
-	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct lpss_private_data *pdata = acpi_driver_data(adev);
 	int ret;
 
 	ret = pm_generic_suspend_late(dev);
@@ -729,17 +730,22 @@ static int acpi_lpss_suspend_late(struct
 	if (pdata->dev_desc->flags & LPSS_SAVE_CTX)
 		acpi_lpss_save_ctx(dev, pdata);
 
-	return acpi_dev_suspend_late(dev);
+	if (adev->power.update_state)
+		return acpi_dev_suspend_late(dev);
+
+	return 0;
 }
 
 static int acpi_lpss_resume_early(struct device *dev)
 {
-	struct lpss_private_data *pdata = acpi_driver_data(ACPI_COMPANION(dev));
-	int ret;
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+	struct lpss_private_data *pdata = acpi_driver_data(adev);
 
-	ret = acpi_dev_resume_early(dev);
-	if (ret)
-		return ret;
+	if (adev->power.update_state) {
+		int ret = acpi_dev_resume_early(dev);
+		if (ret)
+			return ret;
+	}
 
 	acpi_lpss_d3_to_d0_delay(pdata);
 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 3/3] PM: i2c-designware-platdrv: System sleep handling rework
  2017-08-29  0:18   ` Rafael J. Wysocki
@ 2017-08-29  0:59     ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:59 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Len Brown, linux-acpi, linux-pm, Kevin Hilman,
	Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jisheng Zhang,
	John Stultz, Guodong Xu, Sumit Semwal, Haojian Zhuang,
	linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

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

Rework the power management part of the i2c-designware-platdrv driver
so that its ->suspend and ->resume callbacks do not point to the
callback routines used by it for runtime PM.  Instead, point its late
suspend and early resume callbacks to pm_runtime_force_suspend() and
pm_runtime_force_resume(), respectively, and make it set the
SAFE_SUSPEND driver flag (introduced earlier) to instruct the generic
ACPI PM domain code that the driver can cope with runtime suspended
devices in its system sleep callbacks.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/i2c/busses/i2c-designware-platdrv.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
===================================================================
--- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
+++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
 	if (dev->pm_disabled) {
 		pm_runtime_forbid(&pdev->dev);
 	} else {
+		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
 		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
 		pm_runtime_use_autosuspend(&pdev->dev);
 		pm_runtime_set_active(&pdev->dev);
@@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
 	.prepare = dw_i2c_plat_prepare,
 	.complete = dw_i2c_plat_complete,
-	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
 };
 



^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 3/3] PM: i2c-designware-platdrv: System sleep handling rework
@ 2017-08-29  0:59     ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29  0:59 UTC (permalink / raw)
  To: linux-arm-kernel

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

Rework the power management part of the i2c-designware-platdrv driver
so that its ->suspend and ->resume callbacks do not point to the
callback routines used by it for runtime PM.  Instead, point its late
suspend and early resume callbacks to pm_runtime_force_suspend() and
pm_runtime_force_resume(), respectively, and make it set the
SAFE_SUSPEND driver flag (introduced earlier) to instruct the generic
ACPI PM domain code that the driver can cope with runtime suspended
devices in its system sleep callbacks.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/i2c/busses/i2c-designware-platdrv.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
===================================================================
--- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
+++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
 	if (dev->pm_disabled) {
 		pm_runtime_forbid(&pdev->dev);
 	} else {
+		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
 		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
 		pm_runtime_use_autosuspend(&pdev->dev);
 		pm_runtime_set_active(&pdev->dev);
@@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
 	.prepare = dw_i2c_plat_prepare,
 	.complete = dw_i2c_plat_complete,
-	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				     pm_runtime_force_resume)
 	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
 };
 

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-29  0:18   ` Rafael J. Wysocki
@ 2017-08-29 10:29     ` Johannes Stezenbach
  -1 siblings, 0 replies; 94+ messages in thread
From: Johannes Stezenbach @ 2017-08-29 10:29 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Ulf Hansson, Wolfram Sang, Len Brown, linux-acpi, linux-pm,
	Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

Hi,

On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> > isn't well optimized for system sleep.
> > 
> > What makes this driver particularly interesting is because it's a cross-SoC
> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> > device and sometimes not. The driver is being used on both x86 and ARM.
...
> Basically, the point is to allow i2c-designware-platdrv to point its late
> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> and pm_runtime_force_resume() which then will do the right thing regardless of
> whether or not the device is runtime suspended when system suspend starts.

I'd like to point out a comment added by Hans de Goede in
https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99

  The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
  attached to I2C7, these methods get executed by acpi_dev_suspend_late /
  acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
  resume callbacks it is already suspended at the time those calls happen,
  leading to a device-suspend error and the system not suspending at all.

It's the reason for the Cherrytrail I2C7 special treatment in
i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
however pm_disabled seems to be a problem for S0ix support.
To solve it, i2c-designware-platdrv needs to suspend after all
devices using ACPI OpRegions for suspend.


Johannes

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29 10:29     ` Johannes Stezenbach
  0 siblings, 0 replies; 94+ messages in thread
From: Johannes Stezenbach @ 2017-08-29 10:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> > isn't well optimized for system sleep.
> > 
> > What makes this driver particularly interesting is because it's a cross-SoC
> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> > device and sometimes not. The driver is being used on both x86 and ARM.
...
> Basically, the point is to allow i2c-designware-platdrv to point its late
> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> and pm_runtime_force_resume() which then will do the right thing regardless of
> whether or not the device is runtime suspended when system suspend starts.

I'd like to point out a comment added by Hans de Goede in
https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99

  The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
  attached to I2C7, these methods get executed by acpi_dev_suspend_late /
  acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
  resume callbacks it is already suspended at the time those calls happen,
  leading to a device-suspend error and the system not suspending at all.

It's the reason for the Cherrytrail I2C7 special treatment in
i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
however pm_disabled seems to be a problem for S0ix support.
To solve it, i2c-designware-platdrv needs to suspend after all
devices using ACPI OpRegions for suspend.


Johannes

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-29 10:29     ` Johannes Stezenbach
@ 2017-08-29 11:44       ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-29 11:44 UTC (permalink / raw)
  To: Johannes Stezenbach
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, linux-pm, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c, Greg Kroah-Hartman

On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
> Hi,
>
> On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
>> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
>> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
>> > isn't well optimized for system sleep.
>> >
>> > What makes this driver particularly interesting is because it's a cross-SoC
>> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
>> > device and sometimes not. The driver is being used on both x86 and ARM.
> ...
>> Basically, the point is to allow i2c-designware-platdrv to point its late
>> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
>> and pm_runtime_force_resume() which then will do the right thing regardless of
>> whether or not the device is runtime suspended when system suspend starts.
>
> I'd like to point out a comment added by Hans de Goede in
> https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
>
>   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
>   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
>   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
>   resume callbacks it is already suspended at the time those calls happen,
>   leading to a device-suspend error and the system not suspending at all.

Yes, that's why I moved those operation to be managed at the
->suspend_late() in my series, and at the same time prevent the
direct_complete patch from executed for this device.

>
> It's the reason for the Cherrytrail I2C7 special treatment in
> i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> however pm_disabled seems to be a problem for S0ix support.
> To solve it, i2c-designware-platdrv needs to suspend after all
> devices using ACPI OpRegions for suspend.
>
>
> Johannes

Did you try out my series (v2) if that could fix this problem in a
more flexible manner?

In other words, is it fine if the device remains runtime PM enabled
during the entire device_suspend() phase, and also not being suspended
until ->suspend_late()?

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29 11:44       ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-29 11:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
> Hi,
>
> On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
>> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
>> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
>> > isn't well optimized for system sleep.
>> >
>> > What makes this driver particularly interesting is because it's a cross-SoC
>> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
>> > device and sometimes not. The driver is being used on both x86 and ARM.
> ...
>> Basically, the point is to allow i2c-designware-platdrv to point its late
>> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
>> and pm_runtime_force_resume() which then will do the right thing regardless of
>> whether or not the device is runtime suspended when system suspend starts.
>
> I'd like to point out a comment added by Hans de Goede in
> https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
>
>   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
>   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
>   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
>   resume callbacks it is already suspended at the time those calls happen,
>   leading to a device-suspend error and the system not suspending at all.

Yes, that's why I moved those operation to be managed at the
->suspend_late() in my series, and at the same time prevent the
direct_complete patch from executed for this device.

>
> It's the reason for the Cherrytrail I2C7 special treatment in
> i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> however pm_disabled seems to be a problem for S0ix support.
> To solve it, i2c-designware-platdrv needs to suspend after all
> devices using ACPI OpRegions for suspend.
>
>
> Johannes

Did you try out my series (v2) if that could fix this problem in a
more flexible manner?

In other words, is it fine if the device remains runtime PM enabled
during the entire device_suspend() phase, and also not being suspended
until ->suspend_late()?

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-29 11:44       ` Ulf Hansson
@ 2017-08-29 13:53         ` Johannes Stezenbach
  -1 siblings, 0 replies; 94+ messages in thread
From: Johannes Stezenbach @ 2017-08-29 13:53 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rafael J. Wysocki, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, linux-pm, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c, Greg Kroah-Hartman

On Tue, Aug 29, 2017 at 01:44:11PM +0200, Ulf Hansson wrote:
> Did you try out my series (v2) if that could fix this problem in a
> more flexible manner?
> 
> In other words, is it fine if the device remains runtime PM enabled
> during the entire device_suspend() phase, and also not being suspended
> until ->suspend_late()?

I tried to try but I also had some test patches applied
and it hung up on suspend but I ran out of time to check why...
I intend to try again soon.

Johannes

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29 13:53         ` Johannes Stezenbach
  0 siblings, 0 replies; 94+ messages in thread
From: Johannes Stezenbach @ 2017-08-29 13:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 29, 2017 at 01:44:11PM +0200, Ulf Hansson wrote:
> Did you try out my series (v2) if that could fix this problem in a
> more flexible manner?
> 
> In other words, is it fine if the device remains runtime PM enabled
> during the entire device_suspend() phase, and also not being suspended
> until ->suspend_late()?

I tried to try but I also had some test patches applied
and it hung up on suspend but I ran out of time to check why...
I intend to try again soon.

Johannes

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-29 11:44       ` Ulf Hansson
@ 2017-08-29 14:43         ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 14:43 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Johannes Stezenbach, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, linux-pm, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c, Greg Kroah-Hartman

On Tuesday, August 29, 2017 1:44:11 PM CEST Ulf Hansson wrote:
> On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
> > Hi,
> >
> > On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> >> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> >> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> >> > isn't well optimized for system sleep.
> >> >
> >> > What makes this driver particularly interesting is because it's a cross-SoC
> >> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> >> > device and sometimes not. The driver is being used on both x86 and ARM.
> > ...
> >> Basically, the point is to allow i2c-designware-platdrv to point its late
> >> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> >> and pm_runtime_force_resume() which then will do the right thing regardless of
> >> whether or not the device is runtime suspended when system suspend starts.
> >
> > I'd like to point out a comment added by Hans de Goede in
> > https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
> >
> >   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
> >   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
> >   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
> >   resume callbacks it is already suspended at the time those calls happen,
> >   leading to a device-suspend error and the system not suspending at all.
> 
> Yes, that's why I moved those operation to be managed at the
> ->suspend_late() in my series, and at the same time prevent the
> direct_complete patch from executed for this device.
> 
> >
> > It's the reason for the Cherrytrail I2C7 special treatment in
> > i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> > however pm_disabled seems to be a problem for S0ix support.
> > To solve it, i2c-designware-platdrv needs to suspend after all
> > devices using ACPI OpRegions for suspend.
> >
> >
> > Johannes
> 
> Did you try out my series (v2) if that could fix this problem in a
> more flexible manner?
> 
> In other words, is it fine if the device remains runtime PM enabled
> during the entire device_suspend() phase, and also not being suspended
> until ->suspend_late()?

Ulf, please, this is a *different* problem.

Can we focus on one problem at a time?

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29 14:43         ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 14:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 29, 2017 1:44:11 PM CEST Ulf Hansson wrote:
> On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
> > Hi,
> >
> > On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> >> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> >> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> >> > isn't well optimized for system sleep.
> >> >
> >> > What makes this driver particularly interesting is because it's a cross-SoC
> >> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> >> > device and sometimes not. The driver is being used on both x86 and ARM.
> > ...
> >> Basically, the point is to allow i2c-designware-platdrv to point its late
> >> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> >> and pm_runtime_force_resume() which then will do the right thing regardless of
> >> whether or not the device is runtime suspended when system suspend starts.
> >
> > I'd like to point out a comment added by Hans de Goede in
> > https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
> >
> >   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
> >   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
> >   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
> >   resume callbacks it is already suspended at the time those calls happen,
> >   leading to a device-suspend error and the system not suspending at all.
> 
> Yes, that's why I moved those operation to be managed at the
> ->suspend_late() in my series, and at the same time prevent the
> direct_complete patch from executed for this device.
> 
> >
> > It's the reason for the Cherrytrail I2C7 special treatment in
> > i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> > however pm_disabled seems to be a problem for S0ix support.
> > To solve it, i2c-designware-platdrv needs to suspend after all
> > devices using ACPI OpRegions for suspend.
> >
> >
> > Johannes
> 
> Did you try out my series (v2) if that could fix this problem in a
> more flexible manner?
> 
> In other words, is it fine if the device remains runtime PM enabled
> during the entire device_suspend() phase, and also not being suspended
> until ->suspend_late()?

Ulf, please, this is a *different* problem.

Can we focus on one problem at a time?

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-29 10:29     ` Johannes Stezenbach
@ 2017-08-29 14:49       ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 14:49 UTC (permalink / raw)
  To: Johannes Stezenbach
  Cc: Ulf Hansson, Wolfram Sang, Len Brown, linux-acpi, linux-pm,
	Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

On Tuesday, August 29, 2017 12:29:27 PM CEST Johannes Stezenbach wrote:
> Hi,
> 
> On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> > On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> > > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> > > isn't well optimized for system sleep.
> > > 
> > > What makes this driver particularly interesting is because it's a cross-SoC
> > > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> > > device and sometimes not. The driver is being used on both x86 and ARM.
> ...
> > Basically, the point is to allow i2c-designware-platdrv to point its late
> > suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> > and pm_runtime_force_resume() which then will do the right thing regardless of
> > whether or not the device is runtime suspended when system suspend starts.
> 
> I'd like to point out a comment added by Hans de Goede in
> https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
> 
>   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
>   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
>   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
>   resume callbacks it is already suspended at the time those calls happen,
>   leading to a device-suspend error and the system not suspending at all.
> 
> It's the reason for the Cherrytrail I2C7 special treatment in
> i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> however pm_disabled seems to be a problem for S0ix support.
> To solve it, i2c-designware-platdrv needs to suspend after all
> devices using ACPI OpRegions for suspend.

That's a totally different issue from the one at hand.

It simply means that the devices using I2C for suspend/resume need to be
suspended *before* the I2C controller and resumed *after* it.

So this is a system suspend/resume *ordering* issue and not a runtime PM
vs system suspend issue.

It can be addressed, for example, by doing the I2C controller's
suspend/resume at the noirq stage.  Has anyone tried that?

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29 14:49       ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 29, 2017 12:29:27 PM CEST Johannes Stezenbach wrote:
> Hi,
> 
> On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> > On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> > > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> > > isn't well optimized for system sleep.
> > > 
> > > What makes this driver particularly interesting is because it's a cross-SoC
> > > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> > > device and sometimes not. The driver is being used on both x86 and ARM.
> ...
> > Basically, the point is to allow i2c-designware-platdrv to point its late
> > suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> > and pm_runtime_force_resume() which then will do the right thing regardless of
> > whether or not the device is runtime suspended when system suspend starts.
> 
> I'd like to point out a comment added by Hans de Goede in
> https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
> 
>   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
>   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
>   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
>   resume callbacks it is already suspended at the time those calls happen,
>   leading to a device-suspend error and the system not suspending at all.
> 
> It's the reason for the Cherrytrail I2C7 special treatment in
> i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> however pm_disabled seems to be a problem for S0ix support.
> To solve it, i2c-designware-platdrv needs to suspend after all
> devices using ACPI OpRegions for suspend.

That's a totally different issue from the one at hand.

It simply means that the devices using I2C for suspend/resume need to be
suspended *before* the I2C controller and resumed *after* it.

So this is a system suspend/resume *ordering* issue and not a runtime PM
vs system suspend issue.

It can be addressed, for example, by doing the I2C controller's
suspend/resume at the noirq stage.  Has anyone tried that?

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 1/3] PM / core: Add SAFE_SUSPEND driver flag
  2017-08-29  0:20     ` Rafael J. Wysocki
@ 2017-08-29 14:57       ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-29 14:57 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Wolfram Sang, Len Brown, ACPI Devel Maling List, linux-pm,
	Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

On 29 August 2017 at 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Add a driver_flags field to struct dev_pm_info for flags that can be
> set by device drivers at the probe time to inform the PM core and/or
> bus types, PM domains and so on on the capabilities and/or
> preferences of device drivers.  It is anticipated that more than one
> flag of this kind will be necessary going forward.
>
> Define and document a SAFE_SUSPEND flag to instruct bus types and PM
> domains that the system suspend callbacks provided by the driver can
> cope with runtime suspended devices, so from the driver's perspective
> it should be safe to leave devices in runtime suspend during system
> suspend.

This changelog is a bit too vague to me. Wouldn't it be more clear if
also adding something along the lines that this also means that
runtime resuming a device isn't needed by the subsystem/PM domain
during system sleep? Because ideally that is what you want to avoid,
right?

Moreover I am also not convinced that this solution really is the
right path. It seems like we might end up adding more bits for the
"driver_flag" field and it gets complicated. Do we really need to
distinguish between all different cases in such detail?

I will continue to review this tomorrow, however in the meantime I
have finalized a re-spin of my v3 series so I decided to post it
anyway. I am adding only one new flag to the PM core, perhaps I am
over-simplifying things, but please have look once more. I think I
have addressed all your concerns you have raised so far.

Kind regards
Uffe

>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  Documentation/driver-api/pm/devices.rst |    7 +++++++
>  drivers/base/dd.c                       |    2 ++
>  include/linux/pm.h                      |   16 ++++++++++++++++
>  3 files changed, 25 insertions(+)
>
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -550,6 +550,21 @@ struct pm_subsys_data {
>  #endif
>  };
>
> +/*
> + * Driver flags to control system suspend/resume behavior.
> + *
> + * These flags can be set by device drivers at the probe time.  They need not be
> + * cleared by the drivers as the driver core will take care of that.
> + *
> + * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
> + *
> + * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
> + * runtime resume the device upfront during system suspend that doing so is not
> + * necessary from the driver's perspective, because the system suspend callbacks
> + * provided by it can cope with a runtime suspended device.
> + */
> +#define DPM_FLAG_SAFE_SUSPEND  BIT(0)
> +
>  struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
> @@ -561,6 +576,7 @@ struct dev_pm_info {
>         bool                    is_late_suspended:1;
>         bool                    early_init:1;   /* Owned by the PM core */
>         bool                    direct_complete:1;      /* Owned by the PM core */
> +       unsigned int            driver_flags;
>         spinlock_t              lock;
>  #ifdef CONFIG_PM_SLEEP
>         struct list_head        entry;
> Index: linux-pm/drivers/base/dd.c
> ===================================================================
> --- linux-pm.orig/drivers/base/dd.c
> +++ linux-pm/drivers/base/dd.c
> @@ -436,6 +436,7 @@ pinctrl_bind_failed:
>         if (dev->pm_domain && dev->pm_domain->dismiss)
>                 dev->pm_domain->dismiss(dev);
>         pm_runtime_reinit(dev);
> +       dev->power.driver_flags = 0;
>
>         switch (ret) {
>         case -EPROBE_DEFER:
> @@ -841,6 +842,7 @@ static void __device_release_driver(stru
>                 if (dev->pm_domain && dev->pm_domain->dismiss)
>                         dev->pm_domain->dismiss(dev);
>                 pm_runtime_reinit(dev);
> +               dev->power.driver_flags = 0;
>
>                 klist_remove(&dev->p->knode_driver);
>                 device_pm_check_callbacks(dev);
> 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
> @@ -729,6 +729,13 @@ state temporarily, for example so that i
>  disabled.  This all depends on the hardware and the design of the subsystem and
>  device driver in question.
>
> +Some bus types and PM domains have a policy to runtime resume all
> +devices upfront in their ``->suspend`` callbacks, but that may not be really
> +necessary if the system suspend-resume callbacks provided by the device's
> +driver can cope with a runtime-suspended device.  The driver can indicate that
> +by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
> +probe time.
> +
>  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
>
>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 1/3] PM / core: Add SAFE_SUSPEND driver flag
@ 2017-08-29 14:57       ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-29 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 August 2017 at 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>
> Add a driver_flags field to struct dev_pm_info for flags that can be
> set by device drivers at the probe time to inform the PM core and/or
> bus types, PM domains and so on on the capabilities and/or
> preferences of device drivers.  It is anticipated that more than one
> flag of this kind will be necessary going forward.
>
> Define and document a SAFE_SUSPEND flag to instruct bus types and PM
> domains that the system suspend callbacks provided by the driver can
> cope with runtime suspended devices, so from the driver's perspective
> it should be safe to leave devices in runtime suspend during system
> suspend.

This changelog is a bit too vague to me. Wouldn't it be more clear if
also adding something along the lines that this also means that
runtime resuming a device isn't needed by the subsystem/PM domain
during system sleep? Because ideally that is what you want to avoid,
right?

Moreover I am also not convinced that this solution really is the
right path. It seems like we might end up adding more bits for the
"driver_flag" field and it gets complicated. Do we really need to
distinguish between all different cases in such detail?

I will continue to review this tomorrow, however in the meantime I
have finalized a re-spin of my v3 series so I decided to post it
anyway. I am adding only one new flag to the PM core, perhaps I am
over-simplifying things, but please have look once more. I think I
have addressed all your concerns you have raised so far.

Kind regards
Uffe

>
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  Documentation/driver-api/pm/devices.rst |    7 +++++++
>  drivers/base/dd.c                       |    2 ++
>  include/linux/pm.h                      |   16 ++++++++++++++++
>  3 files changed, 25 insertions(+)
>
> Index: linux-pm/include/linux/pm.h
> ===================================================================
> --- linux-pm.orig/include/linux/pm.h
> +++ linux-pm/include/linux/pm.h
> @@ -550,6 +550,21 @@ struct pm_subsys_data {
>  #endif
>  };
>
> +/*
> + * Driver flags to control system suspend/resume behavior.
> + *
> + * These flags can be set by device drivers at the probe time.  They need not be
> + * cleared by the drivers as the driver core will take care of that.
> + *
> + * SAFE_SUSPEND: No need to runtime resume the device during system suspend.
> + *
> + * Setting SAFE_SUSPEND instructs bus types and PM domains which may want to
> + * runtime resume the device upfront during system suspend that doing so is not
> + * necessary from the driver's perspective, because the system suspend callbacks
> + * provided by it can cope with a runtime suspended device.
> + */
> +#define DPM_FLAG_SAFE_SUSPEND  BIT(0)
> +
>  struct dev_pm_info {
>         pm_message_t            power_state;
>         unsigned int            can_wakeup:1;
> @@ -561,6 +576,7 @@ struct dev_pm_info {
>         bool                    is_late_suspended:1;
>         bool                    early_init:1;   /* Owned by the PM core */
>         bool                    direct_complete:1;      /* Owned by the PM core */
> +       unsigned int            driver_flags;
>         spinlock_t              lock;
>  #ifdef CONFIG_PM_SLEEP
>         struct list_head        entry;
> Index: linux-pm/drivers/base/dd.c
> ===================================================================
> --- linux-pm.orig/drivers/base/dd.c
> +++ linux-pm/drivers/base/dd.c
> @@ -436,6 +436,7 @@ pinctrl_bind_failed:
>         if (dev->pm_domain && dev->pm_domain->dismiss)
>                 dev->pm_domain->dismiss(dev);
>         pm_runtime_reinit(dev);
> +       dev->power.driver_flags = 0;
>
>         switch (ret) {
>         case -EPROBE_DEFER:
> @@ -841,6 +842,7 @@ static void __device_release_driver(stru
>                 if (dev->pm_domain && dev->pm_domain->dismiss)
>                         dev->pm_domain->dismiss(dev);
>                 pm_runtime_reinit(dev);
> +               dev->power.driver_flags = 0;
>
>                 klist_remove(&dev->p->knode_driver);
>                 device_pm_check_callbacks(dev);
> 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
> @@ -729,6 +729,13 @@ state temporarily, for example so that i
>  disabled.  This all depends on the hardware and the design of the subsystem and
>  device driver in question.
>
> +Some bus types and PM domains have a policy to runtime resume all
> +devices upfront in their ``->suspend`` callbacks, but that may not be really
> +necessary if the system suspend-resume callbacks provided by the device's
> +driver can cope with a runtime-suspended device.  The driver can indicate that
> +by setting ``DPM_FLAG_SAFE_SUSPEND`` in :c:member:`power.driver_flags` at the
> +probe time.
> +
>  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
>
>

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 1/3] PM / core: Add SAFE_SUSPEND driver flag
  2017-08-29 14:57       ` Ulf Hansson
@ 2017-08-29 15:02         ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 15:02 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Len Brown, ACPI Devel Maling List, linux-pm,
	Kevin Hilman, Jarkko Nikula, Andy Shevchenko, Mika Westerberg,
	Jisheng Zhang, John Stultz, Guodong Xu, Sumit Semwal,
	Haojian Zhuang, linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

On Tuesday, August 29, 2017 4:57:28 PM CEST Ulf Hansson wrote:
> On 29 August 2017 at 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > Add a driver_flags field to struct dev_pm_info for flags that can be
> > set by device drivers at the probe time to inform the PM core and/or
> > bus types, PM domains and so on on the capabilities and/or
> > preferences of device drivers.  It is anticipated that more than one
> > flag of this kind will be necessary going forward.
> >
> > Define and document a SAFE_SUSPEND flag to instruct bus types and PM
> > domains that the system suspend callbacks provided by the driver can
> > cope with runtime suspended devices, so from the driver's perspective
> > it should be safe to leave devices in runtime suspend during system
> > suspend.
> 
> This changelog is a bit too vague to me. Wouldn't it be more clear if
> also adding something along the lines that this also means that
> runtime resuming a device isn't needed by the subsystem/PM domain
> during system sleep?

No.

> Because ideally that is what you want to avoid, right?

Not really.  The driver doesn't know what the needs of the higher level
are.  It may only say what it can do and the bus type can use this
information to make a decision.

> Moreover I am also not convinced that this solution really is the
> right path. It seems like we might end up adding more bits for the
> "driver_flag" field and it gets complicated. Do we really need to
> distinguish between all different cases in such detail?

Yes, we do.

Every time we try to address two different problems with one mechanism,
it backfires later.

> I will continue to review this tomorrow, however in the meantime I
> have finalized a re-spin of my v3 series so I decided to post it
> anyway. I am adding only one new flag to the PM core, perhaps I am
> over-simplifying things, but please have look once more. I think I
> have addressed all your concerns you have raised so far.

I'll have a look, but I really don't want to conflate the "I'm fine
with not resuming the device" case with the "I don't want to use
direct_complete with it" one.  To me, they are fundamentally different
and I'm not going to apply any patches conflating them.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 1/3] PM / core: Add SAFE_SUSPEND driver flag
@ 2017-08-29 15:02         ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 15:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 29, 2017 4:57:28 PM CEST Ulf Hansson wrote:
> On 29 August 2017 at 02:20, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > Add a driver_flags field to struct dev_pm_info for flags that can be
> > set by device drivers at the probe time to inform the PM core and/or
> > bus types, PM domains and so on on the capabilities and/or
> > preferences of device drivers.  It is anticipated that more than one
> > flag of this kind will be necessary going forward.
> >
> > Define and document a SAFE_SUSPEND flag to instruct bus types and PM
> > domains that the system suspend callbacks provided by the driver can
> > cope with runtime suspended devices, so from the driver's perspective
> > it should be safe to leave devices in runtime suspend during system
> > suspend.
> 
> This changelog is a bit too vague to me. Wouldn't it be more clear if
> also adding something along the lines that this also means that
> runtime resuming a device isn't needed by the subsystem/PM domain
> during system sleep?

No.

> Because ideally that is what you want to avoid, right?

Not really.  The driver doesn't know what the needs of the higher level
are.  It may only say what it can do and the bus type can use this
information to make a decision.

> Moreover I am also not convinced that this solution really is the
> right path. It seems like we might end up adding more bits for the
> "driver_flag" field and it gets complicated. Do we really need to
> distinguish between all different cases in such detail?

Yes, we do.

Every time we try to address two different problems with one mechanism,
it backfires later.

> I will continue to review this tomorrow, however in the meantime I
> have finalized a re-spin of my v3 series so I decided to post it
> anyway. I am adding only one new flag to the PM core, perhaps I am
> over-simplifying things, but please have look once more. I think I
> have addressed all your concerns you have raised so far.

I'll have a look, but I really don't want to conflate the "I'm fine
with not resuming the device" case with the "I don't want to use
direct_complete with it" one.  To me, they are fundamentally different
and I'm not going to apply any patches conflating them.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-29 14:43         ` Rafael J. Wysocki
@ 2017-08-29 15:05           ` Ulf Hansson
  -1 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-29 15:05 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Johannes Stezenbach, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, linux-pm, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c, Greg Kroah-Hartman

On 29 August 2017 at 16:43, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Tuesday, August 29, 2017 1:44:11 PM CEST Ulf Hansson wrote:
>> On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
>> > Hi,
>> >
>> > On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
>> >> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
>> >> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
>> >> > isn't well optimized for system sleep.
>> >> >
>> >> > What makes this driver particularly interesting is because it's a cross-SoC
>> >> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
>> >> > device and sometimes not. The driver is being used on both x86 and ARM.
>> > ...
>> >> Basically, the point is to allow i2c-designware-platdrv to point its late
>> >> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
>> >> and pm_runtime_force_resume() which then will do the right thing regardless of
>> >> whether or not the device is runtime suspended when system suspend starts.
>> >
>> > I'd like to point out a comment added by Hans de Goede in
>> > https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
>> >
>> >   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
>> >   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
>> >   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
>> >   resume callbacks it is already suspended at the time those calls happen,
>> >   leading to a device-suspend error and the system not suspending at all.
>>
>> Yes, that's why I moved those operation to be managed at the
>> ->suspend_late() in my series, and at the same time prevent the
>> direct_complete patch from executed for this device.
>>
>> >
>> > It's the reason for the Cherrytrail I2C7 special treatment in
>> > i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
>> > however pm_disabled seems to be a problem for S0ix support.
>> > To solve it, i2c-designware-platdrv needs to suspend after all
>> > devices using ACPI OpRegions for suspend.
>> >
>> >
>> > Johannes
>>
>> Did you try out my series (v2) if that could fix this problem in a
>> more flexible manner?
>>
>> In other words, is it fine if the device remains runtime PM enabled
>> during the entire device_suspend() phase, and also not being suspended
>> until ->suspend_late()?
>
> Ulf, please, this is a *different* problem.

Yes, it is!

Just wanted to point out that if the device remains runtime PM enabled
the entire device_suspend() phase, that *could* solve the problem.

>
> Can we focus on one problem at a time?

Yes!

However, there is lots of things following when we try to enable the
runtime PM centric path for ACPI. :-)

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29 15:05           ` Ulf Hansson
  0 siblings, 0 replies; 94+ messages in thread
From: Ulf Hansson @ 2017-08-29 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 29 August 2017 at 16:43, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> On Tuesday, August 29, 2017 1:44:11 PM CEST Ulf Hansson wrote:
>> On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
>> > Hi,
>> >
>> > On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
>> >> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
>> >> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
>> >> > isn't well optimized for system sleep.
>> >> >
>> >> > What makes this driver particularly interesting is because it's a cross-SoC
>> >> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
>> >> > device and sometimes not. The driver is being used on both x86 and ARM.
>> > ...
>> >> Basically, the point is to allow i2c-designware-platdrv to point its late
>> >> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
>> >> and pm_runtime_force_resume() which then will do the right thing regardless of
>> >> whether or not the device is runtime suspended when system suspend starts.
>> >
>> > I'd like to point out a comment added by Hans de Goede in
>> > https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
>> >
>> >   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
>> >   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
>> >   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
>> >   resume callbacks it is already suspended at the time those calls happen,
>> >   leading to a device-suspend error and the system not suspending at all.
>>
>> Yes, that's why I moved those operation to be managed at the
>> ->suspend_late() in my series, and at the same time prevent the
>> direct_complete patch from executed for this device.
>>
>> >
>> > It's the reason for the Cherrytrail I2C7 special treatment in
>> > i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
>> > however pm_disabled seems to be a problem for S0ix support.
>> > To solve it, i2c-designware-platdrv needs to suspend after all
>> > devices using ACPI OpRegions for suspend.
>> >
>> >
>> > Johannes
>>
>> Did you try out my series (v2) if that could fix this problem in a
>> more flexible manner?
>>
>> In other words, is it fine if the device remains runtime PM enabled
>> during the entire device_suspend() phase, and also not being suspended
>> until ->suspend_late()?
>
> Ulf, please, this is a *different* problem.

Yes, it is!

Just wanted to point out that if the device remains runtime PM enabled
the entire device_suspend() phase, that *could* solve the problem.

>
> Can we focus on one problem at a time?

Yes!

However, there is lots of things following when we try to enable the
runtime PM centric path for ACPI. :-)

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 3/3] PM: i2c-designware-platdrv: System sleep handling rework
  2017-08-29  0:59     ` Rafael J. Wysocki
@ 2017-08-29 16:38       ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 16:38 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Len Brown, linux-acpi, linux-pm, Kevin Hilman,
	Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jisheng Zhang,
	John Stultz, Guodong Xu, Sumit Semwal, Haojian Zhuang,
	linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

On Tuesday, August 29, 2017 2:59:49 AM CEST Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Rework the power management part of the i2c-designware-platdrv driver
> so that its ->suspend and ->resume callbacks do not point to the
> callback routines used by it for runtime PM.  Instead, point its late
> suspend and early resume callbacks to pm_runtime_force_suspend() and
> pm_runtime_force_resume(), respectively, and make it set the
> SAFE_SUSPEND driver flag (introduced earlier) to instruct the generic
> ACPI PM domain code that the driver can cope with runtime suspended
> devices in its system sleep callbacks.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/i2c/busses/i2c-designware-platdrv.c |    4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> ===================================================================
> --- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
>  	if (dev->pm_disabled) {
>  		pm_runtime_forbid(&pdev->dev);
>  	} else {
> +		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
>  		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
>  		pm_runtime_use_autosuspend(&pdev->dev);
>  		pm_runtime_set_active(&pdev->dev);
> @@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
>  static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
>  	.prepare = dw_i2c_plat_prepare,
>  	.complete = dw_i2c_plat_complete,
> -	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
> +	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				     pm_runtime_force_resume)
>  	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
>  };

This isn't going to work, because pm_runtime_force_suspend() will invoke
the bus type callback and not the driver's one.

So scratch this, please.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 3/3] PM: i2c-designware-platdrv: System sleep handling rework
@ 2017-08-29 16:38       ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 16:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 29, 2017 2:59:49 AM CEST Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Rework the power management part of the i2c-designware-platdrv driver
> so that its ->suspend and ->resume callbacks do not point to the
> callback routines used by it for runtime PM.  Instead, point its late
> suspend and early resume callbacks to pm_runtime_force_suspend() and
> pm_runtime_force_resume(), respectively, and make it set the
> SAFE_SUSPEND driver flag (introduced earlier) to instruct the generic
> ACPI PM domain code that the driver can cope with runtime suspended
> devices in its system sleep callbacks.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/i2c/busses/i2c-designware-platdrv.c |    4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> ===================================================================
> --- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
>  	if (dev->pm_disabled) {
>  		pm_runtime_forbid(&pdev->dev);
>  	} else {
> +		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
>  		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
>  		pm_runtime_use_autosuspend(&pdev->dev);
>  		pm_runtime_set_active(&pdev->dev);
> @@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
>  static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
>  	.prepare = dw_i2c_plat_prepare,
>  	.complete = dw_i2c_plat_complete,
> -	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
> +	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				     pm_runtime_force_resume)
>  	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
>  };

This isn't going to work, because pm_runtime_force_suspend() will invoke
the bus type callback and not the driver's one.

So scratch this, please.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 3/3] PM: i2c-designware-platdrv: System sleep handling rework
  2017-08-29 16:38       ` Rafael J. Wysocki
@ 2017-08-29 16:40         ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 16:40 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Wolfram Sang, Len Brown, linux-acpi, linux-pm, Kevin Hilman,
	Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Jisheng Zhang,
	John Stultz, Guodong Xu, Sumit Semwal, Haojian Zhuang,
	linux-arm-kernel, linux-i2c, Greg Kroah-Hartman

On Tuesday, August 29, 2017 6:38:11 PM CEST Rafael J. Wysocki wrote:
> On Tuesday, August 29, 2017 2:59:49 AM CEST Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > 
> > Rework the power management part of the i2c-designware-platdrv driver
> > so that its ->suspend and ->resume callbacks do not point to the
> > callback routines used by it for runtime PM.  Instead, point its late
> > suspend and early resume callbacks to pm_runtime_force_suspend() and
> > pm_runtime_force_resume(), respectively, and make it set the
> > SAFE_SUSPEND driver flag (introduced earlier) to instruct the generic
> > ACPI PM domain code that the driver can cope with runtime suspended
> > devices in its system sleep callbacks.
> > 
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/i2c/busses/i2c-designware-platdrv.c |    4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> > ===================================================================
> > --- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
> > +++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> > @@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
> >  	if (dev->pm_disabled) {
> >  		pm_runtime_forbid(&pdev->dev);
> >  	} else {
> > +		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
> >  		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
> >  		pm_runtime_use_autosuspend(&pdev->dev);
> >  		pm_runtime_set_active(&pdev->dev);
> > @@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
> >  static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
> >  	.prepare = dw_i2c_plat_prepare,
> >  	.complete = dw_i2c_plat_complete,
> > -	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
> > +	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> > +				     pm_runtime_force_resume)
> >  	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
> >  };
> 
> This isn't going to work, because pm_runtime_force_suspend() will invoke
> the bus type callback and not the driver's one.
> 
> So scratch this, please.

BTW, I don't think it is OK to mess up with bus type _runtime_suspend and
_runtime_resume and try to make them magically handle the system suspend
case as well.  There has to be a different way ...

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 3/3] PM: i2c-designware-platdrv: System sleep handling rework
@ 2017-08-29 16:40         ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 16:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 29, 2017 6:38:11 PM CEST Rafael J. Wysocki wrote:
> On Tuesday, August 29, 2017 2:59:49 AM CEST Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > 
> > Rework the power management part of the i2c-designware-platdrv driver
> > so that its ->suspend and ->resume callbacks do not point to the
> > callback routines used by it for runtime PM.  Instead, point its late
> > suspend and early resume callbacks to pm_runtime_force_suspend() and
> > pm_runtime_force_resume(), respectively, and make it set the
> > SAFE_SUSPEND driver flag (introduced earlier) to instruct the generic
> > ACPI PM domain code that the driver can cope with runtime suspended
> > devices in its system sleep callbacks.
> > 
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/i2c/busses/i2c-designware-platdrv.c |    4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > Index: linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> > ===================================================================
> > --- linux-pm.orig/drivers/i2c/busses/i2c-designware-platdrv.c
> > +++ linux-pm/drivers/i2c/busses/i2c-designware-platdrv.c
> > @@ -358,6 +358,7 @@ static int dw_i2c_plat_probe(struct plat
> >  	if (dev->pm_disabled) {
> >  		pm_runtime_forbid(&pdev->dev);
> >  	} else {
> > +		dev->power.driver_flags = DPM_FLAG_SAFE_SUSPEND;
> >  		pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
> >  		pm_runtime_use_autosuspend(&pdev->dev);
> >  		pm_runtime_set_active(&pdev->dev);
> > @@ -455,7 +456,8 @@ static int dw_i2c_plat_resume(struct dev
> >  static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
> >  	.prepare = dw_i2c_plat_prepare,
> >  	.complete = dw_i2c_plat_complete,
> > -	SET_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
> > +	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> > +				     pm_runtime_force_resume)
> >  	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
> >  };
> 
> This isn't going to work, because pm_runtime_force_suspend() will invoke
> the bus type callback and not the driver's one.
> 
> So scratch this, please.

BTW, I don't think it is OK to mess up with bus type _runtime_suspend and
_runtime_resume and try to make them magically handle the system suspend
case as well.  There has to be a different way ...

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

* Re: [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
  2017-08-29 15:05           ` Ulf Hansson
@ 2017-08-29 16:44             ` Rafael J. Wysocki
  -1 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 16:44 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Johannes Stezenbach, Wolfram Sang, Len Brown,
	ACPI Devel Maling List, linux-pm, Kevin Hilman, Jarkko Nikula,
	Andy Shevchenko, Mika Westerberg, Jisheng Zhang, John Stultz,
	Guodong Xu, Sumit Semwal, Haojian Zhuang, linux-arm-kernel,
	linux-i2c, Greg Kroah-Hartman

On Tuesday, August 29, 2017 5:05:20 PM CEST Ulf Hansson wrote:
> On 29 August 2017 at 16:43, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Tuesday, August 29, 2017 1:44:11 PM CEST Ulf Hansson wrote:
> >> On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
> >> > Hi,
> >> >
> >> > On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> >> >> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> >> >> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> >> >> > isn't well optimized for system sleep.
> >> >> >
> >> >> > What makes this driver particularly interesting is because it's a cross-SoC
> >> >> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> >> >> > device and sometimes not. The driver is being used on both x86 and ARM.
> >> > ...
> >> >> Basically, the point is to allow i2c-designware-platdrv to point its late
> >> >> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> >> >> and pm_runtime_force_resume() which then will do the right thing regardless of
> >> >> whether or not the device is runtime suspended when system suspend starts.
> >> >
> >> > I'd like to point out a comment added by Hans de Goede in
> >> > https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
> >> >
> >> >   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
> >> >   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
> >> >   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
> >> >   resume callbacks it is already suspended at the time those calls happen,
> >> >   leading to a device-suspend error and the system not suspending at all.
> >>
> >> Yes, that's why I moved those operation to be managed at the
> >> ->suspend_late() in my series, and at the same time prevent the
> >> direct_complete patch from executed for this device.
> >>
> >> >
> >> > It's the reason for the Cherrytrail I2C7 special treatment in
> >> > i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> >> > however pm_disabled seems to be a problem for S0ix support.
> >> > To solve it, i2c-designware-platdrv needs to suspend after all
> >> > devices using ACPI OpRegions for suspend.
> >> >
> >> >
> >> > Johannes
> >>
> >> Did you try out my series (v2) if that could fix this problem in a
> >> more flexible manner?
> >>
> >> In other words, is it fine if the device remains runtime PM enabled
> >> during the entire device_suspend() phase, and also not being suspended
> >> until ->suspend_late()?
> >
> > Ulf, please, this is a *different* problem.
> 
> Yes, it is!
> 
> Just wanted to point out that if the device remains runtime PM enabled
> the entire device_suspend() phase, that *could* solve the problem.
> 
> >
> > Can we focus on one problem at a time?
> 
> Yes!
> 
> However, there is lots of things following when we try to enable the
> runtime PM centric path for ACPI. :-)

Which, I guess, we won't do after all ...

So I would prefer to think about addressing problems instead of trying to
"enable the runtime PM centric path for ACPI" just for the sake of it.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 94+ messages in thread

* [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling
@ 2017-08-29 16:44             ` Rafael J. Wysocki
  0 siblings, 0 replies; 94+ messages in thread
From: Rafael J. Wysocki @ 2017-08-29 16:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday, August 29, 2017 5:05:20 PM CEST Ulf Hansson wrote:
> On 29 August 2017 at 16:43, Rafael J. Wysocki <rjw@rjwysocki.net> wrote:
> > On Tuesday, August 29, 2017 1:44:11 PM CEST Ulf Hansson wrote:
> >> On 29 August 2017 at 12:29, Johannes Stezenbach <js@sig21.net> wrote:
> >> > Hi,
> >> >
> >> > On Tue, Aug 29, 2017 at 02:18:13AM +0200, Rafael J. Wysocki wrote:
> >> >> On Wednesday, August 23, 2017 4:42:00 PM CEST Ulf Hansson wrote:
> >> >> > The i2c designware platform driver, drivers/i2c/busses/i2c-designware-platdrv.c,
> >> >> > isn't well optimized for system sleep.
> >> >> >
> >> >> > What makes this driver particularly interesting is because it's a cross-SoC
> >> >> > driver, which sometimes means there is an ACPI PM domain attached to the i2c
> >> >> > device and sometimes not. The driver is being used on both x86 and ARM.
> >> > ...
> >> >> Basically, the point is to allow i2c-designware-platdrv to point its late
> >> >> suspend and early resume callbacks, respectively, to pm_runtime_force_suspend()
> >> >> and pm_runtime_force_resume() which then will do the right thing regardless of
> >> >> whether or not the device is runtime suspended when system suspend starts.
> >> >
> >> > I'd like to point out a comment added by Hans de Goede in
> >> > https://bugzilla.kernel.org/show_bug.cgi?id=193891#c99
> >> >
> >> >   The D0 / D3 methods of some devices use ACPI OpRegions on the PMIC which is
> >> >   attached to I2C7, these methods get executed by acpi_dev_suspend_late /
> >> >   acpi_dev_resume_early. Since the i2c-designware driver uses regular suspend /
> >> >   resume callbacks it is already suspended at the time those calls happen,
> >> >   leading to a device-suspend error and the system not suspending at all.
> >>
> >> Yes, that's why I moved those operation to be managed at the
> >> ->suspend_late() in my series, and at the same time prevent the
> >> direct_complete patch from executed for this device.
> >>
> >> >
> >> > It's the reason for the Cherrytrail I2C7 special treatment in
> >> > i2c-designware-platdrv.c and pm_disabled = true in i2c-designware-baytrail.c,
> >> > however pm_disabled seems to be a problem for S0ix support.
> >> > To solve it, i2c-designware-platdrv needs to suspend after all
> >> > devices using ACPI OpRegions for suspend.
> >> >
> >> >
> >> > Johannes
> >>
> >> Did you try out my series (v2) if that could fix this problem in a
> >> more flexible manner?
> >>
> >> In other words, is it fine if the device remains runtime PM enabled
> >> during the entire device_suspend() phase, and also not being suspended
> >> until ->suspend_late()?
> >
> > Ulf, please, this is a *different* problem.
> 
> Yes, it is!
> 
> Just wanted to point out that if the device remains runtime PM enabled
> the entire device_suspend() phase, that *could* solve the problem.
> 
> >
> > Can we focus on one problem at a time?
> 
> Yes!
> 
> However, there is lots of things following when we try to enable the
> runtime PM centric path for ACPI. :-)

Which, I guess, we won't do after all ...

So I would prefer to think about addressing problems instead of trying to
"enable the runtime PM centric path for ACPI" just for the sake of it.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 94+ messages in thread

end of thread, other threads:[~2017-08-29 16:52 UTC | newest]

Thread overview: 94+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-23 14:42 [PATCH v2 0/9] PM / ACPI / i2c: Deploy runtime PM centric path for system sleep Ulf Hansson
2017-08-23 14:42 ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 1/9] PM / ACPI: Restore acpi_subsys_complete() Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 22:41   ` Rafael J. Wysocki
2017-08-23 22:41     ` Rafael J. Wysocki
2017-08-23 14:42 ` [PATCH v2 2/9] PM / Sleep: Remove pm_complete_with_resume_check() Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 3/9] PM / ACPI: Split code validating need for runtime resume in ->prepare() Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 4/9] PM / ACPI: Split acpi_lpss_suspend_late|resume_early() Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 5/9] PM / ACPI: Provide option to disable direct_complete for ACPI devices Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 23:39   ` Rafael J. Wysocki
2017-08-23 23:39     ` Rafael J. Wysocki
2017-08-24  0:13     ` Rafael J. Wysocki
2017-08-24  0:13       ` Rafael J. Wysocki
2017-08-24  0:20       ` Rafael J. Wysocki
2017-08-24  0:20         ` Rafael J. Wysocki
2017-08-24  1:03         ` Rafael J. Wysocki
2017-08-24  1:03           ` Rafael J. Wysocki
2017-08-24  9:15           ` Ulf Hansson
2017-08-24  9:15             ` Ulf Hansson
2017-08-24 16:35             ` Rafael J. Wysocki
2017-08-24 16:35               ` Rafael J. Wysocki
2017-08-24 21:50               ` Rafael J. Wysocki
2017-08-24 21:50                 ` Rafael J. Wysocki
2017-08-25 13:42                 ` Rafael J. Wysocki
2017-08-25 13:42                   ` Rafael J. Wysocki
2017-08-28  1:30                   ` Rafael J. Wysocki
2017-08-28  1:30                     ` Rafael J. Wysocki
2017-08-28  8:31                     ` Ulf Hansson
2017-08-28  8:31                       ` Ulf Hansson
2017-08-28 12:39                       ` Rafael J. Wysocki
2017-08-28 12:39                         ` Rafael J. Wysocki
2017-08-28 12:54                         ` Ulf Hansson
2017-08-28 12:54                           ` Ulf Hansson
2017-08-28 13:40                           ` Rafael J. Wysocki
2017-08-28 13:40                             ` Rafael J. Wysocki
2017-08-28 14:24                             ` Ulf Hansson
2017-08-28 14:24                               ` Ulf Hansson
2017-08-28 21:14                               ` Rafael J. Wysocki
2017-08-28 21:14                                 ` Rafael J. Wysocki
2017-08-25  9:28               ` Ulf Hansson
2017-08-25  9:28                 ` Ulf Hansson
2017-08-25 12:23                 ` Rafael J. Wysocki
2017-08-25 12:23                   ` Rafael J. Wysocki
2017-08-24  8:19     ` Ulf Hansson
2017-08-24  8:19       ` Ulf Hansson
2017-08-24 14:57       ` Rafael J. Wysocki
2017-08-24 14:57         ` Rafael J. Wysocki
2017-08-25  9:04         ` Ulf Hansson
2017-08-25  9:04           ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 6/9] PM / ACPI: Enable the runtime PM centric approach for system sleep Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 7/9] PM / ACPI: Avoid runtime resuming device in acpi_subsys_suspend|freeze() Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 8/9] i2c: designware: Don't resume device in the ->complete() callback Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-23 14:42 ` [PATCH v2 9/9] i2c: designware: Deploy the runtime PM centric approach for system sleep Ulf Hansson
2017-08-23 14:42   ` Ulf Hansson
2017-08-25 14:10 ` [PATCH v2 0/9] PM / ACPI / i2c: Deploy runtime PM centric path " Jarkko Nikula
2017-08-25 14:10   ` Jarkko Nikula
2017-08-29  0:18 ` [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling Rafael J. Wysocki
2017-08-29  0:18   ` Rafael J. Wysocki
2017-08-29  0:20   ` [PATCH 1/3] PM / core: Add SAFE_SUSPEND driver flag Rafael J. Wysocki
2017-08-29  0:20     ` Rafael J. Wysocki
2017-08-29 14:57     ` Ulf Hansson
2017-08-29 14:57       ` Ulf Hansson
2017-08-29 15:02       ` Rafael J. Wysocki
2017-08-29 15:02         ` Rafael J. Wysocki
2017-08-29  0:59   ` [PATCH 2/3] PM / ACPI: Use SAFE_SUSPEND in the generic ACPI PM domain Rafael J. Wysocki
2017-08-29  0:59     ` Rafael J. Wysocki
2017-08-29  0:59   ` [PATCH 3/3] PM: i2c-designware-platdrv: System sleep handling rework Rafael J. Wysocki
2017-08-29  0:59     ` Rafael J. Wysocki
2017-08-29 16:38     ` Rafael J. Wysocki
2017-08-29 16:38       ` Rafael J. Wysocki
2017-08-29 16:40       ` Rafael J. Wysocki
2017-08-29 16:40         ` Rafael J. Wysocki
2017-08-29 10:29   ` [PATCH 0/3] PM / ACPI / i2c: Runtime PM aware system sleep handling Johannes Stezenbach
2017-08-29 10:29     ` Johannes Stezenbach
2017-08-29 11:44     ` Ulf Hansson
2017-08-29 11:44       ` Ulf Hansson
2017-08-29 13:53       ` Johannes Stezenbach
2017-08-29 13:53         ` Johannes Stezenbach
2017-08-29 14:43       ` Rafael J. Wysocki
2017-08-29 14:43         ` Rafael J. Wysocki
2017-08-29 15:05         ` Ulf Hansson
2017-08-29 15:05           ` Ulf Hansson
2017-08-29 16:44           ` Rafael J. Wysocki
2017-08-29 16:44             ` Rafael J. Wysocki
2017-08-29 14:49     ` Rafael J. Wysocki
2017-08-29 14:49       ` Rafael J. Wysocki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.