Merge tag 'for-5.11/io_uring-2020-12-14' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / drivers / acpi / scan.c
index 519963b..a1b226e 100644 (file)
@@ -51,8 +51,8 @@ static u64 spcr_uart_addr;
 
 struct acpi_dep_data {
        struct list_head node;
-       acpi_handle master;
-       acpi_handle slave;
+       acpi_handle supplier;
+       acpi_handle consumer;
 };
 
 void acpi_scan_lock_acquire(void)
@@ -719,6 +719,42 @@ int acpi_device_add(struct acpi_device *device,
 /* --------------------------------------------------------------------------
                                  Device Enumeration
    -------------------------------------------------------------------------- */
+static bool acpi_info_matches_ids(struct acpi_device_info *info,
+                                 const char * const ids[])
+{
+       struct acpi_pnp_device_id_list *cid_list = NULL;
+       int i;
+
+       if (!(info->valid & ACPI_VALID_HID))
+               return false;
+
+       if (info->valid & ACPI_VALID_CID)
+               cid_list = &info->compatible_id_list;
+
+       for (i = 0; ids[i]; i++) {
+               int j;
+
+               if (!strcmp(info->hardware_id.string, ids[i]))
+                       return true;
+
+               if (!cid_list)
+                       continue;
+
+               for (j = 0; j < cid_list->count; j++) {
+                       if (!strcmp(cid_list->ids[j].string, ids[i]))
+                               return true;
+               }
+       }
+
+       return false;
+}
+
+/* List of HIDs for which we ignore matching ACPI devices, when checking _DEP lists. */
+static const char * const acpi_ignore_dep_ids[] = {
+       "PNP0D80", /* Windows-compatible System Power Management Controller */
+       NULL
+};
+
 static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
 {
        struct acpi_device *device = NULL;
@@ -1236,10 +1272,8 @@ static bool acpi_object_is_system_bus(acpi_handle handle)
 }
 
 static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
-                               int device_type)
+                               int device_type, struct acpi_device_info *info)
 {
-       acpi_status status;
-       struct acpi_device_info *info;
        struct acpi_pnp_device_id_list *cid_list;
        int i;
 
@@ -1250,8 +1284,7 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
                        break;
                }
 
-               status = acpi_get_object_info(handle, &info);
-               if (ACPI_FAILURE(status)) {
+               if (!info) {
                        pr_err(PREFIX "%s: Error reading device info\n",
                                        __func__);
                        return;
@@ -1276,8 +1309,6 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
                if (info->valid & ACPI_VALID_CLS)
                        acpi_add_id(pnp, info->class_code.string);
 
-               kfree(info);
-
                /*
                 * Some devices don't reliably have _HIDs & _CIDs, so add
                 * synthetic HIDs to make sure drivers can find them.
@@ -1583,7 +1614,8 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
 }
 
 void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
-                            int type, unsigned long long sta)
+                            int type, unsigned long long sta,
+                            struct acpi_device_info *info)
 {
        INIT_LIST_HEAD(&device->pnp.ids);
        device->device_type = type;
@@ -1592,7 +1624,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
        fwnode_init(&device->fwnode, &acpi_device_fwnode_ops);
        acpi_set_device_status(device, sta);
        acpi_device_get_busid(device);
-       acpi_set_pnp_ids(handle, &device->pnp, type);
+       acpi_set_pnp_ids(handle, &device->pnp, type, info);
        acpi_init_properties(device);
        acpi_bus_get_flags(device);
        device->flags.match_driver = false;
@@ -1620,14 +1652,20 @@ static int acpi_add_single_object(struct acpi_device **child,
        int result;
        struct acpi_device *device;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+       struct acpi_device_info *info = NULL;
+
+       if (handle != ACPI_ROOT_OBJECT && type == ACPI_BUS_TYPE_DEVICE)
+               acpi_get_object_info(handle, &info);
 
        device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
        if (!device) {
                printk(KERN_ERR PREFIX "Memory allocation error\n");
+               kfree(info);
                return -ENOMEM;
        }
 
-       acpi_init_device_object(device, handle, type, sta);
+       acpi_init_device_object(device, handle, type, sta, info);
+       kfree(info);
        /*
         * For ACPI_BUS_TYPE_DEVICE getting the status is delayed till here so
         * that we can call acpi_bus_get_status() and use its quirk handling.
@@ -1833,13 +1871,7 @@ static void acpi_device_dep_initialize(struct acpi_device *adev)
                        continue;
                }
 
-               /*
-                * Skip the dependency of Windows System Power
-                * Management Controller
-                */
-               skip = info->valid & ACPI_VALID_HID &&
-                       !strcmp(info->hardware_id.string, "INT3396");
-
+               skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids);
                kfree(info);
 
                if (skip)
@@ -1849,8 +1881,8 @@ static void acpi_device_dep_initialize(struct acpi_device *adev)
                if (!dep)
                        return;
 
-               dep->master = dep_devices.handles[i];
-               dep->slave  = adev->handle;
+               dep->supplier = dep_devices.handles[i];
+               dep->consumer  = adev->handle;
                adev->dep_unmet++;
 
                mutex_lock(&acpi_dep_list_lock);
@@ -2026,8 +2058,8 @@ void acpi_walk_dep_device_list(acpi_handle handle)
 
        mutex_lock(&acpi_dep_list_lock);
        list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
-               if (dep->master == handle) {
-                       acpi_bus_get_device(dep->slave, &adev);
+               if (dep->supplier == handle) {
+                       acpi_bus_get_device(dep->consumer, &adev);
                        if (!adev)
                                continue;