Skip to content

Commit 285fc3d

Browse files
committed
Merge tag 'acpi-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI updates from Rafael Wysocki: "These add support for a new ACPI device configuration object called _DSC, fix some issues including one recent regression, add two new items to quirk lists and clean up assorted pieces of code. Specifics: - Add support for new ACPI device configuration object called _DSC ("Deepest State for Configuration") to allow certain devices to be probed without changing their power states, document it and make two drivers use it (Sakari Ailus, Rajmohan Mani). - Fix device wakeup power reference counting broken recently by mistake (Rafael Wysocki). - Drop unused symbol and macros depending on it from acgcc.h (Rafael Wysocki). - Add HP ZHAN 66 Pro to the "no EC wakeup" quirk list (Binbin Zhou). - Add Xiaomi Mi Pad 2 to the backlight quirk list and drop an unused piece of data from all of the list entries (Hans de Goede). - Fix register read accesses handling in the Intel PMIC operation region driver (Hans de Goede). - Clean up static variables initialization in the EC driver (wangzhitong)" * tag 'acpi-5.16-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Documentation: ACPI: Fix non-D0 probe _DSC object example ACPI: Drop ACPI_USE_BUILTIN_STDARG ifdef from acgcc.h ACPI: PM: Fix device wakeup power reference counting error ACPI: video: use platform backlight driver on Xiaomi Mi Pad 2 ACPI: video: Drop dmi_system_id.ident settings from video_detect_dmi_table[] ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses ACPI: EC: Remove initialization of static variables to false ACPI: EC: Use ec_no_wakeup on HP ZHAN 66 Pro at24: Support probing while in non-zero ACPI D state media: i2c: imx319: Support device probe in non-zero ACPI D state ACPI: Add a convenience function to tell a device is in D0 state Documentation: ACPI: Document _DSC object usage for enum power state i2c: Allow an ACPI driver to manage the device's power state during probe ACPI: scan: Obtain device's desired enumeration power state
2 parents e68a7d3 + 314c6e2 commit 285fc3d

File tree

16 files changed

+301
-129
lines changed

16 files changed

+301
-129
lines changed

Documentation/firmware-guide/acpi/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ ACPI Support
2626
acpi-lid
2727
lpit
2828
video_extension
29+
non-d0-probe
2930
extcon-intel-int3496
3031
intel-pmc-mux
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
========================================
4+
Probing devices in other D states than 0
5+
========================================
6+
7+
Introduction
8+
============
9+
10+
In some cases it may be preferred to leave certain devices powered off for the
11+
entire system bootup if powering on these devices has adverse side effects,
12+
beyond just powering on the said device.
13+
14+
How it works
15+
============
16+
17+
The _DSC (Device State for Configuration) object that evaluates to an integer
18+
may be used to tell Linux the highest allowed D state for a device during
19+
probe. The support for _DSC requires support from the kernel bus type if the
20+
bus driver normally sets the device in D0 state for probe.
21+
22+
The downside of using _DSC is that as the device is not powered on, even if
23+
there's a problem with the device, the driver likely probes just fine but the
24+
first user will find out the device doesn't work, instead of a failure at probe
25+
time. This feature should thus be used sparingly.
26+
27+
I²C
28+
---
29+
30+
If an I²C driver indicates its support for this by setting the
31+
I2C_DRV_ACPI_WAIVE_D0_PROBE flag in struct i2c_driver.flags field and the
32+
_DSC object evaluates to integer higher than the D state of the device,
33+
the device will not be powered on (put in D0 state) for probe.
34+
35+
D states
36+
--------
37+
38+
The D states and thus also the allowed values for _DSC are listed below. Refer
39+
to [1] for more information on device power states.
40+
41+
.. code-block:: text
42+
43+
Number State Description
44+
0 D0 Device fully powered on
45+
1 D1
46+
2 D2
47+
3 D3hot
48+
4 D3cold Off
49+
50+
References
51+
==========
52+
53+
[1] https://uefi.org/specifications/ACPI/6.4/02_Definition_of_Terms/Definition_of_Terms.html#device-power-state-definitions
54+
55+
Example
56+
=======
57+
58+
An ASL example describing an ACPI device using _DSC object to tell Operating
59+
System the device should remain powered off during probe looks like this. Some
60+
objects not relevant from the example point of view have been omitted.
61+
62+
.. code-block:: text
63+
64+
Device (CAM0)
65+
{
66+
Name (_HID, "SONY319A")
67+
Name (_UID, Zero)
68+
Name (_CRS, ResourceTemplate ()
69+
{
70+
I2cSerialBus(0x0020, ControllerInitiated, 0x00061A80,
71+
AddressingMode7Bit, "\\_SB.PCI0.I2C0",
72+
0x00, ResourceConsumer)
73+
})
74+
Method (_DSC, 0, NotSerialized)
75+
{
76+
Return (0x4)
77+
}
78+
}

drivers/acpi/device_pm.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,4 +1400,30 @@ bool acpi_storage_d3(struct device *dev)
14001400
}
14011401
EXPORT_SYMBOL_GPL(acpi_storage_d3);
14021402

1403+
/**
1404+
* acpi_dev_state_d0 - Tell if the device is in D0 power state
1405+
* @dev: Physical device the ACPI power state of which to check
1406+
*
1407+
* On a system without ACPI, return true. On a system with ACPI, return true if
1408+
* the current ACPI power state of the device is D0, or false otherwise.
1409+
*
1410+
* Note that the power state of a device is not well-defined after it has been
1411+
* passed to acpi_device_set_power() and before that function returns, so it is
1412+
* not valid to ask for the ACPI power state of the device in that time frame.
1413+
*
1414+
* This function is intended to be used in a driver's probe or remove
1415+
* function. See Documentation/firmware-guide/acpi/low-power-probe.rst for
1416+
* more information.
1417+
*/
1418+
bool acpi_dev_state_d0(struct device *dev)
1419+
{
1420+
struct acpi_device *adev = ACPI_COMPANION(dev);
1421+
1422+
if (!adev)
1423+
return true;
1424+
1425+
return adev->power.state == ACPI_STATE_D0;
1426+
}
1427+
EXPORT_SYMBOL_GPL(acpi_dev_state_d0);
1428+
14031429
#endif /* CONFIG_PM */

drivers/acpi/ec.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ static unsigned int ec_storm_threshold __read_mostly = 8;
133133
module_param(ec_storm_threshold, uint, 0644);
134134
MODULE_PARM_DESC(ec_storm_threshold, "Maxim false GPE numbers not considered as GPE storm");
135135

136-
static bool ec_freeze_events __read_mostly = false;
136+
static bool ec_freeze_events __read_mostly;
137137
module_param(ec_freeze_events, bool, 0644);
138138
MODULE_PARM_DESC(ec_freeze_events, "Disabling event handling during suspend/resume");
139139

@@ -177,7 +177,7 @@ struct acpi_ec *first_ec;
177177
EXPORT_SYMBOL(first_ec);
178178

179179
static struct acpi_ec *boot_ec;
180-
static bool boot_ec_is_ecdt = false;
180+
static bool boot_ec_is_ecdt;
181181
static struct workqueue_struct *ec_wq;
182182
static struct workqueue_struct *ec_query_wq;
183183

@@ -2152,6 +2152,13 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
21522152
DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Yoga 3rd"),
21532153
},
21542154
},
2155+
{
2156+
.ident = "HP ZHAN 66 Pro",
2157+
.matches = {
2158+
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
2159+
DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"),
2160+
},
2161+
},
21552162
{ },
21562163
};
21572164

drivers/acpi/pmic/intel_pmic.c

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -211,31 +211,36 @@ static acpi_status intel_pmic_regs_handler(u32 function,
211211
void *handler_context, void *region_context)
212212
{
213213
struct intel_pmic_opregion *opregion = region_context;
214-
int result = 0;
214+
int result = -EINVAL;
215+
216+
if (function == ACPI_WRITE) {
217+
switch (address) {
218+
case 0:
219+
return AE_OK;
220+
case 1:
221+
opregion->ctx.addr |= (*value64 & 0xff) << 8;
222+
return AE_OK;
223+
case 2:
224+
opregion->ctx.addr |= *value64 & 0xff;
225+
return AE_OK;
226+
case 3:
227+
opregion->ctx.val = *value64 & 0xff;
228+
return AE_OK;
229+
case 4:
230+
if (*value64) {
231+
result = regmap_write(opregion->regmap, opregion->ctx.addr,
232+
opregion->ctx.val);
233+
} else {
234+
result = regmap_read(opregion->regmap, opregion->ctx.addr,
235+
&opregion->ctx.val);
236+
}
237+
opregion->ctx.addr = 0;
238+
}
239+
}
215240

216-
switch (address) {
217-
case 0:
218-
return AE_OK;
219-
case 1:
220-
opregion->ctx.addr |= (*value64 & 0xff) << 8;
221-
return AE_OK;
222-
case 2:
223-
opregion->ctx.addr |= *value64 & 0xff;
241+
if (function == ACPI_READ && address == 3) {
242+
*value64 = opregion->ctx.val;
224243
return AE_OK;
225-
case 3:
226-
opregion->ctx.val = *value64 & 0xff;
227-
return AE_OK;
228-
case 4:
229-
if (*value64) {
230-
result = regmap_write(opregion->regmap, opregion->ctx.addr,
231-
opregion->ctx.val);
232-
} else {
233-
result = regmap_read(opregion->regmap, opregion->ctx.addr,
234-
&opregion->ctx.val);
235-
if (result == 0)
236-
*value64 = opregion->ctx.val;
237-
}
238-
memset(&opregion->ctx, 0x00, sizeof(opregion->ctx));
239244
}
240245

241246
if (result < 0) {

drivers/acpi/power.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -757,13 +757,11 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
757757

758758
mutex_lock(&acpi_device_lock);
759759

760-
if (dev->wakeup.prepare_count > 1) {
761-
dev->wakeup.prepare_count--;
760+
/* Do nothing if wakeup power has not been enabled for this device. */
761+
if (dev->wakeup.prepare_count <= 0)
762762
goto out;
763-
}
764763

765-
/* Do nothing if wakeup power has not been enabled for this device. */
766-
if (!dev->wakeup.prepare_count)
764+
if (--dev->wakeup.prepare_count > 0)
767765
goto out;
768766

769767
err = acpi_device_sleep_wake(dev, 0, 0, 0);

drivers/acpi/scan.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,7 @@ static void acpi_bus_init_power_state(struct acpi_device *device, int state)
10171017

10181018
static void acpi_bus_get_power_flags(struct acpi_device *device)
10191019
{
1020+
unsigned long long dsc = ACPI_STATE_D0;
10201021
u32 i;
10211022

10221023
/* Presence of _PS0|_PR0 indicates 'power manageable' */
@@ -1038,6 +1039,9 @@ static void acpi_bus_get_power_flags(struct acpi_device *device)
10381039
if (acpi_has_method(device->handle, "_DSW"))
10391040
device->power.flags.dsw_present = 1;
10401041

1042+
acpi_evaluate_integer(device->handle, "_DSC", NULL, &dsc);
1043+
device->power.state_for_enumeration = dsc;
1044+
10411045
/*
10421046
* Enumerate supported power management states
10431047
*/

0 commit comments

Comments
 (0)