aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2024-02-26 17:46:41 +0100
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2024-02-27 17:54:59 +0100
commit4f4a335acfbb72bd11185c97394b3c0890e72453 (patch)
treef1abf577b8ea713fc392a476e6983315564e3044 /drivers/acpi
parent520c2286c222c0a6c9b366e9c2a6c42c3fc091ed (diff)
downloadlinux-4f4a335acfbb72bd11185c97394b3c0890e72453.tar.gz
ACPI: scan: Consolidate Device Check and Bus Check notification handling
There is no particular reason why device object subtree rescans in acpi_scan_device_check() and acpi_scan_device_check() should be carried out differently, so move the rescan code into a new function called acpi_scan_rescan_bus() and make both the functions above invoke it. While at it, in the Device Check case, start the device object subtree rescan mentioned above from the target device's parent, as per the specification. [1] Link: https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#device-object-notification-values # [1] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/scan.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b35722b650abce..3b722e4c0f0624 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -336,9 +336,25 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
return 0;
}
+static int acpi_scan_rescan_bus(struct acpi_device *adev)
+{
+ struct acpi_scan_handler *handler = adev->handler;
+ int ret;
+
+ if (handler && handler->hotplug.scan_dependent)
+ ret = handler->hotplug.scan_dependent(adev);
+ else
+ ret = acpi_bus_scan(adev->handle);
+
+ if (ret)
+ dev_info(&adev->dev, "Namespace scan failure\n");
+
+ return ret;
+}
+
static int acpi_scan_device_check(struct acpi_device *adev)
{
- int error;
+ struct acpi_device *parent;
acpi_scan_check_subtree(adev);
@@ -356,36 +372,26 @@ static int acpi_scan_device_check(struct acpi_device *adev)
dev_dbg(&adev->dev, "Already enumerated\n");
return 0;
}
- error = acpi_bus_scan(adev->handle);
- if (error)
- dev_warn(&adev->dev, "Namespace scan failure\n");
- return error;
+ parent = acpi_dev_parent(adev);
+ if (!parent)
+ parent = adev;
+
+ return acpi_scan_rescan_bus(parent);
}
-static int acpi_scan_bus_check(struct acpi_device *adev, void *not_used)
+static int acpi_scan_bus_check(struct acpi_device *adev)
{
- struct acpi_scan_handler *handler = adev->handler;
- int error;
-
acpi_scan_check_subtree(adev);
- if (handler && handler->hotplug.scan_dependent)
- return handler->hotplug.scan_dependent(adev);
-
- error = acpi_bus_scan(adev->handle);
- if (error) {
- dev_warn(&adev->dev, "Namespace scan failure\n");
- return error;
- }
- return acpi_dev_for_each_child(adev, acpi_scan_bus_check, NULL);
+ return acpi_scan_rescan_bus(adev);
}
static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type)
{
switch (type) {
case ACPI_NOTIFY_BUS_CHECK:
- return acpi_scan_bus_check(adev, NULL);
+ return acpi_scan_bus_check(adev);
case ACPI_NOTIFY_DEVICE_CHECK:
return acpi_scan_device_check(adev);
case ACPI_NOTIFY_EJECT_REQUEST: