Linux-HyperV Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early()
@ 2019-10-14 23:00 Bjorn Helgaas
  2019-10-14 23:00 ` [PATCH 1/7] PCI/PM: Always return devices to D0 when thawing Bjorn Helgaas
                   ` (8 more replies)
  0 siblings, 9 replies; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

From: Bjorn Helgaas <bhelgaas@google.com>

Dexuan, the important thing here is the first patch, which is your [1],
which I modified by doing pci_restore_state() as well as setting to D0:

  pci_set_power_state(pci_dev, PCI_D0);
  pci_restore_state(pci_dev);

I'm proposing some more patches on top.  None are relevant to the problem
you're solving; they're just minor doc and other updates in the same area.

Rafael, if you have a chance to look at these, I'd appreciate it.  I tried
to make the doc match the code, but I'm no PM expert.

[1] https://lore.kernel.org/r/KU1P153MB016637CAEAD346F0AA8E3801BFAD0@KU1P153MB0166.APCP153.PROD.OUTLOOK.COM


Dexuan Cui (1):
  PCI/PM: Always return devices to D0 when thawing

Bjorn Helgaas (6):
  PCI/PM: Correct pci_pm_thaw_noirq() documentation
  PCI/PM: Clear PCIe PME Status even for legacy power management
  PCI/PM: Run resume fixups before disabling wakeup events
  PCI/PM: Make power management op coding style consistent
  PCI/PM: Wrap long lines in documentation
  PCI/MSI: Move power state check out of pci_msi_supported()

 Documentation/power/pci.rst | 38 +++++++-------
 drivers/pci/msi.c           |  6 +--
 drivers/pci/pci-driver.c    | 99 ++++++++++++++++++-------------------
 3 files changed, 71 insertions(+), 72 deletions(-)

-- 
2.23.0.700.g56cf767bdb-goog


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

* [PATCH 1/7] PCI/PM: Always return devices to D0 when thawing
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
@ 2019-10-14 23:00 ` Bjorn Helgaas
  2019-10-15 17:15   ` Rafael J. Wysocki
  2019-10-14 23:00 ` [PATCH 2/7] PCI/PM: Correct pci_pm_thaw_noirq() documentation Bjorn Helgaas
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas,
	stable

From: Dexuan Cui <decui@microsoft.com>

pci_pm_thaw_noirq() is supposed to return the device to D0 and restore its
configuration registers, but previously it only did that for devices whose
drivers implemented the new power management ops.

Hibernation, e.g., via "echo disk > /sys/power/state", involves freezing
devices, creating a hibernation image, thawing devices, writing the image,
and powering off.  The fact that thawing did not return devices with legacy
power management to D0 caused errors, e.g., in this path:

  pci_pm_thaw_noirq
    if (pci_has_legacy_pm_support(pci_dev)) # true for Mellanox VF driver
      return pci_legacy_resume_early(dev)   # ... legacy PM skips the rest
    pci_set_power_state(pci_dev, PCI_D0)
    pci_restore_state(pci_dev)
  pci_pm_thaw
    if (pci_has_legacy_pm_support(pci_dev))
      pci_legacy_resume
	drv->resume
	  mlx4_resume
	    ...
	      pci_enable_msix_range
	        ...
		  if (dev->current_state != PCI_D0)  # <---
		    return -EINVAL;

which caused these warnings:

  mlx4_core a6d1:00:02.0: INTx is not supported in multi-function mode, aborting
  PM: dpm_run_callback(): pci_pm_thaw+0x0/0xd7 returns -95
  PM: Device a6d1:00:02.0 failed to thaw: error -95

Return devices to D0 and restore config registers for all devices, not just
those whose drivers support new power management.

[bhelgaas: also call pci_restore_state() before pci_legacy_resume_early(),
update comment, add stable tag, commit log]
Link: https://lore.kernel.org/r/KU1P153MB016637CAEAD346F0AA8E3801BFAD0@KU1P153MB0166.APCP153.PROD.OUTLOOK.COM
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org	# v4.13+
---
 drivers/pci/pci-driver.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index a8124e47bf6e..d4ac8ce8c1f9 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1076,17 +1076,22 @@ static int pci_pm_thaw_noirq(struct device *dev)
 			return error;
 	}
 
-	if (pci_has_legacy_pm_support(pci_dev))
-		return pci_legacy_resume_early(dev);
-
 	/*
-	 * pci_restore_state() requires the device to be in D0 (because of MSI
-	 * restoration among other things), so force it into D0 in case the
-	 * driver's "freeze" callbacks put it into a low-power state directly.
+	 * Both the legacy ->resume_early() and the new pm->thaw_noirq()
+	 * callbacks assume the device has been returned to D0 and its
+	 * config state has been restored.
+	 *
+	 * In addition, pci_restore_state() restores MSI-X state in MMIO
+	 * space, which requires the device to be in D0, so return it to D0
+	 * in case the driver's "freeze" callbacks put it into a low-power
+	 * state.
 	 */
 	pci_set_power_state(pci_dev, PCI_D0);
 	pci_restore_state(pci_dev);
 
+	if (pci_has_legacy_pm_support(pci_dev))
+		return pci_legacy_resume_early(dev);
+
 	if (drv && drv->pm && drv->pm->thaw_noirq)
 		error = drv->pm->thaw_noirq(dev);
 
-- 
2.23.0.700.g56cf767bdb-goog


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

* [PATCH 2/7] PCI/PM: Correct pci_pm_thaw_noirq() documentation
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
  2019-10-14 23:00 ` [PATCH 1/7] PCI/PM: Always return devices to D0 when thawing Bjorn Helgaas
@ 2019-10-14 23:00 ` Bjorn Helgaas
  2019-10-15 17:17   ` Rafael J. Wysocki
  2019-10-14 23:00 ` [PATCH 3/7] PCI/PM: Clear PCIe PME Status even for legacy power management Bjorn Helgaas
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

From: Bjorn Helgaas <bhelgaas@google.com>

According to the documentation, pci_pm_thaw_noirq() did not put the device
into the full-power state and restore its standard configuration registers.
This is incorrect, so update the documentation to match the code.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 Documentation/power/pci.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/power/pci.rst b/Documentation/power/pci.rst
index 0e2ef7429304..1525c594d631 100644
--- a/Documentation/power/pci.rst
+++ b/Documentation/power/pci.rst
@@ -600,17 +600,17 @@ using the following PCI bus type's callbacks::
 
 respectively.
 
-The first of them, pci_pm_thaw_noirq(), is analogous to pci_pm_resume_noirq(),
-but it doesn't put the device into the full power state and doesn't attempt to
-restore its standard configuration registers.  It also executes the device
-driver's pm->thaw_noirq() callback, if defined, instead of pm->resume_noirq().
+The first of them, pci_pm_thaw_noirq(), is analogous to pci_pm_resume_noirq().
+It puts the device into the full power state and restores its standard
+configuration registers.  It also executes the device driver's pm->thaw_noirq()
+callback, if defined, instead of pm->resume_noirq().
 
 The pci_pm_thaw() routine is similar to pci_pm_resume(), but it runs the device
 driver's pm->thaw() callback instead of pm->resume().  It is executed
 asynchronously for different PCI devices that don't depend on each other in a
 known way.
 
-The complete phase it the same as for system resume.
+The complete phase is the same as for system resume.
 
 After saving the image, devices need to be powered down before the system can
 enter the target sleep state (ACPI S4 for ACPI-based systems).  This is done in
-- 
2.23.0.700.g56cf767bdb-goog


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

* [PATCH 3/7] PCI/PM: Clear PCIe PME Status even for legacy power management
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
  2019-10-14 23:00 ` [PATCH 1/7] PCI/PM: Always return devices to D0 when thawing Bjorn Helgaas
  2019-10-14 23:00 ` [PATCH 2/7] PCI/PM: Correct pci_pm_thaw_noirq() documentation Bjorn Helgaas
@ 2019-10-14 23:00 ` Bjorn Helgaas
  2019-10-15 17:20   ` Rafael J. Wysocki
  2019-10-14 23:00 ` [PATCH 4/7] PCI/PM: Run resume fixups before disabling wakeup events Bjorn Helgaas
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

From: Bjorn Helgaas <bhelgaas@google.com>

Previously, pci_pm_resume_noirq() cleared the PME Status bit in the Root
Status register only if the device had no driver or the driver did not
implement legacy power management.  It should clear PME Status regardless
of what sort of power management the driver supports, so do this before
checking for legacy power management.

This affects Root Ports and Root Complex Event Collectors, for which the
usual driver is the PCIe portdrv, which implements new power management, so
this change is just on principle, not to fix any actual defects.

Fixes: a39bd851dccf ("PCI/PM: Clear PCIe PME Status bit in core, not PCIe port driver")
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-driver.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index d4ac8ce8c1f9..0c3086793e4e 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -941,12 +941,11 @@ static int pci_pm_resume_noirq(struct device *dev)
 		pci_pm_default_resume_early(pci_dev);
 
 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
+	pcie_pme_root_status_cleanup(pci_dev);
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume_early(dev);
 
-	pcie_pme_root_status_cleanup(pci_dev);
-
 	if (drv && drv->pm && drv->pm->resume_noirq)
 		error = drv->pm->resume_noirq(dev);
 
-- 
2.23.0.700.g56cf767bdb-goog


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

* [PATCH 4/7] PCI/PM: Run resume fixups before disabling wakeup events
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
                   ` (2 preceding siblings ...)
  2019-10-14 23:00 ` [PATCH 3/7] PCI/PM: Clear PCIe PME Status even for legacy power management Bjorn Helgaas
@ 2019-10-14 23:00 ` Bjorn Helgaas
  2019-10-15 17:21   ` Rafael J. Wysocki
  2019-10-14 23:00 ` [PATCH 5/7] PCI/PM: Make power management op coding style consistent Bjorn Helgaas
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

From: Bjorn Helgaas <bhelgaas@google.com>

pci_pm_resume() and pci_pm_restore() call pci_pm_default_resume(), which
runs resume fixups before disabling wakeup events:

  static void pci_pm_default_resume(struct pci_dev *pci_dev)
  {
    pci_fixup_device(pci_fixup_resume, pci_dev);
    pci_enable_wake(pci_dev, PCI_D0, false);
  }

pci_pm_runtime_resume() does both of these, but in the opposite order:

  pci_enable_wake(pci_dev, PCI_D0, false);
  pci_fixup_device(pci_fixup_resume, pci_dev);

We should always use the same ordering unless there's a reason to do
otherwise.  Change pci_pm_runtime_resume() to call pci_pm_default_resume()
instead of open-coding this, so the fixups are always done before disabling
wakeup events.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-driver.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 0c3086793e4e..55acb658273f 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1345,8 +1345,7 @@ static int pci_pm_runtime_resume(struct device *dev)
 		return 0;
 
 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
-	pci_enable_wake(pci_dev, PCI_D0, false);
-	pci_fixup_device(pci_fixup_resume, pci_dev);
+	pci_pm_default_resume(pci_dev);
 
 	if (pm && pm->runtime_resume)
 		rc = pm->runtime_resume(dev);
-- 
2.23.0.700.g56cf767bdb-goog


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

* [PATCH 5/7] PCI/PM: Make power management op coding style consistent
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
                   ` (3 preceding siblings ...)
  2019-10-14 23:00 ` [PATCH 4/7] PCI/PM: Run resume fixups before disabling wakeup events Bjorn Helgaas
@ 2019-10-14 23:00 ` Bjorn Helgaas
  2019-10-15 17:22   ` Rafael J. Wysocki
  2019-10-16 13:50   ` Dan Carpenter
  2019-10-14 23:00 ` [PATCH 6/7] PCI/PM: Wrap long lines in documentation Bjorn Helgaas
                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

From: Bjorn Helgaas <bhelgaas@google.com>

Some of the power management ops use this style:

  struct device_driver *drv = dev->driver;
  if (drv && drv->pm && drv->pm->prepare(dev))
    drv->pm->prepare(dev);

while others use this:

  const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
  if (pm && pm->runtime_resume)
    pm->runtime_resume(dev);

Convert the first style to the second so they're all consistent.  Remove
local "error" variables when unnecessary.  No functional change intended.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-driver.c | 76 +++++++++++++++++++---------------------
 1 file changed, 36 insertions(+), 40 deletions(-)

diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 55acb658273f..abbf5c39cb9c 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -679,11 +679,11 @@ static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
 
 static int pci_pm_prepare(struct device *dev)
 {
-	struct device_driver *drv = dev->driver;
 	struct pci_dev *pci_dev = to_pci_dev(dev);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
-	if (drv && drv->pm && drv->pm->prepare) {
-		int error = drv->pm->prepare(dev);
+	if (pm && pm->prepare) {
+		int error = pm->prepare(dev);
 		if (error < 0)
 			return error;
 
@@ -917,8 +917,7 @@ static int pci_pm_suspend_noirq(struct device *dev)
 static int pci_pm_resume_noirq(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
-	int error = 0;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (dev_pm_may_skip_resume(dev))
 		return 0;
@@ -946,17 +945,16 @@ static int pci_pm_resume_noirq(struct device *dev)
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume_early(dev);
 
-	if (drv && drv->pm && drv->pm->resume_noirq)
-		error = drv->pm->resume_noirq(dev);
+	if (pm && pm->resume_noirq)
+		return pm->resume_noirq(dev);
 
-	return error;
+	return 0;
 }
 
 static int pci_pm_resume(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int error = 0;
 
 	/*
 	 * This is necessary for the suspend error path in which resume is
@@ -972,12 +970,12 @@ static int pci_pm_resume(struct device *dev)
 
 	if (pm) {
 		if (pm->resume)
-			error = pm->resume(dev);
+			return pm->resume(dev);
 	} else {
 		pci_pm_reenable_device(pci_dev);
 	}
 
-	return error;
+	return 0;
 }
 
 #else /* !CONFIG_SUSPEND */
@@ -1038,16 +1036,16 @@ static int pci_pm_freeze(struct device *dev)
 static int pci_pm_freeze_noirq(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend_late(dev, PMSG_FREEZE);
 
-	if (drv && drv->pm && drv->pm->freeze_noirq) {
+	if (pm && pm->freeze_noirq) {
 		int error;
 
-		error = drv->pm->freeze_noirq(dev);
-		suspend_report_result(drv->pm->freeze_noirq, error);
+		error = pm->freeze_noirq(dev);
+		suspend_report_result(pm->freeze_noirq, error);
 		if (error)
 			return error;
 	}
@@ -1066,8 +1064,8 @@ static int pci_pm_freeze_noirq(struct device *dev)
 static int pci_pm_thaw_noirq(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
-	int error = 0;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int error;
 
 	if (pcibios_pm_ops.thaw_noirq) {
 		error = pcibios_pm_ops.thaw_noirq(dev);
@@ -1091,10 +1089,10 @@ static int pci_pm_thaw_noirq(struct device *dev)
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume_early(dev);
 
-	if (drv && drv->pm && drv->pm->thaw_noirq)
-		error = drv->pm->thaw_noirq(dev);
+	if (pm && pm->thaw_noirq)
+		return pm->thaw_noirq(dev);
 
-	return error;
+	return 0;
 }
 
 static int pci_pm_thaw(struct device *dev)
@@ -1165,24 +1163,24 @@ static int pci_pm_poweroff_late(struct device *dev)
 static int pci_pm_poweroff_noirq(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (dev_pm_smart_suspend_and_suspended(dev))
 		return 0;
 
-	if (pci_has_legacy_pm_support(to_pci_dev(dev)))
+	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
 
-	if (!drv || !drv->pm) {
+	if (!pm) {
 		pci_fixup_device(pci_fixup_suspend_late, pci_dev);
 		return 0;
 	}
 
-	if (drv->pm->poweroff_noirq) {
+	if (pm->poweroff_noirq) {
 		int error;
 
-		error = drv->pm->poweroff_noirq(dev);
-		suspend_report_result(drv->pm->poweroff_noirq, error);
+		error = pm->poweroff_noirq(dev);
+		suspend_report_result(pm->poweroff_noirq, error);
 		if (error)
 			return error;
 	}
@@ -1208,8 +1206,8 @@ static int pci_pm_poweroff_noirq(struct device *dev)
 static int pci_pm_restore_noirq(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct device_driver *drv = dev->driver;
-	int error = 0;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int error;
 
 	if (pcibios_pm_ops.restore_noirq) {
 		error = pcibios_pm_ops.restore_noirq(dev);
@@ -1223,17 +1221,16 @@ static int pci_pm_restore_noirq(struct device *dev)
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_resume_early(dev);
 
-	if (drv && drv->pm && drv->pm->restore_noirq)
-		error = drv->pm->restore_noirq(dev);
+	if (pm && pm->restore_noirq)
+		return pm->restore_noirq(dev);
 
-	return error;
+	return 0;
 }
 
 static int pci_pm_restore(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int error = 0;
 
 	/*
 	 * This is necessary for the hibernation error path in which restore is
@@ -1249,12 +1246,12 @@ static int pci_pm_restore(struct device *dev)
 
 	if (pm) {
 		if (pm->restore)
-			error = pm->restore(dev);
+			return pm->restore(dev);
 	} else {
 		pci_pm_reenable_device(pci_dev);
 	}
 
-	return error;
+	return 0;
 }
 
 #else /* !CONFIG_HIBERNATE_CALLBACKS */
@@ -1330,9 +1327,9 @@ static int pci_pm_runtime_suspend(struct device *dev)
 
 static int pci_pm_runtime_resume(struct device *dev)
 {
-	int rc = 0;
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	int error = 0;
 
 	/*
 	 * Restoring config space is necessary even if the device is not bound
@@ -1348,18 +1345,17 @@ static int pci_pm_runtime_resume(struct device *dev)
 	pci_pm_default_resume(pci_dev);
 
 	if (pm && pm->runtime_resume)
-		rc = pm->runtime_resume(dev);
+		error = pm->runtime_resume(dev);
 
 	pci_dev->runtime_d3cold = false;
 
-	return rc;
+	return error;
 }
 
 static int pci_pm_runtime_idle(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int ret = 0;
 
 	/*
 	 * If pci_dev->driver is not set (unbound), the device should
@@ -1372,9 +1368,9 @@ static int pci_pm_runtime_idle(struct device *dev)
 		return -ENOSYS;
 
 	if (pm->runtime_idle)
-		ret = pm->runtime_idle(dev);
+		return pm->runtime_idle(dev);
 
-	return ret;
+	return 0;
 }
 
 static const struct dev_pm_ops pci_dev_pm_ops = {
-- 
2.23.0.700.g56cf767bdb-goog


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

* [PATCH 6/7] PCI/PM: Wrap long lines in documentation
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
                   ` (4 preceding siblings ...)
  2019-10-14 23:00 ` [PATCH 5/7] PCI/PM: Make power management op coding style consistent Bjorn Helgaas
@ 2019-10-14 23:00 ` Bjorn Helgaas
  2019-10-15 17:23   ` Rafael J. Wysocki
  2019-10-14 23:00 ` [PATCH 7/7] PCI/MSI: Move power state check out of pci_msi_supported() Bjorn Helgaas
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

From: Bjorn Helgaas <bhelgaas@google.com>

Documentation/power/pci.rst is wrapped to fit in 80 columns, but directory
structure changes made a few lines longer.  Wrap them so they all fit in 80
columns again.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 Documentation/power/pci.rst | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/Documentation/power/pci.rst b/Documentation/power/pci.rst
index 1525c594d631..db41a770a2f5 100644
--- a/Documentation/power/pci.rst
+++ b/Documentation/power/pci.rst
@@ -426,12 +426,12 @@ pm->runtime_idle() callback.
 2.4. System-Wide Power Transitions
 ----------------------------------
 There are a few different types of system-wide power transitions, described in
-Documentation/driver-api/pm/devices.rst.  Each of them requires devices to be handled
-in a specific way and the PM core executes subsystem-level power management
-callbacks for this purpose.  They are executed in phases such that each phase
-involves executing the same subsystem-level callback for every device belonging
-to the given subsystem before the next phase begins.  These phases always run
-after tasks have been frozen.
+Documentation/driver-api/pm/devices.rst.  Each of them requires devices to be
+handled in a specific way and the PM core executes subsystem-level power
+management callbacks for this purpose.  They are executed in phases such that
+each phase involves executing the same subsystem-level callback for every device
+belonging to the given subsystem before the next phase begins.  These phases
+always run after tasks have been frozen.
 
 2.4.1. System Suspend
 ^^^^^^^^^^^^^^^^^^^^^
@@ -636,12 +636,12 @@ System restore requires a hibernation image to be loaded into memory and the
 pre-hibernation memory contents to be restored before the pre-hibernation system
 activity can be resumed.
 
-As described in Documentation/driver-api/pm/devices.rst, the hibernation image is loaded
-into memory by a fresh instance of the kernel, called the boot kernel, which in
-turn is loaded and run by a boot loader in the usual way.  After the boot kernel
-has loaded the image, it needs to replace its own code and data with the code
-and data of the "hibernated" kernel stored within the image, called the image
-kernel.  For this purpose all devices are frozen just like before creating
+As described in Documentation/driver-api/pm/devices.rst, the hibernation image
+is loaded into memory by a fresh instance of the kernel, called the boot kernel,
+which in turn is loaded and run by a boot loader in the usual way.  After the
+boot kernel has loaded the image, it needs to replace its own code and data with
+the code and data of the "hibernated" kernel stored within the image, called the
+image kernel.  For this purpose all devices are frozen just like before creating
 the image during hibernation, in the
 
 	prepare, freeze, freeze_noirq
@@ -691,8 +691,8 @@ controlling the runtime power management of their devices.
 
 At the time of this writing there are two ways to define power management
 callbacks for a PCI device driver, the recommended one, based on using a
-dev_pm_ops structure described in Documentation/driver-api/pm/devices.rst, and the
-"legacy" one, in which the .suspend(), .suspend_late(), .resume_early(), and
+dev_pm_ops structure described in Documentation/driver-api/pm/devices.rst, and
+the "legacy" one, in which the .suspend(), .suspend_late(), .resume_early(), and
 .resume() callbacks from struct pci_driver are used.  The legacy approach,
 however, doesn't allow one to define runtime power management callbacks and is
 not really suitable for any new drivers.  Therefore it is not covered by this
-- 
2.23.0.700.g56cf767bdb-goog


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

* [PATCH 7/7] PCI/MSI: Move power state check out of pci_msi_supported()
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
                   ` (5 preceding siblings ...)
  2019-10-14 23:00 ` [PATCH 6/7] PCI/PM: Wrap long lines in documentation Bjorn Helgaas
@ 2019-10-14 23:00 ` Bjorn Helgaas
  2019-10-15 17:24   ` Rafael J. Wysocki
  2019-10-15 18:24 ` [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Dexuan Cui
  2019-10-15 18:42 ` Bjorn Helgaas
  8 siblings, 1 reply; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-14 23:00 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

From: Bjorn Helgaas <bhelgaas@google.com>

27e20603c54b ("PCI/MSI: Move D0 check into pci_msi_check_device()")
moved the power state check into pci_msi_check_device(), which was
subsequently renamed to pci_msi_supported().  This didn't change the
behavior, since both callers checked the power state.

However, it doesn't fit the current "pci_msi_supported()" name, which
should return what the device is capable of, independent of the power
state.

Move the power state check back into the callers for readability.  No
functional change intended.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/msi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 0884bedcfc7a..20e9c729617c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -861,7 +861,7 @@ static int pci_msi_supported(struct pci_dev *dev, int nvec)
 	if (!pci_msi_enable)
 		return 0;
 
-	if (!dev || dev->no_msi || dev->current_state != PCI_D0)
+	if (!dev || dev->no_msi)
 		return 0;
 
 	/*
@@ -972,7 +972,7 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
 	int nr_entries;
 	int i, j;
 
-	if (!pci_msi_supported(dev, nvec))
+	if (!pci_msi_supported(dev, nvec) || dev->current_state != PCI_D0)
 		return -EINVAL;
 
 	nr_entries = pci_msix_vec_count(dev);
@@ -1058,7 +1058,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
 	int nvec;
 	int rc;
 
-	if (!pci_msi_supported(dev, minvec))
+	if (!pci_msi_supported(dev, minvec) || dev->current_state != PCI_D0)
 		return -EINVAL;
 
 	/* Check whether driver already requested MSI-X IRQs */
-- 
2.23.0.700.g56cf767bdb-goog


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

* Re: [PATCH 1/7] PCI/PM: Always return devices to D0 when thawing
  2019-10-14 23:00 ` [PATCH 1/7] PCI/PM: Always return devices to D0 when thawing Bjorn Helgaas
@ 2019-10-15 17:15   ` Rafael J. Wysocki
  0 siblings, 0 replies; 18+ messages in thread
From: Rafael J. Wysocki @ 2019-10-15 17:15 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, Rafael J . Wysocki, Lorenzo Pieralisi,
	Michael Kelley, Sasha Levin, Haiyang Zhang, KY Srinivasan,
	Stephen Hemminger, olaf, apw, jasowang, vkuznets, marcelo.cerri,
	jackm, linux-pci, linux-hyperv, linux-kernel, driverdev-devel,
	Bjorn Helgaas, Linux PM

On Tuesday, October 15, 2019 1:00:10 AM CEST Bjorn Helgaas wrote:
> From: Dexuan Cui <decui@microsoft.com>
> 
> pci_pm_thaw_noirq() is supposed to return the device to D0 and restore its
> configuration registers, but previously it only did that for devices whose
> drivers implemented the new power management ops.
> 
> Hibernation, e.g., via "echo disk > /sys/power/state", involves freezing
> devices, creating a hibernation image, thawing devices, writing the image,
> and powering off.  The fact that thawing did not return devices with legacy
> power management to D0 caused errors, e.g., in this path:
> 
>   pci_pm_thaw_noirq
>     if (pci_has_legacy_pm_support(pci_dev)) # true for Mellanox VF driver
>       return pci_legacy_resume_early(dev)   # ... legacy PM skips the rest
>     pci_set_power_state(pci_dev, PCI_D0)
>     pci_restore_state(pci_dev)
>   pci_pm_thaw
>     if (pci_has_legacy_pm_support(pci_dev))
>       pci_legacy_resume
> 	drv->resume
> 	  mlx4_resume
> 	    ...
> 	      pci_enable_msix_range
> 	        ...
> 		  if (dev->current_state != PCI_D0)  # <---
> 		    return -EINVAL;
> 
> which caused these warnings:
> 
>   mlx4_core a6d1:00:02.0: INTx is not supported in multi-function mode, aborting
>   PM: dpm_run_callback(): pci_pm_thaw+0x0/0xd7 returns -95
>   PM: Device a6d1:00:02.0 failed to thaw: error -95
> 
> Return devices to D0 and restore config registers for all devices, not just
> those whose drivers support new power management.
> 
> [bhelgaas: also call pci_restore_state() before pci_legacy_resume_early(),
> update comment, add stable tag, commit log]
> Link: https://lore.kernel.org/r/KU1P153MB016637CAEAD346F0AA8E3801BFAD0@KU1P153MB0166.APCP153.PROD.OUTLOOK.COM
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> Cc: stable@vger.kernel.org	# v4.13+

No issues found, so

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

> ---
>  drivers/pci/pci-driver.c | 17 +++++++++++------
>  1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index a8124e47bf6e..d4ac8ce8c1f9 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -1076,17 +1076,22 @@ static int pci_pm_thaw_noirq(struct device *dev)
>  			return error;
>  	}
>  
> -	if (pci_has_legacy_pm_support(pci_dev))
> -		return pci_legacy_resume_early(dev);
> -
>  	/*
> -	 * pci_restore_state() requires the device to be in D0 (because of MSI
> -	 * restoration among other things), so force it into D0 in case the
> -	 * driver's "freeze" callbacks put it into a low-power state directly.
> +	 * Both the legacy ->resume_early() and the new pm->thaw_noirq()
> +	 * callbacks assume the device has been returned to D0 and its
> +	 * config state has been restored.
> +	 *
> +	 * In addition, pci_restore_state() restores MSI-X state in MMIO
> +	 * space, which requires the device to be in D0, so return it to D0
> +	 * in case the driver's "freeze" callbacks put it into a low-power
> +	 * state.
>  	 */
>  	pci_set_power_state(pci_dev, PCI_D0);
>  	pci_restore_state(pci_dev);
>  
> +	if (pci_has_legacy_pm_support(pci_dev))
> +		return pci_legacy_resume_early(dev);
> +
>  	if (drv && drv->pm && drv->pm->thaw_noirq)
>  		error = drv->pm->thaw_noirq(dev);
>  
> 





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

* Re: [PATCH 2/7] PCI/PM: Correct pci_pm_thaw_noirq() documentation
  2019-10-14 23:00 ` [PATCH 2/7] PCI/PM: Correct pci_pm_thaw_noirq() documentation Bjorn Helgaas
@ 2019-10-15 17:17   ` Rafael J. Wysocki
  0 siblings, 0 replies; 18+ messages in thread
From: Rafael J. Wysocki @ 2019-10-15 17:17 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, Rafael J . Wysocki, Lorenzo Pieralisi,
	Michael Kelley, Sasha Levin, Haiyang Zhang, KY Srinivasan,
	Stephen Hemminger, olaf, apw, jasowang, vkuznets, marcelo.cerri,
	jackm, linux-pci, linux-hyperv, linux-kernel, driverdev-devel,
	Bjorn Helgaas

On Tuesday, October 15, 2019 1:00:11 AM CEST Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> According to the documentation, pci_pm_thaw_noirq() did not put the device
> into the full-power state and restore its standard configuration registers.
> This is incorrect, so update the documentation to match the code.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

Right, the documentation is outdated, so

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

> ---
>  Documentation/power/pci.rst | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/power/pci.rst b/Documentation/power/pci.rst
> index 0e2ef7429304..1525c594d631 100644
> --- a/Documentation/power/pci.rst
> +++ b/Documentation/power/pci.rst
> @@ -600,17 +600,17 @@ using the following PCI bus type's callbacks::
>  
>  respectively.
>  
> -The first of them, pci_pm_thaw_noirq(), is analogous to pci_pm_resume_noirq(),
> -but it doesn't put the device into the full power state and doesn't attempt to
> -restore its standard configuration registers.  It also executes the device
> -driver's pm->thaw_noirq() callback, if defined, instead of pm->resume_noirq().
> +The first of them, pci_pm_thaw_noirq(), is analogous to pci_pm_resume_noirq().
> +It puts the device into the full power state and restores its standard
> +configuration registers.  It also executes the device driver's pm->thaw_noirq()
> +callback, if defined, instead of pm->resume_noirq().
>  
>  The pci_pm_thaw() routine is similar to pci_pm_resume(), but it runs the device
>  driver's pm->thaw() callback instead of pm->resume().  It is executed
>  asynchronously for different PCI devices that don't depend on each other in a
>  known way.
>  
> -The complete phase it the same as for system resume.
> +The complete phase is the same as for system resume.
>  
>  After saving the image, devices need to be powered down before the system can
>  enter the target sleep state (ACPI S4 for ACPI-based systems).  This is done in
> 





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

* Re: [PATCH 3/7] PCI/PM: Clear PCIe PME Status even for legacy power management
  2019-10-14 23:00 ` [PATCH 3/7] PCI/PM: Clear PCIe PME Status even for legacy power management Bjorn Helgaas
@ 2019-10-15 17:20   ` Rafael J. Wysocki
  0 siblings, 0 replies; 18+ messages in thread
From: Rafael J. Wysocki @ 2019-10-15 17:20 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, Rafael J . Wysocki, Lorenzo Pieralisi,
	Michael Kelley, Sasha Levin, Haiyang Zhang, KY Srinivasan,
	Stephen Hemminger, olaf, apw, jasowang, vkuznets, marcelo.cerri,
	jackm, linux-pci, linux-hyperv, linux-kernel, driverdev-devel,
	Bjorn Helgaas

On Tuesday, October 15, 2019 1:00:12 AM CEST Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> Previously, pci_pm_resume_noirq() cleared the PME Status bit in the Root
> Status register only if the device had no driver or the driver did not
> implement legacy power management.  It should clear PME Status regardless
> of what sort of power management the driver supports, so do this before
> checking for legacy power management.
> 
> This affects Root Ports and Root Complex Event Collectors, for which the
> usual driver is the PCIe portdrv, which implements new power management, so
> this change is just on principle, not to fix any actual defects.
> 
> Fixes: a39bd851dccf ("PCI/PM: Clear PCIe PME Status bit in core, not PCIe port driver")
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

This is a reasonable change in my view, so

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

> ---
>  drivers/pci/pci-driver.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index d4ac8ce8c1f9..0c3086793e4e 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -941,12 +941,11 @@ static int pci_pm_resume_noirq(struct device *dev)
>  		pci_pm_default_resume_early(pci_dev);
>  
>  	pci_fixup_device(pci_fixup_resume_early, pci_dev);
> +	pcie_pme_root_status_cleanup(pci_dev);
>  
>  	if (pci_has_legacy_pm_support(pci_dev))
>  		return pci_legacy_resume_early(dev);
>  
> -	pcie_pme_root_status_cleanup(pci_dev);
> -
>  	if (drv && drv->pm && drv->pm->resume_noirq)
>  		error = drv->pm->resume_noirq(dev);
>  
> 





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

* Re: [PATCH 4/7] PCI/PM: Run resume fixups before disabling wakeup events
  2019-10-14 23:00 ` [PATCH 4/7] PCI/PM: Run resume fixups before disabling wakeup events Bjorn Helgaas
@ 2019-10-15 17:21   ` Rafael J. Wysocki
  0 siblings, 0 replies; 18+ messages in thread
From: Rafael J. Wysocki @ 2019-10-15 17:21 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, Rafael J . Wysocki, Lorenzo Pieralisi,
	Michael Kelley, Sasha Levin, Haiyang Zhang, KY Srinivasan,
	Stephen Hemminger, olaf, apw, jasowang, vkuznets, marcelo.cerri,
	jackm, linux-pci, linux-hyperv, linux-kernel, driverdev-devel,
	Bjorn Helgaas

On Tuesday, October 15, 2019 1:00:13 AM CEST Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> pci_pm_resume() and pci_pm_restore() call pci_pm_default_resume(), which
> runs resume fixups before disabling wakeup events:
> 
>   static void pci_pm_default_resume(struct pci_dev *pci_dev)
>   {
>     pci_fixup_device(pci_fixup_resume, pci_dev);
>     pci_enable_wake(pci_dev, PCI_D0, false);
>   }
> 
> pci_pm_runtime_resume() does both of these, but in the opposite order:
> 
>   pci_enable_wake(pci_dev, PCI_D0, false);
>   pci_fixup_device(pci_fixup_resume, pci_dev);
> 
> We should always use the same ordering unless there's a reason to do
> otherwise.

Right.

> Change pci_pm_runtime_resume() to call pci_pm_default_resume()
> instead of open-coding this, so the fixups are always done before disabling
> wakeup events.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

No concerns about this change, so

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

> ---
>  drivers/pci/pci-driver.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index 0c3086793e4e..55acb658273f 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -1345,8 +1345,7 @@ static int pci_pm_runtime_resume(struct device *dev)
>  		return 0;
>  
>  	pci_fixup_device(pci_fixup_resume_early, pci_dev);
> -	pci_enable_wake(pci_dev, PCI_D0, false);
> -	pci_fixup_device(pci_fixup_resume, pci_dev);
> +	pci_pm_default_resume(pci_dev);
>  
>  	if (pm && pm->runtime_resume)
>  		rc = pm->runtime_resume(dev);
> 





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

* Re: [PATCH 5/7] PCI/PM: Make power management op coding style consistent
  2019-10-14 23:00 ` [PATCH 5/7] PCI/PM: Make power management op coding style consistent Bjorn Helgaas
@ 2019-10-15 17:22   ` Rafael J. Wysocki
  2019-10-16 13:50   ` Dan Carpenter
  1 sibling, 0 replies; 18+ messages in thread
From: Rafael J. Wysocki @ 2019-10-15 17:22 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, Rafael J . Wysocki, Lorenzo Pieralisi,
	Michael Kelley, Sasha Levin, Haiyang Zhang, KY Srinivasan,
	Stephen Hemminger, olaf, apw, jasowang, vkuznets, marcelo.cerri,
	jackm, linux-pci, linux-hyperv, linux-kernel, driverdev-devel,
	Bjorn Helgaas

On Tuesday, October 15, 2019 1:00:14 AM CEST Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> Some of the power management ops use this style:
> 
>   struct device_driver *drv = dev->driver;
>   if (drv && drv->pm && drv->pm->prepare(dev))
>     drv->pm->prepare(dev);
> 
> while others use this:
> 
>   const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>   if (pm && pm->runtime_resume)
>     pm->runtime_resume(dev);
> 
> Convert the first style to the second so they're all consistent.  Remove
> local "error" variables when unnecessary.  No functional change intended.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

No issues found, so

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

> ---
>  drivers/pci/pci-driver.c | 76 +++++++++++++++++++---------------------
>  1 file changed, 36 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index 55acb658273f..abbf5c39cb9c 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -679,11 +679,11 @@ static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
>  
>  static int pci_pm_prepare(struct device *dev)
>  {
> -	struct device_driver *drv = dev->driver;
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>  
> -	if (drv && drv->pm && drv->pm->prepare) {
> -		int error = drv->pm->prepare(dev);
> +	if (pm && pm->prepare) {
> +		int error = pm->prepare(dev);
>  		if (error < 0)
>  			return error;
>  
> @@ -917,8 +917,7 @@ static int pci_pm_suspend_noirq(struct device *dev)
>  static int pci_pm_resume_noirq(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> -	struct device_driver *drv = dev->driver;
> -	int error = 0;
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>  
>  	if (dev_pm_may_skip_resume(dev))
>  		return 0;
> @@ -946,17 +945,16 @@ static int pci_pm_resume_noirq(struct device *dev)
>  	if (pci_has_legacy_pm_support(pci_dev))
>  		return pci_legacy_resume_early(dev);
>  
> -	if (drv && drv->pm && drv->pm->resume_noirq)
> -		error = drv->pm->resume_noirq(dev);
> +	if (pm && pm->resume_noirq)
> +		return pm->resume_noirq(dev);
>  
> -	return error;
> +	return 0;
>  }
>  
>  static int pci_pm_resume(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
>  	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -	int error = 0;
>  
>  	/*
>  	 * This is necessary for the suspend error path in which resume is
> @@ -972,12 +970,12 @@ static int pci_pm_resume(struct device *dev)
>  
>  	if (pm) {
>  		if (pm->resume)
> -			error = pm->resume(dev);
> +			return pm->resume(dev);
>  	} else {
>  		pci_pm_reenable_device(pci_dev);
>  	}
>  
> -	return error;
> +	return 0;
>  }
>  
>  #else /* !CONFIG_SUSPEND */
> @@ -1038,16 +1036,16 @@ static int pci_pm_freeze(struct device *dev)
>  static int pci_pm_freeze_noirq(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> -	struct device_driver *drv = dev->driver;
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>  
>  	if (pci_has_legacy_pm_support(pci_dev))
>  		return pci_legacy_suspend_late(dev, PMSG_FREEZE);
>  
> -	if (drv && drv->pm && drv->pm->freeze_noirq) {
> +	if (pm && pm->freeze_noirq) {
>  		int error;
>  
> -		error = drv->pm->freeze_noirq(dev);
> -		suspend_report_result(drv->pm->freeze_noirq, error);
> +		error = pm->freeze_noirq(dev);
> +		suspend_report_result(pm->freeze_noirq, error);
>  		if (error)
>  			return error;
>  	}
> @@ -1066,8 +1064,8 @@ static int pci_pm_freeze_noirq(struct device *dev)
>  static int pci_pm_thaw_noirq(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> -	struct device_driver *drv = dev->driver;
> -	int error = 0;
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	int error;
>  
>  	if (pcibios_pm_ops.thaw_noirq) {
>  		error = pcibios_pm_ops.thaw_noirq(dev);
> @@ -1091,10 +1089,10 @@ static int pci_pm_thaw_noirq(struct device *dev)
>  	if (pci_has_legacy_pm_support(pci_dev))
>  		return pci_legacy_resume_early(dev);
>  
> -	if (drv && drv->pm && drv->pm->thaw_noirq)
> -		error = drv->pm->thaw_noirq(dev);
> +	if (pm && pm->thaw_noirq)
> +		return pm->thaw_noirq(dev);
>  
> -	return error;
> +	return 0;
>  }
>  
>  static int pci_pm_thaw(struct device *dev)
> @@ -1165,24 +1163,24 @@ static int pci_pm_poweroff_late(struct device *dev)
>  static int pci_pm_poweroff_noirq(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> -	struct device_driver *drv = dev->driver;
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>  
>  	if (dev_pm_smart_suspend_and_suspended(dev))
>  		return 0;
>  
> -	if (pci_has_legacy_pm_support(to_pci_dev(dev)))
> +	if (pci_has_legacy_pm_support(pci_dev))
>  		return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
>  
> -	if (!drv || !drv->pm) {
> +	if (!pm) {
>  		pci_fixup_device(pci_fixup_suspend_late, pci_dev);
>  		return 0;
>  	}
>  
> -	if (drv->pm->poweroff_noirq) {
> +	if (pm->poweroff_noirq) {
>  		int error;
>  
> -		error = drv->pm->poweroff_noirq(dev);
> -		suspend_report_result(drv->pm->poweroff_noirq, error);
> +		error = pm->poweroff_noirq(dev);
> +		suspend_report_result(pm->poweroff_noirq, error);
>  		if (error)
>  			return error;
>  	}
> @@ -1208,8 +1206,8 @@ static int pci_pm_poweroff_noirq(struct device *dev)
>  static int pci_pm_restore_noirq(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
> -	struct device_driver *drv = dev->driver;
> -	int error = 0;
> +	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	int error;
>  
>  	if (pcibios_pm_ops.restore_noirq) {
>  		error = pcibios_pm_ops.restore_noirq(dev);
> @@ -1223,17 +1221,16 @@ static int pci_pm_restore_noirq(struct device *dev)
>  	if (pci_has_legacy_pm_support(pci_dev))
>  		return pci_legacy_resume_early(dev);
>  
> -	if (drv && drv->pm && drv->pm->restore_noirq)
> -		error = drv->pm->restore_noirq(dev);
> +	if (pm && pm->restore_noirq)
> +		return pm->restore_noirq(dev);
>  
> -	return error;
> +	return 0;
>  }
>  
>  static int pci_pm_restore(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
>  	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -	int error = 0;
>  
>  	/*
>  	 * This is necessary for the hibernation error path in which restore is
> @@ -1249,12 +1246,12 @@ static int pci_pm_restore(struct device *dev)
>  
>  	if (pm) {
>  		if (pm->restore)
> -			error = pm->restore(dev);
> +			return pm->restore(dev);
>  	} else {
>  		pci_pm_reenable_device(pci_dev);
>  	}
>  
> -	return error;
> +	return 0;
>  }
>  
>  #else /* !CONFIG_HIBERNATE_CALLBACKS */
> @@ -1330,9 +1327,9 @@ static int pci_pm_runtime_suspend(struct device *dev)
>  
>  static int pci_pm_runtime_resume(struct device *dev)
>  {
> -	int rc = 0;
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
>  	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> +	int error = 0;
>  
>  	/*
>  	 * Restoring config space is necessary even if the device is not bound
> @@ -1348,18 +1345,17 @@ static int pci_pm_runtime_resume(struct device *dev)
>  	pci_pm_default_resume(pci_dev);
>  
>  	if (pm && pm->runtime_resume)
> -		rc = pm->runtime_resume(dev);
> +		error = pm->runtime_resume(dev);
>  
>  	pci_dev->runtime_d3cold = false;
>  
> -	return rc;
> +	return error;
>  }
>  
>  static int pci_pm_runtime_idle(struct device *dev)
>  {
>  	struct pci_dev *pci_dev = to_pci_dev(dev);
>  	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> -	int ret = 0;
>  
>  	/*
>  	 * If pci_dev->driver is not set (unbound), the device should
> @@ -1372,9 +1368,9 @@ static int pci_pm_runtime_idle(struct device *dev)
>  		return -ENOSYS;
>  
>  	if (pm->runtime_idle)
> -		ret = pm->runtime_idle(dev);
> +		return pm->runtime_idle(dev);
>  
> -	return ret;
> +	return 0;
>  }
>  
>  static const struct dev_pm_ops pci_dev_pm_ops = {
> 





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

* Re: [PATCH 6/7] PCI/PM: Wrap long lines in documentation
  2019-10-14 23:00 ` [PATCH 6/7] PCI/PM: Wrap long lines in documentation Bjorn Helgaas
@ 2019-10-15 17:23   ` Rafael J. Wysocki
  0 siblings, 0 replies; 18+ messages in thread
From: Rafael J. Wysocki @ 2019-10-15 17:23 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, Rafael J . Wysocki, Lorenzo Pieralisi,
	Michael Kelley, Sasha Levin, Haiyang Zhang, KY Srinivasan,
	Stephen Hemminger, olaf, apw, jasowang, vkuznets, marcelo.cerri,
	jackm, linux-pci, linux-hyperv, linux-kernel, driverdev-devel,
	Bjorn Helgaas

On Tuesday, October 15, 2019 1:00:15 AM CEST Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> Documentation/power/pci.rst is wrapped to fit in 80 columns, but directory
> structure changes made a few lines longer.  Wrap them so they all fit in 80
> columns again.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

Well, looks better this way. :-)

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

> ---
>  Documentation/power/pci.rst | 28 ++++++++++++++--------------
>  1 file changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/Documentation/power/pci.rst b/Documentation/power/pci.rst
> index 1525c594d631..db41a770a2f5 100644
> --- a/Documentation/power/pci.rst
> +++ b/Documentation/power/pci.rst
> @@ -426,12 +426,12 @@ pm->runtime_idle() callback.
>  2.4. System-Wide Power Transitions
>  ----------------------------------
>  There are a few different types of system-wide power transitions, described in
> -Documentation/driver-api/pm/devices.rst.  Each of them requires devices to be handled
> -in a specific way and the PM core executes subsystem-level power management
> -callbacks for this purpose.  They are executed in phases such that each phase
> -involves executing the same subsystem-level callback for every device belonging
> -to the given subsystem before the next phase begins.  These phases always run
> -after tasks have been frozen.
> +Documentation/driver-api/pm/devices.rst.  Each of them requires devices to be
> +handled in a specific way and the PM core executes subsystem-level power
> +management callbacks for this purpose.  They are executed in phases such that
> +each phase involves executing the same subsystem-level callback for every device
> +belonging to the given subsystem before the next phase begins.  These phases
> +always run after tasks have been frozen.
>  
>  2.4.1. System Suspend
>  ^^^^^^^^^^^^^^^^^^^^^
> @@ -636,12 +636,12 @@ System restore requires a hibernation image to be loaded into memory and the
>  pre-hibernation memory contents to be restored before the pre-hibernation system
>  activity can be resumed.
>  
> -As described in Documentation/driver-api/pm/devices.rst, the hibernation image is loaded
> -into memory by a fresh instance of the kernel, called the boot kernel, which in
> -turn is loaded and run by a boot loader in the usual way.  After the boot kernel
> -has loaded the image, it needs to replace its own code and data with the code
> -and data of the "hibernated" kernel stored within the image, called the image
> -kernel.  For this purpose all devices are frozen just like before creating
> +As described in Documentation/driver-api/pm/devices.rst, the hibernation image
> +is loaded into memory by a fresh instance of the kernel, called the boot kernel,
> +which in turn is loaded and run by a boot loader in the usual way.  After the
> +boot kernel has loaded the image, it needs to replace its own code and data with
> +the code and data of the "hibernated" kernel stored within the image, called the
> +image kernel.  For this purpose all devices are frozen just like before creating
>  the image during hibernation, in the
>  
>  	prepare, freeze, freeze_noirq
> @@ -691,8 +691,8 @@ controlling the runtime power management of their devices.
>  
>  At the time of this writing there are two ways to define power management
>  callbacks for a PCI device driver, the recommended one, based on using a
> -dev_pm_ops structure described in Documentation/driver-api/pm/devices.rst, and the
> -"legacy" one, in which the .suspend(), .suspend_late(), .resume_early(), and
> +dev_pm_ops structure described in Documentation/driver-api/pm/devices.rst, and
> +the "legacy" one, in which the .suspend(), .suspend_late(), .resume_early(), and
>  .resume() callbacks from struct pci_driver are used.  The legacy approach,
>  however, doesn't allow one to define runtime power management callbacks and is
>  not really suitable for any new drivers.  Therefore it is not covered by this
> 





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

* Re: [PATCH 7/7] PCI/MSI: Move power state check out of pci_msi_supported()
  2019-10-14 23:00 ` [PATCH 7/7] PCI/MSI: Move power state check out of pci_msi_supported() Bjorn Helgaas
@ 2019-10-15 17:24   ` Rafael J. Wysocki
  0 siblings, 0 replies; 18+ messages in thread
From: Rafael J. Wysocki @ 2019-10-15 17:24 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, Rafael J . Wysocki, Lorenzo Pieralisi,
	Michael Kelley, Sasha Levin, Haiyang Zhang, KY Srinivasan,
	Stephen Hemminger, olaf, apw, jasowang, vkuznets, marcelo.cerri,
	jackm, linux-pci, linux-hyperv, linux-kernel, driverdev-devel,
	Bjorn Helgaas

On Tuesday, October 15, 2019 1:00:16 AM CEST Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> 27e20603c54b ("PCI/MSI: Move D0 check into pci_msi_check_device()")
> moved the power state check into pci_msi_check_device(), which was
> subsequently renamed to pci_msi_supported().  This didn't change the
> behavior, since both callers checked the power state.
> 
> However, it doesn't fit the current "pci_msi_supported()" name, which
> should return what the device is capable of, independent of the power
> state.
> 
> Move the power state check back into the callers for readability.  No
> functional change intended.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

No issues found, so

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

> ---
>  drivers/pci/msi.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index 0884bedcfc7a..20e9c729617c 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -861,7 +861,7 @@ static int pci_msi_supported(struct pci_dev *dev, int nvec)
>  	if (!pci_msi_enable)
>  		return 0;
>  
> -	if (!dev || dev->no_msi || dev->current_state != PCI_D0)
> +	if (!dev || dev->no_msi)
>  		return 0;
>  
>  	/*
> @@ -972,7 +972,7 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
>  	int nr_entries;
>  	int i, j;
>  
> -	if (!pci_msi_supported(dev, nvec))
> +	if (!pci_msi_supported(dev, nvec) || dev->current_state != PCI_D0)
>  		return -EINVAL;
>  
>  	nr_entries = pci_msix_vec_count(dev);
> @@ -1058,7 +1058,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
>  	int nvec;
>  	int rc;
>  
> -	if (!pci_msi_supported(dev, minvec))
> +	if (!pci_msi_supported(dev, minvec) || dev->current_state != PCI_D0)
>  		return -EINVAL;
>  
>  	/* Check whether driver already requested MSI-X IRQs */
> 





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

* RE: [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early()
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
                   ` (6 preceding siblings ...)
  2019-10-14 23:00 ` [PATCH 7/7] PCI/MSI: Move power state check out of pci_msi_supported() Bjorn Helgaas
@ 2019-10-15 18:24 ` Dexuan Cui
  2019-10-15 18:42 ` Bjorn Helgaas
  8 siblings, 0 replies; 18+ messages in thread
From: Dexuan Cui @ 2019-10-15 18:24 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel, Bjorn Helgaas

> From: Bjorn Helgaas <helgaas@kernel.org>
> Sent: Monday, October 14, 2019 4:00 PM
>  ...
> 
> Dexuan, the important thing here is the first patch, which is your [1],
> which I modified by doing pci_restore_state() as well as setting to D0:
> 
>   pci_set_power_state(pci_dev, PCI_D0);
>   pci_restore_state(pci_dev);
> 
> I'm proposing some more patches on top.  None are relevant to the problem
> you're solving; they're just minor doc and other updates in the same area.
> 
> Rafael, if you have a chance to look at these, I'd appreciate it.  I tried
> to make the doc match the code, but I'm no PM expert.
 
Thank you very much, Bjorn! The patchset looks good to me.

Thanks,
-- Dexuan

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

* Re: [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early()
  2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
                   ` (7 preceding siblings ...)
  2019-10-15 18:24 ` [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Dexuan Cui
@ 2019-10-15 18:42 ` Bjorn Helgaas
  8 siblings, 0 replies; 18+ messages in thread
From: Bjorn Helgaas @ 2019-10-15 18:42 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Rafael J . Wysocki, Lorenzo Pieralisi, Michael Kelley,
	Sasha Levin, Haiyang Zhang, KY Srinivasan, Stephen Hemminger,
	olaf, apw, jasowang, vkuznets, marcelo.cerri, jackm, linux-pci,
	linux-hyperv, linux-kernel, driverdev-devel

On Mon, Oct 14, 2019 at 06:00:09PM -0500, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> Dexuan, the important thing here is the first patch, which is your [1],
> which I modified by doing pci_restore_state() as well as setting to D0:
> 
>   pci_set_power_state(pci_dev, PCI_D0);
>   pci_restore_state(pci_dev);
> 
> I'm proposing some more patches on top.  None are relevant to the problem
> you're solving; they're just minor doc and other updates in the same area.
> 
> Rafael, if you have a chance to look at these, I'd appreciate it.  I tried
> to make the doc match the code, but I'm no PM expert.
> 
> [1] https://lore.kernel.org/r/KU1P153MB016637CAEAD346F0AA8E3801BFAD0@KU1P153MB0166.APCP153.PROD.OUTLOOK.COM
> 
> 
> Dexuan Cui (1):
>   PCI/PM: Always return devices to D0 when thawing
> 
> Bjorn Helgaas (6):
>   PCI/PM: Correct pci_pm_thaw_noirq() documentation
>   PCI/PM: Clear PCIe PME Status even for legacy power management
>   PCI/PM: Run resume fixups before disabling wakeup events
>   PCI/PM: Make power management op coding style consistent
>   PCI/PM: Wrap long lines in documentation
>   PCI/MSI: Move power state check out of pci_msi_supported()
> 
>  Documentation/power/pci.rst | 38 +++++++-------
>  drivers/pci/msi.c           |  6 +--
>  drivers/pci/pci-driver.c    | 99 ++++++++++++++++++-------------------
>  3 files changed, 71 insertions(+), 72 deletions(-)

Thanks Dexuan and Rafael for taking a look at these!

I applied the first six to pci/pm and the last to pci/msi, all for
v5.5.

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

* Re: [PATCH 5/7] PCI/PM: Make power management op coding style consistent
  2019-10-14 23:00 ` [PATCH 5/7] PCI/PM: Make power management op coding style consistent Bjorn Helgaas
  2019-10-15 17:22   ` Rafael J. Wysocki
@ 2019-10-16 13:50   ` Dan Carpenter
  1 sibling, 0 replies; 18+ messages in thread
From: Dan Carpenter @ 2019-10-16 13:50 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Dexuan Cui, driverdev-devel, olaf, Lorenzo Pieralisi,
	Stephen Hemminger, jackm, Haiyang Zhang, Rafael J . Wysocki,
	linux-hyperv, Michael Kelley, Sasha Levin, marcelo.cerri,
	linux-pci, apw, vkuznets, Bjorn Helgaas, jasowang, linux-kernel

On Mon, Oct 14, 2019 at 06:00:14PM -0500, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas@google.com>
> 
> Some of the power management ops use this style:
> 
>   struct device_driver *drv = dev->driver;
>   if (drv && drv->pm && drv->pm->prepare(dev))
>     drv->pm->prepare(dev);
> 
> while others use this:
> 
>   const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

I like this patch a lot, especially the direct returns.  But it
occurs to me that in the future this conditional would look better as

	const struct dev_pm_ops *pm = driver_to_pm(dev->driver);

or something.

regards,
dan carpenter


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

end of thread, back to index

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-14 23:00 [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Bjorn Helgaas
2019-10-14 23:00 ` [PATCH 1/7] PCI/PM: Always return devices to D0 when thawing Bjorn Helgaas
2019-10-15 17:15   ` Rafael J. Wysocki
2019-10-14 23:00 ` [PATCH 2/7] PCI/PM: Correct pci_pm_thaw_noirq() documentation Bjorn Helgaas
2019-10-15 17:17   ` Rafael J. Wysocki
2019-10-14 23:00 ` [PATCH 3/7] PCI/PM: Clear PCIe PME Status even for legacy power management Bjorn Helgaas
2019-10-15 17:20   ` Rafael J. Wysocki
2019-10-14 23:00 ` [PATCH 4/7] PCI/PM: Run resume fixups before disabling wakeup events Bjorn Helgaas
2019-10-15 17:21   ` Rafael J. Wysocki
2019-10-14 23:00 ` [PATCH 5/7] PCI/PM: Make power management op coding style consistent Bjorn Helgaas
2019-10-15 17:22   ` Rafael J. Wysocki
2019-10-16 13:50   ` Dan Carpenter
2019-10-14 23:00 ` [PATCH 6/7] PCI/PM: Wrap long lines in documentation Bjorn Helgaas
2019-10-15 17:23   ` Rafael J. Wysocki
2019-10-14 23:00 ` [PATCH 7/7] PCI/MSI: Move power state check out of pci_msi_supported() Bjorn Helgaas
2019-10-15 17:24   ` Rafael J. Wysocki
2019-10-15 18:24 ` [PATCH v3 0/7] PCI: PM: Move to D0 before calling pci_legacy_resume_early() Dexuan Cui
2019-10-15 18:42 ` Bjorn Helgaas

Linux-HyperV Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-hyperv/0 linux-hyperv/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-hyperv linux-hyperv/ https://lore.kernel.org/linux-hyperv \
		linux-hyperv@vger.kernel.org
	public-inbox-index linux-hyperv

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-hyperv


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git