aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/device_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/device_pm.c')
-rw-r--r--drivers/acpi/device_pm.c100
1 files changed, 60 insertions, 40 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 735db11a9b00..88dbbb115285 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -98,17 +98,16 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
98 98
99 /* 99 /*
100 * The power resources settings may indicate a power state 100 * The power resources settings may indicate a power state
101 * shallower than the actual power state of the device. 101 * shallower than the actual power state of the device, because
102 * the same power resources may be referenced by other devices.
102 * 103 *
103 * Moreover, on systems predating ACPI 4.0, if the device 104 * For systems predating ACPI 4.0 we assume that D3hot is the
104 * doesn't depend on any power resources and _PSC returns 3, 105 * deepest state that can be supported.
105 * that means "power off". We need to maintain compatibility
106 * with those systems.
107 */ 106 */
108 if (psc > result && psc < ACPI_STATE_D3_COLD) 107 if (psc > result && psc < ACPI_STATE_D3_COLD)
109 result = psc; 108 result = psc;
110 else if (result == ACPI_STATE_UNKNOWN) 109 else if (result == ACPI_STATE_UNKNOWN)
111 result = psc > ACPI_STATE_D2 ? ACPI_STATE_D3_COLD : psc; 110 result = psc > ACPI_STATE_D2 ? ACPI_STATE_D3_HOT : psc;
112 } 111 }
113 112
114 /* 113 /*
@@ -153,8 +152,8 @@ static int acpi_dev_pm_explicit_set(struct acpi_device *adev, int state)
153 */ 152 */
154int acpi_device_set_power(struct acpi_device *device, int state) 153int acpi_device_set_power(struct acpi_device *device, int state)
155{ 154{
155 int target_state = state;
156 int result = 0; 156 int result = 0;
157 bool cut_power = false;
158 157
159 if (!device || !device->flags.power_manageable 158 if (!device || !device->flags.power_manageable
160 || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) 159 || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
@@ -169,11 +168,21 @@ int acpi_device_set_power(struct acpi_device *device, int state)
169 return 0; 168 return 0;
170 } 169 }
171 170
172 if (!device->power.states[state].flags.valid) { 171 if (state == ACPI_STATE_D3_COLD) {
172 /*
173 * For transitions to D3cold we need to execute _PS3 and then
174 * possibly drop references to the power resources in use.
175 */
176 state = ACPI_STATE_D3_HOT;
177 /* If _PR3 is not available, use D3hot as the target state. */
178 if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid)
179 target_state = state;
180 } else if (!device->power.states[state].flags.valid) {
173 dev_warn(&device->dev, "Power state %s not supported\n", 181 dev_warn(&device->dev, "Power state %s not supported\n",
174 acpi_power_state_string(state)); 182 acpi_power_state_string(state));
175 return -ENODEV; 183 return -ENODEV;
176 } 184 }
185
177 if (!device->power.flags.ignore_parent && 186 if (!device->power.flags.ignore_parent &&
178 device->parent && (state < device->parent->power.state)) { 187 device->parent && (state < device->parent->power.state)) {
179 dev_warn(&device->dev, 188 dev_warn(&device->dev,
@@ -183,39 +192,38 @@ int acpi_device_set_power(struct acpi_device *device, int state)
183 return -ENODEV; 192 return -ENODEV;
184 } 193 }
185 194
186 /* For D3cold we should first transition into D3hot. */
187 if (state == ACPI_STATE_D3_COLD
188 && device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible) {
189 state = ACPI_STATE_D3_HOT;
190 cut_power = true;
191 }
192
193 if (state < device->power.state && state != ACPI_STATE_D0
194 && device->power.state >= ACPI_STATE_D3_HOT) {
195 dev_warn(&device->dev,
196 "Cannot transition to non-D0 state from D3\n");
197 return -ENODEV;
198 }
199
200 /* 195 /*
201 * Transition Power 196 * Transition Power
202 * ---------------- 197 * ----------------
203 * In accordance with the ACPI specification first apply power (via 198 * In accordance with ACPI 6, _PSx is executed before manipulating power
204 * power resources) and then evaluate _PSx. 199 * resources, unless the target state is D0, in which case _PS0 is
200 * supposed to be executed after turning the power resources on.
205 */ 201 */
206 if (device->power.flags.power_resources) { 202 if (state > ACPI_STATE_D0) {
207 result = acpi_power_transition(device, state); 203 /*
204 * According to ACPI 6, devices cannot go from lower-power
205 * (deeper) states to higher-power (shallower) states.
206 */
207 if (state < device->power.state) {
208 dev_warn(&device->dev, "Cannot transition from %s to %s\n",
209 acpi_power_state_string(device->power.state),
210 acpi_power_state_string(state));
211 return -ENODEV;
212 }
213
214 result = acpi_dev_pm_explicit_set(device, state);
208 if (result) 215 if (result)
209 goto end; 216 goto end;
210 }
211 result = acpi_dev_pm_explicit_set(device, state);
212 if (result)
213 goto end;
214 217
215 if (cut_power) { 218 if (device->power.flags.power_resources)
216 device->power.state = state; 219 result = acpi_power_transition(device, target_state);
217 state = ACPI_STATE_D3_COLD; 220 } else {
218 result = acpi_power_transition(device, state); 221 if (device->power.flags.power_resources) {
222 result = acpi_power_transition(device, ACPI_STATE_D0);
223 if (result)
224 goto end;
225 }
226 result = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0);
219 } 227 }
220 228
221 end: 229 end:
@@ -223,7 +231,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
223 dev_warn(&device->dev, "Failed to change power state to %s\n", 231 dev_warn(&device->dev, "Failed to change power state to %s\n",
224 acpi_power_state_string(state)); 232 acpi_power_state_string(state));
225 } else { 233 } else {
226 device->power.state = state; 234 device->power.state = target_state;
227 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 235 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
228 "Device [%s] transitioned to %s\n", 236 "Device [%s] transitioned to %s\n",
229 device->pnp.bus_id, 237 device->pnp.bus_id,
@@ -264,13 +272,24 @@ int acpi_bus_init_power(struct acpi_device *device)
264 return result; 272 return result;
265 273
266 if (state < ACPI_STATE_D3_COLD && device->power.flags.power_resources) { 274 if (state < ACPI_STATE_D3_COLD && device->power.flags.power_resources) {
275 /* Reference count the power resources. */
267 result = acpi_power_on_resources(device, state); 276 result = acpi_power_on_resources(device, state);
268 if (result) 277 if (result)
269 return result; 278 return result;
270 279
271 result = acpi_dev_pm_explicit_set(device, state); 280 if (state == ACPI_STATE_D0) {
272 if (result) 281 /*
273 return result; 282 * If _PSC is not present and the state inferred from
283 * power resources appears to be D0, it still may be
284 * necessary to execute _PS0 at this point, because
285 * another device using the same power resources may
286 * have been put into D0 previously and that's why we
287 * see D0 here.
288 */
289 result = acpi_dev_pm_explicit_set(device, state);
290 if (result)
291 return result;
292 }
274 } else if (state == ACPI_STATE_UNKNOWN) { 293 } else if (state == ACPI_STATE_UNKNOWN) {
275 /* 294 /*
276 * No power resources and missing _PSC? Cross fingers and make 295 * No power resources and missing _PSC? Cross fingers and make
@@ -603,12 +622,12 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
603 if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3_COLD) 622 if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3_COLD)
604 return -EINVAL; 623 return -EINVAL;
605 624
606 if (d_max_in > ACPI_STATE_D3_HOT) { 625 if (d_max_in > ACPI_STATE_D2) {
607 enum pm_qos_flags_status stat; 626 enum pm_qos_flags_status stat;
608 627
609 stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF); 628 stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF);
610 if (stat == PM_QOS_FLAGS_ALL) 629 if (stat == PM_QOS_FLAGS_ALL)
611 d_max_in = ACPI_STATE_D3_HOT; 630 d_max_in = ACPI_STATE_D2;
612 } 631 }
613 632
614 adev = ACPI_COMPANION(dev); 633 adev = ACPI_COMPANION(dev);
@@ -953,6 +972,7 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
953 */ 972 */
954void acpi_subsys_complete(struct device *dev) 973void acpi_subsys_complete(struct device *dev)
955{ 974{
975 pm_generic_complete(dev);
956 /* 976 /*
957 * If the device had been runtime-suspended before the system went into 977 * If the device had been runtime-suspended before the system went into
958 * the sleep state it is going out of and it has never been resumed till 978 * the sleep state it is going out of and it has never been resumed till