hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/acpi/device_pm.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * drivers/acpi/device_pm.c - ACPI device power management routines.
34 *
....@@ -5,15 +6,6 @@
56 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
67 *
78 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as published
11
- * by the Free Software Foundation.
12
- *
13
- * This program is distributed in the hope that it will be useful, but
14
- * WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
- * General Public License for more details.
179 *
1810 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1911 */
....@@ -26,6 +18,7 @@
2618 #include <linux/pm_runtime.h>
2719 #include <linux/suspend.h>
2820
21
+#include "fan.h"
2922 #include "internal.h"
3023
3124 #define _COMPONENT ACPI_POWER_COMPONENT
....@@ -53,6 +46,19 @@
5346 }
5447 }
5548
49
+static int acpi_dev_pm_explicit_get(struct acpi_device *device, int *state)
50
+{
51
+ unsigned long long psc;
52
+ acpi_status status;
53
+
54
+ status = acpi_evaluate_integer(device->handle, "_PSC", NULL, &psc);
55
+ if (ACPI_FAILURE(status))
56
+ return -ENODEV;
57
+
58
+ *state = psc;
59
+ return 0;
60
+}
61
+
5662 /**
5763 * acpi_device_get_power - Get power state of an ACPI device.
5864 * @device: Device to get the power state of.
....@@ -61,10 +67,16 @@
6167 * This function does not update the device's power.state field, but it may
6268 * update its parent's power.state field (when the parent's power state is
6369 * unknown and the device's power state turns out to be D0).
70
+ *
71
+ * Also, it does not update power resource reference counters to ensure that
72
+ * the power state returned by it will be persistent and it may return a power
73
+ * state shallower than previously set by acpi_device_set_power() for @device
74
+ * (if that power state depends on any power resources).
6475 */
6576 int acpi_device_get_power(struct acpi_device *device, int *state)
6677 {
6778 int result = ACPI_STATE_UNKNOWN;
79
+ int error;
6880
6981 if (!device || !state)
7082 return -EINVAL;
....@@ -81,18 +93,16 @@
8193 * if available.
8294 */
8395 if (device->power.flags.power_resources) {
84
- int error = acpi_power_get_inferred_state(device, &result);
96
+ error = acpi_power_get_inferred_state(device, &result);
8597 if (error)
8698 return error;
8799 }
88100 if (device->power.flags.explicit_get) {
89
- acpi_handle handle = device->handle;
90
- unsigned long long psc;
91
- acpi_status status;
101
+ int psc;
92102
93
- status = acpi_evaluate_integer(handle, "_PSC", NULL, &psc);
94
- if (ACPI_FAILURE(status))
95
- return -ENODEV;
103
+ error = acpi_dev_pm_explicit_get(device, &psc);
104
+ if (error)
105
+ return error;
96106
97107 /*
98108 * The power resources settings may indicate a power state
....@@ -157,9 +167,14 @@
157167 || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
158168 return -EINVAL;
159169
170
+ acpi_handle_debug(device->handle, "Power state change: %s -> %s\n",
171
+ acpi_power_state_string(device->power.state),
172
+ acpi_power_state_string(state));
173
+
160174 /* Make sure this is a valid target state */
161175
162
- if (state == device->power.state) {
176
+ /* There is a special case for D0 addressed below. */
177
+ if (state > ACPI_STATE_D0 && state == device->power.state) {
163178 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already in %s\n",
164179 device->pnp.bus_id,
165180 acpi_power_state_string(state)));
....@@ -209,18 +224,50 @@
209224 return -ENODEV;
210225 }
211226
212
- result = acpi_dev_pm_explicit_set(device, state);
213
- if (result)
214
- goto end;
227
+ /*
228
+ * If the device goes from D3hot to D3cold, _PS3 has been
229
+ * evaluated for it already, so skip it in that case.
230
+ */
231
+ if (device->power.state < ACPI_STATE_D3_HOT) {
232
+ result = acpi_dev_pm_explicit_set(device, state);
233
+ if (result)
234
+ goto end;
235
+ }
215236
216237 if (device->power.flags.power_resources)
217238 result = acpi_power_transition(device, target_state);
218239 } else {
240
+ int cur_state = device->power.state;
241
+
219242 if (device->power.flags.power_resources) {
220243 result = acpi_power_transition(device, ACPI_STATE_D0);
221244 if (result)
222245 goto end;
223246 }
247
+
248
+ if (cur_state == ACPI_STATE_D0) {
249
+ int psc;
250
+
251
+ /* Nothing to do here if _PSC is not present. */
252
+ if (!device->power.flags.explicit_get)
253
+ return 0;
254
+
255
+ /*
256
+ * The power state of the device was set to D0 last
257
+ * time, but that might have happened before a
258
+ * system-wide transition involving the platform
259
+ * firmware, so it may be necessary to evaluate _PS0
260
+ * for the device here. However, use extra care here
261
+ * and evaluate _PSC to check the device's current power
262
+ * state, and only invoke _PS0 if the evaluation of _PSC
263
+ * is successful and it returns a power state different
264
+ * from D0.
265
+ */
266
+ result = acpi_dev_pm_explicit_get(device, &psc);
267
+ if (result || psc == ACPI_STATE_D0)
268
+ return 0;
269
+ }
270
+
224271 result = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0);
225272 }
226273
....@@ -413,7 +460,7 @@
413460 if (adev->wakeup.flags.notifier_present) {
414461 pm_wakeup_ws_event(adev->wakeup.ws, 0, acpi_s2idle_wakeup());
415462 if (adev->wakeup.context.func) {
416
- acpi_handle_debug(handle, "Running %pF for %s\n",
463
+ acpi_handle_debug(handle, "Running %pS for %s\n",
417464 adev->wakeup.context.func,
418465 dev_name(adev->wakeup.context.dev));
419466 adev->wakeup.context.func(&adev->wakeup.context);
....@@ -729,6 +776,9 @@
729776 goto out;
730777 }
731778
779
+ acpi_handle_debug(adev->handle, "GPE%2X enabled for wakeup\n",
780
+ (unsigned int)wakeup->gpe_number);
781
+
732782 inc:
733783 wakeup->enable_count++;
734784
....@@ -1018,7 +1068,7 @@
10181068 {
10191069 int ret;
10201070
1021
- if (dev_pm_smart_suspend_and_suspended(dev))
1071
+ if (dev_pm_skip_suspend(dev))
10221072 return 0;
10231073
10241074 ret = pm_generic_suspend_late(dev);
....@@ -1034,10 +1084,8 @@
10341084 {
10351085 int ret;
10361086
1037
- if (dev_pm_smart_suspend_and_suspended(dev)) {
1038
- dev->power.may_skip_resume = true;
1087
+ if (dev_pm_skip_suspend(dev))
10391088 return 0;
1040
- }
10411089
10421090 ret = pm_generic_suspend_noirq(dev);
10431091 if (ret)
....@@ -1050,8 +1098,8 @@
10501098 * acpi_subsys_complete() to take care of fixing up the device's state
10511099 * anyway, if need be.
10521100 */
1053
- dev->power.may_skip_resume = device_may_wakeup(dev) ||
1054
- !device_can_wakeup(dev);
1101
+ if (device_can_wakeup(dev) && !device_may_wakeup(dev))
1102
+ dev->power.may_skip_resume = false;
10551103
10561104 return 0;
10571105 }
....@@ -1063,16 +1111,8 @@
10631111 */
10641112 static int acpi_subsys_resume_noirq(struct device *dev)
10651113 {
1066
- if (dev_pm_may_skip_resume(dev))
1114
+ if (dev_pm_skip_resume(dev))
10671115 return 0;
1068
-
1069
- /*
1070
- * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend
1071
- * during system suspend, so update their runtime PM status to "active"
1072
- * as they will be put into D0 going forward.
1073
- */
1074
- if (dev_pm_smart_suspend_and_suspended(dev))
1075
- pm_runtime_set_active(dev);
10761116
10771117 return pm_generic_resume_noirq(dev);
10781118 }
....@@ -1087,7 +1127,12 @@
10871127 */
10881128 static int acpi_subsys_resume_early(struct device *dev)
10891129 {
1090
- int ret = acpi_dev_resume(dev);
1130
+ int ret;
1131
+
1132
+ if (dev_pm_skip_resume(dev))
1133
+ return 0;
1134
+
1135
+ ret = acpi_dev_resume(dev);
10911136 return ret ? ret : pm_generic_resume_early(dev);
10921137 }
10931138
....@@ -1152,7 +1197,7 @@
11521197 {
11531198 int ret;
11541199
1155
- if (dev_pm_smart_suspend_and_suspended(dev))
1200
+ if (dev_pm_skip_suspend(dev))
11561201 return 0;
11571202
11581203 ret = pm_generic_poweroff_late(dev);
....@@ -1168,7 +1213,7 @@
11681213 */
11691214 static int acpi_subsys_poweroff_noirq(struct device *dev)
11701215 {
1171
- if (dev_pm_smart_suspend_and_suspended(dev))
1216
+ if (dev_pm_skip_suspend(dev))
11721217 return 0;
11731218
11741219 return pm_generic_poweroff_noirq(dev);
....@@ -1254,8 +1299,7 @@
12541299 * with the generic ACPI PM domain.
12551300 */
12561301 static const struct acpi_device_id special_pm_ids[] = {
1257
- {"PNP0C0B", }, /* Generic ACPI fan */
1258
- {"INT3404", }, /* Fan */
1302
+ ACPI_FAN_DEVICE_IDS,
12591303 {}
12601304 };
12611305 struct acpi_device *adev = ACPI_COMPANION(dev);