diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-03-26 11:33:39 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-03-26 11:33:39 -0700 | 
| commit | 7931c531fc527da650e1761d35216ff8edf28a94 (patch) | |
| tree | 90108b2169f5f62ab4a6bbdfe853d127f1c85f58 /drivers/acpi/scan.c | |
| parent | 8a3cbdda181024f9ee7200504e748d2e91adad1a (diff) | |
| parent | e1db18b59729e24f001459b98955019344d5b12b (diff) | |
Merge tag 'acpi-5.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI fixes from Rafael Wysocki:
 "These fix a memory management regression in ACPICA, repair an ACPI
  blacklist entry damaged inadvertently during the 5.11 cycle and fix
  the bookkeeping of devices with the same primary device ID in the ACPI
  core.
  Specifics:
   - Make ACPICA use the same object cache consistently when allocating
     and freeing objects (Vegard Nossum)
   - Add a callback pointer removed inadvertently during the 5.11 cycle
     to the ACPI backlight blacklist entry for Sony VPCEH3U1E (Chris
     Chiu)
   - Make the ACPI device enumeration core use IDA for creating names of
     ACPI device objects with the same primary device ID to avoid using
     duplicate device object names in some cases (Andy Shevchenko)"
* tag 'acpi-5.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPICA: Always create namespace nodes using acpi_ns_create_node()
  ACPI: scan: Use unique number for instance_no
  ACPI: video: Add missing callback back for Sony VPCEH3U1E
Diffstat (limited to 'drivers/acpi/scan.c')
| -rw-r--r-- | drivers/acpi/scan.c | 33 | 
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index a184529d8fa4..84bb7c1929f1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -479,9 +479,8 @@ static void acpi_device_del(struct acpi_device *device)  	list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node)  		if (!strcmp(acpi_device_bus_id->bus_id,  			    acpi_device_hid(device))) { -			if (acpi_device_bus_id->instance_no > 0) -				acpi_device_bus_id->instance_no--; -			else { +			ida_simple_remove(&acpi_device_bus_id->instance_ida, device->pnp.instance_no); +			if (ida_is_empty(&acpi_device_bus_id->instance_ida)) {  				list_del(&acpi_device_bus_id->node);  				kfree_const(acpi_device_bus_id->bus_id);  				kfree(acpi_device_bus_id); @@ -631,6 +630,21 @@ static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)  	return NULL;  } +static int acpi_device_set_name(struct acpi_device *device, +				struct acpi_device_bus_id *acpi_device_bus_id) +{ +	struct ida *instance_ida = &acpi_device_bus_id->instance_ida; +	int result; + +	result = ida_simple_get(instance_ida, 0, ACPI_MAX_DEVICE_INSTANCES, GFP_KERNEL); +	if (result < 0) +		return result; + +	device->pnp.instance_no = result; +	dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, result); +	return 0; +} +  int acpi_device_add(struct acpi_device *device,  		    void (*release)(struct device *))  { @@ -665,7 +679,9 @@ int acpi_device_add(struct acpi_device *device,  	acpi_device_bus_id = acpi_device_bus_id_match(acpi_device_hid(device));  	if (acpi_device_bus_id) { -		acpi_device_bus_id->instance_no++; +		result = acpi_device_set_name(device, acpi_device_bus_id); +		if (result) +			goto err_unlock;  	} else {  		acpi_device_bus_id = kzalloc(sizeof(*acpi_device_bus_id),  					     GFP_KERNEL); @@ -681,9 +697,16 @@ int acpi_device_add(struct acpi_device *device,  			goto err_unlock;  		} +		ida_init(&acpi_device_bus_id->instance_ida); + +		result = acpi_device_set_name(device, acpi_device_bus_id); +		if (result) { +			kfree(acpi_device_bus_id); +			goto err_unlock; +		} +  		list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);  	} -	dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);  	if (device->parent)  		list_add_tail(&device->node, &device->parent->children);  | 
