summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2012-06-22 22:23:51 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-06-23 12:50:59 -0400
commit448bd857d48e69b33ef323739dc6d8ca20d4cda7 (patch)
tree4c1178f9c7dd2d78af2ac1ed26b214b04be1554a /drivers/pci/pci.c
parent8497f696686ae1ab3f01e5956046d59844b9f500 (diff)
PCI/PM: add PCIe runtime D3cold support
This patch adds runtime D3cold support and corresponding ACPI platform support. This patch only enables runtime D3cold support; it does not enable D3cold support during system suspend/hibernate. D3cold is the deepest power saving state for a PCIe device, where its main power is removed. While it is in D3cold, you can't access the device at all, not even its configuration space (which is still accessible in D3hot). Therefore the PCI PM registers can not be used to transition into/out of the D3cold state; that must be done by platform logic such as ACPI _PR3. To support wakeup from D3cold, a system may provide auxiliary power, which allows a device to request wakeup using a Beacon or the sideband WAKE# signal. WAKE# is usually connected to platform logic such as ACPI GPE. This is quite different from other power saving states, where devices request wakeup via a PME message on the PCIe link. Some devices, such as those in plug-in slots, have no direct platform logic. For example, there is usually no ACPI _PR3 for them. D3cold support for these devices can be done via the PCIe Downstream Port leading to the device. When the PCIe port is powered on/off, the device is powered on/off too. Wakeup events from the device will be notified to the corresponding PCIe port. For more information about PCIe D3cold and corresponding ACPI support, please refer to: - PCI Express Base Specification Revision 2.0 - Advanced Configuration and Power Interface Specification Revision 5.0 [bhelgaas: changelog] Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl> Originally-by: Zheng Yan <zheng.z.yan@intel.com> Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c114
1 files changed, 105 insertions, 9 deletions
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 */
695static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state) 706static 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 */
735static 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 */
748static 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 */
708int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state) 761int __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}
713EXPORT_SYMBOL_GPL(__pci_complete_power_transition); 773EXPORT_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 */
1570static 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 */
1581void 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;