summaryrefslogtreecommitdiff
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-04-26 15:03:23 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-04-26 15:03:23 -0700
commitd8f9176b4ece17e831306072678cd9ae49688cf5 (patch)
treeb91e5f4e8036bba02622c3ecffa62c684d929556 /drivers/acpi/scan.c
parent47080f2286110c371b9cf75ac7b34a6f2f1cf4ba (diff)
parentb6237f61fc9ca79b8771a4fa412d2c630c9f8d2b (diff)
downloadlinux-d8f9176b4ece17e831306072678cd9ae49688cf5.tar.gz
linux-d8f9176b4ece17e831306072678cd9ae49688cf5.tar.bz2
linux-d8f9176b4ece17e831306072678cd9ae49688cf5.zip
Merge tag 'acpi-5.13-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 the most recent upstream revision including (but not limited to) new material introduced in the 6.4 version of the spec, update message printing in the ACPI-related code, address a few issues and clean up code in a number of places. Specifics: - Update ACPICA code in the kernel to upstream revision 20210331 including the following changes: * Add parsing for IVRS IVHD 40h and device entry F0h (Alexander Monakov). * Add new CEDT table for CXL 2.0 and iASL support for it (Ben Widawsky, Bob Moore). * NFIT: add Location Cookie field (Bob Moore). * HMAT: add new fields/flags (Bob Moore). * Add new flags in SRAT (Bob Moore). * PMTT: add new fields/structures (Bob Moore). * Add CSI2Bus resource template (Bob Moore). * iASL: Decode subtable type field for VIOT (Bob Moore). * Fix various typos and spelling mistakes (Colin Ian King). * Add new predefined objects _BPC, _BPS, and _BPT (Erik Kaneda). * Add USB4 capabilities UUID (Erik Kaneda). * Add CXL ACPI device ID and _CBR object (Erik Kaneda). * MADT: add Multiprocessor Wakeup Structure (Erik Kaneda). * PCCT: add support for subtable type 5 (Erik Kaneda). * PPTT: add new version of subtable type 1 (Erik Kaneda). * Add SDEV secure access components (Erik Kaneda). * Add support for PHAT table (Erik Kaneda). * iASL: Add definitions for the VIOT table (Jean-Philippe Brucker). * acpisrc: Add missing conversion for VIOT support (Jean-Philippe Brucker). * IORT: Updates for revision E.b (Shameer Kolothum). - Rearrange message printing in ACPI-related code to avoid using the ACPICA's internal message printing macros outside ACPICA and do some related code cleanups (Rafael Wysocki). - Modify the device enumeration code to turn off all of the unused ACPI power resources at the end (Rafael Wysocki). - Change the ACPI power resources handling code to turn off unused ACPI power resources without checking their status which should not be necessary by the spec (Rafael Wysocki). - Add empty stubs for CPPC-related functions to be used when CONFIG_ACPI_CPPC_LIB is not set (Rafael Wysocki). - Simplify device enumeration code (Rafael Wysocki). - Change device enumeration code to use match_string() for string matching (Andy Shevchenko). - Modify irqresource_disabled() to retain the resouce flags that have been set already (Angela Czubak). - Add native backlight whitelist entry for GA401/GA502/GA503 (Luke Jones). - Modify the ACPI backlight driver to let the native backlight handling take over on hardware-reduced systems (Hans de Goede). - Introduce acpi_dev_get() and switch over the ACPI core code to using it (Andy Shevchenko). - Use kobj_attribute as callback argument instead of a local struct type in the CPPC linrary code (Nathan Chancellor). - Drop unneeded initializatio of a static variable from the ACPI processor driver (Tian Tao). - Drop unnecessary local variable assignment from the ACPI APEI code (Colin Ian King). - Document for_each_acpi_dev_match() macro (Andy Shevchenko). - Address assorted coding style issues in multiple places (Xiaofei Tan). - Capitalize TLAs in a few comments (Andy Shevchenko). - Correct assorted typos in comments (Tom Saeger)" * tag 'acpi-5.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (68 commits) ACPI: video: use native backlight for GA401/GA502/GA503 ACPI: APEI: remove redundant assignment to variable rc ACPI: utils: Capitalize abbreviations in the comments ACPI: utils: Document for_each_acpi_dev_match() macro ACPI: bus: Introduce acpi_dev_get() and reuse it in ACPI code ACPI: scan: Utilize match_string() API resource: Prevent irqresource_disabled() from erasing flags ACPI: CPPC: Replace cppc_attr with kobj_attribute ACPI: scan: Call acpi_get_object_info() from acpi_set_pnp_ids() ACPI: scan: Drop sta argument from acpi_init_device_object() ACPI: scan: Drop sta argument from acpi_add_single_object() ACPI: scan: Rearrange checks in acpi_bus_check_add() ACPI: scan: Fold acpi_bus_type_and_status() into its caller ACPI: video: Check LCD flag on ACPI-reduced-hardware devices ACPI: utils: Add acpi_reduced_hardware() helper ACPI: dock: fix some coding style issues ACPI: sysfs: fix some coding style issues ACPI: PM: add a missed blank line after declarations ACPI: custom_method: fix a coding style issue ACPI: CPPC: fix some coding style issues ...
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c178
1 files changed, 73 insertions, 105 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 6efe7edd7b1e..bc973fbd70b2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -530,7 +530,7 @@ static void acpi_device_del_work_fn(struct work_struct *work_not_used)
* used by the device.
*/
acpi_power_transition(adev, ACPI_STATE_D3_COLD);
- put_device(&adev->dev);
+ acpi_dev_put(adev);
}
}
@@ -560,7 +560,7 @@ static void acpi_scan_drop_device(acpi_handle handle, void *context)
* prevents attempts to register device objects identical to those being
* deleted from happening concurrently (such attempts result from
* hotplug events handled via the ACPI hotplug workqueue). It also will
- * run after all of the work items submitted previosuly, which helps
+ * run after all of the work items submitted previously, which helps
* those work items to ensure that they are not accessing stale device
* objects.
*/
@@ -604,8 +604,7 @@ EXPORT_SYMBOL(acpi_bus_get_device);
static void get_acpi_device(void *dev)
{
- if (dev)
- get_device(&((struct acpi_device *)dev)->dev);
+ acpi_dev_get(dev);
}
struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle)
@@ -615,7 +614,7 @@ struct acpi_device *acpi_bus_get_acpi_device(acpi_handle handle)
void acpi_bus_put_acpi_device(struct acpi_device *adev)
{
- put_device(&adev->dev);
+ acpi_dev_put(adev);
}
static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
@@ -757,27 +756,25 @@ 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;
+ int i, index;
if (!(info->valid & ACPI_VALID_HID))
return false;
+ index = match_string(ids, -1, info->hardware_id.string);
+ if (index >= 0)
+ return true;
+
if (info->valid & ACPI_VALID_CID)
cid_list = &info->compatible_id_list;
- for (i = 0; ids[i]; i++) {
- int j;
+ if (!cid_list)
+ return false;
- if (!strcmp(info->hardware_id.string, ids[i]))
+ for (i = 0; i < cid_list->count; i++) {
+ index = match_string(ids, -1, cid_list->ids[i].string);
+ if (index >= 0)
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;
@@ -1307,8 +1304,9 @@ 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, struct acpi_device_info *info)
+ int device_type)
{
+ struct acpi_device_info *info = NULL;
struct acpi_pnp_device_id_list *cid_list;
int i;
@@ -1319,6 +1317,7 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
break;
}
+ acpi_get_object_info(handle, &info);
if (!info) {
pr_err(PREFIX "%s: Error reading device info\n",
__func__);
@@ -1344,6 +1343,8 @@ 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.
@@ -1649,17 +1650,16 @@ 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,
- struct acpi_device_info *info)
+ int type)
{
INIT_LIST_HEAD(&device->pnp.ids);
device->device_type = type;
device->handle = handle;
device->parent = acpi_bus_get_parent(handle);
fwnode_init(&device->fwnode, &acpi_device_fwnode_ops);
- acpi_set_device_status(device, sta);
+ acpi_set_device_status(device, ACPI_STA_DEFAULT);
acpi_device_get_busid(device);
- acpi_set_pnp_ids(handle, &device->pnp, type, info);
+ acpi_set_pnp_ids(handle, &device->pnp, type);
acpi_init_properties(device);
acpi_bus_get_flags(device);
device->flags.match_driver = false;
@@ -1680,33 +1680,30 @@ void acpi_device_add_finalize(struct acpi_device *device)
kobject_uevent(&device->dev.kobj, KOBJ_ADD);
}
+static void acpi_scan_init_status(struct acpi_device *adev)
+{
+ if (acpi_bus_get_status(adev))
+ acpi_set_device_status(adev, 0);
+}
+
static int acpi_add_single_object(struct acpi_device **child,
- acpi_handle handle, int type,
- unsigned long long sta)
+ acpi_handle handle, int type)
{
- struct acpi_device_info *info = NULL;
struct acpi_device *device;
int result;
- 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) {
- kfree(info);
+ if (!device)
return -ENOMEM;
- }
- acpi_init_device_object(device, handle, type, sta, info);
- kfree(info);
+ acpi_init_device_object(device, handle, type);
/*
- * 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.
- * Note this must be done before the get power-/wakeup_dev-flags calls.
+ * Getting the status is delayed till here so that we can call
+ * acpi_bus_get_status() and use its quirk handling. Note that
+ * this must be done before the get power-/wakeup_dev-flags calls.
*/
- if (type == ACPI_BUS_TYPE_DEVICE)
- if (acpi_bus_get_status(device) < 0)
- acpi_set_device_status(device, 0);
+ if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR)
+ acpi_scan_init_status(device);
acpi_bus_get_power_flags(device);
acpi_bus_get_wakeup_device_flags(device);
@@ -1763,50 +1760,6 @@ static bool acpi_device_should_be_hidden(acpi_handle handle)
return true;
}
-static int acpi_bus_type_and_status(acpi_handle handle, int *type,
- unsigned long long *sta)
-{
- acpi_status status;
- acpi_object_type acpi_type;
-
- status = acpi_get_type(handle, &acpi_type);
- if (ACPI_FAILURE(status))
- return -ENODEV;
-
- switch (acpi_type) {
- case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */
- case ACPI_TYPE_DEVICE:
- if (acpi_device_should_be_hidden(handle))
- return -ENODEV;
-
- *type = ACPI_BUS_TYPE_DEVICE;
- /*
- * acpi_add_single_object updates this once we've an acpi_device
- * so that acpi_bus_get_status' quirk handling can be used.
- */
- *sta = ACPI_STA_DEFAULT;
- break;
- case ACPI_TYPE_PROCESSOR:
- *type = ACPI_BUS_TYPE_PROCESSOR;
- status = acpi_bus_get_status_handle(handle, sta);
- if (ACPI_FAILURE(status))
- return -ENODEV;
- break;
- case ACPI_TYPE_THERMAL:
- *type = ACPI_BUS_TYPE_THERMAL;
- *sta = ACPI_STA_DEFAULT;
- break;
- case ACPI_TYPE_POWER:
- *type = ACPI_BUS_TYPE_POWER;
- *sta = ACPI_STA_DEFAULT;
- break;
- default:
- return -ENODEV;
- }
-
- return 0;
-}
-
bool acpi_device_is_present(const struct acpi_device *adev)
{
return adev->status.present || adev->status.functional;
@@ -1875,7 +1828,7 @@ static void acpi_scan_init_hotplug(struct acpi_device *adev)
}
}
-static u32 acpi_scan_check_dep(acpi_handle handle)
+static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
{
struct acpi_handle_list dep_devices;
acpi_status status;
@@ -1888,7 +1841,8 @@ static u32 acpi_scan_check_dep(acpi_handle handle)
* 2. ACPI nodes describing USB ports.
* Still, checking for _HID catches more then just these cases ...
*/
- if (!acpi_has_method(handle, "_DEP") || !acpi_has_method(handle, "_HID"))
+ if (!check_dep || !acpi_has_method(handle, "_DEP") ||
+ !acpi_has_method(handle, "_HID"))
return 0;
status = acpi_evaluate_reference(handle, "_DEP", NULL, &dep_devices);
@@ -1953,33 +1907,48 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
struct acpi_device **adev_p)
{
struct acpi_device *device = NULL;
- unsigned long long sta;
+ acpi_object_type acpi_type;
int type;
- int result;
acpi_bus_get_device(handle, &device);
if (device)
goto out;
- result = acpi_bus_type_and_status(handle, &type, &sta);
- if (result)
+ if (ACPI_FAILURE(acpi_get_type(handle, &acpi_type)))
return AE_OK;
- if (type == ACPI_BUS_TYPE_POWER) {
- acpi_add_power_resource(handle);
- return AE_OK;
- }
+ switch (acpi_type) {
+ case ACPI_TYPE_DEVICE:
+ if (acpi_device_should_be_hidden(handle))
+ return AE_OK;
- if (type == ACPI_BUS_TYPE_DEVICE && check_dep) {
- u32 count = acpi_scan_check_dep(handle);
- /* Bail out if the number of recorded dependencies is not 0. */
- if (count > 0) {
+ /* Bail out if there are dependencies. */
+ if (acpi_scan_check_dep(handle, check_dep) > 0) {
acpi_bus_scan_second_pass = true;
return AE_CTRL_DEPTH;
}
+
+ fallthrough;
+ case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */
+ type = ACPI_BUS_TYPE_DEVICE;
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+ type = ACPI_BUS_TYPE_PROCESSOR;
+ break;
+
+ case ACPI_TYPE_THERMAL:
+ type = ACPI_BUS_TYPE_THERMAL;
+ break;
+
+ case ACPI_TYPE_POWER:
+ acpi_add_power_resource(handle);
+ fallthrough;
+ default:
+ return AE_OK;
}
- acpi_add_single_object(&device, handle, type, sta);
+ acpi_add_single_object(&device, handle, type);
if (!device)
return AE_CTRL_DEPTH;
@@ -2253,8 +2222,7 @@ int acpi_bus_register_early_device(int type)
struct acpi_device *device = NULL;
int result;
- result = acpi_add_single_object(&device, NULL,
- type, ACPI_STA_DEFAULT);
+ result = acpi_add_single_object(&device, NULL, type);
if (result)
return result;
@@ -2274,8 +2242,7 @@ static int acpi_bus_scan_fixed(void)
struct acpi_device *device = NULL;
result = acpi_add_single_object(&device, NULL,
- ACPI_BUS_TYPE_POWER_BUTTON,
- ACPI_STA_DEFAULT);
+ ACPI_BUS_TYPE_POWER_BUTTON);
if (result)
return result;
@@ -2291,8 +2258,7 @@ static int acpi_bus_scan_fixed(void)
struct acpi_device *device = NULL;
result = acpi_add_single_object(&device, NULL,
- ACPI_BUS_TYPE_SLEEP_BUTTON,
- ACPI_STA_DEFAULT);
+ ACPI_BUS_TYPE_SLEEP_BUTTON);
if (result)
return result;
@@ -2388,11 +2354,13 @@ int __init acpi_scan_init(void)
acpi_detach_data(acpi_root->handle,
acpi_scan_drop_device);
acpi_device_del(acpi_root);
- put_device(&acpi_root->dev);
+ acpi_bus_put_acpi_device(acpi_root);
goto out;
}
}
+ acpi_turn_off_unused_power_resources();
+
acpi_scan_initialized = true;
out: