All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] PM: Unify the handling of device wakeup settings
@ 2017-06-19 21:31 Rafael J. Wysocki
  2017-06-19 21:33 ` [PATCH 1/6] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
                   ` (7 more replies)
  0 siblings, 8 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-19 21:31 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

Hi All,

The handling of device wakeup settings, especially in the ACPI core and the PCI
bus type, depends on whether it is about system wakeup from sleep states or
remote wakeup in the working state (runtime).  However, that distinction is
mostly based on the ACPI concept of "wakeup" and "runtime" GPEs, which is
somewhat artificial, because the underlying hardware mechanism is basically
the same in both cases.

Moreover, suspend-to-idle is now supported as a sleep state and wakeup from it
is based on exactly the same hardware capabilities as the working-state
(runtime) remote wakeup.

The following patch series removes that distinction and unifies the handling of
device wakeup settings between system sleep and runtime.  It also fixes one
issue related to wakeup signaling through PCI bridges.

[1/6]: Get rid of the "runtime wakeup" concept from the ACPI core.
[2/6]: Unify device wakeup settings code paths in the ACPI core.
[3-4/6]: Unify device wakeup settings code paths in the PCI bus type code.
[5/6]: Fix wakeup-related issue with bridges in the PCI bus type code.
[6/6]: Get rid of the "runtime wakeup" concept from the driver core.

The series is based on current linux-next and will be made available for
testing in the linux-pm.git tree in a couple of days.

Thanks,
Rafael

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

* [PATCH 1/6] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
@ 2017-06-19 21:33 ` Rafael J. Wysocki
  2017-06-19 21:33 ` [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code Rafael J. Wysocki
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-19 21:33 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

The run_wake flag in struct acpi_device_wakeup_flags stores the
information on whether or not the device can generate wakeup
signals at run time, but in ACPI that really is equivalent to
being able to generate wakeup signals at all.

In fact, run_wake will always be set after successful executeion of
acpi_setup_gpe_for_wake(), but if that fails, the device will not be
able to use a wakeup GPE at all, so it won't be able to wake up the
systems from sleep states too.  Hence, run_wake actually means that
the device is capable of triggering wakeup and so it is equivalent
to the valid flag.

For this reason, drop run_wake from struct acpi_device_wakeup_flags
and make sure that the valid flag is only set if
acpi_setup_gpe_for_wake() has been successful.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/pci_root.c |    2 +-
 drivers/acpi/proc.c     |    4 ++--
 drivers/acpi/scan.c     |   23 ++++++++---------------
 drivers/pci/pci-acpi.c  |    3 +--
 include/acpi/acpi_bus.h |    1 -
 5 files changed, 12 insertions(+), 21 deletions(-)

Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -835,7 +835,7 @@ static int acpi_bus_extract_wakeup_devic
 	return err;
 }
 
-static void acpi_wakeup_gpe_init(struct acpi_device *device)
+static bool acpi_wakeup_gpe_init(struct acpi_device *device)
 {
 	static const struct acpi_device_id button_device_ids[] = {
 		{"PNP0C0C", 0},
@@ -845,13 +845,11 @@ static void acpi_wakeup_gpe_init(struct
 	};
 	struct acpi_device_wakeup *wakeup = &device->wakeup;
 	acpi_status status;
-	acpi_event_status event_status;
 
 	wakeup->flags.notifier_present = 0;
 
 	/* Power button, Lid switch always enable wakeup */
 	if (!acpi_match_device_ids(device, button_device_ids)) {
-		wakeup->flags.run_wake = 1;
 		if (!acpi_match_device_ids(device, &button_device_ids[1])) {
 			/* Do not use Lid/sleep button for S5 wakeup */
 			if (wakeup->sleep_state == ACPI_STATE_S5)
@@ -859,17 +857,12 @@ static void acpi_wakeup_gpe_init(struct
 		}
 		acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
 		device_set_wakeup_capable(&device->dev, true);
-		return;
+		return true;
 	}
 
-	acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
-				wakeup->gpe_number);
-	status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number,
-				     &event_status);
-	if (ACPI_FAILURE(status))
-		return;
-
-	wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER);
+	status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
+					 wakeup->gpe_number);
+	return ACPI_SUCCESS(status);
 }
 
 static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
@@ -887,10 +880,10 @@ static void acpi_bus_get_wakeup_device_f
 		return;
 	}
 
-	device->wakeup.flags.valid = 1;
+	device->wakeup.flags.valid = acpi_wakeup_gpe_init(device);
 	device->wakeup.prepare_count = 0;
-	acpi_wakeup_gpe_init(device);
-	/* Call _PSW/_DSW object to disable its ability to wake the sleeping
+	/*
+	 * Call _PSW/_DSW object to disable its ability to wake the sleeping
 	 * system for the ACPI device with the _PRW object.
 	 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
 	 * So it is necessary to call _DSW object first. Only when it is not
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -313,7 +313,6 @@ struct acpi_device_perf {
 /* Wakeup Management */
 struct acpi_device_wakeup_flags {
 	u8 valid:1;		/* Can successfully enable wakeup? */
-	u8 run_wake:1;		/* Run-Wake GPE devices */
 	u8 notifier_present:1;  /* Wake-up notify handler has been installed */
 	u8 enabled:1;		/* Enabled for wakeup */
 };
Index: linux-pm/drivers/acpi/pci_root.c
===================================================================
--- linux-pm.orig/drivers/acpi/pci_root.c
+++ linux-pm/drivers/acpi/pci_root.c
@@ -608,7 +608,7 @@ static int acpi_pci_root_add(struct acpi
 		pcie_no_aspm();
 
 	pci_acpi_add_bus_pm_notifier(device);
-	if (device->wakeup.flags.run_wake)
+	if (device->wakeup.flags.valid)
 		device_set_run_wake(root->bus->bridge, true);
 
 	if (hotadd) {
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -778,9 +778,8 @@ static void pci_acpi_setup(struct device
 		return;
 
 	device_set_wakeup_capable(dev, true);
+	device_set_run_wake(dev, true);
 	acpi_pci_sleep_wake(pci_dev, false);
-	if (adev->wakeup.flags.run_wake)
-		device_set_run_wake(dev, true);
 }
 
 static void pci_acpi_cleanup(struct device *dev)
Index: linux-pm/drivers/acpi/proc.c
===================================================================
--- linux-pm.orig/drivers/acpi/proc.c
+++ linux-pm/drivers/acpi/proc.c
@@ -42,7 +42,7 @@ acpi_system_wakeup_device_seq_show(struc
 
 		if (!dev->physical_node_count) {
 			seq_printf(seq, "%c%-8s\n",
-				dev->wakeup.flags.run_wake ? '*' : ' ',
+				dev->wakeup.flags.valid ? '*' : ' ',
 				device_may_wakeup(&dev->dev) ?
 					"enabled" : "disabled");
 		} else {
@@ -58,7 +58,7 @@ acpi_system_wakeup_device_seq_show(struc
 					seq_printf(seq, "\t\t");
 
 				seq_printf(seq, "%c%-8s  %s:%s\n",
-					dev->wakeup.flags.run_wake ? '*' : ' ',
+					dev->wakeup.flags.valid ? '*' : ' ',
 					(device_may_wakeup(&dev->dev) ||
 					device_may_wakeup(ldev)) ?
 					"enabled" : "disabled",

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

* [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
  2017-06-19 21:33 ` [PATCH 1/6] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
@ 2017-06-19 21:33 ` Rafael J. Wysocki
  2017-06-22  7:39   ` Mika Westerberg
  2017-06-19 21:34 ` [PATCH 3/6] PCI / PM: Drop pme_interrupt flag from struct pci_dev Rafael J. Wysocki
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-19 21:33 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

Currently, there are two separate ways of handling device wakeup
settings in the ACPI core, depending on whether this is runtime
wakeup or system wakeup (from sleep states).  However, after the
previous commit eliminating the run_wake ACPI device wakeup flag,
there is no difference between the two any more at the ACPI level,
so they can be combined.

For this reason, introduce acpi_pm_device_wakeup() to replace both
acpi_pm_device_run_wake() and acpi_pm_device_sleep_wake() and make it
check the ACPI device object's wakeup.valid flag to determine whether
or not the device can be set up to generate wakeup signals.

Also notice that zpodd_enable/disable_run_wake() only call
device_set_run_wake() because acpi_pm_device_run_wake() called
device_run_wake(), which is not done by acpi_pm_device_wakeup(),
so drop the now redundant device_set_run_wake() calls from there.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/device_pm.c   |   39 ++++++++-------------------------------
 drivers/ata/libata-zpodd.c |    9 +++------
 drivers/pci/pci-acpi.c     |   12 ++++++------
 drivers/pnp/pnpacpi/core.c |    6 +++---
 include/acpi/acpi_bus.h    |   13 ++-----------
 5 files changed, 22 insertions(+), 57 deletions(-)

Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -717,55 +717,32 @@ static int acpi_device_wakeup(struct acp
 }
 
 /**
- * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device.
- * @dev: Device to enable/disable the platform to wake up.
+ * acpi_pm_device_wakeup - Enable/disable remote wakeup for given device.
+ * @dev: Device to enable/disable to generate wakeup events.
  * @enable: Whether to enable or disable the wakeup functionality.
  */
-int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
-{
-	struct acpi_device *adev;
-
-	if (!device_run_wake(phys_dev))
-		return -EINVAL;
-
-	adev = ACPI_COMPANION(phys_dev);
-	if (!adev) {
-		dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__);
-		return -ENODEV;
-	}
-
-	return acpi_device_wakeup(adev, ACPI_STATE_S0, enable);
-}
-EXPORT_SYMBOL(acpi_pm_device_run_wake);
-
-#ifdef CONFIG_PM_SLEEP
-/**
- * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
- * @dev: Device to enable/desible to wake up the system from sleep states.
- * @enable: Whether to enable or disable @dev to wake up the system.
- */
-int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
+int acpi_pm_device_wakeup(struct device *dev, bool enable)
 {
 	struct acpi_device *adev;
 	int error;
 
-	if (!device_can_wakeup(dev))
-		return -EINVAL;
-
 	adev = ACPI_COMPANION(dev);
 	if (!adev) {
 		dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
 		return -ENODEV;
 	}
 
+	if (!acpi_device_can_wakeup(adev))
+		return -EINVAL;
+
 	error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
 	if (!error)
-		dev_dbg(dev, "System wakeup %s by ACPI\n",
+		dev_dbg(dev, "Wakeup %s by ACPI\n",
 			enable ? "enabled" : "disabled");
 
 	return error;
 }
-#endif /* CONFIG_PM_SLEEP */
+EXPORT_SYMBOL(acpi_pm_device_wakeup);
 
 /**
  * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
Index: linux-pm/drivers/ata/libata-zpodd.c
===================================================================
--- linux-pm.orig/drivers/ata/libata-zpodd.c
+++ linux-pm/drivers/ata/libata-zpodd.c
@@ -174,8 +174,7 @@ void zpodd_enable_run_wake(struct ata_de
 	sdev_disable_disk_events(dev->sdev);
 
 	zpodd->powered_off = true;
-	device_set_run_wake(&dev->tdev, true);
-	acpi_pm_device_run_wake(&dev->tdev, true);
+	acpi_pm_device_wakeup(&dev->tdev, true);
 }
 
 /* Disable runtime wake capability if it is enabled */
@@ -183,10 +182,8 @@ void zpodd_disable_run_wake(struct ata_d
 {
 	struct zpodd *zpodd = dev->zpodd;
 
-	if (zpodd->powered_off) {
-		acpi_pm_device_run_wake(&dev->tdev, false);
-		device_set_run_wake(&dev->tdev, false);
-	}
+	if (zpodd->powered_off)
+		acpi_pm_device_wakeup(&dev->tdev, false);
 }
 
 /*
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -579,20 +579,20 @@ static bool acpi_pci_can_wakeup(struct p
 static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
 {
 	while (bus->parent) {
-		if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable))
+		if (!acpi_pm_device_wakeup(&bus->self->dev, enable))
 			return;
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
-		acpi_pm_device_sleep_wake(bus->bridge, enable);
+		acpi_pm_device_wakeup(bus->bridge, enable);
 }
 
 static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
 {
 	if (acpi_pci_can_wakeup(dev))
-		return acpi_pm_device_sleep_wake(&dev->dev, enable);
+		return acpi_pm_device_wakeup(&dev->dev, enable);
 
 	acpi_pci_propagate_wakeup_enable(dev->bus, enable);
 	return 0;
@@ -605,14 +605,14 @@ static void acpi_pci_propagate_run_wake(
 
 		if (bridge->pme_interrupt)
 			return;
-		if (!acpi_pm_device_run_wake(&bridge->dev, enable))
+		if (!acpi_pm_device_wakeup(&bridge->dev, enable))
 			return;
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
-		acpi_pm_device_run_wake(bus->bridge, enable);
+		acpi_pm_device_wakeup(bus->bridge, enable);
 }
 
 static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
@@ -626,7 +626,7 @@ static int acpi_pci_run_wake(struct pci_
 	if (dev->pme_interrupt && !dev->runtime_d3cold)
 		return 0;
 
-	if (!acpi_pm_device_run_wake(&dev->dev, enable))
+	if (!acpi_pm_device_wakeup(&dev->dev, enable))
 		return 0;
 
 	acpi_pci_propagate_run_wake(dev->bus, enable);
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -602,7 +602,7 @@ acpi_status acpi_add_pm_notifier(struct
 			void (*func)(struct acpi_device_wakeup_context *context));
 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
-int acpi_pm_device_run_wake(struct device *, bool);
+int acpi_pm_device_wakeup(struct device *dev, bool enable);
 #else
 static inline void acpi_pm_wakeup_event(struct device *dev)
 {
@@ -625,16 +625,7 @@ static inline int acpi_pm_device_sleep_s
 	return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
 		m : ACPI_STATE_D0;
 }
-static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
-{
-	return -ENODEV;
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-int acpi_pm_device_sleep_wake(struct device *, bool);
-#else
-static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
+static inline int acpi_pm_device_wakeup(struct device *dev, bool enable)
 {
 	return -ENODEV;
 }
Index: linux-pm/drivers/pnp/pnpacpi/core.c
===================================================================
--- linux-pm.orig/drivers/pnp/pnpacpi/core.c
+++ linux-pm/drivers/pnp/pnpacpi/core.c
@@ -149,8 +149,8 @@ static int pnpacpi_suspend(struct pnp_de
 	}
 
 	if (device_can_wakeup(&dev->dev)) {
-		error = acpi_pm_device_sleep_wake(&dev->dev,
-				device_may_wakeup(&dev->dev));
+		error = acpi_pm_device_wakeup(&dev->dev,
+					      device_may_wakeup(&dev->dev));
 		if (error)
 			return error;
 	}
@@ -185,7 +185,7 @@ static int pnpacpi_resume(struct pnp_dev
 	}
 
 	if (device_may_wakeup(&dev->dev))
-		acpi_pm_device_sleep_wake(&dev->dev, false);
+		acpi_pm_device_wakeup(&dev->dev, false);
 
 	if (acpi_device_power_manageable(acpi_dev))
 		error = acpi_device_set_power(acpi_dev, ACPI_STATE_D0);

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

* [PATCH 3/6] PCI / PM: Drop pme_interrupt flag from struct pci_dev
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
  2017-06-19 21:33 ` [PATCH 1/6] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
  2017-06-19 21:33 ` [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code Rafael J. Wysocki
@ 2017-06-19 21:34 ` Rafael J. Wysocki
  2017-06-19 21:35 ` [PATCH 4/6] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-19 21:34 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

The pme_interrupt flag in struct pci_dev is set when PMEs generated
by the device are going to be signaled via root port PME interrupts.

Ironically enough, that information is only used by the code setting
up device wakeup through ACPI which returns as soon as it sees the
pme_interrupt flag set while setting up "remote runtime wakeup".
That is questionable, however, because in theory there may be PCIe
devices using out-of-band PME signaling under root ports handled
by the native PME code.  For such devices, ACPI wakeup should be
set up regardless of whether or not native PME signaling is used
in general.

For this reason, drop the pme_interrupt flag and rework the code
using it which then allows the ACPI-based device wakeup handling
in PCI to be consolidated to use one code path for both "runtime
remote wakeup" and system wakeup (from sleep states).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/device_pm.c |   10 +++++-
 drivers/pci/pci-acpi.c   |   68 ++++++++++-------------------------------------
 drivers/pci/pcie/pme.c   |   14 ++++-----
 include/acpi/acpi_bus.h  |    5 +++
 include/linux/pci.h      |    1 
 5 files changed, 34 insertions(+), 64 deletions(-)

Index: linux-pm/include/linux/pci.h
===================================================================
--- linux-pm.orig/include/linux/pci.h
+++ linux-pm/include/linux/pci.h
@@ -307,7 +307,6 @@ struct pci_dev {
 	u8		pm_cap;		/* PM capability offset */
 	unsigned int	pme_support:5;	/* Bitmask of states from which PME#
 					   can be generated */
-	unsigned int	pme_interrupt:1;
 	unsigned int	pme_poll:1;	/* Poll device's PME status bit */
 	unsigned int	d1_support:1;	/* Low power state D1 is supported */
 	unsigned int	d2_support:1;	/* Low power state D2 is supported */
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -570,67 +570,29 @@ static pci_power_t acpi_pci_get_power_st
 	return state_conv[state];
 }
 
-static bool acpi_pci_can_wakeup(struct pci_dev *dev)
-{
-	struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
-	return adev ? acpi_device_can_wakeup(adev) : false;
-}
-
-static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
+static int acpi_pci_propagate_wakeup(struct pci_bus *bus, bool enable)
 {
 	while (bus->parent) {
-		if (!acpi_pm_device_wakeup(&bus->self->dev, enable))
-			return;
-		bus = bus->parent;
-	}
+		if (acpi_pm_device_can_wakeup(&bus->self->dev))
+			return acpi_pm_device_wakeup(&bus->self->dev, enable);
 
-	/* We have reached the root bus. */
-	if (bus->bridge)
-		acpi_pm_device_wakeup(bus->bridge, enable);
-}
-
-static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
-{
-	if (acpi_pci_can_wakeup(dev))
-		return acpi_pm_device_wakeup(&dev->dev, enable);
-
-	acpi_pci_propagate_wakeup_enable(dev->bus, enable);
-	return 0;
-}
-
-static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable)
-{
-	while (bus->parent) {
-		struct pci_dev *bridge = bus->self;
-
-		if (bridge->pme_interrupt)
-			return;
-		if (!acpi_pm_device_wakeup(&bridge->dev, enable))
-			return;
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
-	if (bus->bridge)
-		acpi_pm_device_wakeup(bus->bridge, enable);
+	if (bus->bridge) {
+		if (acpi_pm_device_can_wakeup(bus->bridge))
+			return acpi_pm_device_wakeup(bus->bridge, enable);
+	}
+	return 0;
 }
 
-static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
+static int acpi_pci_wakeup(struct pci_dev *dev, bool enable)
 {
-	/*
-	 * Per PCI Express Base Specification Revision 2.0 section
-	 * 5.3.3.2 Link Wakeup, platform support is needed for D3cold
-	 * waking up to power on the main link even if there is PME
-	 * support for D3cold
-	 */
-	if (dev->pme_interrupt && !dev->runtime_d3cold)
-		return 0;
-
-	if (!acpi_pm_device_wakeup(&dev->dev, enable))
-		return 0;
+	if (acpi_pm_device_can_wakeup(&dev->dev))
+		return acpi_pm_device_wakeup(&dev->dev, enable);
 
-	acpi_pci_propagate_run_wake(dev->bus, enable);
-	return 0;
+	return acpi_pci_propagate_wakeup(dev->bus, enable);
 }
 
 static bool acpi_pci_need_resume(struct pci_dev *dev)
@@ -654,8 +616,8 @@ static const struct pci_platform_pm_ops
 	.set_state = acpi_pci_set_power_state,
 	.get_state = acpi_pci_get_power_state,
 	.choose_state = acpi_pci_choose_state,
-	.sleep_wake = acpi_pci_sleep_wake,
-	.run_wake = acpi_pci_run_wake,
+	.sleep_wake = acpi_pci_wakeup,
+	.run_wake = acpi_pci_wakeup,
 	.need_resume = acpi_pci_need_resume,
 };
 
@@ -779,7 +741,7 @@ static void pci_acpi_setup(struct device
 
 	device_set_wakeup_capable(dev, true);
 	device_set_run_wake(dev, true);
-	acpi_pci_sleep_wake(pci_dev, false);
+	acpi_pci_wakeup(pci_dev, false);
 }
 
 static void pci_acpi_cleanup(struct device *dev)
Index: linux-pm/drivers/pci/pcie/pme.c
===================================================================
--- linux-pm.orig/drivers/pci/pcie/pme.c
+++ linux-pm/drivers/pci/pcie/pme.c
@@ -294,31 +294,29 @@ static irqreturn_t pcie_pme_irq(int irq,
 }
 
 /**
- * pcie_pme_set_native - Set the PME interrupt flag for given device.
+ * pcie_pme_can_wakeup - Set the wakeup capability flag.
  * @dev: PCI device to handle.
  * @ign: Ignored.
  */
-static int pcie_pme_set_native(struct pci_dev *dev, void *ign)
+static int pcie_pme_can_wakeup(struct pci_dev *dev, void *ign)
 {
 	device_set_run_wake(&dev->dev, true);
-	dev->pme_interrupt = true;
 	return 0;
 }
 
 /**
- * pcie_pme_mark_devices - Set the PME interrupt flag for devices below a port.
+ * pcie_pme_mark_devices - Set the wakeup flag for devices below a port.
  * @port: PCIe root port or event collector to handle.
  *
  * For each device below given root port, including the port itself (or for each
  * root complex integrated endpoint if @port is a root complex event collector)
- * set the flag indicating that it can signal run-time wake-up events via PCIe
- * PME interrupts.
+ * set the flag indicating that it can signal run-time wake-up events.
  */
 static void pcie_pme_mark_devices(struct pci_dev *port)
 {
-	pcie_pme_set_native(port, NULL);
+	pcie_pme_can_wakeup(port, NULL);
 	if (port->subordinate)
-		pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL);
+		pci_walk_bus(port->subordinate, pcie_pme_can_wakeup, NULL);
 }
 
 /**
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -496,6 +496,13 @@ bool acpi_bus_can_wakeup(acpi_handle han
 }
 EXPORT_SYMBOL(acpi_bus_can_wakeup);
 
+bool acpi_pm_device_can_wakeup(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	return adev ? acpi_device_can_wakeup(adev) : false;
+}
+
 /**
  * acpi_dev_pm_get_state - Get preferred power state of ACPI device.
  * @dev: Device whose preferred target power state to return.
@@ -737,8 +744,7 @@ int acpi_pm_device_wakeup(struct device
 
 	error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
 	if (!error)
-		dev_dbg(dev, "Wakeup %s by ACPI\n",
-			enable ? "enabled" : "disabled");
+		dev_dbg(dev, "Wakeup %s by ACPI\n", enable ? "enabled" : "disabled");
 
 	return error;
 }
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -601,6 +601,7 @@ void acpi_pm_wakeup_event(struct device
 acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
 			void (*func)(struct acpi_device_wakeup_context *context));
 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
+bool acpi_pm_device_can_wakeup(struct device *dev);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
 int acpi_pm_device_wakeup(struct device *dev, bool enable);
 #else
@@ -617,6 +618,10 @@ static inline acpi_status acpi_remove_pm
 {
 	return AE_SUPPORT;
 }
+static inline bool acpi_pm_device_can_wakeup(struct device *dev)
+{
+	return false;
+}
 static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
 {
 	if (p)

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

* [PATCH 4/6] PCI / PM: Simplify device wakeup settings code
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
                   ` (2 preceding siblings ...)
  2017-06-19 21:34 ` [PATCH 3/6] PCI / PM: Drop pme_interrupt flag from struct pci_dev Rafael J. Wysocki
@ 2017-06-19 21:35 ` Rafael J. Wysocki
  2017-06-20 14:00   ` kbuild test robot
                     ` (2 more replies)
  2017-06-19 21:36 ` [PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early Rafael J. Wysocki
                   ` (3 subsequent siblings)
  7 siblings, 3 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-19 21:35 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

After previous changes it is not necessary to distinguish between
device wakeup for run time and device wakeup from system sleep states
any more, so rework the PCI device wakeup settings code accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/pci/pci-acpi.c   |    3 +--
 drivers/pci/pci-driver.c |    2 +-
 drivers/pci/pci.c        |   36 ++++++++++--------------------------
 drivers/pci/pci.h        |    9 ++-------
 include/linux/pci.h      |    9 +--------
 5 files changed, 15 insertions(+), 44 deletions(-)

Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -616,8 +616,7 @@ static const struct pci_platform_pm_ops
 	.set_state = acpi_pci_set_power_state,
 	.get_state = acpi_pci_get_power_state,
 	.choose_state = acpi_pci_choose_state,
-	.sleep_wake = acpi_pci_wakeup,
-	.run_wake = acpi_pci_wakeup,
+	.set_wakeup = acpi_pci_wakeup,
 	.need_resume = acpi_pci_need_resume,
 };
 
Index: linux-pm/drivers/pci/pci.c
===================================================================
--- linux-pm.orig/drivers/pci/pci.c
+++ linux-pm/drivers/pci/pci.c
@@ -574,8 +574,7 @@ static const struct pci_platform_pm_ops
 int pci_set_platform_pm(const struct pci_platform_pm_ops *ops)
 {
 	if (!ops->is_manageable || !ops->set_state  || !ops->get_state ||
-	    !ops->choose_state  || !ops->sleep_wake || !ops->run_wake  ||
-	    !ops->need_resume)
+	    !ops->choose_state  || !ops->set_wakeup || !ops->need_resume)
 		return -EINVAL;
 	pci_platform_pm = ops;
 	return 0;
@@ -603,16 +602,10 @@ static inline pci_power_t platform_pci_c
 			pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
 }
 
-static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
+static inline int platform_pci_set_wakeup(struct pci_dev *dev, bool enable)
 {
 	return pci_platform_pm ?
-			pci_platform_pm->sleep_wake(dev, enable) : -ENODEV;
-}
-
-static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable)
-{
-	return pci_platform_pm ?
-			pci_platform_pm->run_wake(dev, enable) : -ENODEV;
+			pci_platform_pm->set_wakeup(dev, enable) : -ENODEV;
 }
 
 static inline bool platform_pci_need_resume(struct pci_dev *dev)
@@ -1889,10 +1882,9 @@ void pci_pme_active(struct pci_dev *dev,
 EXPORT_SYMBOL(pci_pme_active);
 
 /**
- * __pci_enable_wake - enable PCI device as wakeup event source
+ * pci_enable_wake - enable PCI device as wakeup event source
  * @dev: PCI device affected
  * @state: PCI state from which device will issue wakeup events
- * @runtime: True if the events are to be generated at run time
  * @enable: True to enable event generation; false to disable
  *
  * This enables the device as a wakeup event source, or disables it.
@@ -1908,14 +1900,10 @@ EXPORT_SYMBOL(pci_pme_active);
  * Error code depending on the platform is returned if both the platform and
  * the native mechanism fail to enable the generation of wake-up events
  */
-int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-		      bool runtime, bool enable)
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
 {
 	int ret = 0;
 
-	if (enable && !runtime && !device_may_wakeup(&dev->dev))
-		return -EINVAL;
-
 	/*
 	 * Don't do the same thing twice in a row for one device, but restore
 	 * PME Enable in case it has been updated by config space restoration.
@@ -1938,24 +1926,20 @@ int __pci_enable_wake(struct pci_dev *de
 			pci_pme_active(dev, true);
 		else
 			ret = 1;
-		error = runtime ? platform_pci_run_wake(dev, true) :
-					platform_pci_sleep_wake(dev, true);
+		error = platform_pci_set_wakeup(dev, true);
 		if (ret)
 			ret = error;
 		if (!ret)
 			dev->wakeup_prepared = true;
 	} else {
-		if (runtime)
-			platform_pci_run_wake(dev, false);
-		else
-			platform_pci_sleep_wake(dev, false);
+		platform_pci_set_wakeup(dev, false);
 		pci_pme_active(dev, false);
 		dev->wakeup_prepared = false;
 	}
 
 	return ret;
 }
-EXPORT_SYMBOL(__pci_enable_wake);
+EXPORT_SYMBOL(pci_enable_wake);
 
 /**
  * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
@@ -2097,12 +2081,12 @@ int pci_finish_runtime_suspend(struct pc
 
 	dev->runtime_d3cold = target_state == PCI_D3cold;
 
-	__pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev));
+	pci_enable_wake(dev, target_state, pci_dev_run_wake(dev));
 
 	error = pci_set_power_state(dev, target_state);
 
 	if (error) {
-		__pci_enable_wake(dev, target_state, true, false);
+		pci_enable_wake(dev, target_state, false);
 		dev->runtime_d3cold = false;
 	}
 
Index: linux-pm/include/linux/pci.h
===================================================================
--- linux-pm.orig/include/linux/pci.h
+++ linux-pm/include/linux/pci.h
@@ -1097,8 +1097,7 @@ int pci_set_power_state(struct pci_dev *
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
 void pci_pme_active(struct pci_dev *dev, bool enable);
-int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-		      bool runtime, bool enable);
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable);
 int pci_wake_from_d3(struct pci_dev *dev, bool enable);
 int pci_prepare_to_sleep(struct pci_dev *dev);
 int pci_back_from_sleep(struct pci_dev *dev);
@@ -1108,12 +1107,6 @@ void pci_pme_wakeup_bus(struct pci_bus *
 void pci_d3cold_enable(struct pci_dev *dev);
 void pci_d3cold_disable(struct pci_dev *dev);
 
-static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-				  bool enable)
-{
-	return __pci_enable_wake(dev, state, false, enable);
-}
-
 /* PCI Virtual Channel */
 int pci_save_vc_state(struct pci_dev *dev);
 void pci_restore_vc_state(struct pci_dev *dev);
Index: linux-pm/drivers/pci/pci.h
===================================================================
--- linux-pm.orig/drivers/pci/pci.h
+++ linux-pm/drivers/pci/pci.h
@@ -47,11 +47,7 @@ int pci_probe_reset_function(struct pci_
  *                platform; to be used during system-wide transitions from a
  *                sleeping state to the working state and vice versa
  *
- * @sleep_wake: enables/disables the system wake up capability of given device
- *
- * @run_wake: enables/disables the platform to generate run-time wake-up events
- *		for given device (the device's wake-up capability has to be
- *		enabled by @sleep_wake for this feature to work)
+ * @set_wakeup: enables/disables wakeup capability for the device
  *
  * @need_resume: returns 'true' if the given device (which is currently
  *		suspended) needs to be resumed to be configured for system
@@ -65,8 +61,7 @@ struct pci_platform_pm_ops {
 	int (*set_state)(struct pci_dev *dev, pci_power_t state);
 	pci_power_t (*get_state)(struct pci_dev *dev);
 	pci_power_t (*choose_state)(struct pci_dev *dev);
-	int (*sleep_wake)(struct pci_dev *dev, bool enable);
-	int (*run_wake)(struct pci_dev *dev, bool enable);
+	int (*set_wakeup)(struct pci_dev *dev, bool enable);
 	bool (*need_resume)(struct pci_dev *dev);
 };
 
Index: linux-pm/drivers/pci/pci-driver.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-driver.c
+++ linux-pm/drivers/pci/pci-driver.c
@@ -1216,7 +1216,7 @@ static int pci_pm_runtime_resume(struct
 
 	pci_restore_standard_config(pci_dev);
 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
-	__pci_enable_wake(pci_dev, PCI_D0, true, false);
+	pci_enable_wake(pci_dev, PCI_D0, false);
 	pci_fixup_device(pci_fixup_resume, pci_dev);
 
 	rc = pm->runtime_resume(dev);

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

* [PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
                   ` (3 preceding siblings ...)
  2017-06-19 21:35 ` [PATCH 4/6] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
@ 2017-06-19 21:36 ` Rafael J. Wysocki
  2017-06-20 12:38   ` kbuild test robot
  2017-06-20 22:24   ` [Update][PATCH " Rafael J. Wysocki
  2017-06-19 21:37 ` [PATCH 6/6] PM / core: Drop run_wake flag from struct dev_pm_info Rafael J. Wysocki
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-19 21:36 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

If acpi_pci_propagate_wakeup() is used, it may trigger wakeup
configuration twice for the same bridge indirectly, when configuring
wakeup for two different PCI devices under that bridge.  Actually,
however, the ACPI wakeup code can only be enabled to trigger wakeup
notifications for the bridge once in a row and there is no reference
counting in that code, so wakeup signaling on the bridge can be
disabled prematurely when it is disabled for the first of those
devices.

To prevent that from happening, add optional reference counting to
the ACPI device wakeup code and make acpi_pci_propagate_wakeup()
use if for bridges.

This works, because ACPI wakeup signaling for PCI bridges is only
set up by acpi_pci_propagate_wakeup(), so the reference counting
will only be used for them.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/device_pm.c |   35 +++++++++++++++++++++++++++++++----
 drivers/pci/pci-acpi.c   |    4 ++--
 include/acpi/acpi_bus.h  |   11 +++++++++--
 3 files changed, 42 insertions(+), 8 deletions(-)

Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -385,6 +385,7 @@ EXPORT_SYMBOL(acpi_bus_power_manageable)
 
 #ifdef CONFIG_PM
 static DEFINE_MUTEX(acpi_pm_notifier_lock);
+static DEFINE_MUTEX(acpi_wakeup_lock);
 
 void acpi_pm_wakeup_event(struct device *dev)
 {
@@ -724,11 +725,11 @@ static int acpi_device_wakeup(struct acp
 }
 
 /**
- * acpi_pm_device_wakeup - Enable/disable remote wakeup for given device.
+ * __acpi_pm_device_wakeup - Enable/disable remote wakeup for given device.
  * @dev: Device to enable/disable to generate wakeup events.
  * @enable: Whether to enable or disable the wakeup functionality.
  */
-int acpi_pm_device_wakeup(struct device *dev, bool enable)
+int __acpi_pm_device_wakeup(struct device *dev, bool enable, bool refcount)
 {
 	struct acpi_device *adev;
 	int error;
@@ -742,13 +743,39 @@ int acpi_pm_device_wakeup(struct device
 	if (!acpi_device_can_wakeup(adev))
 		return -EINVAL;
 
+	if (refcount) {
+		mutex_lock(&acpi_wakeup_lock);
+
+		if (enable) {
+			if (++adev->wakeup.enable_count > 1)
+				goto out;
+		} else {
+			if (WARN_ON_ONCE(adev->wakeup.enable_count == 0))
+				goto out;
+
+			if (--adev->wakeup.enable_count > 0)
+				goto out;
+		}
+	}
 	error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
-	if (!error)
+	if (error) {
+		if (refcount) {
+			if (enable)
+				adev->wakeup.enable_count--;
+			else
+				adev->wakeup.enable_count++;
+		}
+	} else {
 		dev_dbg(dev, "Wakeup %s by ACPI\n", enable ? "enabled" : "disabled");
+	}
+
+out:
+	if (refcount)
+		mutex_unlock(&acpi_wakeup_lock);
 
 	return error;
 }
-EXPORT_SYMBOL(acpi_pm_device_wakeup);
+EXPORT_SYMBOL(__acpi_pm_device_wakeup);
 
 /**
  * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -331,6 +331,7 @@ struct acpi_device_wakeup {
 	struct acpi_device_wakeup_context context;
 	struct wakeup_source *ws;
 	int prepare_count;
+	unsigned int enable_count;
 };
 
 struct acpi_device_physical_node {
@@ -603,7 +604,7 @@ acpi_status acpi_add_pm_notifier(struct
 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
 bool acpi_pm_device_can_wakeup(struct device *dev);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
-int acpi_pm_device_wakeup(struct device *dev, bool enable);
+int __acpi_pm_device_wakeup(struct device *dev, bool enable, bool refcount);
 #else
 static inline void acpi_pm_wakeup_event(struct device *dev)
 {
@@ -630,12 +631,18 @@ static inline int acpi_pm_device_sleep_s
 	return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
 		m : ACPI_STATE_D0;
 }
-static inline int acpi_pm_device_wakeup(struct device *dev, bool enable)
+static inline int __acpi_pm_device_wakeup(struct device *dev, bool enable,
+					  bool refcount)
 {
 	return -ENODEV;
 }
 #endif
 
+static inline int acpi_pm_device_wakeup(struct device *dev, bool enable)
+{
+	return __acpi_pm_device_wakeup(dev, enable, false);
+}
+
 #ifdef CONFIG_ACPI_SLEEP
 u32 acpi_target_system_state(void);
 #else
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -574,7 +574,7 @@ static int acpi_pci_propagate_wakeup(str
 {
 	while (bus->parent) {
 		if (acpi_pm_device_can_wakeup(&bus->self->dev))
-			return acpi_pm_device_wakeup(&bus->self->dev, enable);
+			return __acpi_pm_device_wakeup(&bus->self->dev, enable, true);
 
 		bus = bus->parent;
 	}
@@ -582,7 +582,7 @@ static int acpi_pci_propagate_wakeup(str
 	/* We have reached the root bus. */
 	if (bus->bridge) {
 		if (acpi_pm_device_can_wakeup(bus->bridge))
-			return acpi_pm_device_wakeup(bus->bridge, enable);
+			return __acpi_pm_device_wakeup(bus->bridge, enable, true);
 	}
 	return 0;
 }

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

* [PATCH 6/6] PM / core: Drop run_wake flag from struct dev_pm_info
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
                   ` (4 preceding siblings ...)
  2017-06-19 21:36 ` [PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early Rafael J. Wysocki
@ 2017-06-19 21:37 ` Rafael J. Wysocki
  2017-06-22  8:22 ` [PATCH 0/6] PM: Unify the handling of device wakeup settings Mika Westerberg
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
  7 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-19 21:37 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

The run_wake flag in struct dev_pm_info is used to indicate whether
or not the device is capable of generating remote wakeup signals at
run time (or in the system working state), but the distinction
between runtime remote wakeup and system wakeup signaling has always
been rather artificial.  The only practical reason for it to exist
at the core level was that ACPI and PCI treated those two cases
differently, but that's not the case any more after recent changes.

For this reason, get rid of the run_wake flag and, when applicable,
use device_set_wakeup_capable() and device_can_wakeup() instead of
device_set_run_wake() and device_run_wake(), respectively.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/pci_root.c     |    5 ++---
 drivers/pci/pci-acpi.c      |    5 +----
 drivers/pci/pci.c           |    6 +++---
 drivers/pci/pcie/pme.c      |    2 +-
 drivers/usb/dwc3/dwc3-pci.c |    3 +--
 drivers/usb/host/uhci-pci.c |    2 +-
 include/linux/pm.h          |    1 -
 include/linux/pm_runtime.h  |   12 ------------
 8 files changed, 9 insertions(+), 27 deletions(-)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -584,7 +584,6 @@ struct dev_pm_info {
 	unsigned int		idle_notification:1;
 	unsigned int		request_pending:1;
 	unsigned int		deferred_resume:1;
-	unsigned int		run_wake:1;
 	unsigned int		runtime_auto:1;
 	bool			ignore_children:1;
 	unsigned int		no_callbacks:1;
Index: linux-pm/include/linux/pm_runtime.h
===================================================================
--- linux-pm.orig/include/linux/pm_runtime.h
+++ linux-pm/include/linux/pm_runtime.h
@@ -76,16 +76,6 @@ static inline void pm_runtime_put_noidle
 	atomic_add_unless(&dev->power.usage_count, -1, 0);
 }
 
-static inline bool device_run_wake(struct device *dev)
-{
-	return dev->power.run_wake;
-}
-
-static inline void device_set_run_wake(struct device *dev, bool enable)
-{
-	dev->power.run_wake = enable;
-}
-
 static inline bool pm_runtime_suspended(struct device *dev)
 {
 	return dev->power.runtime_status == RPM_SUSPENDED
@@ -163,8 +153,6 @@ static inline void pm_runtime_forbid(str
 static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
 static inline void pm_runtime_get_noresume(struct device *dev) {}
 static inline void pm_runtime_put_noidle(struct device *dev) {}
-static inline bool device_run_wake(struct device *dev) { return false; }
-static inline void device_set_run_wake(struct device *dev, bool enable) {}
 static inline bool pm_runtime_suspended(struct device *dev) { return false; }
 static inline bool pm_runtime_active(struct device *dev) { return true; }
 static inline bool pm_runtime_status_suspended(struct device *dev) { return false; }
Index: linux-pm/drivers/acpi/pci_root.c
===================================================================
--- linux-pm.orig/drivers/acpi/pci_root.c
+++ linux-pm/drivers/acpi/pci_root.c
@@ -608,8 +608,7 @@ static int acpi_pci_root_add(struct acpi
 		pcie_no_aspm();
 
 	pci_acpi_add_bus_pm_notifier(device);
-	if (device->wakeup.flags.valid)
-		device_set_run_wake(root->bus->bridge, true);
+	device_set_wakeup_capable(root->bus->bridge, device->wakeup.flags.valid);
 
 	if (hotadd) {
 		pcibios_resource_survey_bus(root->bus);
@@ -649,7 +648,7 @@ static void acpi_pci_root_remove(struct
 	pci_stop_root_bus(root->bus);
 
 	pci_ioapic_remove(root);
-	device_set_run_wake(root->bus->bridge, false);
+	device_set_wakeup_capable(root->bus->bridge, false);
 	pci_acpi_remove_bus_pm_notifier(device);
 
 	pci_remove_root_bus(root->bus);
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -739,7 +739,6 @@ static void pci_acpi_setup(struct device
 		return;
 
 	device_set_wakeup_capable(dev, true);
-	device_set_run_wake(dev, true);
 	acpi_pci_wakeup(pci_dev, false);
 }
 
@@ -751,10 +750,8 @@ static void pci_acpi_cleanup(struct devi
 		return;
 
 	pci_acpi_remove_pm_notifier(adev);
-	if (adev->wakeup.flags.valid) {
+	if (adev->wakeup.flags.valid)
 		device_set_wakeup_capable(dev, false);
-		device_set_run_wake(dev, false);
-	}
 }
 
 static bool pci_acpi_bus_match(struct device *dev)
Index: linux-pm/drivers/pci/pcie/pme.c
===================================================================
--- linux-pm.orig/drivers/pci/pcie/pme.c
+++ linux-pm/drivers/pci/pcie/pme.c
@@ -300,7 +300,7 @@ static irqreturn_t pcie_pme_irq(int irq,
  */
 static int pcie_pme_can_wakeup(struct pci_dev *dev, void *ign)
 {
-	device_set_run_wake(&dev->dev, true);
+	device_set_wakeup_capable(&dev->dev, true);
 	return 0;
 }
 
Index: linux-pm/drivers/usb/dwc3/dwc3-pci.c
===================================================================
--- linux-pm.orig/drivers/usb/dwc3/dwc3-pci.c
+++ linux-pm/drivers/usb/dwc3/dwc3-pci.c
@@ -230,7 +230,6 @@ static int dwc3_pci_probe(struct pci_dev
 	}
 
 	device_init_wakeup(dev, true);
-	device_set_run_wake(dev, true);
 	pci_set_drvdata(pci, dwc);
 	pm_runtime_put(dev);
 
@@ -310,7 +309,7 @@ static int dwc3_pci_runtime_suspend(stru
 {
 	struct dwc3_pci		*dwc = dev_get_drvdata(dev);
 
-	if (device_run_wake(dev))
+	if (device_can_wakeup(dev))
 		return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
 
 	return -EBUSY;
Index: linux-pm/drivers/usb/host/uhci-pci.c
===================================================================
--- linux-pm.orig/drivers/usb/host/uhci-pci.c
+++ linux-pm/drivers/usb/host/uhci-pci.c
@@ -131,7 +131,7 @@ static int uhci_pci_init(struct usb_hcd
 
 	/* Intel controllers use non-PME wakeup signalling */
 	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
-		device_set_run_wake(uhci_dev(uhci), 1);
+		device_set_wakeup_capable(uhci_dev(uhci), true);
 
 	/* Set up pointers to PCI-specific functions */
 	uhci->reset_hc = uhci_pci_reset_hc;
Index: linux-pm/drivers/pci/pci.c
===================================================================
--- linux-pm.orig/drivers/pci/pci.c
+++ linux-pm/drivers/pci/pci.c
@@ -2105,7 +2105,7 @@ bool pci_dev_run_wake(struct pci_dev *de
 {
 	struct pci_bus *bus = dev->bus;
 
-	if (device_run_wake(&dev->dev))
+	if (device_can_wakeup(&dev->dev))
 		return true;
 
 	if (!dev->pme_support)
@@ -2118,7 +2118,7 @@ bool pci_dev_run_wake(struct pci_dev *de
 	while (bus->parent) {
 		struct pci_dev *bridge = bus->self;
 
-		if (device_run_wake(&bridge->dev))
+		if (device_can_wakeup(&bridge->dev))
 			return true;
 
 		bus = bus->parent;
@@ -2126,7 +2126,7 @@ bool pci_dev_run_wake(struct pci_dev *de
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
-		return device_run_wake(bus->bridge);
+		return device_can_wakeup(bus->bridge);
 
 	return false;
 }

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

* Re: [PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early
  2017-06-19 21:36 ` [PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early Rafael J. Wysocki
@ 2017-06-20 12:38   ` kbuild test robot
  2017-06-20 22:24   ` [Update][PATCH " Rafael J. Wysocki
  1 sibling, 0 replies; 25+ messages in thread
From: kbuild test robot @ 2017-06-20 12:38 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: kbuild-all, Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas,
	Mika Westerberg, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 3313 bytes --]

Hi Rafael,

[auto build test WARNING on pm/linux-next]
[also build test WARNING on next-20170620]
[cannot apply to v4.12-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Rafael-J-Wysocki/PM-Unify-the-handling-of-device-wakeup-settings/20170620-195729
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: x86_64-randconfig-x019-201725 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers/acpi/device_pm.c: In function '__acpi_pm_device_wakeup':
>> drivers/acpi/device_pm.c:735:6: warning: 'error' may be used uninitialized in this function [-Wmaybe-uninitialized]
     int error;
         ^~~~~

vim +/error +735 drivers/acpi/device_pm.c

235d81a6 Rafael J. Wysocki 2017-06-12  719  	} else if (adev->wakeup.flags.enabled) {
dee8370c Rafael J. Wysocki 2012-11-02  720  		acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
dee8370c Rafael J. Wysocki 2012-11-02  721  		acpi_disable_wakeup_device_power(adev);
235d81a6 Rafael J. Wysocki 2017-06-12  722  		adev->wakeup.flags.enabled = 0;
dee8370c Rafael J. Wysocki 2012-11-02  723  	}
dee8370c Rafael J. Wysocki 2012-11-02  724  	return 0;
dee8370c Rafael J. Wysocki 2012-11-02  725  }
dee8370c Rafael J. Wysocki 2012-11-02  726  
dee8370c Rafael J. Wysocki 2012-11-02  727  /**
6909f7ad Rafael J. Wysocki 2017-06-19  728   * __acpi_pm_device_wakeup - Enable/disable remote wakeup for given device.
9f7d805b Rafael J. Wysocki 2017-06-19  729   * @dev: Device to enable/disable to generate wakeup events.
dee8370c Rafael J. Wysocki 2012-11-02  730   * @enable: Whether to enable or disable the wakeup functionality.
cd7bd02d Rafael J. Wysocki 2012-11-02  731   */
6909f7ad Rafael J. Wysocki 2017-06-19  732  int __acpi_pm_device_wakeup(struct device *dev, bool enable, bool refcount)
a6ae7594 Rafael J. Wysocki 2012-11-02  733  {
a6ae7594 Rafael J. Wysocki 2012-11-02  734  	struct acpi_device *adev;
a6ae7594 Rafael J. Wysocki 2012-11-02 @735  	int error;
a6ae7594 Rafael J. Wysocki 2012-11-02  736  
17653a3e Rafael J. Wysocki 2014-07-23  737  	adev = ACPI_COMPANION(dev);
17653a3e Rafael J. Wysocki 2014-07-23  738  	if (!adev) {
17653a3e Rafael J. Wysocki 2014-07-23  739  		dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
a6ae7594 Rafael J. Wysocki 2012-11-02  740  		return -ENODEV;
a6ae7594 Rafael J. Wysocki 2012-11-02  741  	}
a6ae7594 Rafael J. Wysocki 2012-11-02  742  
9f7d805b Rafael J. Wysocki 2017-06-19  743  	if (!acpi_device_can_wakeup(adev))

:::::: The code at line 735 was first introduced by commit
:::::: a6ae7594b1b157e0e7976ed105a7be27d69a5361 ACPI / PM: Move device PM functions related to sleep states

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

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 24782 bytes --]

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

* Re: [PATCH 4/6] PCI / PM: Simplify device wakeup settings code
  2017-06-19 21:35 ` [PATCH 4/6] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
@ 2017-06-20 14:00   ` kbuild test robot
  2017-06-20 16:16   ` kbuild test robot
  2017-06-20 22:23   ` [Update][PATCH " Rafael J. Wysocki
  2 siblings, 0 replies; 25+ messages in thread
From: kbuild test robot @ 2017-06-20 14:00 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: kbuild-all, Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas,
	Mika Westerberg, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 2557 bytes --]

Hi Rafael,

[auto build test ERROR on pm/linux-next]
[also build test ERROR on next-20170620]
[cannot apply to v4.12-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Rafael-J-Wysocki/PM-Unify-the-handling-of-device-wakeup-settings/20170620-195729
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: x86_64-randconfig-s5-06202012 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> drivers//pci/pci-mid.c:62:2: error: unknown field 'sleep_wake' specified in initializer
     .sleep_wake = mid_pci_sleep_wake,
     ^
>> drivers//pci/pci-mid.c:63:2: error: unknown field 'run_wake' specified in initializer
     .run_wake = mid_pci_run_wake,
     ^
>> drivers//pci/pci-mid.c:63:14: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .run_wake = mid_pci_run_wake,
                 ^~~~~~~~~~~~~~~~
   drivers//pci/pci-mid.c:63:14: note: (near initialization for 'mid_pci_platform_pm.need_resume')
   cc1: some warnings being treated as errors

vim +/sleep_wake +62 drivers//pci/pci-mid.c

5823d0893 Andy Shevchenko 2016-06-14  56  
c93122548 Lukas Wunner    2016-12-12  57  static const struct pci_platform_pm_ops mid_pci_platform_pm = {
5823d0893 Andy Shevchenko 2016-06-14  58  	.is_manageable	= mid_pci_power_manageable,
5823d0893 Andy Shevchenko 2016-06-14  59  	.set_state	= mid_pci_set_power_state,
e8a6123e9 Lukas Wunner    2016-10-23  60  	.get_state	= mid_pci_get_power_state,
5823d0893 Andy Shevchenko 2016-06-14  61  	.choose_state	= mid_pci_choose_state,
5823d0893 Andy Shevchenko 2016-06-14 @62  	.sleep_wake	= mid_pci_sleep_wake,
5823d0893 Andy Shevchenko 2016-06-14 @63  	.run_wake	= mid_pci_run_wake,
5823d0893 Andy Shevchenko 2016-06-14  64  	.need_resume	= mid_pci_need_resume,
5823d0893 Andy Shevchenko 2016-06-14  65  };
5823d0893 Andy Shevchenko 2016-06-14  66  

:::::: The code at line 62 was first introduced by commit
:::::: 5823d0893ec284f37902e2ecd332dbb396a143d1 x86/platform/intel-mid: Add Power Management Unit driver

:::::: TO: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
:::::: CC: Ingo Molnar <mingo@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28304 bytes --]

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

* Re: [PATCH 4/6] PCI / PM: Simplify device wakeup settings code
  2017-06-19 21:35 ` [PATCH 4/6] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
  2017-06-20 14:00   ` kbuild test robot
@ 2017-06-20 16:16   ` kbuild test robot
  2017-06-20 22:23   ` [Update][PATCH " Rafael J. Wysocki
  2 siblings, 0 replies; 25+ messages in thread
From: kbuild test robot @ 2017-06-20 16:16 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: kbuild-all, Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas,
	Mika Westerberg, Greg Kroah-Hartman

[-- Attachment #1: Type: text/plain, Size: 2431 bytes --]

Hi Rafael,

[auto build test WARNING on pm/linux-next]
[also build test WARNING on next-20170620]
[cannot apply to v4.12-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Rafael-J-Wysocki/PM-Unify-the-handling-of-device-wakeup-settings/20170620-195729
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next
config: x86_64-randconfig-n0-06202146 (attached as .config)
compiler: gcc-4.8 (Debian 4.8.4-1) 4.8.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All warnings (new ones prefixed by >>):

   drivers/pci/pci-mid.c:62:2: error: unknown field 'sleep_wake' specified in initializer
     .sleep_wake = mid_pci_sleep_wake,
     ^
   drivers/pci/pci-mid.c:63:2: error: unknown field 'run_wake' specified in initializer
     .run_wake = mid_pci_run_wake,
     ^
>> drivers/pci/pci-mid.c:63:2: warning: initialization from incompatible pointer type [enabled by default]
   drivers/pci/pci-mid.c:63:2: warning: (near initialization for 'mid_pci_platform_pm.need_resume') [enabled by default]

vim +63 drivers/pci/pci-mid.c

5823d0893 Andy Shevchenko 2016-06-14  56  
c93122548 Lukas Wunner    2016-12-12  57  static const struct pci_platform_pm_ops mid_pci_platform_pm = {
5823d0893 Andy Shevchenko 2016-06-14  58  	.is_manageable	= mid_pci_power_manageable,
5823d0893 Andy Shevchenko 2016-06-14  59  	.set_state	= mid_pci_set_power_state,
e8a6123e9 Lukas Wunner    2016-10-23  60  	.get_state	= mid_pci_get_power_state,
5823d0893 Andy Shevchenko 2016-06-14  61  	.choose_state	= mid_pci_choose_state,
5823d0893 Andy Shevchenko 2016-06-14 @62  	.sleep_wake	= mid_pci_sleep_wake,
5823d0893 Andy Shevchenko 2016-06-14 @63  	.run_wake	= mid_pci_run_wake,
5823d0893 Andy Shevchenko 2016-06-14  64  	.need_resume	= mid_pci_need_resume,
5823d0893 Andy Shevchenko 2016-06-14  65  };
5823d0893 Andy Shevchenko 2016-06-14  66  

:::::: The code at line 63 was first introduced by commit
:::::: 5823d0893ec284f37902e2ecd332dbb396a143d1 x86/platform/intel-mid: Add Power Management Unit driver

:::::: TO: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
:::::: CC: Ingo Molnar <mingo@kernel.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25308 bytes --]

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

* [Update][PATCH 4/6] PCI / PM: Simplify device wakeup settings code
  2017-06-19 21:35 ` [PATCH 4/6] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
  2017-06-20 14:00   ` kbuild test robot
  2017-06-20 16:16   ` kbuild test robot
@ 2017-06-20 22:23   ` Rafael J. Wysocki
  2 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-20 22:23 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

After previous changes it is not necessary to distinguish between
device wakeup for run time and device wakeup from system sleep states
any more, so rework the PCI device wakeup settings code accordingly.

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

Updated to fix a build issue in pci-mid.c reported by 0-day.

---
 drivers/pci/pci-acpi.c   |    3 +--
 drivers/pci/pci-driver.c |    2 +-
 drivers/pci/pci-mid.c    |   10 ++--------
 drivers/pci/pci.c        |   36 ++++++++++--------------------------
 drivers/pci/pci.h        |    9 ++-------
 include/linux/pci.h      |    9 +--------
 6 files changed, 17 insertions(+), 52 deletions(-)

Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -616,8 +616,7 @@ static const struct pci_platform_pm_ops
 	.set_state = acpi_pci_set_power_state,
 	.get_state = acpi_pci_get_power_state,
 	.choose_state = acpi_pci_choose_state,
-	.sleep_wake = acpi_pci_wakeup,
-	.run_wake = acpi_pci_wakeup,
+	.set_wakeup = acpi_pci_wakeup,
 	.need_resume = acpi_pci_need_resume,
 };
 
Index: linux-pm/drivers/pci/pci.c
===================================================================
--- linux-pm.orig/drivers/pci/pci.c
+++ linux-pm/drivers/pci/pci.c
@@ -574,8 +574,7 @@ static const struct pci_platform_pm_ops
 int pci_set_platform_pm(const struct pci_platform_pm_ops *ops)
 {
 	if (!ops->is_manageable || !ops->set_state  || !ops->get_state ||
-	    !ops->choose_state  || !ops->sleep_wake || !ops->run_wake  ||
-	    !ops->need_resume)
+	    !ops->choose_state  || !ops->set_wakeup || !ops->need_resume)
 		return -EINVAL;
 	pci_platform_pm = ops;
 	return 0;
@@ -603,16 +602,10 @@ static inline pci_power_t platform_pci_c
 			pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
 }
 
-static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
+static inline int platform_pci_set_wakeup(struct pci_dev *dev, bool enable)
 {
 	return pci_platform_pm ?
-			pci_platform_pm->sleep_wake(dev, enable) : -ENODEV;
-}
-
-static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable)
-{
-	return pci_platform_pm ?
-			pci_platform_pm->run_wake(dev, enable) : -ENODEV;
+			pci_platform_pm->set_wakeup(dev, enable) : -ENODEV;
 }
 
 static inline bool platform_pci_need_resume(struct pci_dev *dev)
@@ -1889,10 +1882,9 @@ void pci_pme_active(struct pci_dev *dev,
 EXPORT_SYMBOL(pci_pme_active);
 
 /**
- * __pci_enable_wake - enable PCI device as wakeup event source
+ * pci_enable_wake - enable PCI device as wakeup event source
  * @dev: PCI device affected
  * @state: PCI state from which device will issue wakeup events
- * @runtime: True if the events are to be generated at run time
  * @enable: True to enable event generation; false to disable
  *
  * This enables the device as a wakeup event source, or disables it.
@@ -1908,14 +1900,10 @@ EXPORT_SYMBOL(pci_pme_active);
  * Error code depending on the platform is returned if both the platform and
  * the native mechanism fail to enable the generation of wake-up events
  */
-int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-		      bool runtime, bool enable)
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
 {
 	int ret = 0;
 
-	if (enable && !runtime && !device_may_wakeup(&dev->dev))
-		return -EINVAL;
-
 	/*
 	 * Don't do the same thing twice in a row for one device, but restore
 	 * PME Enable in case it has been updated by config space restoration.
@@ -1938,24 +1926,20 @@ int __pci_enable_wake(struct pci_dev *de
 			pci_pme_active(dev, true);
 		else
 			ret = 1;
-		error = runtime ? platform_pci_run_wake(dev, true) :
-					platform_pci_sleep_wake(dev, true);
+		error = platform_pci_set_wakeup(dev, true);
 		if (ret)
 			ret = error;
 		if (!ret)
 			dev->wakeup_prepared = true;
 	} else {
-		if (runtime)
-			platform_pci_run_wake(dev, false);
-		else
-			platform_pci_sleep_wake(dev, false);
+		platform_pci_set_wakeup(dev, false);
 		pci_pme_active(dev, false);
 		dev->wakeup_prepared = false;
 	}
 
 	return ret;
 }
-EXPORT_SYMBOL(__pci_enable_wake);
+EXPORT_SYMBOL(pci_enable_wake);
 
 /**
  * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
@@ -2097,12 +2081,12 @@ int pci_finish_runtime_suspend(struct pc
 
 	dev->runtime_d3cold = target_state == PCI_D3cold;
 
-	__pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev));
+	pci_enable_wake(dev, target_state, pci_dev_run_wake(dev));
 
 	error = pci_set_power_state(dev, target_state);
 
 	if (error) {
-		__pci_enable_wake(dev, target_state, true, false);
+		pci_enable_wake(dev, target_state, false);
 		dev->runtime_d3cold = false;
 	}
 
Index: linux-pm/include/linux/pci.h
===================================================================
--- linux-pm.orig/include/linux/pci.h
+++ linux-pm/include/linux/pci.h
@@ -1097,8 +1097,7 @@ int pci_set_power_state(struct pci_dev *
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
 void pci_pme_active(struct pci_dev *dev, bool enable);
-int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-		      bool runtime, bool enable);
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable);
 int pci_wake_from_d3(struct pci_dev *dev, bool enable);
 int pci_prepare_to_sleep(struct pci_dev *dev);
 int pci_back_from_sleep(struct pci_dev *dev);
@@ -1108,12 +1107,6 @@ void pci_pme_wakeup_bus(struct pci_bus *
 void pci_d3cold_enable(struct pci_dev *dev);
 void pci_d3cold_disable(struct pci_dev *dev);
 
-static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-				  bool enable)
-{
-	return __pci_enable_wake(dev, state, false, enable);
-}
-
 /* PCI Virtual Channel */
 int pci_save_vc_state(struct pci_dev *dev);
 void pci_restore_vc_state(struct pci_dev *dev);
Index: linux-pm/drivers/pci/pci.h
===================================================================
--- linux-pm.orig/drivers/pci/pci.h
+++ linux-pm/drivers/pci/pci.h
@@ -47,11 +47,7 @@ int pci_probe_reset_function(struct pci_
  *                platform; to be used during system-wide transitions from a
  *                sleeping state to the working state and vice versa
  *
- * @sleep_wake: enables/disables the system wake up capability of given device
- *
- * @run_wake: enables/disables the platform to generate run-time wake-up events
- *		for given device (the device's wake-up capability has to be
- *		enabled by @sleep_wake for this feature to work)
+ * @set_wakeup: enables/disables wakeup capability for the device
  *
  * @need_resume: returns 'true' if the given device (which is currently
  *		suspended) needs to be resumed to be configured for system
@@ -65,8 +61,7 @@ struct pci_platform_pm_ops {
 	int (*set_state)(struct pci_dev *dev, pci_power_t state);
 	pci_power_t (*get_state)(struct pci_dev *dev);
 	pci_power_t (*choose_state)(struct pci_dev *dev);
-	int (*sleep_wake)(struct pci_dev *dev, bool enable);
-	int (*run_wake)(struct pci_dev *dev, bool enable);
+	int (*set_wakeup)(struct pci_dev *dev, bool enable);
 	bool (*need_resume)(struct pci_dev *dev);
 };
 
Index: linux-pm/drivers/pci/pci-driver.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-driver.c
+++ linux-pm/drivers/pci/pci-driver.c
@@ -1216,7 +1216,7 @@ static int pci_pm_runtime_resume(struct
 
 	pci_restore_standard_config(pci_dev);
 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
-	__pci_enable_wake(pci_dev, PCI_D0, true, false);
+	pci_enable_wake(pci_dev, PCI_D0, false);
 	pci_fixup_device(pci_fixup_resume, pci_dev);
 
 	rc = pm->runtime_resume(dev);
Index: linux-pm/drivers/pci/pci-mid.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-mid.c
+++ linux-pm/drivers/pci/pci-mid.c
@@ -39,12 +39,7 @@ static pci_power_t mid_pci_choose_state(
 	return PCI_D3hot;
 }
 
-static int mid_pci_sleep_wake(struct pci_dev *dev, bool enable)
-{
-	return 0;
-}
-
-static int mid_pci_run_wake(struct pci_dev *dev, bool enable)
+static int mid_pci_wakeup(struct pci_dev *dev, bool enable)
 {
 	return 0;
 }
@@ -59,8 +54,7 @@ static const struct pci_platform_pm_ops
 	.set_state	= mid_pci_set_power_state,
 	.get_state	= mid_pci_get_power_state,
 	.choose_state	= mid_pci_choose_state,
-	.sleep_wake	= mid_pci_sleep_wake,
-	.run_wake	= mid_pci_run_wake,
+	.set_wakeup	= mid_pci_wakeup,
 	.need_resume	= mid_pci_need_resume,
 };
 

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

* [Update][PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early
  2017-06-19 21:36 ` [PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early Rafael J. Wysocki
  2017-06-20 12:38   ` kbuild test robot
@ 2017-06-20 22:24   ` Rafael J. Wysocki
  1 sibling, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-20 22:24 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

If acpi_pci_propagate_wakeup() is used, it may trigger wakeup
configuration twice for the same bridge indirectly, when configuring
wakeup for two different PCI devices under that bridge.  Actually,
however, the ACPI wakeup code can only be enabled to trigger wakeup
notifications for the bridge once in a row and there is no reference
counting in that code, so wakeup signaling on the bridge can be
disabled prematurely when it is disabled for the first of those
devices.

To prevent that from happening, add optional reference counting to
the ACPI device wakeup code and make acpi_pci_propagate_wakeup()
use if for bridges.

This works, because ACPI wakeup signaling for PCI bridges is only
set up by acpi_pci_propagate_wakeup(), so the reference counting
will only be used for them.

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

Updated to fix an uninitialized variable bug reported by 0-day.

---
 drivers/acpi/device_pm.c |   37 ++++++++++++++++++++++++++++++++-----
 drivers/pci/pci-acpi.c   |    4 ++--
 include/acpi/acpi_bus.h  |   11 +++++++++--
 3 files changed, 43 insertions(+), 9 deletions(-)

Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -385,6 +385,7 @@ EXPORT_SYMBOL(acpi_bus_power_manageable)
 
 #ifdef CONFIG_PM
 static DEFINE_MUTEX(acpi_pm_notifier_lock);
+static DEFINE_MUTEX(acpi_wakeup_lock);
 
 void acpi_pm_wakeup_event(struct device *dev)
 {
@@ -724,14 +725,14 @@ static int acpi_device_wakeup(struct acp
 }
 
 /**
- * acpi_pm_device_wakeup - Enable/disable remote wakeup for given device.
+ * __acpi_pm_device_wakeup - Enable/disable remote wakeup for given device.
  * @dev: Device to enable/disable to generate wakeup events.
  * @enable: Whether to enable or disable the wakeup functionality.
  */
-int acpi_pm_device_wakeup(struct device *dev, bool enable)
+int __acpi_pm_device_wakeup(struct device *dev, bool enable, bool refcount)
 {
 	struct acpi_device *adev;
-	int error;
+	int error = 0;
 
 	adev = ACPI_COMPANION(dev);
 	if (!adev) {
@@ -742,13 +743,39 @@ int acpi_pm_device_wakeup(struct device
 	if (!acpi_device_can_wakeup(adev))
 		return -EINVAL;
 
+	if (refcount) {
+		mutex_lock(&acpi_wakeup_lock);
+
+		if (enable) {
+			if (++adev->wakeup.enable_count > 1)
+				goto out;
+		} else {
+			if (WARN_ON_ONCE(adev->wakeup.enable_count == 0))
+				goto out;
+
+			if (--adev->wakeup.enable_count > 0)
+				goto out;
+		}
+	}
 	error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
-	if (!error)
+	if (error) {
+		if (refcount) {
+			if (enable)
+				adev->wakeup.enable_count--;
+			else
+				adev->wakeup.enable_count++;
+		}
+	} else {
 		dev_dbg(dev, "Wakeup %s by ACPI\n", enable ? "enabled" : "disabled");
+	}
+
+out:
+	if (refcount)
+		mutex_unlock(&acpi_wakeup_lock);
 
 	return error;
 }
-EXPORT_SYMBOL(acpi_pm_device_wakeup);
+EXPORT_SYMBOL(__acpi_pm_device_wakeup);
 
 /**
  * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -331,6 +331,7 @@ struct acpi_device_wakeup {
 	struct acpi_device_wakeup_context context;
 	struct wakeup_source *ws;
 	int prepare_count;
+	unsigned int enable_count;
 };
 
 struct acpi_device_physical_node {
@@ -603,7 +604,7 @@ acpi_status acpi_add_pm_notifier(struct
 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
 bool acpi_pm_device_can_wakeup(struct device *dev);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
-int acpi_pm_device_wakeup(struct device *dev, bool enable);
+int __acpi_pm_device_wakeup(struct device *dev, bool enable, bool refcount);
 #else
 static inline void acpi_pm_wakeup_event(struct device *dev)
 {
@@ -630,12 +631,18 @@ static inline int acpi_pm_device_sleep_s
 	return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
 		m : ACPI_STATE_D0;
 }
-static inline int acpi_pm_device_wakeup(struct device *dev, bool enable)
+static inline int __acpi_pm_device_wakeup(struct device *dev, bool enable,
+					  bool refcount)
 {
 	return -ENODEV;
 }
 #endif
 
+static inline int acpi_pm_device_wakeup(struct device *dev, bool enable)
+{
+	return __acpi_pm_device_wakeup(dev, enable, false);
+}
+
 #ifdef CONFIG_ACPI_SLEEP
 u32 acpi_target_system_state(void);
 #else
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -574,7 +574,7 @@ static int acpi_pci_propagate_wakeup(str
 {
 	while (bus->parent) {
 		if (acpi_pm_device_can_wakeup(&bus->self->dev))
-			return acpi_pm_device_wakeup(&bus->self->dev, enable);
+			return __acpi_pm_device_wakeup(&bus->self->dev, enable, true);
 
 		bus = bus->parent;
 	}
@@ -582,7 +582,7 @@ static int acpi_pci_propagate_wakeup(str
 	/* We have reached the root bus. */
 	if (bus->bridge) {
 		if (acpi_pm_device_can_wakeup(bus->bridge))
-			return acpi_pm_device_wakeup(bus->bridge, enable);
+			return __acpi_pm_device_wakeup(bus->bridge, enable, true);
 	}
 	return 0;
 }

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

* Re: [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code
  2017-06-19 21:33 ` [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code Rafael J. Wysocki
@ 2017-06-22  7:39   ` Mika Westerberg
  2017-06-22 14:38     ` Rafael J. Wysocki
  0 siblings, 1 reply; 25+ messages in thread
From: Mika Westerberg @ 2017-06-22  7:39 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Greg Kroah-Hartman

On Mon, Jun 19, 2017 at 11:33:52PM +0200, Rafael J. Wysocki wrote:
> -#ifdef CONFIG_PM_SLEEP
> -/**
> - * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
> - * @dev: Device to enable/desible to wake up the system from sleep states.
> - * @enable: Whether to enable or disable @dev to wake up the system.
> - */
> -int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
> +int acpi_pm_device_wakeup(struct device *dev, bool enable)

Can we call it acpi_pm_device_enable_wakeup() and then provide
corresponding acpi_pm_device_disable_wakeup()? I find those easier to
understand than acpi_pm_device_wakeup() that sounds like the device
should be woken up now.

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

* Re: [PATCH 0/6] PM: Unify the handling of device wakeup settings
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
                   ` (5 preceding siblings ...)
  2017-06-19 21:37 ` [PATCH 6/6] PM / core: Drop run_wake flag from struct dev_pm_info Rafael J. Wysocki
@ 2017-06-22  8:22 ` Mika Westerberg
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
  7 siblings, 0 replies; 25+ messages in thread
From: Mika Westerberg @ 2017-06-22  8:22 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Greg Kroah-Hartman

On Mon, Jun 19, 2017 at 11:31:58PM +0200, Rafael J. Wysocki wrote:
> Hi All,
> 
> The handling of device wakeup settings, especially in the ACPI core and the PCI
> bus type, depends on whether it is about system wakeup from sleep states or
> remote wakeup in the working state (runtime).  However, that distinction is
> mostly based on the ACPI concept of "wakeup" and "runtime" GPEs, which is
> somewhat artificial, because the underlying hardware mechanism is basically
> the same in both cases.
> 
> Moreover, suspend-to-idle is now supported as a sleep state and wakeup from it
> is based on exactly the same hardware capabilities as the working-state
> (runtime) remote wakeup.
> 
> The following patch series removes that distinction and unifies the handling of
> device wakeup settings between system sleep and runtime.  It also fixes one
> issue related to wakeup signaling through PCI bridges.
> 
> [1/6]: Get rid of the "runtime wakeup" concept from the ACPI core.
> [2/6]: Unify device wakeup settings code paths in the ACPI core.
> [3-4/6]: Unify device wakeup settings code paths in the PCI bus type code.
> [5/6]: Fix wakeup-related issue with bridges in the PCI bus type code.
> [6/6]: Get rid of the "runtime wakeup" concept from the driver core.
> 
> The series is based on current linux-next and will be made available for
> testing in the linux-pm.git tree in a couple of days.

Apart from that one minor comment, this looks good to me. I'm happy that
we get rid of those run_wake things which I always find really
confusing :)

For the whole series,

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>

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

* Re: [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code
  2017-06-22  7:39   ` Mika Westerberg
@ 2017-06-22 14:38     ` Rafael J. Wysocki
  2017-06-23  1:05       ` Rafael J. Wysocki
  0 siblings, 1 reply; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-22 14:38 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Greg Kroah-Hartman

On Thursday, June 22, 2017 10:39:37 AM Mika Westerberg wrote:
> On Mon, Jun 19, 2017 at 11:33:52PM +0200, Rafael J. Wysocki wrote:
> > -#ifdef CONFIG_PM_SLEEP
> > -/**
> > - * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
> > - * @dev: Device to enable/desible to wake up the system from sleep states.
> > - * @enable: Whether to enable or disable @dev to wake up the system.
> > - */
> > -int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
> > +int acpi_pm_device_wakeup(struct device *dev, bool enable)
> 
> Can we call it acpi_pm_device_enable_wakeup() and then provide
> corresponding acpi_pm_device_disable_wakeup()? I find those easier to
> understand than acpi_pm_device_wakeup() that sounds like the device
> should be woken up now.

OK, fair enough.  I'll change it this way.

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

* Re: [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code
  2017-06-22 14:38     ` Rafael J. Wysocki
@ 2017-06-23  1:05       ` Rafael J. Wysocki
  2017-06-26 13:29         ` Mika Westerberg
  0 siblings, 1 reply; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-23  1:05 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Greg Kroah-Hartman

On Thursday, June 22, 2017 04:38:49 PM Rafael J. Wysocki wrote:
> On Thursday, June 22, 2017 10:39:37 AM Mika Westerberg wrote:
> > On Mon, Jun 19, 2017 at 11:33:52PM +0200, Rafael J. Wysocki wrote:
> > > -#ifdef CONFIG_PM_SLEEP
> > > -/**
> > > - * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
> > > - * @dev: Device to enable/desible to wake up the system from sleep states.
> > > - * @enable: Whether to enable or disable @dev to wake up the system.
> > > - */
> > > -int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
> > > +int acpi_pm_device_wakeup(struct device *dev, bool enable)
> > 
> > Can we call it acpi_pm_device_enable_wakeup() and then provide
> > corresponding acpi_pm_device_disable_wakeup()? I find those easier to
> > understand than acpi_pm_device_wakeup() that sounds like the device
> > should be woken up now.
> 
> OK, fair enough.  I'll change it this way.

Well, sorry, I'd rather not to, or we'll have to add a wrapper around them in
pci-acpi.c. :-)

I can rename it to acpi_pm_device_set_wakeup(), though.

Thanks,
Rafael


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

* [PATCH v2 0/5] PM: Unify the handling of device wakeup settings
  2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
                   ` (6 preceding siblings ...)
  2017-06-22  8:22 ` [PATCH 0/6] PM: Unify the handling of device wakeup settings Mika Westerberg
@ 2017-06-23 23:50 ` Rafael J. Wysocki
  2017-06-23 23:53   ` [PATCH v2 1/5] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
                     ` (5 more replies)
  7 siblings, 6 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-23 23:50 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

On Monday, June 19, 2017 11:31:58 PM Rafael J. Wysocki wrote:
> Hi All,
> 
> The handling of device wakeup settings, especially in the ACPI core and the PCI
> bus type, depends on whether it is about system wakeup from sleep states or
> remote wakeup in the working state (runtime).  However, that distinction is
> mostly based on the ACPI concept of "wakeup" and "runtime" GPEs, which is
> somewhat artificial, because the underlying hardware mechanism is basically
> the same in both cases.
> 
> Moreover, suspend-to-idle is now supported as a sleep state and wakeup from it
> is based on exactly the same hardware capabilities as the working-state
> (runtime) remote wakeup.
> 
> The following patch series removes that distinction and unifies the handling of
> device wakeup settings between system sleep and runtime.  It also fixes one
> issue related to wakeup signaling through PCI bridges.
> 
> [1/6]: Get rid of the "runtime wakeup" concept from the ACPI core.
> [2/6]: Unify device wakeup settings code paths in the ACPI core.
> [3-4/6]: Unify device wakeup settings code paths in the PCI bus type code.
> [5/6]: Fix wakeup-related issue with bridges in the PCI bus type code.
> [6/6]: Get rid of the "runtime wakeup" concept from the driver core.
> 
> The series is based on current linux-next and will be made available for
> testing in the linux-pm.git tree in a couple of days.

Here's a v2 with tentatively added Reviewed-by tags from Mika.

I've dropped patch [5/6] from the previous iteration as it didn't really belong
here and the issue it attempted to fix is rather theoretical.  I'm going to
take a different approach there.

Apart from this, the function previously called acpi_pm_device_wakeup() has
a different name now: acpi_pm_set_device_wakeup(), to possibly avoid
confusion about its purpose.

Also the changelog of patch [3/5] has been modified slightly.

Thanks,
Rafael

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

* [PATCH v2 1/5] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
@ 2017-06-23 23:53   ` Rafael J. Wysocki
  2017-06-23 23:54   ` [PATCH v2 2/5] ACPI / PM: Consolidate device wakeup settings code Rafael J. Wysocki
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-23 23:53 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

The run_wake flag in struct acpi_device_wakeup_flags stores the
information on whether or not the device can generate wakeup
signals at run time, but in ACPI that really is equivalent to
being able to generate wakeup signals at all.

In fact, run_wake will always be set after successful executeion of
acpi_setup_gpe_for_wake(), but if that fails, the device will not be
able to use a wakeup GPE at all, so it won't be able to wake up the
systems from sleep states too.  Hence, run_wake actually means that
the device is capable of triggering wakeup and so it is equivalent
to the valid flag.

For this reason, drop run_wake from struct acpi_device_wakeup_flags
and make sure that the valid flag is only set if
acpi_setup_gpe_for_wake() has been successful.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---

-> v2: No changes.

---
 drivers/acpi/pci_root.c |    2 +-
 drivers/acpi/proc.c     |    4 ++--
 drivers/acpi/scan.c     |   23 ++++++++---------------
 drivers/pci/pci-acpi.c  |    3 +--
 include/acpi/acpi_bus.h |    1 -
 5 files changed, 12 insertions(+), 21 deletions(-)

Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -835,7 +835,7 @@ static int acpi_bus_extract_wakeup_devic
 	return err;
 }
 
-static void acpi_wakeup_gpe_init(struct acpi_device *device)
+static bool acpi_wakeup_gpe_init(struct acpi_device *device)
 {
 	static const struct acpi_device_id button_device_ids[] = {
 		{"PNP0C0C", 0},
@@ -845,13 +845,11 @@ static void acpi_wakeup_gpe_init(struct
 	};
 	struct acpi_device_wakeup *wakeup = &device->wakeup;
 	acpi_status status;
-	acpi_event_status event_status;
 
 	wakeup->flags.notifier_present = 0;
 
 	/* Power button, Lid switch always enable wakeup */
 	if (!acpi_match_device_ids(device, button_device_ids)) {
-		wakeup->flags.run_wake = 1;
 		if (!acpi_match_device_ids(device, &button_device_ids[1])) {
 			/* Do not use Lid/sleep button for S5 wakeup */
 			if (wakeup->sleep_state == ACPI_STATE_S5)
@@ -859,17 +857,12 @@ static void acpi_wakeup_gpe_init(struct
 		}
 		acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
 		device_set_wakeup_capable(&device->dev, true);
-		return;
+		return true;
 	}
 
-	acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
-				wakeup->gpe_number);
-	status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number,
-				     &event_status);
-	if (ACPI_FAILURE(status))
-		return;
-
-	wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER);
+	status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
+					 wakeup->gpe_number);
+	return ACPI_SUCCESS(status);
 }
 
 static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
@@ -887,10 +880,10 @@ static void acpi_bus_get_wakeup_device_f
 		return;
 	}
 
-	device->wakeup.flags.valid = 1;
+	device->wakeup.flags.valid = acpi_wakeup_gpe_init(device);
 	device->wakeup.prepare_count = 0;
-	acpi_wakeup_gpe_init(device);
-	/* Call _PSW/_DSW object to disable its ability to wake the sleeping
+	/*
+	 * Call _PSW/_DSW object to disable its ability to wake the sleeping
 	 * system for the ACPI device with the _PRW object.
 	 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
 	 * So it is necessary to call _DSW object first. Only when it is not
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -314,7 +314,6 @@ struct acpi_device_perf {
 /* Wakeup Management */
 struct acpi_device_wakeup_flags {
 	u8 valid:1;		/* Can successfully enable wakeup? */
-	u8 run_wake:1;		/* Run-Wake GPE devices */
 	u8 notifier_present:1;  /* Wake-up notify handler has been installed */
 	u8 enabled:1;		/* Enabled for wakeup */
 };
Index: linux-pm/drivers/acpi/pci_root.c
===================================================================
--- linux-pm.orig/drivers/acpi/pci_root.c
+++ linux-pm/drivers/acpi/pci_root.c
@@ -608,7 +608,7 @@ static int acpi_pci_root_add(struct acpi
 		pcie_no_aspm();
 
 	pci_acpi_add_bus_pm_notifier(device);
-	if (device->wakeup.flags.run_wake)
+	if (device->wakeup.flags.valid)
 		device_set_run_wake(root->bus->bridge, true);
 
 	if (hotadd) {
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -777,9 +777,8 @@ static void pci_acpi_setup(struct device
 		return;
 
 	device_set_wakeup_capable(dev, true);
+	device_set_run_wake(dev, true);
 	acpi_pci_sleep_wake(pci_dev, false);
-	if (adev->wakeup.flags.run_wake)
-		device_set_run_wake(dev, true);
 }
 
 static void pci_acpi_cleanup(struct device *dev)
Index: linux-pm/drivers/acpi/proc.c
===================================================================
--- linux-pm.orig/drivers/acpi/proc.c
+++ linux-pm/drivers/acpi/proc.c
@@ -42,7 +42,7 @@ acpi_system_wakeup_device_seq_show(struc
 
 		if (!dev->physical_node_count) {
 			seq_printf(seq, "%c%-8s\n",
-				dev->wakeup.flags.run_wake ? '*' : ' ',
+				dev->wakeup.flags.valid ? '*' : ' ',
 				device_may_wakeup(&dev->dev) ?
 					"enabled" : "disabled");
 		} else {
@@ -58,7 +58,7 @@ acpi_system_wakeup_device_seq_show(struc
 					seq_printf(seq, "\t\t");
 
 				seq_printf(seq, "%c%-8s  %s:%s\n",
-					dev->wakeup.flags.run_wake ? '*' : ' ',
+					dev->wakeup.flags.valid ? '*' : ' ',
 					(device_may_wakeup(&dev->dev) ||
 					device_may_wakeup(ldev)) ?
 					"enabled" : "disabled",

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

* [PATCH v2 2/5] ACPI / PM: Consolidate device wakeup settings code
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
  2017-06-23 23:53   ` [PATCH v2 1/5] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
@ 2017-06-23 23:54   ` Rafael J. Wysocki
  2017-06-23 23:56   ` [PATCH v2 3/5] PCI / PM: Drop pme_interrupt flag from struct pci_dev Rafael J. Wysocki
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-23 23:54 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

Currently, there are two separate ways of handling device wakeup
settings in the ACPI core, depending on whether this is runtime
wakeup or system wakeup (from sleep states).  However, after the
previous commit eliminating the run_wake ACPI device wakeup flag,
there is no difference between the two any more at the ACPI level,
so they can be combined.

For this reason, introduce acpi_pm_set_device_wakeup() to replace both
acpi_pm_device_run_wake() and acpi_pm_device_sleep_wake() and make it
check the ACPI device object's wakeup.valid flag to determine whether
or not the device can be set up to generate wakeup signals.

Also notice that zpodd_enable/disable_run_wake() only call
device_set_run_wake() because acpi_pm_device_run_wake() called
device_run_wake(), which is not done by acpi_pm_set_device_wakeup(),
so drop the now redundant device_set_run_wake() calls from there.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---

-> v2: Rename acpi_pm_device_wakeup() to acpi_pm_set_device_wakeup().

---
 drivers/acpi/device_pm.c   |   39 ++++++++-------------------------------
 drivers/ata/libata-zpodd.c |    9 +++------
 drivers/pci/pci-acpi.c     |   12 ++++++------
 drivers/pnp/pnpacpi/core.c |    6 +++---
 include/acpi/acpi_bus.h    |   13 ++-----------
 5 files changed, 22 insertions(+), 57 deletions(-)

Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -717,55 +717,32 @@ static int acpi_device_wakeup(struct acp
 }
 
 /**
- * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device.
- * @dev: Device to enable/disable the platform to wake up.
+ * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device.
+ * @dev: Device to enable/disable to generate wakeup events.
  * @enable: Whether to enable or disable the wakeup functionality.
  */
-int acpi_pm_device_run_wake(struct device *phys_dev, bool enable)
-{
-	struct acpi_device *adev;
-
-	if (!device_run_wake(phys_dev))
-		return -EINVAL;
-
-	adev = ACPI_COMPANION(phys_dev);
-	if (!adev) {
-		dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__);
-		return -ENODEV;
-	}
-
-	return acpi_device_wakeup(adev, ACPI_STATE_S0, enable);
-}
-EXPORT_SYMBOL(acpi_pm_device_run_wake);
-
-#ifdef CONFIG_PM_SLEEP
-/**
- * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
- * @dev: Device to enable/desible to wake up the system from sleep states.
- * @enable: Whether to enable or disable @dev to wake up the system.
- */
-int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
+int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
 {
 	struct acpi_device *adev;
 	int error;
 
-	if (!device_can_wakeup(dev))
-		return -EINVAL;
-
 	adev = ACPI_COMPANION(dev);
 	if (!adev) {
 		dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
 		return -ENODEV;
 	}
 
+	if (!acpi_device_can_wakeup(adev))
+		return -EINVAL;
+
 	error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
 	if (!error)
-		dev_dbg(dev, "System wakeup %s by ACPI\n",
+		dev_dbg(dev, "Wakeup %s by ACPI\n",
 			enable ? "enabled" : "disabled");
 
 	return error;
 }
-#endif /* CONFIG_PM_SLEEP */
+EXPORT_SYMBOL(acpi_pm_set_device_wakeup);
 
 /**
  * acpi_dev_pm_low_power - Put ACPI device into a low-power state.
Index: linux-pm/drivers/ata/libata-zpodd.c
===================================================================
--- linux-pm.orig/drivers/ata/libata-zpodd.c
+++ linux-pm/drivers/ata/libata-zpodd.c
@@ -174,8 +174,7 @@ void zpodd_enable_run_wake(struct ata_de
 	sdev_disable_disk_events(dev->sdev);
 
 	zpodd->powered_off = true;
-	device_set_run_wake(&dev->tdev, true);
-	acpi_pm_device_run_wake(&dev->tdev, true);
+	acpi_pm_set_device_wakeup(&dev->tdev, true);
 }
 
 /* Disable runtime wake capability if it is enabled */
@@ -183,10 +182,8 @@ void zpodd_disable_run_wake(struct ata_d
 {
 	struct zpodd *zpodd = dev->zpodd;
 
-	if (zpodd->powered_off) {
-		acpi_pm_device_run_wake(&dev->tdev, false);
-		device_set_run_wake(&dev->tdev, false);
-	}
+	if (zpodd->powered_off)
+		acpi_pm_set_device_wakeup(&dev->tdev, false);
 }
 
 /*
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -578,20 +578,20 @@ static bool acpi_pci_can_wakeup(struct p
 static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
 {
 	while (bus->parent) {
-		if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable))
+		if (!acpi_pm_set_device_wakeup(&bus->self->dev, enable))
 			return;
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
-		acpi_pm_device_sleep_wake(bus->bridge, enable);
+		acpi_pm_set_device_wakeup(bus->bridge, enable);
 }
 
 static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
 {
 	if (acpi_pci_can_wakeup(dev))
-		return acpi_pm_device_sleep_wake(&dev->dev, enable);
+		return acpi_pm_set_device_wakeup(&dev->dev, enable);
 
 	acpi_pci_propagate_wakeup_enable(dev->bus, enable);
 	return 0;
@@ -604,14 +604,14 @@ static void acpi_pci_propagate_run_wake(
 
 		if (bridge->pme_interrupt)
 			return;
-		if (!acpi_pm_device_run_wake(&bridge->dev, enable))
+		if (!acpi_pm_set_device_wakeup(&bridge->dev, enable))
 			return;
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
-		acpi_pm_device_run_wake(bus->bridge, enable);
+		acpi_pm_set_device_wakeup(bus->bridge, enable);
 }
 
 static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
@@ -625,7 +625,7 @@ static int acpi_pci_run_wake(struct pci_
 	if (dev->pme_interrupt && !dev->runtime_d3cold)
 		return 0;
 
-	if (!acpi_pm_device_run_wake(&dev->dev, enable))
+	if (!acpi_pm_set_device_wakeup(&dev->dev, enable))
 		return 0;
 
 	acpi_pci_propagate_run_wake(dev->bus, enable);
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -603,7 +603,7 @@ acpi_status acpi_add_pm_notifier(struct
 			void (*func)(struct acpi_device_wakeup_context *context));
 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
-int acpi_pm_device_run_wake(struct device *, bool);
+int acpi_pm_set_device_wakeup(struct device *dev, bool enable);
 #else
 static inline void acpi_pm_wakeup_event(struct device *dev)
 {
@@ -626,16 +626,7 @@ static inline int acpi_pm_device_sleep_s
 	return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
 		m : ACPI_STATE_D0;
 }
-static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
-{
-	return -ENODEV;
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-int acpi_pm_device_sleep_wake(struct device *, bool);
-#else
-static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
+static inline int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
 {
 	return -ENODEV;
 }
Index: linux-pm/drivers/pnp/pnpacpi/core.c
===================================================================
--- linux-pm.orig/drivers/pnp/pnpacpi/core.c
+++ linux-pm/drivers/pnp/pnpacpi/core.c
@@ -149,8 +149,8 @@ static int pnpacpi_suspend(struct pnp_de
 	}
 
 	if (device_can_wakeup(&dev->dev)) {
-		error = acpi_pm_device_sleep_wake(&dev->dev,
-				device_may_wakeup(&dev->dev));
+		error = acpi_pm_set_device_wakeup(&dev->dev,
+					      device_may_wakeup(&dev->dev));
 		if (error)
 			return error;
 	}
@@ -185,7 +185,7 @@ static int pnpacpi_resume(struct pnp_dev
 	}
 
 	if (device_may_wakeup(&dev->dev))
-		acpi_pm_device_sleep_wake(&dev->dev, false);
+		acpi_pm_set_device_wakeup(&dev->dev, false);
 
 	if (acpi_device_power_manageable(acpi_dev))
 		error = acpi_device_set_power(acpi_dev, ACPI_STATE_D0);

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

* [PATCH v2 3/5] PCI / PM: Drop pme_interrupt flag from struct pci_dev
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
  2017-06-23 23:53   ` [PATCH v2 1/5] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
  2017-06-23 23:54   ` [PATCH v2 2/5] ACPI / PM: Consolidate device wakeup settings code Rafael J. Wysocki
@ 2017-06-23 23:56   ` Rafael J. Wysocki
  2017-06-23 23:57   ` [PATCH v2 4/5] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-23 23:56 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

The pme_interrupt flag in struct pci_dev is set when PMEs generated
by the device are going to be signaled via root port PME interrupts.

Ironically enough, that information is only used by the code setting
up device wakeup through ACPI which returns as soon as it sees the
pme_interrupt flag set while setting up "remote runtime wakeup".
That is questionable, however, because in theory there may be PCIe
devices using out-of-band PME signaling under root ports handled
by the native PME code or devices requiring wakeup power setup to be
carried out by AML.  For such devices, ACPI wakeup should be invoked
regardless of whether or not native PME signaling is used in general.

For this reason, drop the pme_interrupt flag and rework the code
using it which then allows the ACPI-based device wakeup handling
in PCI to be consolidated to use one code path for both "runtime
remote wakeup" and system wakeup (from sleep states).

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---

-> v2: Rename acpi_pm_device_wakeup() to acpi_pm_set_device_wakeup(),
          update the changelog.

---
 drivers/acpi/device_pm.c |   10 +++++-
 drivers/pci/pci-acpi.c   |   68 ++++++++++-------------------------------------
 drivers/pci/pcie/pme.c   |   14 ++++-----
 include/acpi/acpi_bus.h  |    5 +++
 include/linux/pci.h      |    1 
 5 files changed, 34 insertions(+), 64 deletions(-)

Index: linux-pm/include/linux/pci.h
===================================================================
--- linux-pm.orig/include/linux/pci.h
+++ linux-pm/include/linux/pci.h
@@ -307,7 +307,6 @@ struct pci_dev {
 	u8		pm_cap;		/* PM capability offset */
 	unsigned int	pme_support:5;	/* Bitmask of states from which PME#
 					   can be generated */
-	unsigned int	pme_interrupt:1;
 	unsigned int	pme_poll:1;	/* Poll device's PME status bit */
 	unsigned int	d1_support:1;	/* Low power state D1 is supported */
 	unsigned int	d2_support:1;	/* Low power state D2 is supported */
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -569,67 +569,29 @@ static pci_power_t acpi_pci_get_power_st
 	return state_conv[state];
 }
 
-static bool acpi_pci_can_wakeup(struct pci_dev *dev)
-{
-	struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
-	return adev ? acpi_device_can_wakeup(adev) : false;
-}
-
-static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
+static int acpi_pci_propagate_wakeup(struct pci_bus *bus, bool enable)
 {
 	while (bus->parent) {
-		if (!acpi_pm_set_device_wakeup(&bus->self->dev, enable))
-			return;
-		bus = bus->parent;
-	}
+		if (acpi_pm_device_can_wakeup(&bus->self->dev))
+			return acpi_pm_set_device_wakeup(&bus->self->dev, enable);
 
-	/* We have reached the root bus. */
-	if (bus->bridge)
-		acpi_pm_set_device_wakeup(bus->bridge, enable);
-}
-
-static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
-{
-	if (acpi_pci_can_wakeup(dev))
-		return acpi_pm_set_device_wakeup(&dev->dev, enable);
-
-	acpi_pci_propagate_wakeup_enable(dev->bus, enable);
-	return 0;
-}
-
-static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable)
-{
-	while (bus->parent) {
-		struct pci_dev *bridge = bus->self;
-
-		if (bridge->pme_interrupt)
-			return;
-		if (!acpi_pm_set_device_wakeup(&bridge->dev, enable))
-			return;
 		bus = bus->parent;
 	}
 
 	/* We have reached the root bus. */
-	if (bus->bridge)
-		acpi_pm_set_device_wakeup(bus->bridge, enable);
+	if (bus->bridge) {
+		if (acpi_pm_device_can_wakeup(bus->bridge))
+			return acpi_pm_set_device_wakeup(bus->bridge, enable);
+	}
+	return 0;
 }
 
-static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
+static int acpi_pci_wakeup(struct pci_dev *dev, bool enable)
 {
-	/*
-	 * Per PCI Express Base Specification Revision 2.0 section
-	 * 5.3.3.2 Link Wakeup, platform support is needed for D3cold
-	 * waking up to power on the main link even if there is PME
-	 * support for D3cold
-	 */
-	if (dev->pme_interrupt && !dev->runtime_d3cold)
-		return 0;
-
-	if (!acpi_pm_set_device_wakeup(&dev->dev, enable))
-		return 0;
+	if (acpi_pm_device_can_wakeup(&dev->dev))
+		return acpi_pm_set_device_wakeup(&dev->dev, enable);
 
-	acpi_pci_propagate_run_wake(dev->bus, enable);
-	return 0;
+	return acpi_pci_propagate_wakeup(dev->bus, enable);
 }
 
 static bool acpi_pci_need_resume(struct pci_dev *dev)
@@ -653,8 +615,8 @@ static const struct pci_platform_pm_ops
 	.set_state = acpi_pci_set_power_state,
 	.get_state = acpi_pci_get_power_state,
 	.choose_state = acpi_pci_choose_state,
-	.sleep_wake = acpi_pci_sleep_wake,
-	.run_wake = acpi_pci_run_wake,
+	.sleep_wake = acpi_pci_wakeup,
+	.run_wake = acpi_pci_wakeup,
 	.need_resume = acpi_pci_need_resume,
 };
 
@@ -778,7 +740,7 @@ static void pci_acpi_setup(struct device
 
 	device_set_wakeup_capable(dev, true);
 	device_set_run_wake(dev, true);
-	acpi_pci_sleep_wake(pci_dev, false);
+	acpi_pci_wakeup(pci_dev, false);
 }
 
 static void pci_acpi_cleanup(struct device *dev)
Index: linux-pm/drivers/pci/pcie/pme.c
===================================================================
--- linux-pm.orig/drivers/pci/pcie/pme.c
+++ linux-pm/drivers/pci/pcie/pme.c
@@ -294,31 +294,29 @@ static irqreturn_t pcie_pme_irq(int irq,
 }
 
 /**
- * pcie_pme_set_native - Set the PME interrupt flag for given device.
+ * pcie_pme_can_wakeup - Set the wakeup capability flag.
  * @dev: PCI device to handle.
  * @ign: Ignored.
  */
-static int pcie_pme_set_native(struct pci_dev *dev, void *ign)
+static int pcie_pme_can_wakeup(struct pci_dev *dev, void *ign)
 {
 	device_set_run_wake(&dev->dev, true);
-	dev->pme_interrupt = true;
 	return 0;
 }
 
 /**
- * pcie_pme_mark_devices - Set the PME interrupt flag for devices below a port.
+ * pcie_pme_mark_devices - Set the wakeup flag for devices below a port.
  * @port: PCIe root port or event collector to handle.
  *
  * For each device below given root port, including the port itself (or for each
  * root complex integrated endpoint if @port is a root complex event collector)
- * set the flag indicating that it can signal run-time wake-up events via PCIe
- * PME interrupts.
+ * set the flag indicating that it can signal run-time wake-up events.
  */
 static void pcie_pme_mark_devices(struct pci_dev *port)
 {
-	pcie_pme_set_native(port, NULL);
+	pcie_pme_can_wakeup(port, NULL);
 	if (port->subordinate)
-		pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL);
+		pci_walk_bus(port->subordinate, pcie_pme_can_wakeup, NULL);
 }
 
 /**
Index: linux-pm/drivers/acpi/device_pm.c
===================================================================
--- linux-pm.orig/drivers/acpi/device_pm.c
+++ linux-pm/drivers/acpi/device_pm.c
@@ -496,6 +496,13 @@ bool acpi_bus_can_wakeup(acpi_handle han
 }
 EXPORT_SYMBOL(acpi_bus_can_wakeup);
 
+bool acpi_pm_device_can_wakeup(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	return adev ? acpi_device_can_wakeup(adev) : false;
+}
+
 /**
  * acpi_dev_pm_get_state - Get preferred power state of ACPI device.
  * @dev: Device whose preferred target power state to return.
@@ -737,8 +744,7 @@ int acpi_pm_set_device_wakeup(struct device
 
 	error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
 	if (!error)
-		dev_dbg(dev, "Wakeup %s by ACPI\n",
-			enable ? "enabled" : "disabled");
+		dev_dbg(dev, "Wakeup %s by ACPI\n", enable ? "enabled" : "disabled");
 
 	return error;
 }
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -602,6 +602,7 @@ void acpi_pm_wakeup_event(struct device
 acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
 			void (*func)(struct acpi_device_wakeup_context *context));
 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
+bool acpi_pm_device_can_wakeup(struct device *dev);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
 int acpi_pm_set_device_wakeup(struct device *dev, bool enable);
 #else
@@ -618,6 +619,10 @@ static inline acpi_status acpi_remove_pm
 {
 	return AE_SUPPORT;
 }
+static inline bool acpi_pm_device_can_wakeup(struct device *dev)
+{
+	return false;
+}
 static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
 {
 	if (p)

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

* [PATCH v2 4/5] PCI / PM: Simplify device wakeup settings code
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
                     ` (2 preceding siblings ...)
  2017-06-23 23:56   ` [PATCH v2 3/5] PCI / PM: Drop pme_interrupt flag from struct pci_dev Rafael J. Wysocki
@ 2017-06-23 23:57   ` Rafael J. Wysocki
  2017-06-23 23:58   ` [PATCH v2 5/5] PM / core: Drop run_wake flag from struct dev_pm_info Rafael J. Wysocki
  2017-06-27 23:43   ` [PATCH v2 0/5] PM: Unify the handling of device wakeup settings Bjorn Helgaas
  5 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-23 23:57 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

After previous changes it is not necessary to distinguish between
device wakeup for run time and device wakeup from system sleep states
any more, so rework the PCI device wakeup settings code accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---

-> v2: No changes.

---
 drivers/pci/pci-acpi.c   |    3 +--
 drivers/pci/pci-driver.c |    2 +-
 drivers/pci/pci-mid.c    |   10 ++--------
 drivers/pci/pci.c        |   36 ++++++++++--------------------------
 drivers/pci/pci.h        |    9 ++-------
 include/linux/pci.h      |    9 +--------
 6 files changed, 17 insertions(+), 52 deletions(-)

Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -615,8 +615,7 @@ static const struct pci_platform_pm_ops
 	.set_state = acpi_pci_set_power_state,
 	.get_state = acpi_pci_get_power_state,
 	.choose_state = acpi_pci_choose_state,
-	.sleep_wake = acpi_pci_wakeup,
-	.run_wake = acpi_pci_wakeup,
+	.set_wakeup = acpi_pci_wakeup,
 	.need_resume = acpi_pci_need_resume,
 };
 
Index: linux-pm/drivers/pci/pci.c
===================================================================
--- linux-pm.orig/drivers/pci/pci.c
+++ linux-pm/drivers/pci/pci.c
@@ -574,8 +574,7 @@ static const struct pci_platform_pm_ops
 int pci_set_platform_pm(const struct pci_platform_pm_ops *ops)
 {
 	if (!ops->is_manageable || !ops->set_state  || !ops->get_state ||
-	    !ops->choose_state  || !ops->sleep_wake || !ops->run_wake  ||
-	    !ops->need_resume)
+	    !ops->choose_state  || !ops->set_wakeup || !ops->need_resume)
 		return -EINVAL;
 	pci_platform_pm = ops;
 	return 0;
@@ -603,16 +602,10 @@ static inline pci_power_t platform_pci_c
 			pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
 }
 
-static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
+static inline int platform_pci_set_wakeup(struct pci_dev *dev, bool enable)
 {
 	return pci_platform_pm ?
-			pci_platform_pm->sleep_wake(dev, enable) : -ENODEV;
-}
-
-static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable)
-{
-	return pci_platform_pm ?
-			pci_platform_pm->run_wake(dev, enable) : -ENODEV;
+			pci_platform_pm->set_wakeup(dev, enable) : -ENODEV;
 }
 
 static inline bool platform_pci_need_resume(struct pci_dev *dev)
@@ -1889,10 +1882,9 @@ void pci_pme_active(struct pci_dev *dev,
 EXPORT_SYMBOL(pci_pme_active);
 
 /**
- * __pci_enable_wake - enable PCI device as wakeup event source
+ * pci_enable_wake - enable PCI device as wakeup event source
  * @dev: PCI device affected
  * @state: PCI state from which device will issue wakeup events
- * @runtime: True if the events are to be generated at run time
  * @enable: True to enable event generation; false to disable
  *
  * This enables the device as a wakeup event source, or disables it.
@@ -1908,14 +1900,10 @@ EXPORT_SYMBOL(pci_pme_active);
  * Error code depending on the platform is returned if both the platform and
  * the native mechanism fail to enable the generation of wake-up events
  */
-int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-		      bool runtime, bool enable)
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
 {
 	int ret = 0;
 
-	if (enable && !runtime && !device_may_wakeup(&dev->dev))
-		return -EINVAL;
-
 	/*
 	 * Don't do the same thing twice in a row for one device, but restore
 	 * PME Enable in case it has been updated by config space restoration.
@@ -1938,24 +1926,20 @@ int __pci_enable_wake(struct pci_dev *de
 			pci_pme_active(dev, true);
 		else
 			ret = 1;
-		error = runtime ? platform_pci_run_wake(dev, true) :
-					platform_pci_sleep_wake(dev, true);
+		error = platform_pci_set_wakeup(dev, true);
 		if (ret)
 			ret = error;
 		if (!ret)
 			dev->wakeup_prepared = true;
 	} else {
-		if (runtime)
-			platform_pci_run_wake(dev, false);
-		else
-			platform_pci_sleep_wake(dev, false);
+		platform_pci_set_wakeup(dev, false);
 		pci_pme_active(dev, false);
 		dev->wakeup_prepared = false;
 	}
 
 	return ret;
 }
-EXPORT_SYMBOL(__pci_enable_wake);
+EXPORT_SYMBOL(pci_enable_wake);
 
 /**
  * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
@@ -2097,12 +2081,12 @@ int pci_finish_runtime_suspend(struct pc
 
 	dev->runtime_d3cold = target_state == PCI_D3cold;
 
-	__pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev));
+	pci_enable_wake(dev, target_state, pci_dev_run_wake(dev));
 
 	error = pci_set_power_state(dev, target_state);
 
 	if (error) {
-		__pci_enable_wake(dev, target_state, true, false);
+		pci_enable_wake(dev, target_state, false);
 		dev->runtime_d3cold = false;
 	}
 
Index: linux-pm/include/linux/pci.h
===================================================================
--- linux-pm.orig/include/linux/pci.h
+++ linux-pm/include/linux/pci.h
@@ -1097,8 +1097,7 @@ int pci_set_power_state(struct pci_dev *
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
 bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
 void pci_pme_active(struct pci_dev *dev, bool enable);
-int __pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-		      bool runtime, bool enable);
+int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable);
 int pci_wake_from_d3(struct pci_dev *dev, bool enable);
 int pci_prepare_to_sleep(struct pci_dev *dev);
 int pci_back_from_sleep(struct pci_dev *dev);
@@ -1108,12 +1107,6 @@ void pci_pme_wakeup_bus(struct pci_bus *
 void pci_d3cold_enable(struct pci_dev *dev);
 void pci_d3cold_disable(struct pci_dev *dev);
 
-static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
-				  bool enable)
-{
-	return __pci_enable_wake(dev, state, false, enable);
-}
-
 /* PCI Virtual Channel */
 int pci_save_vc_state(struct pci_dev *dev);
 void pci_restore_vc_state(struct pci_dev *dev);
Index: linux-pm/drivers/pci/pci.h
===================================================================
--- linux-pm.orig/drivers/pci/pci.h
+++ linux-pm/drivers/pci/pci.h
@@ -47,11 +47,7 @@ int pci_probe_reset_function(struct pci_
  *                platform; to be used during system-wide transitions from a
  *                sleeping state to the working state and vice versa
  *
- * @sleep_wake: enables/disables the system wake up capability of given device
- *
- * @run_wake: enables/disables the platform to generate run-time wake-up events
- *		for given device (the device's wake-up capability has to be
- *		enabled by @sleep_wake for this feature to work)
+ * @set_wakeup: enables/disables wakeup capability for the device
  *
  * @need_resume: returns 'true' if the given device (which is currently
  *		suspended) needs to be resumed to be configured for system
@@ -65,8 +61,7 @@ struct pci_platform_pm_ops {
 	int (*set_state)(struct pci_dev *dev, pci_power_t state);
 	pci_power_t (*get_state)(struct pci_dev *dev);
 	pci_power_t (*choose_state)(struct pci_dev *dev);
-	int (*sleep_wake)(struct pci_dev *dev, bool enable);
-	int (*run_wake)(struct pci_dev *dev, bool enable);
+	int (*set_wakeup)(struct pci_dev *dev, bool enable);
 	bool (*need_resume)(struct pci_dev *dev);
 };
 
Index: linux-pm/drivers/pci/pci-driver.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-driver.c
+++ linux-pm/drivers/pci/pci-driver.c
@@ -1216,7 +1216,7 @@ static int pci_pm_runtime_resume(struct
 
 	pci_restore_standard_config(pci_dev);
 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
-	__pci_enable_wake(pci_dev, PCI_D0, true, false);
+	pci_enable_wake(pci_dev, PCI_D0, false);
 	pci_fixup_device(pci_fixup_resume, pci_dev);
 
 	rc = pm->runtime_resume(dev);
Index: linux-pm/drivers/pci/pci-mid.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-mid.c
+++ linux-pm/drivers/pci/pci-mid.c
@@ -39,12 +39,7 @@ static pci_power_t mid_pci_choose_state(
 	return PCI_D3hot;
 }
 
-static int mid_pci_sleep_wake(struct pci_dev *dev, bool enable)
-{
-	return 0;
-}
-
-static int mid_pci_run_wake(struct pci_dev *dev, bool enable)
+static int mid_pci_wakeup(struct pci_dev *dev, bool enable)
 {
 	return 0;
 }
@@ -59,8 +54,7 @@ static const struct pci_platform_pm_ops
 	.set_state	= mid_pci_set_power_state,
 	.get_state	= mid_pci_get_power_state,
 	.choose_state	= mid_pci_choose_state,
-	.sleep_wake	= mid_pci_sleep_wake,
-	.run_wake	= mid_pci_run_wake,
+	.set_wakeup	= mid_pci_wakeup,
 	.need_resume	= mid_pci_need_resume,
 };
 

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

* [PATCH v2 5/5] PM / core: Drop run_wake flag from struct dev_pm_info
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
                     ` (3 preceding siblings ...)
  2017-06-23 23:57   ` [PATCH v2 4/5] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
@ 2017-06-23 23:58   ` Rafael J. Wysocki
  2017-06-27 23:43   ` [PATCH v2 0/5] PM: Unify the handling of device wakeup settings Bjorn Helgaas
  5 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-23 23:58 UTC (permalink / raw)
  To: Linux PM
  Cc: LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Mika Westerberg,
	Greg Kroah-Hartman

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

The run_wake flag in struct dev_pm_info is used to indicate whether
or not the device is capable of generating remote wakeup signals at
run time (or in the system working state), but the distinction
between runtime remote wakeup and system wakeup signaling has always
been rather artificial.  The only practical reason for it to exist
at the core level was that ACPI and PCI treated those two cases
differently, but that's not the case any more after recent changes.

For this reason, get rid of the run_wake flag and, when applicable,
use device_set_wakeup_capable() and device_can_wakeup() instead of
device_set_run_wake() and device_run_wake(), respectively.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---

-> v2: No changes, but it was [6/6] previously.

---
 Documentation/power/runtime_pm.txt |    7 ++-----
 drivers/acpi/pci_root.c            |    5 ++---
 drivers/pci/pci-acpi.c             |    5 +----
 drivers/pci/pci.c                  |    6 +++---
 drivers/pci/pcie/pme.c             |    2 +-
 drivers/usb/dwc3/dwc3-pci.c        |    3 +--
 drivers/usb/host/uhci-pci.c        |    2 +-
 include/linux/pm.h                 |    1 -
 include/linux/pm_runtime.h         |   12 ------------
 9 files changed, 11 insertions(+), 32 deletions(-)

Index: linux-pm/include/linux/pm.h
===================================================================
--- linux-pm.orig/include/linux/pm.h
+++ linux-pm/include/linux/pm.h
@@ -584,7 +584,6 @@ struct dev_pm_info {
 	unsigned int		idle_notification:1;
 	unsigned int		request_pending:1;
 	unsigned int		deferred_resume:1;
-	unsigned int		run_wake:1;
 	unsigned int		runtime_auto:1;
 	bool			ignore_children:1;
 	unsigned int		no_callbacks:1;
Index: linux-pm/include/linux/pm_runtime.h
===================================================================
--- linux-pm.orig/include/linux/pm_runtime.h
+++ linux-pm/include/linux/pm_runtime.h
@@ -76,16 +76,6 @@ static inline void pm_runtime_put_noidle
 	atomic_add_unless(&dev->power.usage_count, -1, 0);
 }
 
-static inline bool device_run_wake(struct device *dev)
-{
-	return dev->power.run_wake;
-}
-
-static inline void device_set_run_wake(struct device *dev, bool enable)
-{
-	dev->power.run_wake = enable;
-}
-
 static inline bool pm_runtime_suspended(struct device *dev)
 {
 	return dev->power.runtime_status == RPM_SUSPENDED
@@ -163,8 +153,6 @@ static inline void pm_runtime_forbid(str
 static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
 static inline void pm_runtime_get_noresume(struct device *dev) {}
 static inline void pm_runtime_put_noidle(struct device *dev) {}
-static inline bool device_run_wake(struct device *dev) { return false; }
-static inline void device_set_run_wake(struct device *dev, bool enable) {}
 static inline bool pm_runtime_suspended(struct device *dev) { return false; }
 static inline bool pm_runtime_active(struct device *dev) { return true; }
 static inline bool pm_runtime_status_suspended(struct device *dev) { return false; }
Index: linux-pm/drivers/acpi/pci_root.c
===================================================================
--- linux-pm.orig/drivers/acpi/pci_root.c
+++ linux-pm/drivers/acpi/pci_root.c
@@ -608,8 +608,7 @@ static int acpi_pci_root_add(struct acpi
 		pcie_no_aspm();
 
 	pci_acpi_add_bus_pm_notifier(device);
-	if (device->wakeup.flags.valid)
-		device_set_run_wake(root->bus->bridge, true);
+	device_set_wakeup_capable(root->bus->bridge, device->wakeup.flags.valid);
 
 	if (hotadd) {
 		pcibios_resource_survey_bus(root->bus);
@@ -649,7 +648,7 @@ static void acpi_pci_root_remove(struct
 	pci_stop_root_bus(root->bus);
 
 	pci_ioapic_remove(root);
-	device_set_run_wake(root->bus->bridge, false);
+	device_set_wakeup_capable(root->bus->bridge, false);
 	pci_acpi_remove_bus_pm_notifier(device);
 
 	pci_remove_root_bus(root->bus);
Index: linux-pm/drivers/pci/pci-acpi.c
===================================================================
--- linux-pm.orig/drivers/pci/pci-acpi.c
+++ linux-pm/drivers/pci/pci-acpi.c
@@ -738,7 +738,6 @@ static void pci_acpi_setup(struct device
 		return;
 
 	device_set_wakeup_capable(dev, true);
-	device_set_run_wake(dev, true);
 	acpi_pci_wakeup(pci_dev, false);
 }
 
@@ -750,10 +749,8 @@ static void pci_acpi_cleanup(struct devi
 		return;
 
 	pci_acpi_remove_pm_notifier(adev);
-	if (adev->wakeup.flags.valid) {
+	if (adev->wakeup.flags.valid)
 		device_set_wakeup_capable(dev, false);
-		device_set_run_wake(dev, false);
-	}
 }
 
 static bool pci_acpi_bus_match(struct device *dev)
Index: linux-pm/drivers/pci/pcie/pme.c
===================================================================
--- linux-pm.orig/drivers/pci/pcie/pme.c
+++ linux-pm/drivers/pci/pcie/pme.c
@@ -300,7 +300,7 @@ static irqreturn_t pcie_pme_irq(int irq,
  */
 static int pcie_pme_can_wakeup(struct pci_dev *dev, void *ign)
 {
-	device_set_run_wake(&dev->dev, true);
+	device_set_wakeup_capable(&dev->dev, true);
 	return 0;
 }
 
Index: linux-pm/drivers/usb/dwc3/dwc3-pci.c
===================================================================
--- linux-pm.orig/drivers/usb/dwc3/dwc3-pci.c
+++ linux-pm/drivers/usb/dwc3/dwc3-pci.c
@@ -230,7 +230,6 @@ static int dwc3_pci_probe(struct pci_dev
 	}
 
 	device_init_wakeup(dev, true);
-	device_set_run_wake(dev, true);
 	pci_set_drvdata(pci, dwc);
 	pm_runtime_put(dev);
 
@@ -310,7 +309,7 @@ static int dwc3_pci_runtime_suspend(stru
 {
 	struct dwc3_pci		*dwc = dev_get_drvdata(dev);
 
-	if (device_run_wake(dev))
+	if (device_can_wakeup(dev))
 		return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3);
 
 	return -EBUSY;
Index: linux-pm/drivers/usb/host/uhci-pci.c
===================================================================
--- linux-pm.orig/drivers/usb/host/uhci-pci.c
+++ linux-pm/drivers/usb/host/uhci-pci.c
@@ -131,7 +131,7 @@ static int uhci_pci_init(struct usb_hcd
 
 	/* Intel controllers use non-PME wakeup signalling */
 	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
-		device_set_run_wake(uhci_dev(uhci), 1);
+		device_set_wakeup_capable(uhci_dev(uhci), true);
 
 	/* Set up pointers to PCI-specific functions */
 	uhci->reset_hc = uhci_pci_reset_hc;
Index: linux-pm/drivers/pci/pci.c
===================================================================
--- linux-pm.orig/drivers/pci/pci.c
+++ linux-pm/drivers/pci/pci.c
@@ -2105,7 +2105,7 @@ bool pci_dev_run_wake(struct pci_dev *de
 {
 	struct pci_bus *bus = dev->bus;
 
-	if (device_run_wake(&dev->dev))
+	if (device_can_wakeup(&dev->dev))
 		return true;
 
 	if (!dev->pme_support)
@@ -2118,7 +2118,7 @@ bool pci_dev_run_wake(struct pci_dev *de
 	while (bus->parent) {
 		struct pci_dev *bridge = bus->self;
 
-		if (device_run_wake(&bridge->dev))
+		if (device_can_wakeup(&bridge->dev))
 			return true;
 
 		bus = bus->parent;
@@ -2126,7 +2126,7 @@ bool pci_dev_run_wake(struct pci_dev *de
 
 	/* We have reached the root bus. */
 	if (bus->bridge)
-		return device_run_wake(bus->bridge);
+		return device_can_wakeup(bus->bridge);
 
 	return false;
 }
Index: linux-pm/Documentation/power/runtime_pm.txt
===================================================================
--- linux-pm.orig/Documentation/power/runtime_pm.txt
+++ linux-pm/Documentation/power/runtime_pm.txt
@@ -105,9 +105,9 @@ knows what to do to handle the device).
 
 In particular, if the driver requires remote wakeup capability (i.e. hardware
 mechanism allowing the device to request a change of its power state, such as
-PCI PME) for proper functioning and device_run_wake() returns 'false' for the
+PCI PME) for proper functioning and device_can_wakeup() returns 'false' for the
 device, then ->runtime_suspend() should return -EBUSY.  On the other hand, if
-device_run_wake() returns 'true' for the device and the device is put into a
+device_can_wakeup() returns 'true' for the device and the device is put into a
 low-power state during the execution of the suspend callback, it is expected
 that remote wakeup will be enabled for the device.  Generally, remote wakeup
 should be enabled for all input devices put into low-power states at run time.
@@ -253,9 +253,6 @@ defined in include/linux/pm.h:
       being executed for that device and it is not practical to wait for the
       suspend to complete; means "start a resume as soon as you've suspended"
 
-  unsigned int run_wake;
-    - set if the device is capable of generating runtime wake-up events
-
   enum rpm_status runtime_status;
     - the runtime PM status of the device; this field's initial value is
       RPM_SUSPENDED, which means that each device is initially regarded by the

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

* Re: [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code
  2017-06-23  1:05       ` Rafael J. Wysocki
@ 2017-06-26 13:29         ` Mika Westerberg
  0 siblings, 0 replies; 25+ messages in thread
From: Mika Westerberg @ 2017-06-26 13:29 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas, Greg Kroah-Hartman

On Fri, Jun 23, 2017 at 03:05:57AM +0200, Rafael J. Wysocki wrote:
> On Thursday, June 22, 2017 04:38:49 PM Rafael J. Wysocki wrote:
> > On Thursday, June 22, 2017 10:39:37 AM Mika Westerberg wrote:
> > > On Mon, Jun 19, 2017 at 11:33:52PM +0200, Rafael J. Wysocki wrote:
> > > > -#ifdef CONFIG_PM_SLEEP
> > > > -/**
> > > > - * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
> > > > - * @dev: Device to enable/desible to wake up the system from sleep states.
> > > > - * @enable: Whether to enable or disable @dev to wake up the system.
> > > > - */
> > > > -int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
> > > > +int acpi_pm_device_wakeup(struct device *dev, bool enable)
> > > 
> > > Can we call it acpi_pm_device_enable_wakeup() and then provide
> > > corresponding acpi_pm_device_disable_wakeup()? I find those easier to
> > > understand than acpi_pm_device_wakeup() that sounds like the device
> > > should be woken up now.
> > 
> > OK, fair enough.  I'll change it this way.
> 
> Well, sorry, I'd rather not to, or we'll have to add a wrapper around them in
> pci-acpi.c. :-)
> 
> I can rename it to acpi_pm_device_set_wakeup(), though.

Works for me :)

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

* Re: [PATCH v2 0/5] PM: Unify the handling of device wakeup settings
  2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
                     ` (4 preceding siblings ...)
  2017-06-23 23:58   ` [PATCH v2 5/5] PM / core: Drop run_wake flag from struct dev_pm_info Rafael J. Wysocki
@ 2017-06-27 23:43   ` Bjorn Helgaas
  2017-06-27 23:49     ` Rafael J. Wysocki
  5 siblings, 1 reply; 25+ messages in thread
From: Bjorn Helgaas @ 2017-06-27 23:43 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux PM, LKML, Linux PCI, Linux ACPI, Bjorn Helgaas,
	Mika Westerberg, Greg Kroah-Hartman

Hi Rafael,

On Sat, Jun 24, 2017 at 01:50:55AM +0200, Rafael J. Wysocki wrote:
> On Monday, June 19, 2017 11:31:58 PM Rafael J. Wysocki wrote:
> > Hi All,
> > 
> > The handling of device wakeup settings, especially in the ACPI core and the PCI
> > bus type, depends on whether it is about system wakeup from sleep states or
> > remote wakeup in the working state (runtime).  However, that distinction is
> > mostly based on the ACPI concept of "wakeup" and "runtime" GPEs, which is
> > somewhat artificial, because the underlying hardware mechanism is basically
> > the same in both cases.
> > 
> > Moreover, suspend-to-idle is now supported as a sleep state and wakeup from it
> > is based on exactly the same hardware capabilities as the working-state
> > (runtime) remote wakeup.
> > 
> > The following patch series removes that distinction and unifies the handling of
> > device wakeup settings between system sleep and runtime.  It also fixes one
> > issue related to wakeup signaling through PCI bridges.
> > 
> > [1/6]: Get rid of the "runtime wakeup" concept from the ACPI core.
> > [2/6]: Unify device wakeup settings code paths in the ACPI core.
> > [3-4/6]: Unify device wakeup settings code paths in the PCI bus type code.
> > [5/6]: Fix wakeup-related issue with bridges in the PCI bus type code.
> > [6/6]: Get rid of the "runtime wakeup" concept from the driver core.
> > 
> > The series is based on current linux-next and will be made available for
> > testing in the linux-pm.git tree in a couple of days.
> 
> Here's a v2 with tentatively added Reviewed-by tags from Mika.
> 
> I've dropped patch [5/6] from the previous iteration as it didn't really belong
> here and the issue it attempted to fix is rather theoretical.  I'm going to
> take a different approach there.
> 
> Apart from this, the function previously called acpi_pm_device_wakeup() has
> a different name now: acpi_pm_set_device_wakeup(), to possibly avoid
> confusion about its purpose.
> 
> Also the changelog of patch [3/5] has been modified slightly.

This series does touch drivers/pci, but is mostly ACPI.  Do you want
to take it via your tree?  I have a couple PM changes in my tree, but
I don't see anything that should conflict with this series.

For the PCI parts:

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

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

* Re: [PATCH v2 0/5] PM: Unify the handling of device wakeup settings
  2017-06-27 23:43   ` [PATCH v2 0/5] PM: Unify the handling of device wakeup settings Bjorn Helgaas
@ 2017-06-27 23:49     ` Rafael J. Wysocki
  0 siblings, 0 replies; 25+ messages in thread
From: Rafael J. Wysocki @ 2017-06-27 23:49 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J. Wysocki, Linux PM, LKML, Linux PCI, Linux ACPI,
	Bjorn Helgaas, Mika Westerberg, Greg Kroah-Hartman

On Wed, Jun 28, 2017 at 1:43 AM, Bjorn Helgaas <helgaas@kernel.org> wrote:
> Hi Rafael,

Hi Bjorn,

> On Sat, Jun 24, 2017 at 01:50:55AM +0200, Rafael J. Wysocki wrote:
>> On Monday, June 19, 2017 11:31:58 PM Rafael J. Wysocki wrote:
>> > Hi All,
>> >
>> > The handling of device wakeup settings, especially in the ACPI core and the PCI
>> > bus type, depends on whether it is about system wakeup from sleep states or
>> > remote wakeup in the working state (runtime).  However, that distinction is
>> > mostly based on the ACPI concept of "wakeup" and "runtime" GPEs, which is
>> > somewhat artificial, because the underlying hardware mechanism is basically
>> > the same in both cases.
>> >
>> > Moreover, suspend-to-idle is now supported as a sleep state and wakeup from it
>> > is based on exactly the same hardware capabilities as the working-state
>> > (runtime) remote wakeup.
>> >
>> > The following patch series removes that distinction and unifies the handling of
>> > device wakeup settings between system sleep and runtime.  It also fixes one
>> > issue related to wakeup signaling through PCI bridges.
>> >
>> > [1/6]: Get rid of the "runtime wakeup" concept from the ACPI core.
>> > [2/6]: Unify device wakeup settings code paths in the ACPI core.
>> > [3-4/6]: Unify device wakeup settings code paths in the PCI bus type code.
>> > [5/6]: Fix wakeup-related issue with bridges in the PCI bus type code.
>> > [6/6]: Get rid of the "runtime wakeup" concept from the driver core.
>> >
>> > The series is based on current linux-next and will be made available for
>> > testing in the linux-pm.git tree in a couple of days.
>>
>> Here's a v2 with tentatively added Reviewed-by tags from Mika.
>>
>> I've dropped patch [5/6] from the previous iteration as it didn't really belong
>> here and the issue it attempted to fix is rather theoretical.  I'm going to
>> take a different approach there.
>>
>> Apart from this, the function previously called acpi_pm_device_wakeup() has
>> a different name now: acpi_pm_set_device_wakeup(), to possibly avoid
>> confusion about its purpose.
>>
>> Also the changelog of patch [3/5] has been modified slightly.
>
> This series does touch drivers/pci, but is mostly ACPI.  Do you want
> to take it via your tree?

Yes, I do.

> I have a couple PM changes in my tree, but
> I don't see anything that should conflict with this series.
>
> For the PCI parts:
>
> Acked-by: Bjorn Helgaas <bhelgaas@google.com>

Thanks!

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

end of thread, other threads:[~2017-06-27 23:49 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-19 21:31 [PATCH 0/6] PM: Unify the handling of device wakeup settings Rafael J. Wysocki
2017-06-19 21:33 ` [PATCH 1/6] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
2017-06-19 21:33 ` [PATCH 2/6] ACPI / PM: Consolidate device wakeup settings code Rafael J. Wysocki
2017-06-22  7:39   ` Mika Westerberg
2017-06-22 14:38     ` Rafael J. Wysocki
2017-06-23  1:05       ` Rafael J. Wysocki
2017-06-26 13:29         ` Mika Westerberg
2017-06-19 21:34 ` [PATCH 3/6] PCI / PM: Drop pme_interrupt flag from struct pci_dev Rafael J. Wysocki
2017-06-19 21:35 ` [PATCH 4/6] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
2017-06-20 14:00   ` kbuild test robot
2017-06-20 16:16   ` kbuild test robot
2017-06-20 22:23   ` [Update][PATCH " Rafael J. Wysocki
2017-06-19 21:36 ` [PATCH 5/6] PCI / ACPI / PM: Avoid disabling wakeup for bridges too early Rafael J. Wysocki
2017-06-20 12:38   ` kbuild test robot
2017-06-20 22:24   ` [Update][PATCH " Rafael J. Wysocki
2017-06-19 21:37 ` [PATCH 6/6] PM / core: Drop run_wake flag from struct dev_pm_info Rafael J. Wysocki
2017-06-22  8:22 ` [PATCH 0/6] PM: Unify the handling of device wakeup settings Mika Westerberg
2017-06-23 23:50 ` [PATCH v2 0/5] " Rafael J. Wysocki
2017-06-23 23:53   ` [PATCH v2 1/5] ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags Rafael J. Wysocki
2017-06-23 23:54   ` [PATCH v2 2/5] ACPI / PM: Consolidate device wakeup settings code Rafael J. Wysocki
2017-06-23 23:56   ` [PATCH v2 3/5] PCI / PM: Drop pme_interrupt flag from struct pci_dev Rafael J. Wysocki
2017-06-23 23:57   ` [PATCH v2 4/5] PCI / PM: Simplify device wakeup settings code Rafael J. Wysocki
2017-06-23 23:58   ` [PATCH v2 5/5] PM / core: Drop run_wake flag from struct dev_pm_info Rafael J. Wysocki
2017-06-27 23:43   ` [PATCH v2 0/5] PM: Unify the handling of device wakeup settings Bjorn Helgaas
2017-06-27 23: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.