Hi, On 11/23/20 1:17 PM, Rafael J. Wysocki wrote: > On Sat, Nov 21, 2020 at 9:31 PM Hans de Goede <hdegoede@xxxxxxxxxx> wrote: >> >> The current solution, of deferring adding of some devices because they >> need access during the OpRegions of other devices while they are added, >> is not very generic. >> >> And support for making the decision to defer adding a device based on >> its _DEP list, instead of the device's HID being in a fixed list of HIDs >> to defer, which should be a more generic way to deal with this. > > Thanks a lot for working on this! You're welcome. > I'll have a more thorough look at the series later this week, stay tuned. Ok. >> Since this is likely to cause issues on some hardware, this new method will >> only be used if the new acpi.defer_scan_based_on_dep kernel commandline >> option is set to 1. > > However, I already can say that I don't like the new command line option. You don't like the name, or you don't like having a commandline option for this? Anyways I'll wait till you have taken a closer look. Regards, Hans > >> Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> >> --- >> drivers/acpi/scan.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 44 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c >> index 407c8536568b..9927036bfe77 100644 >> --- a/drivers/acpi/scan.c >> +++ b/drivers/acpi/scan.c >> @@ -31,6 +31,11 @@ extern struct acpi_device *acpi_root; >> >> #define INVALID_ACPI_HANDLE ((acpi_handle)empty_zero_page) >> >> +static int defer_scan_based_on_dep = -1; >> +module_param(defer_scan_based_on_dep, int, 0444); >> +MODULE_PARM_DESC(defer_scan_based_on_dep, >> + "Use new scan-scheme deferring addition of devices with non empty _DEP list (-1=auto, 0=no, 1=yes)"); >> + >> static const char *dummy_hid = "device"; >> >> static LIST_HEAD(acpi_dep_list); >> @@ -1657,11 +1662,45 @@ void acpi_device_add_finalize(struct acpi_device *device) >> >> static bool acpi_should_defer_add(acpi_handle handle, struct acpi_device_info *info) >> { >> + struct acpi_handle_list dep_devices; >> + acpi_status status; >> + int i; >> + >> if (!acpi_check_defer_add || !info) >> return false; >> >> - if (acpi_info_matches_hids(info, acpi_defer_add_hids)) >> + if (!defer_scan_based_on_dep) >> + return acpi_info_matches_hids(info, acpi_defer_add_hids); >> + >> + /* >> + * We check for _ADR here to avoid deferring the adding of the following: >> + * 1. PCI devices >> + * 2. ACPI nodes describing USB ports >> + * Note checking for _ADR catches more then just these cases... > > s/then/than/ > >> + */ >> + if (info->valid & ACPI_VALID_ADR) >> + return false; >> + >> + status = acpi_evaluate_reference(handle, "_DEP", NULL, &dep_devices); >> + if (ACPI_FAILURE(status)) >> + return false; >> + >> + for (i = 0; i < dep_devices.count; i++) { >> + struct acpi_device_info *dep_info; >> + bool ignore; >> + >> + status = acpi_get_object_info(dep_devices.handles[i], &dep_info); >> + if (ACPI_FAILURE(status)) >> + continue; >> + >> + ignore = acpi_info_matches_hids(dep_info, acpi_ignore_dep_hids); >> + kfree(dep_info); >> + >> + if (ignore) >> + continue; >> + >> return true; >> + } >> >> return false; >> } >> @@ -2251,6 +2290,10 @@ int __init acpi_scan_init(void) >> struct acpi_table_stao *stao_ptr; >> struct acpi_deferred_dev *deferred_dev, *tmp; >> >> + /* Currently no devices are known which need _dep based scan deferral */ >> + if (defer_scan_based_on_dep == -1) >> + defer_scan_based_on_dep = 0; >> + >> acpi_pci_root_init(); >> acpi_pci_link_init(); >> acpi_processor_init(); >> -- >> 2.28.0 >> >