[PATCH 6/7] ACPI: scan: Fix battery devices not working with acpi.defer_scan_based_on_dep=1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When battery devices get added during the second step of the now 2 step
scan-process, then acpi_walk_dep_device_list() may have already been
called for some deps during the first step.

In this case acpi_device_dep_initialize() should not add these deps to
the acpi_dep_list; and it should not increase adev->dep_unmet.

Add a check for already registered (and bound to a driver) devices to
acpi_device_dep_initialize(). This fixes battery devices (which honor the
dep_unmet value) not working with acpi.defer_scan_based_on_dep=1.

Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
---
 drivers/acpi/scan.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9927036bfe77..44001610f6a4 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -17,6 +17,8 @@
 #include <linux/platform_data/x86/apple.h>
 #include <linux/pgtable.h>
 
+#include "acpica/accommon.h"
+#include "acpica/acnamesp.h"
 #include "internal.h"
 
 #define _COMPONENT		ACPI_BUS_COMPONENT
@@ -1935,7 +1937,10 @@ static void acpi_device_dep_initialize(struct acpi_device *adev)
 	}
 
 	for (i = 0; i < dep_devices.count; i++) {
+		struct acpi_device *dep_adev = NULL;
+		struct acpi_namespace_node *node;
 		struct acpi_device_info *info;
+		struct device *dep_dev;
 		int skip;
 
 		status = acpi_get_object_info(dep_devices.handles[i], &info);
@@ -1950,6 +1955,30 @@ static void acpi_device_dep_initialize(struct acpi_device *adev)
 		if (skip)
 			continue;
 
+		/*
+		 * Skip devices which already have a driver bound
+		 * and thus are already available for use.
+		 * We only need to do this during the second scan step,
+		 * when acpi_check_defer_add == false.
+		 */
+		if (!acpi_check_defer_add) {
+			/*
+			 * Cannot call acpi_bus_get_device here as we are called
+			 * with ACPI_MTX_NAMESPACE held.
+			 */
+			node = acpi_ns_validate_handle(dep_devices.handles[i]);
+			if (!node)
+				continue; /* Should never happen */
+
+			status = acpi_ns_get_attached_data(node, acpi_scan_drop_device,
+							   (void **)&dep_adev);
+			if (ACPI_SUCCESS(status) && dep_adev) {
+				dep_dev = acpi_get_first_physical_node(dep_adev);
+				if (dep_dev && dep_dev->driver)
+					continue;
+			}
+		}
+
 		dep = kzalloc(sizeof(struct acpi_dep_data), GFP_KERNEL);
 		if (!dep)
 			return;
-- 
2.28.0




[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux