summaryrefslogtreecommitdiff
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 2c80765670bc..89c4ae6ef3ec 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -797,6 +797,12 @@ static const char * const acpi_ignore_dep_ids[] = {
NULL
};
+/* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */
+static const char * const acpi_honor_dep_ids[] = {
+ "INT3472", /* Camera sensor PMIC / clk and regulator info */
+ NULL
+};
+
static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
{
struct acpi_device *device = NULL;
@@ -1762,8 +1768,12 @@ static void acpi_scan_dep_init(struct acpi_device *adev)
struct acpi_dep_data *dep;
list_for_each_entry(dep, &acpi_dep_list, node) {
- if (dep->consumer == adev->handle)
+ if (dep->consumer == adev->handle) {
+ if (dep->honor_dep)
+ adev->flags.honor_deps = 1;
+
adev->dep_unmet++;
+ }
}
}
@@ -1967,7 +1977,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
for (count = 0, i = 0; i < dep_devices.count; i++) {
struct acpi_device_info *info;
struct acpi_dep_data *dep;
- bool skip;
+ bool skip, honor_dep;
status = acpi_get_object_info(dep_devices.handles[i], &info);
if (ACPI_FAILURE(status)) {
@@ -1976,6 +1986,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
}
skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids);
+ honor_dep = acpi_info_matches_ids(info, acpi_honor_dep_ids);
kfree(info);
if (skip)
@@ -1989,6 +2000,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
dep->supplier = dep_devices.handles[i];
dep->consumer = handle;
+ dep->honor_dep = honor_dep;
mutex_lock(&acpi_dep_list_lock);
list_add_tail(&dep->node , &acpi_dep_list);
@@ -2155,8 +2167,8 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
register_dock_dependent_device(device, ejd);
acpi_bus_get_status(device);
- /* Skip devices that are not present. */
- if (!acpi_device_is_present(device)) {
+ /* Skip devices that are not ready for enumeration (e.g. not present) */
+ if (!acpi_dev_ready_for_enumeration(device)) {
device->flags.initialized = false;
acpi_device_clear_enumerated(device);
device->flags.power_manageable = 0;
@@ -2319,6 +2331,23 @@ void acpi_dev_clear_dependencies(struct acpi_device *supplier)
EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
/**
+ * acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration
+ * @device: Pointer to the &struct acpi_device to check
+ *
+ * Check if the device is present and has no unmet dependencies.
+ *
+ * Return true if the device is ready for enumeratino. Otherwise, return false.
+ */
+bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
+{
+ if (device->flags.honor_deps && device->dep_unmet)
+ return false;
+
+ return acpi_device_is_present(device);
+}
+EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
+
+/**
* acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
* @supplier: Pointer to the dependee device
*