aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pcie/portdrv_pci.c74
1 files changed, 0 insertions, 74 deletions
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 2ccc9b926ea7..be35da2e105e 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -93,77 +93,6 @@ static int pcie_port_resume_noirq(struct device *dev)
93 return 0; 93 return 0;
94} 94}
95 95
96#ifdef CONFIG_PM_RUNTIME
97struct d3cold_info {
98 bool no_d3cold;
99 unsigned int d3cold_delay;
100};
101
102static int pci_dev_d3cold_info(struct pci_dev *pdev, void *data)
103{
104 struct d3cold_info *info = data;
105
106 info->d3cold_delay = max_t(unsigned int, pdev->d3cold_delay,
107 info->d3cold_delay);
108 if (pdev->no_d3cold)
109 info->no_d3cold = true;
110 return 0;
111}
112
113static int pcie_port_runtime_suspend(struct device *dev)
114{
115 struct pci_dev *pdev = to_pci_dev(dev);
116 struct d3cold_info d3cold_info = {
117 .no_d3cold = false,
118 .d3cold_delay = PCI_PM_D3_WAIT,
119 };
120
121 /*
122 * If any subordinate device disable D3cold, we should not put
123 * the port into D3cold. The D3cold delay of port should be
124 * the max of that of all subordinate devices.
125 */
126 pci_walk_bus(pdev->subordinate, pci_dev_d3cold_info, &d3cold_info);
127 pdev->no_d3cold = d3cold_info.no_d3cold;
128 pdev->d3cold_delay = d3cold_info.d3cold_delay;
129 return 0;
130}
131
132static int pcie_port_runtime_resume(struct device *dev)
133{
134 return 0;
135}
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
146static int pcie_port_runtime_idle(struct device *dev)
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);
156 /* Delay for a short while to prevent too frequent suspend/resume */
157 if (!pme_poll)
158 pm_schedule_suspend(dev, 10);
159 return -EBUSY;
160}
161#else
162#define pcie_port_runtime_suspend NULL
163#define pcie_port_runtime_resume NULL
164#define pcie_port_runtime_idle NULL
165#endif
166
167static const struct dev_pm_ops pcie_portdrv_pm_ops = { 96static const struct dev_pm_ops pcie_portdrv_pm_ops = {
168 .suspend = pcie_port_device_suspend, 97 .suspend = pcie_port_device_suspend,
169 .resume = pcie_port_device_resume, 98 .resume = pcie_port_device_resume,
@@ -172,9 +101,6 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
172 .poweroff = pcie_port_device_suspend, 101 .poweroff = pcie_port_device_suspend,
173 .restore = pcie_port_device_resume, 102 .restore = pcie_port_device_resume,
174 .resume_noirq = pcie_port_resume_noirq, 103 .resume_noirq = pcie_port_resume_noirq,
175 .runtime_suspend = pcie_port_runtime_suspend,
176 .runtime_resume = pcie_port_runtime_resume,
177 .runtime_idle = pcie_port_runtime_idle,
178}; 104};
179 105
180#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) 106#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)