diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/apei/einj.c | 3 | ||||
-rw-r--r-- | drivers/acpi/apei/ghes.c | 2 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 37 |
3 files changed, 36 insertions, 6 deletions
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c index edb2622fd35f..95cc2a9f3e05 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -545,7 +545,8 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, ((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE) != REGION_INTERSECTS) && (region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY) - != REGION_INTERSECTS))) + != REGION_INTERSECTS) && + !arch_is_platform_page(base_addr))) return -EINVAL; inject: diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 0c8330ed1ffd..0c5c9acc6254 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -449,7 +449,7 @@ static bool ghes_do_memory_failure(u64 physical_addr, int flags) return false; pfn = PHYS_PFN(physical_addr); - if (!pfn_valid(pfn)) { + if (!pfn_valid(pfn) && !arch_is_platform_page(physical_addr)) { pr_warn_ratelimited(FW_WARN GHES_PFX "Invalid address in generic error data: %#llx\n", physical_addr); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 4dd3a9efcd0f..1185ecea59d1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -810,6 +810,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; @@ -1784,8 +1790,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++; + } } } @@ -1989,7 +1999,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)) { @@ -1998,6 +2008,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) @@ -2011,6 +2022,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); @@ -2176,8 +2188,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; @@ -2340,6 +2352,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 * |