aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r--drivers/pci/pci-acpi.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 61e2fefeedab..fbf7b26c7c8a 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -48,6 +48,12 @@ 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 return; 49 return;
50 50
51 if (pci_dev->current_state == PCI_D3cold) {
52 pci_wakeup_event(pci_dev);
53 pm_runtime_resume(&pci_dev->dev);
54 return;
55 }
56
51 if (!pci_dev->pm_cap || !pci_dev->pme_support 57 if (!pci_dev->pm_cap || !pci_dev->pme_support
52 || pci_check_pme_status(pci_dev)) { 58 || pci_check_pme_status(pci_dev)) {
53 if (pci_dev->pme_poll) 59 if (pci_dev->pme_poll)
@@ -162,6 +168,20 @@ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
162 return remove_pm_notifier(dev, pci_acpi_wake_dev); 168 return remove_pm_notifier(dev, pci_acpi_wake_dev);
163} 169}
164 170
171phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
172{
173 acpi_status status = AE_NOT_EXIST;
174 unsigned long long mcfg_addr;
175
176 if (handle)
177 status = acpi_evaluate_integer(handle, METHOD_NAME__CBA,
178 NULL, &mcfg_addr);
179 if (ACPI_FAILURE(status))
180 return 0;
181
182 return (phys_addr_t)mcfg_addr;
183}
184
165/* 185/*
166 * _SxD returns the D-state with the highest power 186 * _SxD returns the D-state with the highest power
167 * (lowest D-state number) supported in the S-state "x". 187 * (lowest D-state number) supported in the S-state "x".
@@ -187,9 +207,13 @@ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
187 207
188static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) 208static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
189{ 209{
190 int acpi_state; 210 int acpi_state, d_max;
191 211
192 acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL); 212 if (pdev->no_d3cold)
213 d_max = ACPI_STATE_D3_HOT;
214 else
215 d_max = ACPI_STATE_D3_COLD;
216 acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL, d_max);
193 if (acpi_state < 0) 217 if (acpi_state < 0)
194 return PCI_POWER_ERROR; 218 return PCI_POWER_ERROR;
195 219
@@ -296,7 +320,13 @@ static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable)
296 320
297static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) 321static int acpi_pci_run_wake(struct pci_dev *dev, bool enable)
298{ 322{
299 if (dev->pme_interrupt) 323 /*
324 * Per PCI Express Base Specification Revision 2.0 section
325 * 5.3.3.2 Link Wakeup, platform support is needed for D3cold
326 * waking up to power on the main link even if there is PME
327 * support for D3cold
328 */
329 if (dev->pme_interrupt && !dev->runtime_d3cold)
300 return 0; 330 return 0;
301 331
302 if (!acpi_pm_device_run_wake(&dev->dev, enable)) 332 if (!acpi_pm_device_run_wake(&dev->dev, enable))