Skip to content

Commit 0f347aa

Browse files
jwrdegoederafaeljw
authored andcommitted
ACPI: scan: Fix battery devices sometimes never binding
With the new 2 step scanning process, which defers instantiating some ACPI-devices based on their _DEP to the second step, the following may happen: 1. During the first acpi_walk_namespace(acpi_bus_check_add) call acpi_scan_check_dep() gets called on the Battery ACPI dev handle and adds one or more deps for this handle to the acpi_dep_list 2. During the first acpi_bus_attach() call one or more of the suppliers of these deps get their driver attached and acpi_walk_dep_device_list(supplier_handle) gets called. At this point acpi_bus_get_device(dep->consumer) get called, but since the battery has DEPs it has not been instantiated during the first acpi_walk_namespace(acpi_bus_check_add), so the acpi_bus_get_device(dep->consumer) call fails. Before this commit, acpi_walk_dep_device_list() would now continue *without* removing the acpi_dep_data entry for this supplier,consumer pair from the acpi_dep_list. 3. During the second acpi_walk_namespace(acpi_bus_check_add) call an acpi_device gets instantiated for the battery and acpi_scan_dep_init() gets called to initialize its dep_unmet val. Before this commit, the dep_unmet count would include DEPs for suppliers for which acpi_walk_dep_device_list(supplier_handle) has already been called, so it will never become 0 and the ACPI battery driver will never get attached / bind. Fix the ACPI battery driver never binding in this scenario by making acpi_walk_dep_device_list() always remove matching acpi_dep_data entries independent of the acpi_bus_get_device(dep->consumer) call succeeding or not. Fixes: 71da201 ("ACPI: scan: Defer enumeration of devices with _DEP lists") Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 1048ba8 commit 0f347aa

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

drivers/acpi/scan.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,12 +2123,12 @@ void acpi_walk_dep_device_list(acpi_handle handle)
21232123
list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
21242124
if (dep->supplier == handle) {
21252125
acpi_bus_get_device(dep->consumer, &adev);
2126-
if (!adev)
2127-
continue;
21282126

2129-
adev->dep_unmet--;
2130-
if (!adev->dep_unmet)
2131-
acpi_bus_attach(adev, true);
2127+
if (adev) {
2128+
adev->dep_unmet--;
2129+
if (!adev->dep_unmet)
2130+
acpi_bus_attach(adev, true);
2131+
}
21322132

21332133
list_del(&dep->node);
21342134
kfree(dep);

0 commit comments

Comments
 (0)