diff options
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r-- | drivers/pci/pci-acpi.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index ea15b0537457..33317df47699 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -109,15 +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 | int error = acpi_pm_device_sleep_wake(&dev->dev, enable); | 131 | if (acpi_pci_can_wakeup(dev)) |
132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); | ||
115 | 133 | ||
116 | if (!error) | 134 | if (!dev->is_pcie) |
117 | dev_printk(KERN_INFO, &dev->dev, | 135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); |
118 | "wake-up capability %s by ACPI\n", | 136 | |
119 | enable ? "enabled" : "disabled"); | 137 | return 0; |
120 | return error; | ||
121 | } | 138 | } |
122 | 139 | ||
123 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { | 140 | static struct pci_platform_pm_ops acpi_pci_platform_pm = { |