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 |