diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 563901cd9c06..0b5302a9fdae 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -574,8 +574,7 @@ static const struct pci_platform_pm_ops *pci_platform_pm; | |||
574 | int pci_set_platform_pm(const struct pci_platform_pm_ops *ops) | 574 | int pci_set_platform_pm(const struct pci_platform_pm_ops *ops) |
575 | { | 575 | { |
576 | if (!ops->is_manageable || !ops->set_state || !ops->get_state || | 576 | if (!ops->is_manageable || !ops->set_state || !ops->get_state || |
577 | !ops->choose_state || !ops->sleep_wake || !ops->run_wake || | 577 | !ops->choose_state || !ops->set_wakeup || !ops->need_resume) |
578 | !ops->need_resume) | ||
579 | return -EINVAL; | 578 | return -EINVAL; |
580 | pci_platform_pm = ops; | 579 | pci_platform_pm = ops; |
581 | return 0; | 580 | return 0; |
@@ -603,16 +602,10 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) | |||
603 | pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; | 602 | pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; |
604 | } | 603 | } |
605 | 604 | ||
606 | static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | 605 | static inline int platform_pci_set_wakeup(struct pci_dev *dev, bool enable) |
607 | { | 606 | { |
608 | return pci_platform_pm ? | 607 | return pci_platform_pm ? |
609 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; | 608 | pci_platform_pm->set_wakeup(dev, enable) : -ENODEV; |
610 | } | ||
611 | |||
612 | static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable) | ||
613 | { | ||
614 | return pci_platform_pm ? | ||
615 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; | ||
616 | } | 609 | } |
617 | 610 | ||
618 | static inline bool platform_pci_need_resume(struct pci_dev *dev) | 611 | static inline bool platform_pci_need_resume(struct pci_dev *dev) |
@@ -1805,6 +1798,23 @@ static void __pci_pme_active(struct pci_dev *dev, bool enable) | |||
1805 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | 1798 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); |
1806 | } | 1799 | } |
1807 | 1800 | ||
1801 | static void pci_pme_restore(struct pci_dev *dev) | ||
1802 | { | ||
1803 | u16 pmcsr; | ||
1804 | |||
1805 | if (!dev->pme_support) | ||
1806 | return; | ||
1807 | |||
1808 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | ||
1809 | if (dev->wakeup_prepared) { | ||
1810 | pmcsr |= PCI_PM_CTRL_PME_ENABLE; | ||
1811 | } else { | ||
1812 | pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; | ||
1813 | pmcsr |= PCI_PM_CTRL_PME_STATUS; | ||
1814 | } | ||
1815 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | ||
1816 | } | ||
1817 | |||
1808 | /** | 1818 | /** |
1809 | * pci_pme_active - enable or disable PCI device's PME# function | 1819 | * pci_pme_active - enable or disable PCI device's PME# function |
1810 | * @dev: PCI device to handle. | 1820 | * @dev: PCI device to handle. |
@@ -1872,10 +1882,9 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1872 | EXPORT_SYMBOL(pci_pme_active); | 1882 | EXPORT_SYMBOL(pci_pme_active); |
1873 | 1883 | ||
1874 | /** | 1884 | /** |
1875 | * __pci_enable_wake - enable PCI device as wakeup event source | 1885 | * pci_enable_wake - enable PCI device as wakeup event source |
1876 | * @dev: PCI device affected | 1886 | * @dev: PCI device affected |
1877 | * @state: PCI state from which device will issue wakeup events | 1887 | * @state: PCI state from which device will issue wakeup events |
1878 | * @runtime: True if the events are to be generated at run time | ||
1879 | * @enable: True to enable event generation; false to disable | 1888 | * @enable: True to enable event generation; false to disable |
1880 | * | 1889 | * |
1881 | * This enables the device as a wakeup event source, or disables it. | 1890 | * This enables the device as a wakeup event source, or disables it. |
@@ -1891,17 +1900,18 @@ EXPORT_SYMBOL(pci_pme_active); | |||
1891 | * Error code depending on the platform is returned if both the platform and | 1900 | * Error code depending on the platform is returned if both the platform and |
1892 | * the native mechanism fail to enable the generation of wake-up events | 1901 | * the native mechanism fail to enable the generation of wake-up events |
1893 | */ | 1902 | */ |
1894 | int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, | 1903 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) |
1895 | bool runtime, bool enable) | ||
1896 | { | 1904 | { |
1897 | int ret = 0; | 1905 | int ret = 0; |
1898 | 1906 | ||
1899 | if (enable && !runtime && !device_may_wakeup(&dev->dev)) | 1907 | /* |
1900 | return -EINVAL; | 1908 | * Don't do the same thing twice in a row for one device, but restore |
1901 | 1909 | * PME Enable in case it has been updated by config space restoration. | |
1902 | /* Don't do the same thing twice in a row for one device. */ | 1910 | */ |
1903 | if (!!enable == !!dev->wakeup_prepared) | 1911 | if (!!enable == !!dev->wakeup_prepared) { |
1912 | pci_pme_restore(dev); | ||
1904 | return 0; | 1913 | return 0; |
1914 | } | ||
1905 | 1915 | ||
1906 | /* | 1916 | /* |
1907 | * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don | 1917 | * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don |
@@ -1916,24 +1926,20 @@ int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, | |||
1916 | pci_pme_active(dev, true); | 1926 | pci_pme_active(dev, true); |
1917 | else | 1927 | else |
1918 | ret = 1; | 1928 | ret = 1; |
1919 | error = runtime ? platform_pci_run_wake(dev, true) : | 1929 | error = platform_pci_set_wakeup(dev, true); |
1920 | platform_pci_sleep_wake(dev, true); | ||
1921 | if (ret) | 1930 | if (ret) |
1922 | ret = error; | 1931 | ret = error; |
1923 | if (!ret) | 1932 | if (!ret) |
1924 | dev->wakeup_prepared = true; | 1933 | dev->wakeup_prepared = true; |
1925 | } else { | 1934 | } else { |
1926 | if (runtime) | 1935 | platform_pci_set_wakeup(dev, false); |
1927 | platform_pci_run_wake(dev, false); | ||
1928 | else | ||
1929 | platform_pci_sleep_wake(dev, false); | ||
1930 | pci_pme_active(dev, false); | 1936 | pci_pme_active(dev, false); |
1931 | dev->wakeup_prepared = false; | 1937 | dev->wakeup_prepared = false; |
1932 | } | 1938 | } |
1933 | 1939 | ||
1934 | return ret; | 1940 | return ret; |
1935 | } | 1941 | } |
1936 | EXPORT_SYMBOL(__pci_enable_wake); | 1942 | EXPORT_SYMBOL(pci_enable_wake); |
1937 | 1943 | ||
1938 | /** | 1944 | /** |
1939 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold | 1945 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold |
@@ -2075,12 +2081,12 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) | |||
2075 | 2081 | ||
2076 | dev->runtime_d3cold = target_state == PCI_D3cold; | 2082 | dev->runtime_d3cold = target_state == PCI_D3cold; |
2077 | 2083 | ||
2078 | __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); | 2084 | pci_enable_wake(dev, target_state, pci_dev_run_wake(dev)); |
2079 | 2085 | ||
2080 | error = pci_set_power_state(dev, target_state); | 2086 | error = pci_set_power_state(dev, target_state); |
2081 | 2087 | ||
2082 | if (error) { | 2088 | if (error) { |
2083 | __pci_enable_wake(dev, target_state, true, false); | 2089 | pci_enable_wake(dev, target_state, false); |
2084 | dev->runtime_d3cold = false; | 2090 | dev->runtime_d3cold = false; |
2085 | } | 2091 | } |
2086 | 2092 | ||
@@ -2099,7 +2105,7 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2099 | { | 2105 | { |
2100 | struct pci_bus *bus = dev->bus; | 2106 | struct pci_bus *bus = dev->bus; |
2101 | 2107 | ||
2102 | if (device_run_wake(&dev->dev)) | 2108 | if (device_can_wakeup(&dev->dev)) |
2103 | return true; | 2109 | return true; |
2104 | 2110 | ||
2105 | if (!dev->pme_support) | 2111 | if (!dev->pme_support) |
@@ -2112,7 +2118,7 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2112 | while (bus->parent) { | 2118 | while (bus->parent) { |
2113 | struct pci_dev *bridge = bus->self; | 2119 | struct pci_dev *bridge = bus->self; |
2114 | 2120 | ||
2115 | if (device_run_wake(&bridge->dev)) | 2121 | if (device_can_wakeup(&bridge->dev)) |
2116 | return true; | 2122 | return true; |
2117 | 2123 | ||
2118 | bus = bus->parent; | 2124 | bus = bus->parent; |
@@ -2120,7 +2126,7 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2120 | 2126 | ||
2121 | /* We have reached the root bus. */ | 2127 | /* We have reached the root bus. */ |
2122 | if (bus->bridge) | 2128 | if (bus->bridge) |
2123 | return device_run_wake(bus->bridge); | 2129 | return device_can_wakeup(bus->bridge); |
2124 | 2130 | ||
2125 | return false; | 2131 | return false; |
2126 | } | 2132 | } |