Merge branches 'acpi-scan', 'acpi-pnp' and 'acpi-sleep'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 22 Dec 2020 14:51:11 +0000 (15:51 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 22 Dec 2020 14:51:11 +0000 (15:51 +0100)
* acpi-scan:
  ACPI: scan: Add Intel Baytrail Mailbox Device to acpi_ignore_dep_ids
  ACPI: scan: Avoid unnecessary second pass in acpi_bus_scan()
  ACPI: scan: Defer enumeration of devices with _DEP lists
  ACPI: scan: Evaluate _DEP before adding the device

* acpi-pnp:
  ACPI: PNP: compare the string length in the matching_id()

* acpi-sleep:
  ACPI: PM: s2idle: Move x86-specific code to the x86 directory
  ACPI: PM: s2idle: Add AMD support to handle _DSM

1  2  3  4 
drivers/acpi/scan.c

@@@@@ -719,42 -719,43 -719,6 -719,6 +719,43 @@@@@ int acpi_device_add(struct acpi_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 */
+ ++    "INT33BD", /* Intel Baytrail Mailbox Device */
  ++    NULL
  ++};
  ++
    static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
    {
        struct acpi_device *device = NULL;
@@@@@ -1621,10 -1622,10 -1589,10 -1589,10 +1622,10 @@@@@ void acpi_init_device_object(struct acp
        device->device_type = type;
        device->handle = handle;
        device->parent = acpi_bus_get_parent(handle);
 ---    device->fwnode.ops = &acpi_device_fwnode_ops;
 +++    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;
@@@@@ -1877,13 -1880,14 -1845,13 -1845,13 +1880,14 @@@@@ static u32 acpi_scan_check_dep(acpi_han
                if (skip)
                        continue;
    
- --            dep = kzalloc(sizeof(struct acpi_dep_data), GFP_KERNEL);
+ ++            dep = kzalloc(sizeof(*dep), GFP_KERNEL);
                if (!dep)
- --                    return;
+ ++                    continue;
+ ++
+ ++            count++;
    
  --            dep->master = dep_devices.handles[i];
  --            dep->slave  = adev->handle;
  --            adev->dep_unmet++;
  ++            dep->supplier = dep_devices.handles[i];
-               dep->consumer  = adev->handle;
-               adev->dep_unmet++;
+ ++            dep->consumer = handle;
    
                mutex_lock(&acpi_dep_list_lock);
                list_add_tail(&dep->node , &acpi_dep_list);
@@@@@ -2090,17 -2139,37 -2058,17 -2058,17 +2139,37 @@@@@ EXPORT_SYMBOL_GPL(acpi_walk_dep_device_
     */
    int acpi_bus_scan(acpi_handle handle)
    {
- --    void *device = NULL;
+ ++    struct acpi_device *device = NULL;
+ ++
+ ++    acpi_bus_scan_second_pass = false;
  ++
-       if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
+ ++    /* Pass 1: Avoid enumerating devices with missing dependencies. */
+   
  --    if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
+ ++    if (ACPI_SUCCESS(acpi_bus_check_add(handle, true, &device)))
                acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
- --                                acpi_bus_check_add, NULL, NULL, &device);
+ ++                                acpi_bus_check_add_1, NULL, NULL,
+ ++                                (void **)&device);
+ ++
+ ++    if (!device)
+ ++            return -ENODEV;
  ++
-       if (device) {
-               acpi_bus_attach(device);
+ ++    acpi_bus_attach(device, true);
+   
  --    if (device) {
  --            acpi_bus_attach(device);
+ ++    if (!acpi_bus_scan_second_pass)
                return 0;
- --    }
- --    return -ENODEV;
+ ++
+ ++    /* Pass 2: Enumerate all of the remaining devices. */
+ ++
+ ++    device = NULL;
+ ++
+ ++    if (ACPI_SUCCESS(acpi_bus_check_add(handle, false, &device)))
+ ++            acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+ ++                                acpi_bus_check_add_2, NULL, NULL,
+ ++                                (void **)&device);
+ ++
+ ++    acpi_bus_attach(device, false);
+ ++
+ ++    return 0;
    }
    EXPORT_SYMBOL(acpi_bus_scan);