Commit 7931c531 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 8a3cbdda e1db18b5
......@@ -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;
......
......@@ -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;
};
......
......@@ -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);
......
......@@ -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"),
......
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment