aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-acpi.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 0bddd787490d..33317df47699 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -109,10 +109,32 @@ static bool acpi_pci_can_wakeup(struct pci_dev *dev)
109 return handle ? acpi_bus_can_wakeup(handle) : false; 109 return handle ? acpi_bus_can_wakeup(handle) : false;
110} 110}
111 111
112static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
113{
114 while (bus->parent) {
115 struct pci_dev *bridge = bus->self;
116 int ret;
117
118 ret = acpi_pm_device_sleep_wake(&bridge->dev, enable);
119 if (!ret || bridge->is_pcie)
120 return;
121 bus = bus->parent;
122 }
123
124 /* We have reached the root bus. */
125 if (bus->bridge)
126 acpi_pm_device_sleep_wake(bus->bridge, enable);
127}
128
112static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) 129static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
113{ 130{
114 return acpi_pci_can_wakeup(dev) ? 131 if (acpi_pci_can_wakeup(dev))
115 acpi_pm_device_sleep_wake(&dev->dev, enable) : 0; 132 return acpi_pm_device_sleep_wake(&dev->dev, enable);
133
134 if (!dev->is_pcie)
135 acpi_pci_propagate_wakeup_enable(dev->bus, enable);
136
137 return 0;
116} 138}
117 139
118static struct pci_platform_pm_ops acpi_pci_platform_pm = { 140static struct pci_platform_pm_ops acpi_pci_platform_pm = {