diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci-acpi.c | 26 |
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 | ||
112 | static 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 | |||
112 | static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | 129 | static 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 | ||
118 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { | 140 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { |