diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pci-acpi.c | 79 |
1 files changed, 11 insertions, 68 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index c5792d622dc4..1af4008182fd 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -17,10 +17,9 @@ | |||
17 | 17 | ||
18 | #include <linux/pci-acpi.h> | 18 | #include <linux/pci-acpi.h> |
19 | #include <linux/pm_runtime.h> | 19 | #include <linux/pm_runtime.h> |
20 | #include <linux/pm_qos.h> | ||
20 | #include "pci.h" | 21 | #include "pci.h" |
21 | 22 | ||
22 | static DEFINE_MUTEX(pci_acpi_pm_notify_mtx); | ||
23 | |||
24 | /** | 23 | /** |
25 | * pci_acpi_wake_bus - Wake-up notification handler for root buses. | 24 | * pci_acpi_wake_bus - Wake-up notification handler for root buses. |
26 | * @handle: ACPI handle of a device the notification is for. | 25 | * @handle: ACPI handle of a device the notification is for. |
@@ -68,67 +67,6 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) | |||
68 | } | 67 | } |
69 | 68 | ||
70 | /** | 69 | /** |
71 | * add_pm_notifier - Register PM notifier for given ACPI device. | ||
72 | * @dev: ACPI device to add the notifier for. | ||
73 | * @context: PCI device or bus to check for PME status if an event is signaled. | ||
74 | * | ||
75 | * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of | ||
76 | * PM wake-up events. For example, wake-up events may be generated for bridges | ||
77 | * if one of the devices below the bridge is signaling PME, even if the bridge | ||
78 | * itself doesn't have a wake-up GPE associated with it. | ||
79 | */ | ||
80 | static acpi_status add_pm_notifier(struct acpi_device *dev, | ||
81 | acpi_notify_handler handler, | ||
82 | void *context) | ||
83 | { | ||
84 | acpi_status status = AE_ALREADY_EXISTS; | ||
85 | |||
86 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
87 | |||
88 | if (dev->wakeup.flags.notifier_present) | ||
89 | goto out; | ||
90 | |||
91 | status = acpi_install_notify_handler(dev->handle, | ||
92 | ACPI_SYSTEM_NOTIFY, | ||
93 | handler, context); | ||
94 | if (ACPI_FAILURE(status)) | ||
95 | goto out; | ||
96 | |||
97 | dev->wakeup.flags.notifier_present = true; | ||
98 | |||
99 | out: | ||
100 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
101 | return status; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * remove_pm_notifier - Unregister PM notifier from given ACPI device. | ||
106 | * @dev: ACPI device to remove the notifier from. | ||
107 | */ | ||
108 | static acpi_status remove_pm_notifier(struct acpi_device *dev, | ||
109 | acpi_notify_handler handler) | ||
110 | { | ||
111 | acpi_status status = AE_BAD_PARAMETER; | ||
112 | |||
113 | mutex_lock(&pci_acpi_pm_notify_mtx); | ||
114 | |||
115 | if (!dev->wakeup.flags.notifier_present) | ||
116 | goto out; | ||
117 | |||
118 | status = acpi_remove_notify_handler(dev->handle, | ||
119 | ACPI_SYSTEM_NOTIFY, | ||
120 | handler); | ||
121 | if (ACPI_FAILURE(status)) | ||
122 | goto out; | ||
123 | |||
124 | dev->wakeup.flags.notifier_present = false; | ||
125 | |||
126 | out: | ||
127 | mutex_unlock(&pci_acpi_pm_notify_mtx); | ||
128 | return status; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. | 70 | * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. |
133 | * @dev: ACPI device to add the notifier for. | 71 | * @dev: ACPI device to add the notifier for. |
134 | * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. | 72 | * @pci_bus: PCI bus to walk checking for PME status if an event is signaled. |
@@ -136,7 +74,7 @@ static acpi_status remove_pm_notifier(struct acpi_device *dev, | |||
136 | acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, | 74 | acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, |
137 | struct pci_bus *pci_bus) | 75 | struct pci_bus *pci_bus) |
138 | { | 76 | { |
139 | return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); | 77 | return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); |
140 | } | 78 | } |
141 | 79 | ||
142 | /** | 80 | /** |
@@ -145,7 +83,7 @@ acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, | |||
145 | */ | 83 | */ |
146 | acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) | 84 | acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) |
147 | { | 85 | { |
148 | return remove_pm_notifier(dev, pci_acpi_wake_bus); | 86 | return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus); |
149 | } | 87 | } |
150 | 88 | ||
151 | /** | 89 | /** |
@@ -156,7 +94,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) | |||
156 | acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | 94 | acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, |
157 | struct pci_dev *pci_dev) | 95 | struct pci_dev *pci_dev) |
158 | { | 96 | { |
159 | return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); | 97 | return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); |
160 | } | 98 | } |
161 | 99 | ||
162 | /** | 100 | /** |
@@ -165,7 +103,7 @@ acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, | |||
165 | */ | 103 | */ |
166 | acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) | 104 | acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) |
167 | { | 105 | { |
168 | return remove_pm_notifier(dev, pci_acpi_wake_dev); | 106 | return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev); |
169 | } | 107 | } |
170 | 108 | ||
171 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) | 109 | phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) |
@@ -257,11 +195,16 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
257 | return -ENODEV; | 195 | return -ENODEV; |
258 | 196 | ||
259 | switch (state) { | 197 | switch (state) { |
198 | case PCI_D3cold: | ||
199 | if (dev_pm_qos_flags(&dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == | ||
200 | PM_QOS_FLAGS_ALL) { | ||
201 | error = -EBUSY; | ||
202 | break; | ||
203 | } | ||
260 | case PCI_D0: | 204 | case PCI_D0: |
261 | case PCI_D1: | 205 | case PCI_D1: |
262 | case PCI_D2: | 206 | case PCI_D2: |
263 | case PCI_D3hot: | 207 | case PCI_D3hot: |
264 | case PCI_D3cold: | ||
265 | error = acpi_bus_set_power(handle, state_conv[state]); | 208 | error = acpi_bus_set_power(handle, state_conv[state]); |
266 | } | 209 | } |
267 | 210 | ||