aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pcie/portdrv_pci.c20
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
137static 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
137static int pcie_port_runtime_idle(struct device *dev) 146static 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