diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci-acpi.c | 1 | ||||
-rw-r--r-- | drivers/pci/pci.c | 20 | ||||
-rw-r--r-- | drivers/pci/pci.h | 1 | ||||
-rw-r--r-- | drivers/pci/pcie/pme/pcie_pme.c | 5 |
4 files changed, 25 insertions, 2 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 2e7a3bf1382..1ab98bbe58d 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -48,6 +48,7 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | |||
48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { | 48 | if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { |
49 | pci_check_pme_status(pci_dev); | 49 | pci_check_pme_status(pci_dev); |
50 | pm_runtime_resume(&pci_dev->dev); | 50 | pm_runtime_resume(&pci_dev->dev); |
51 | pci_wakeup_event(pci_dev); | ||
51 | if (pci_dev->subordinate) | 52 | if (pci_dev->subordinate) |
52 | pci_pme_wakeup_bus(pci_dev->subordinate); | 53 | pci_pme_wakeup_bus(pci_dev->subordinate); |
53 | } | 54 | } |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 740fb4ea966..130ed1daf0f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1275,6 +1275,22 @@ bool pci_check_pme_status(struct pci_dev *dev) | |||
1275 | return ret; | 1275 | return ret; |
1276 | } | 1276 | } |
1277 | 1277 | ||
1278 | /* | ||
1279 | * Time to wait before the system can be put into a sleep state after reporting | ||
1280 | * a wakeup event signaled by a PCI device. | ||
1281 | */ | ||
1282 | #define PCI_WAKEUP_COOLDOWN 100 | ||
1283 | |||
1284 | /** | ||
1285 | * pci_wakeup_event - Report a wakeup event related to a given PCI device. | ||
1286 | * @dev: Device to report the wakeup event for. | ||
1287 | */ | ||
1288 | void pci_wakeup_event(struct pci_dev *dev) | ||
1289 | { | ||
1290 | if (device_may_wakeup(&dev->dev)) | ||
1291 | pm_wakeup_event(&dev->dev, PCI_WAKEUP_COOLDOWN); | ||
1292 | } | ||
1293 | |||
1278 | /** | 1294 | /** |
1279 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. | 1295 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. |
1280 | * @dev: Device to handle. | 1296 | * @dev: Device to handle. |
@@ -1285,8 +1301,10 @@ bool pci_check_pme_status(struct pci_dev *dev) | |||
1285 | */ | 1301 | */ |
1286 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) | 1302 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) |
1287 | { | 1303 | { |
1288 | if (pci_check_pme_status(dev)) | 1304 | if (pci_check_pme_status(dev)) { |
1289 | pm_request_resume(&dev->dev); | 1305 | pm_request_resume(&dev->dev); |
1306 | pci_wakeup_event(dev); | ||
1307 | } | ||
1290 | return 0; | 1308 | return 0; |
1291 | } | 1309 | } |
1292 | 1310 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index f8077b3c8c8..c8b7fd056cc 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -56,6 +56,7 @@ extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | |||
56 | extern void pci_disable_enabled_device(struct pci_dev *dev); | 56 | extern void pci_disable_enabled_device(struct pci_dev *dev); |
57 | extern bool pci_check_pme_status(struct pci_dev *dev); | 57 | extern bool pci_check_pme_status(struct pci_dev *dev); |
58 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | 58 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); |
59 | extern void pci_wakeup_event(struct pci_dev *dev); | ||
59 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | 60 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
60 | extern void pci_pme_wakeup_bus(struct pci_bus *bus); | 61 | extern void pci_pme_wakeup_bus(struct pci_bus *bus); |
61 | extern void pci_pm_init(struct pci_dev *dev); | 62 | extern void pci_pm_init(struct pci_dev *dev); |
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c index d672a0a6381..bbdea18693d 100644 --- a/drivers/pci/pcie/pme/pcie_pme.c +++ b/drivers/pci/pcie/pme/pcie_pme.c | |||
@@ -154,6 +154,7 @@ static bool pcie_pme_walk_bus(struct pci_bus *bus) | |||
154 | /* Skip PCIe devices in case we started from a root port. */ | 154 | /* Skip PCIe devices in case we started from a root port. */ |
155 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { | 155 | if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { |
156 | pm_request_resume(&dev->dev); | 156 | pm_request_resume(&dev->dev); |
157 | pci_wakeup_event(dev); | ||
157 | ret = true; | 158 | ret = true; |
158 | } | 159 | } |
159 | 160 | ||
@@ -254,8 +255,10 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id) | |||
254 | if (found) { | 255 | if (found) { |
255 | /* The device is there, but we have to check its PME status. */ | 256 | /* The device is there, but we have to check its PME status. */ |
256 | found = pci_check_pme_status(dev); | 257 | found = pci_check_pme_status(dev); |
257 | if (found) | 258 | if (found) { |
258 | pm_request_resume(&dev->dev); | 259 | pm_request_resume(&dev->dev); |
260 | pci_wakeup_event(dev); | ||
261 | } | ||
259 | pci_dev_put(dev); | 262 | pci_dev_put(dev); |
260 | } else if (devfn) { | 263 | } else if (devfn) { |
261 | /* | 264 | /* |