diff options
| -rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index d4824cb78b49..08c243ab034e 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
| @@ -134,10 +134,28 @@ static int pcie_port_runtime_resume(struct device *dev) | |||
| 134 | return 0; | 134 | return 0; |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static int pci_dev_pme_poll(struct pci_dev *pdev, void *data) | ||
| 138 | { | ||
| 139 | bool *pme_poll = data; | ||
| 140 | |||
| 141 | if (pdev->pme_poll) | ||
| 142 | *pme_poll = true; | ||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | |||
| 137 | static int pcie_port_runtime_idle(struct device *dev) | 146 | static int pcie_port_runtime_idle(struct device *dev) |
| 138 | { | 147 | { |
| 148 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 149 | bool pme_poll = false; | ||
| 150 | |||
| 151 | /* | ||
| 152 | * If any subordinate device needs pme poll, we should keep | ||
| 153 | * the port in D0, because we need port in D0 to poll it. | ||
| 154 | */ | ||
| 155 | pci_walk_bus(pdev->subordinate, pci_dev_pme_poll, &pme_poll); | ||
| 139 | /* Delay for a short while to prevent too frequent suspend/resume */ | 156 | /* Delay for a short while to prevent too frequent suspend/resume */ |
| 140 | pm_schedule_suspend(dev, 10); | 157 | if (!pme_poll) |
| 158 | pm_schedule_suspend(dev, 10); | ||
| 141 | return -EBUSY; | 159 | return -EBUSY; |
| 142 | } | 160 | } |
| 143 | #else | 161 | #else |
