summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/device_pm.c10
-rw-r--r--drivers/pci/pci-acpi.c68
-rw-r--r--drivers/pci/pcie/pme.c14
-rw-r--r--include/acpi/acpi_bus.h5
-rw-r--r--include/linux/pci.h1
5 files changed, 34 insertions, 64 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index d2e985a4bac2..28938b5a334e 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -496,6 +496,13 @@ bool acpi_bus_can_wakeup(acpi_handle handle)
}
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 *dev, bool enable)
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;
}
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index eb014b8ab01a..de255bc9736b 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -569,67 +569,29 @@ static pci_power_t acpi_pci_get_power_state(struct pci_dev *dev)
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;
- }
-
- /* We have reached the root bus. */
- if (bus->bridge)
- acpi_pm_set_device_wakeup(bus->bridge, enable);
-}
+ if (acpi_pm_device_can_wakeup(&bus->self->dev))
+ return acpi_pm_set_device_wakeup(&bus->self->dev, 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 acpi_pci_platform_pm = {
.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 *dev)
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)
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 2dd1c68e6de8..1db1615838ac 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -294,31 +294,29 @@ static irqreturn_t pcie_pme_irq(int irq, void *context)
}
/**
- * 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);
}
/**
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 6bf0f843f7d7..be6b6bb4ef9c 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -602,6 +602,7 @@ void acpi_pm_wakeup_event(struct device *dev);
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_notifier(struct acpi_device *adev)
{
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)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8039f9f0ca05..d3d5bca82b43 100644
--- a/include/linux/pci.h
+++ b/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 */
OpenPOWER on IntegriCloud