Commit 7931c531 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 8a3cbdda e1db18b5
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -99,13 +99,12 @@ acpi_status acpi_ns_root_initialize(void)
		 * just create and link the new node(s) here.
		 */
		new_node =
		    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node));
		    acpi_ns_create_node(*ACPI_CAST_PTR(u32, init_val->name));
		if (!new_node) {
			status = AE_NO_MEMORY;
			goto unlock_and_exit;
		}

		ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name);
		new_node->descriptor_type = ACPI_DESC_TYPE_NAMED;
		new_node->type = init_val->type;

+5 −1
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@
#ifndef _ACPI_INTERNAL_H_
#define _ACPI_INTERNAL_H_

#include <linux/idr.h>

#define PREFIX "ACPI: "

int early_acpi_osi_init(void);
@@ -96,9 +98,11 @@ void acpi_scan_table_handler(u32 event, void *table, void *context);

extern struct list_head acpi_bus_id_list;

#define ACPI_MAX_DEVICE_INSTANCES	4096

struct acpi_device_bus_id {
	const char *bus_id;
	unsigned int instance_no;
	struct ida instance_ida;
	struct list_head node;
};

+28 −5
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
		},
	},
	{
	.callback = video_detect_force_vendor,
	.ident = "Sony VPCEH3U1E",
	.matches = {
		DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+1 −0
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ struct acpi_pnp_type {

struct acpi_device_pnp {
	acpi_bus_id bus_id;		/* Object name */
	int instance_no;		/* Instance number of this object */
	struct acpi_pnp_type type;	/* ID type */
	acpi_bus_address bus_address;	/* _ADR */
	char *unique_id;		/* _UID */