diff options
-rw-r--r-- | drivers/pci/pci-acpi.c | 23 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 10 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 29 | ||||
-rw-r--r-- | drivers/pci/pci.c | 114 | ||||
-rw-r--r-- | drivers/pci/pci.h | 1 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 44 | ||||
-rw-r--r-- | include/linux/pci.h | 16 |
7 files changed, 215 insertions, 22 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index a9efebc586b4..e1658afef873 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) |
@@ -187,10 +193,13 @@ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | |||
187 | 193 | ||
188 | static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) | 194 | static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) |
189 | { | 195 | { |
190 | int acpi_state; | 196 | int acpi_state, d_max; |
191 | 197 | ||
192 | acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL, | 198 | if (pdev->no_d3cold) |
193 | ACPI_STATE_D3); | 199 | d_max = ACPI_STATE_D3_HOT; |
200 | else | ||
201 | d_max = ACPI_STATE_D3_COLD; | ||
202 | acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL, d_max); | ||
194 | if (acpi_state < 0) | 203 | if (acpi_state < 0) |
195 | return PCI_POWER_ERROR; | 204 | return PCI_POWER_ERROR; |
196 | 205 | ||
@@ -297,7 +306,13 @@ static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | |||
297 | 306 | ||
298 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | 307 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) |
299 | { | 308 | { |
300 | if (dev->pme_interrupt) | 309 | /* |
310 | * Per PCI Express Base Specification Revision 2.0 section | ||
311 | * 5.3.3.2 Link Wakeup, platform support is needed for D3cold | ||
312 | * waking up to power on the main link even if there is PME | ||
313 | * support for D3cold | ||
314 | */ | ||
315 | if (dev->pme_interrupt && !dev->runtime_d3cold) | ||
301 | return 0; | 316 | return 0; |
302 | 317 | ||
303 | if (!acpi_pm_device_run_wake(&dev->dev, enable)) | 318 | if (!acpi_pm_device_run_wake(&dev->dev, enable)) |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index bf0cee629b60..ca2e4c79a588 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -1019,10 +1019,13 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
1019 | if (!pm || !pm->runtime_suspend) | 1019 | if (!pm || !pm->runtime_suspend) |
1020 | return -ENOSYS; | 1020 | return -ENOSYS; |
1021 | 1021 | ||
1022 | pci_dev->no_d3cold = false; | ||
1022 | error = pm->runtime_suspend(dev); | 1023 | error = pm->runtime_suspend(dev); |
1023 | suspend_report_result(pm->runtime_suspend, error); | 1024 | suspend_report_result(pm->runtime_suspend, error); |
1024 | if (error) | 1025 | if (error) |
1025 | return error; | 1026 | return error; |
1027 | if (!pci_dev->d3cold_allowed) | ||
1028 | pci_dev->no_d3cold = true; | ||
1026 | 1029 | ||
1027 | pci_fixup_device(pci_fixup_suspend, pci_dev); | 1030 | pci_fixup_device(pci_fixup_suspend, pci_dev); |
1028 | 1031 | ||
@@ -1044,6 +1047,7 @@ static int pci_pm_runtime_suspend(struct device *dev) | |||
1044 | 1047 | ||
1045 | static int pci_pm_runtime_resume(struct device *dev) | 1048 | static int pci_pm_runtime_resume(struct device *dev) |
1046 | { | 1049 | { |
1050 | int rc; | ||
1047 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1051 | struct pci_dev *pci_dev = to_pci_dev(dev); |
1048 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | 1052 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; |
1049 | 1053 | ||
@@ -1054,7 +1058,11 @@ static int pci_pm_runtime_resume(struct device *dev) | |||
1054 | __pci_enable_wake(pci_dev, PCI_D0, true, false); | 1058 | __pci_enable_wake(pci_dev, PCI_D0, true, false); |
1055 | pci_fixup_device(pci_fixup_resume, pci_dev); | 1059 | pci_fixup_device(pci_fixup_resume, pci_dev); |
1056 | 1060 | ||
1057 | return pm->runtime_resume(dev); | 1061 | rc = pm->runtime_resume(dev); |
1062 | |||
1063 | pci_dev->runtime_d3cold = false; | ||
1064 | |||
1065 | return rc; | ||
1058 | } | 1066 | } |
1059 | 1067 | ||
1060 | static int pci_pm_runtime_idle(struct device *dev) | 1068 | static int pci_pm_runtime_idle(struct device *dev) |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 86c63fe45d11..1426db0c0607 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/pci-aspm.h> | 28 | #include <linux/pci-aspm.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/vgaarb.h> | 30 | #include <linux/vgaarb.h> |
31 | #include <linux/pm_runtime.h> | ||
31 | #include "pci.h" | 32 | #include "pci.h" |
32 | 33 | ||
33 | static int sysfs_initialized; /* = 0 */ | 34 | static int sysfs_initialized; /* = 0 */ |
@@ -378,6 +379,31 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr, | |||
378 | 379 | ||
379 | #endif | 380 | #endif |
380 | 381 | ||
382 | #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) | ||
383 | static ssize_t d3cold_allowed_store(struct device *dev, | ||
384 | struct device_attribute *attr, | ||
385 | const char *buf, size_t count) | ||
386 | { | ||
387 | struct pci_dev *pdev = to_pci_dev(dev); | ||
388 | unsigned long val; | ||
389 | |||
390 | if (strict_strtoul(buf, 0, &val) < 0) | ||
391 | return -EINVAL; | ||
392 | |||
393 | pdev->d3cold_allowed = !!val; | ||
394 | pm_runtime_resume(dev); | ||
395 | |||
396 | return count; | ||
397 | } | ||
398 | |||
399 | static ssize_t d3cold_allowed_show(struct device *dev, | ||
400 | struct device_attribute *attr, char *buf) | ||
401 | { | ||
402 | struct pci_dev *pdev = to_pci_dev(dev); | ||
403 | return sprintf (buf, "%u\n", pdev->d3cold_allowed); | ||
404 | } | ||
405 | #endif | ||
406 | |||
381 | struct device_attribute pci_dev_attrs[] = { | 407 | struct device_attribute pci_dev_attrs[] = { |
382 | __ATTR_RO(resource), | 408 | __ATTR_RO(resource), |
383 | __ATTR_RO(vendor), | 409 | __ATTR_RO(vendor), |
@@ -402,6 +428,9 @@ struct device_attribute pci_dev_attrs[] = { | |||
402 | __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store), | 428 | __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store), |
403 | __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store), | 429 | __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store), |
404 | #endif | 430 | #endif |
431 | #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) | ||
432 | __ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store), | ||
433 | #endif | ||
405 | __ATTR_NULL, | 434 | __ATTR_NULL, |
406 | }; | 435 | }; |
407 | 436 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 9eae64b17954..8effb9b23eec 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -622,7 +622,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
622 | dev_info(&dev->dev, "Refused to change power state, " | 622 | dev_info(&dev->dev, "Refused to change power state, " |
623 | "currently in D%d\n", dev->current_state); | 623 | "currently in D%d\n", dev->current_state); |
624 | 624 | ||
625 | /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT | 625 | /* |
626 | * According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT | ||
626 | * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning | 627 | * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning |
627 | * from D3hot to D0 _may_ perform an internal reset, thereby | 628 | * from D3hot to D0 _may_ perform an internal reset, thereby |
628 | * going to "D0 Uninitialized" rather than "D0 Initialized". | 629 | * going to "D0 Uninitialized" rather than "D0 Initialized". |
@@ -654,6 +655,16 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state) | |||
654 | if (dev->pm_cap) { | 655 | if (dev->pm_cap) { |
655 | u16 pmcsr; | 656 | u16 pmcsr; |
656 | 657 | ||
658 | /* | ||
659 | * Configuration space is not accessible for device in | ||
660 | * D3cold, so just keep or set D3cold for safety | ||
661 | */ | ||
662 | if (dev->current_state == PCI_D3cold) | ||
663 | return; | ||
664 | if (state == PCI_D3cold) { | ||
665 | dev->current_state = PCI_D3cold; | ||
666 | return; | ||
667 | } | ||
657 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | 668 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); |
658 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); | 669 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); |
659 | } else { | 670 | } else { |
@@ -694,8 +705,50 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) | |||
694 | */ | 705 | */ |
695 | static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) | 706 | static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) |
696 | { | 707 | { |
697 | if (state == PCI_D0) | 708 | if (state == PCI_D0) { |
698 | pci_platform_power_transition(dev, PCI_D0); | 709 | pci_platform_power_transition(dev, PCI_D0); |
710 | /* | ||
711 | * Mandatory power management transition delays, see | ||
712 | * PCI Express Base Specification Revision 2.0 Section | ||
713 | * 6.6.1: Conventional Reset. Do not delay for | ||
714 | * devices powered on/off by corresponding bridge, | ||
715 | * because have already delayed for the bridge. | ||
716 | */ | ||
717 | if (dev->runtime_d3cold) { | ||
718 | msleep(dev->d3cold_delay); | ||
719 | /* | ||
720 | * When powering on a bridge from D3cold, the | ||
721 | * whole hierarchy may be powered on into | ||
722 | * D0uninitialized state, resume them to give | ||
723 | * them a chance to suspend again | ||
724 | */ | ||
725 | pci_wakeup_bus(dev->subordinate); | ||
726 | } | ||
727 | } | ||
728 | } | ||
729 | |||
730 | /** | ||
731 | * __pci_dev_set_current_state - Set current state of a PCI device | ||
732 | * @dev: Device to handle | ||
733 | * @data: pointer to state to be set | ||
734 | */ | ||
735 | static int __pci_dev_set_current_state(struct pci_dev *dev, void *data) | ||
736 | { | ||
737 | pci_power_t state = *(pci_power_t *)data; | ||
738 | |||
739 | dev->current_state = state; | ||
740 | return 0; | ||
741 | } | ||
742 | |||
743 | /** | ||
744 | * __pci_bus_set_current_state - Walk given bus and set current state of devices | ||
745 | * @bus: Top bus of the subtree to walk. | ||
746 | * @state: state to be set | ||
747 | */ | ||
748 | static void __pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state) | ||
749 | { | ||
750 | if (bus) | ||
751 | pci_walk_bus(bus, __pci_dev_set_current_state, &state); | ||
699 | } | 752 | } |
700 | 753 | ||
701 | /** | 754 | /** |
@@ -707,8 +760,15 @@ static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) | |||
707 | */ | 760 | */ |
708 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) | 761 | int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) |
709 | { | 762 | { |
710 | return state >= PCI_D0 ? | 763 | int ret; |
711 | pci_platform_power_transition(dev, state) : -EINVAL; | 764 | |
765 | if (state < PCI_D0) | ||
766 | return -EINVAL; | ||
767 | ret = pci_platform_power_transition(dev, state); | ||
768 | /* Power off the bridge may power off the whole hierarchy */ | ||
769 | if (!ret && state == PCI_D3cold) | ||
770 | __pci_bus_set_current_state(dev->subordinate, PCI_D3cold); | ||
771 | return ret; | ||
712 | } | 772 | } |
713 | EXPORT_SYMBOL_GPL(__pci_complete_power_transition); | 773 | EXPORT_SYMBOL_GPL(__pci_complete_power_transition); |
714 | 774 | ||
@@ -732,8 +792,8 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
732 | int error; | 792 | int error; |
733 | 793 | ||
734 | /* bound the state we're entering */ | 794 | /* bound the state we're entering */ |
735 | if (state > PCI_D3hot) | 795 | if (state > PCI_D3cold) |
736 | state = PCI_D3hot; | 796 | state = PCI_D3cold; |
737 | else if (state < PCI_D0) | 797 | else if (state < PCI_D0) |
738 | state = PCI_D0; | 798 | state = PCI_D0; |
739 | else if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) | 799 | else if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) |
@@ -748,10 +808,15 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
748 | 808 | ||
749 | /* This device is quirked not to be put into D3, so | 809 | /* This device is quirked not to be put into D3, so |
750 | don't put it in D3 */ | 810 | don't put it in D3 */ |
751 | if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) | 811 | if (state >= PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) |
752 | return 0; | 812 | return 0; |
753 | 813 | ||
754 | error = pci_raw_set_power_state(dev, state); | 814 | /* |
815 | * To put device in D3cold, we put device into D3hot in native | ||
816 | * way, then put device into D3cold with platform ops | ||
817 | */ | ||
818 | error = pci_raw_set_power_state(dev, state > PCI_D3hot ? | ||
819 | PCI_D3hot : state); | ||
755 | 820 | ||
756 | if (!__pci_complete_power_transition(dev, state)) | 821 | if (!__pci_complete_power_transition(dev, state)) |
757 | error = 0; | 822 | error = 0; |
@@ -1498,6 +1563,28 @@ void pci_pme_wakeup_bus(struct pci_bus *bus) | |||
1498 | } | 1563 | } |
1499 | 1564 | ||
1500 | /** | 1565 | /** |
1566 | * pci_wakeup - Wake up a PCI device | ||
1567 | * @dev: Device to handle. | ||
1568 | * @ign: ignored parameter | ||
1569 | */ | ||
1570 | static int pci_wakeup(struct pci_dev *pci_dev, void *ign) | ||
1571 | { | ||
1572 | pci_wakeup_event(pci_dev); | ||
1573 | pm_request_resume(&pci_dev->dev); | ||
1574 | return 0; | ||
1575 | } | ||
1576 | |||
1577 | /** | ||
1578 | * pci_wakeup_bus - Walk given bus and wake up devices on it | ||
1579 | * @bus: Top bus of the subtree to walk. | ||
1580 | */ | ||
1581 | void pci_wakeup_bus(struct pci_bus *bus) | ||
1582 | { | ||
1583 | if (bus) | ||
1584 | pci_walk_bus(bus, pci_wakeup, NULL); | ||
1585 | } | ||
1586 | |||
1587 | /** | ||
1501 | * pci_pme_capable - check the capability of PCI device to generate PME# | 1588 | * pci_pme_capable - check the capability of PCI device to generate PME# |
1502 | * @dev: PCI device to handle. | 1589 | * @dev: PCI device to handle. |
1503 | * @state: PCI state from which device will issue PME#. | 1590 | * @state: PCI state from which device will issue PME#. |
@@ -1754,6 +1841,10 @@ int pci_prepare_to_sleep(struct pci_dev *dev) | |||
1754 | if (target_state == PCI_POWER_ERROR) | 1841 | if (target_state == PCI_POWER_ERROR) |
1755 | return -EIO; | 1842 | return -EIO; |
1756 | 1843 | ||
1844 | /* D3cold during system suspend/hibernate is not supported */ | ||
1845 | if (target_state > PCI_D3hot) | ||
1846 | target_state = PCI_D3hot; | ||
1847 | |||
1757 | pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); | 1848 | pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); |
1758 | 1849 | ||
1759 | error = pci_set_power_state(dev, target_state); | 1850 | error = pci_set_power_state(dev, target_state); |
@@ -1791,12 +1882,16 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) | |||
1791 | if (target_state == PCI_POWER_ERROR) | 1882 | if (target_state == PCI_POWER_ERROR) |
1792 | return -EIO; | 1883 | return -EIO; |
1793 | 1884 | ||
1885 | dev->runtime_d3cold = target_state == PCI_D3cold; | ||
1886 | |||
1794 | __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); | 1887 | __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); |
1795 | 1888 | ||
1796 | error = pci_set_power_state(dev, target_state); | 1889 | error = pci_set_power_state(dev, target_state); |
1797 | 1890 | ||
1798 | if (error) | 1891 | if (error) { |
1799 | __pci_enable_wake(dev, target_state, true, false); | 1892 | __pci_enable_wake(dev, target_state, true, false); |
1893 | dev->runtime_d3cold = false; | ||
1894 | } | ||
1800 | 1895 | ||
1801 | return error; | 1896 | return error; |
1802 | } | 1897 | } |
@@ -1866,6 +1961,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
1866 | 1961 | ||
1867 | dev->pm_cap = pm; | 1962 | dev->pm_cap = pm; |
1868 | dev->d3_delay = PCI_PM_D3_WAIT; | 1963 | dev->d3_delay = PCI_PM_D3_WAIT; |
1964 | dev->d3cold_delay = PCI_PM_D3COLD_WAIT; | ||
1869 | 1965 | ||
1870 | dev->d1_support = false; | 1966 | dev->d1_support = false; |
1871 | dev->d2_support = false; | 1967 | dev->d2_support = false; |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index e4943479b234..5cd3dce7a245 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -70,6 +70,7 @@ extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state); | |||
70 | extern void pci_disable_enabled_device(struct pci_dev *dev); | 70 | extern void pci_disable_enabled_device(struct pci_dev *dev); |
71 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); | 71 | extern int pci_finish_runtime_suspend(struct pci_dev *dev); |
72 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | 72 | extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); |
73 | extern void pci_wakeup_bus(struct pci_bus *bus); | ||
73 | extern void pci_pm_init(struct pci_dev *dev); | 74 | extern void pci_pm_init(struct pci_dev *dev); |
74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 75 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 76 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 7c576b9aa01d..3a7eefcb270a 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -101,12 +101,48 @@ static int pcie_port_resume_noirq(struct device *dev) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | #ifdef CONFIG_PM_RUNTIME | 103 | #ifdef CONFIG_PM_RUNTIME |
104 | static int pcie_port_runtime_pm(struct device *dev) | 104 | struct d3cold_info { |
105 | bool no_d3cold; | ||
106 | unsigned int d3cold_delay; | ||
107 | }; | ||
108 | |||
109 | static int pci_dev_d3cold_info(struct pci_dev *pdev, void *data) | ||
110 | { | ||
111 | struct d3cold_info *info = data; | ||
112 | |||
113 | info->d3cold_delay = max_t(unsigned int, pdev->d3cold_delay, | ||
114 | info->d3cold_delay); | ||
115 | if (pdev->no_d3cold) | ||
116 | info->no_d3cold = true; | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int pcie_port_runtime_suspend(struct device *dev) | ||
121 | { | ||
122 | struct pci_dev *pdev = to_pci_dev(dev); | ||
123 | struct d3cold_info d3cold_info = { | ||
124 | .no_d3cold = false, | ||
125 | .d3cold_delay = PCI_PM_D3_WAIT, | ||
126 | }; | ||
127 | |||
128 | /* | ||
129 | * If any subordinate device disable D3cold, we should not put | ||
130 | * the port into D3cold. The D3cold delay of port should be | ||
131 | * the max of that of all subordinate devices. | ||
132 | */ | ||
133 | pci_walk_bus(pdev->subordinate, pci_dev_d3cold_info, &d3cold_info); | ||
134 | pdev->no_d3cold = d3cold_info.no_d3cold; | ||
135 | pdev->d3cold_delay = d3cold_info.d3cold_delay; | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int pcie_port_runtime_resume(struct device *dev) | ||
105 | { | 140 | { |
106 | return 0; | 141 | return 0; |
107 | } | 142 | } |
108 | #else | 143 | #else |
109 | #define pcie_port_runtime_pm NULL | 144 | #define pcie_port_runtime_suspend NULL |
145 | #define pcie_port_runtime_resume NULL | ||
110 | #endif | 146 | #endif |
111 | 147 | ||
112 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { | 148 | static const struct dev_pm_ops pcie_portdrv_pm_ops = { |
@@ -117,8 +153,8 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
117 | .poweroff = pcie_port_device_suspend, | 153 | .poweroff = pcie_port_device_suspend, |
118 | .restore = pcie_port_device_resume, | 154 | .restore = pcie_port_device_resume, |
119 | .resume_noirq = pcie_port_resume_noirq, | 155 | .resume_noirq = pcie_port_resume_noirq, |
120 | .runtime_suspend = pcie_port_runtime_pm, | 156 | .runtime_suspend = pcie_port_runtime_suspend, |
121 | .runtime_resume = pcie_port_runtime_pm, | 157 | .runtime_resume = pcie_port_runtime_resume, |
122 | }; | 158 | }; |
123 | 159 | ||
124 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) | 160 | #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) |
diff --git a/include/linux/pci.h b/include/linux/pci.h index d8c379dba6ad..002cfd3e33ca 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -132,9 +132,10 @@ static inline const char *pci_power_name(pci_power_t state) | |||
132 | return pci_power_names[1 + (int) state]; | 132 | return pci_power_names[1 + (int) state]; |
133 | } | 133 | } |
134 | 134 | ||
135 | #define PCI_PM_D2_DELAY 200 | 135 | #define PCI_PM_D2_DELAY 200 |
136 | #define PCI_PM_D3_WAIT 10 | 136 | #define PCI_PM_D3_WAIT 10 |
137 | #define PCI_PM_BUS_WAIT 50 | 137 | #define PCI_PM_D3COLD_WAIT 100 |
138 | #define PCI_PM_BUS_WAIT 50 | ||
138 | 139 | ||
139 | /** The pci_channel state describes connectivity between the CPU and | 140 | /** The pci_channel state describes connectivity between the CPU and |
140 | * the pci device. If some PCI bus between here and the pci device | 141 | * the pci device. If some PCI bus between here and the pci device |
@@ -278,11 +279,18 @@ struct pci_dev { | |||
278 | unsigned int pme_poll:1; /* Poll device's PME status bit */ | 279 | unsigned int pme_poll:1; /* Poll device's PME status bit */ |
279 | unsigned int d1_support:1; /* Low power state D1 is supported */ | 280 | unsigned int d1_support:1; /* Low power state D1 is supported */ |
280 | unsigned int d2_support:1; /* Low power state D2 is supported */ | 281 | unsigned int d2_support:1; /* Low power state D2 is supported */ |
281 | unsigned int no_d1d2:1; /* Only allow D0 and D3 */ | 282 | unsigned int no_d1d2:1; /* D1 and D2 are forbidden */ |
283 | unsigned int no_d3cold:1; /* D3cold is forbidden */ | ||
284 | unsigned int d3cold_allowed:1; /* D3cold is allowed by user */ | ||
282 | unsigned int mmio_always_on:1; /* disallow turning off io/mem | 285 | unsigned int mmio_always_on:1; /* disallow turning off io/mem |
283 | decoding during bar sizing */ | 286 | decoding during bar sizing */ |
284 | unsigned int wakeup_prepared:1; | 287 | unsigned int wakeup_prepared:1; |
288 | unsigned int runtime_d3cold:1; /* whether go through runtime | ||
289 | D3cold, not set for devices | ||
290 | powered on/off by the | ||
291 | corresponding bridge */ | ||
285 | unsigned int d3_delay; /* D3->D0 transition time in ms */ | 292 | unsigned int d3_delay; /* D3->D0 transition time in ms */ |
293 | unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */ | ||
286 | 294 | ||
287 | #ifdef CONFIG_PCIEASPM | 295 | #ifdef CONFIG_PCIEASPM |
288 | struct pcie_link_state *link_state; /* ASPM link state. */ | 296 | struct pcie_link_state *link_state; /* ASPM link state. */ |