summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 16:39:06 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2020-12-15 16:39:06 -0800
commitaab7ce2b099bd9df82573cd3170acf6518fdebeb (patch)
tree88caa27e82f334f1f949dacc874e7af1b276af7e /drivers/acpi/scan.c
parentb4ec805464a4a0299216a003278351d0b4806450 (diff)
parent38a0925c5fc89689433f2a2ad415982397cf626e (diff)
downloadlinux-aab7ce2b099bd9df82573cd3170acf6518fdebeb.tar.bz2
Merge tag 'acpi-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI updates from Rafael Wysocki: "These update the ACPICA code in the kernel to upstream revision 20201113, fix and clean up some resources manipulation code, extend the enumeration and gpio-line-names property documentation, clean up the handling of _DEP during device enumeration, add a new backlight DMI quirk, clean up transaction handling in the EC driver and make some assorted janitorial changes. Specifics: - Update ACPICA code in the kernel to upstream revision 20201113 with changes as follows: * Add 5 new UUIDs to the known UUID table (Bob Moore) * Remove extreaneous "the" in comments (Colin Ian King) * Add function trace macros to improve debugging (Erik Kaneda) * Fix interpreter memory leak (Erik Kaneda) * Handle "orphan" _REG for GPIO OpRegions (Hans de Goede) - Introduce resource_union() and resource_intersection() helpers and clean up some resource-manipulation code with the help of them (Andy Shevchenko) - Revert problematic commit related to the handling of resources in the ACPI core (Daniel Scally) - Extend the ACPI device enumeration documentation and the gpio-line-names _DSD property documentation, clean up the latter (Flavio Suligoi) - Clean up _DEP handling during device enumeration, modify the list of _DEP exceptions and the handling of it and fix up terminology related to _DEP (Hans de Goede, Rafael Wysocki) - Eliminate in_interrupt() usage from the ACPI EC driver (Sebastian Andrzej Siewior) - Clean up the advance_transaction() routine and related code in the ACPI EC driver (Rafael Wysocki) - Add new backlight quirk for GIGABYTE GB-BXBT-2807 (Jasper St Pierre) - Make assorted janitorial changes in several ACPI-related pieces of code (Hanjun Guo, Jason Yan, Punit Agrawal)" * tag 'acpi-5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (40 commits) ACPI: scan: Fix up _DEP-related terminology with supplier/consumer ACPI: scan: Drop INT3396 from acpi_ignore_dep_ids[] ACPI: video: Add DMI quirk for GIGABYTE GB-BXBT-2807 Revert "ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources walks" ACPI: scan: Add PNP0D80 to the _DEP exceptions list ACPI: scan: Call acpi_get_object_info() from acpi_add_single_object() ACPI: scan: Add acpi_info_matches_hids() helper ACPICA: Update version to 20201113 ACPICA: Interpreter: fix memory leak by using existing buffer ACPICA: Add function trace macros to improve debugging ACPICA: Also handle "orphan" _REG methods for GPIO OpRegions ACPICA: Remove extreaneous "the" in comments ACPICA: Add 5 new UUIDs to the known UUID table resource: provide meaningful MODULE_LICENSE() in test suite ASoC: Intel: catpt: Replace open coded variant of resource_intersection() ACPI: processor: Drop duplicate setting of shared_cpu_map ACPI: EC: Clean up status flags checks in advance_transaction() ACPI: EC: Untangle error handling in advance_transaction() ACPI: EC: Simplify error handling in advance_transaction() ACPI: EC: Rename acpi_ec_is_gpe_raised() ...
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c78
1 files changed, 55 insertions, 23 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 519963bcc047..a1b226eb2ce2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -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;