From 2649a0f29a39f455ff39eb2296269e20df3bba0d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Mar 2024 14:33:00 +0200 Subject: ACPI: scan: Use list_first_entry_or_null() in acpi_device_hid() To replace list_empty() + list_first_entry() pair to simplify code. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7c157bf92695..dc625653b198 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1298,10 +1298,10 @@ const char *acpi_device_hid(struct acpi_device *device) { struct acpi_hardware_id *hid; - if (list_empty(&device->pnp.ids)) + hid = list_first_entry_or_null(&device->pnp.ids, struct acpi_hardware_id, list); + if (!hid) return dummy_hid; - hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); return hid->id; } EXPORT_SYMBOL(acpi_device_hid); -- cgit v1.2.3 From e80d4122df9c707ebc9cfe20ab60be302fc9b833 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Mar 2024 14:33:01 +0200 Subject: ACPI: scan: Move misleading comment to acpi_dma_configure_id() The acpi_iommu_configure_id() implementation has a misleading comment since after it the flow does something different to what it states. Move the commit to the caller and with that unshadow the error code inside acpi_iommu_configure_id(). Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index dc625653b198..e64e1ec626b3 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1625,12 +1625,11 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in) if (!err && dev->bus) err = iommu_probe_device(dev); - /* Ignore all other errors apart from EPROBE_DEFER */ - if (err == -EPROBE_DEFER) { + if (err == -EPROBE_DEFER) return err; - } else if (err) { + if (err) { dev_dbg(dev, "Adding to IOMMU failed: %d\n", err); - return -ENODEV; + return err; } if (!acpi_iommu_fwspec_ops(dev)) return -ENODEV; @@ -1671,13 +1670,14 @@ int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr, acpi_arch_dma_setup(dev); + /* Ignore all other errors apart from EPROBE_DEFER */ ret = acpi_iommu_configure_id(dev, input_id); if (ret == -EPROBE_DEFER) return -EPROBE_DEFER; /* * Historically this routine doesn't fail driver probing due to errors - * in acpi_iommu_configure_id() + * in acpi_iommu_configure_id(). */ arch_setup_dma_ops(dev, 0, U64_MAX, attr == DEV_DMA_COHERENT); -- cgit v1.2.3 From 602401e32847f90c513df4a34bcac4dd6b02dd8d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Mar 2024 14:33:02 +0200 Subject: ACPI: scan: Use standard error checking pattern Check for an error and return it as it's the usual way to handle this. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e64e1ec626b3..b9a33364e553 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1581,12 +1581,13 @@ int acpi_iommu_fwspec_init(struct device *dev, u32 id, struct fwnode_handle *fwnode, const struct iommu_ops *ops) { - int ret = iommu_fwspec_init(dev, fwnode, ops); + int ret; - if (!ret) - ret = iommu_fwspec_add_ids(dev, &id, 1); + ret = iommu_fwspec_init(dev, fwnode, ops); + if (ret) + return ret; - return ret; + return iommu_fwspec_add_ids(dev, &id, 1); } static inline const struct iommu_ops *acpi_iommu_fwspec_ops(struct device *dev) -- cgit v1.2.3 From f5c519fc3628915c2eccd65f86d7ee2ce5cc8645 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 25 Mar 2024 14:33:03 +0200 Subject: ACPI: scan: Introduce typedef:s for struct acpi_hotplug_context members Follow the struct acpi_device_ops approach and introduce typedef:s for the members. It makes code less verbose and more particular on what parameters we take or types we use. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 48 +++++++++++++++++------------------------------- drivers/acpi/scan.c | 5 ++--- include/acpi/acpi_bus.h | 13 ++++++++----- 3 files changed, 27 insertions(+), 39 deletions(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index a7c00ef78086..34affbda295e 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -88,43 +88,29 @@ static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, enum dock_callback_type cb_type) { struct acpi_device *adev = dd->adev; + acpi_hp_fixup fixup = NULL; + acpi_hp_uevent uevent = NULL; + acpi_hp_notify notify = NULL; acpi_lock_hp_context(); - if (!adev->hp) - goto out; - - if (cb_type == DOCK_CALL_FIXUP) { - void (*fixup)(struct acpi_device *); - - fixup = adev->hp->fixup; - if (fixup) { - acpi_unlock_hp_context(); - fixup(adev); - return; - } - } else if (cb_type == DOCK_CALL_UEVENT) { - void (*uevent)(struct acpi_device *, u32); - - uevent = adev->hp->uevent; - if (uevent) { - acpi_unlock_hp_context(); - uevent(adev, event); - return; - } - } else { - int (*notify)(struct acpi_device *, u32); - - notify = adev->hp->notify; - if (notify) { - acpi_unlock_hp_context(); - notify(adev, event); - return; - } + if (adev->hp) { + if (cb_type == DOCK_CALL_FIXUP) + fixup = adev->hp->fixup; + else if (cb_type == DOCK_CALL_UEVENT) + uevent = adev->hp->uevent; + else + notify = adev->hp->notify; } - out: acpi_unlock_hp_context(); + + if (fixup) + fixup(adev); + else if (uevent) + uevent(adev, event); + else if (notify) + notify(adev, event); } static struct dock_station *find_dock_station(acpi_handle handle) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b9a33364e553..f06d92b1183f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -73,8 +73,7 @@ void acpi_unlock_hp_context(void) void acpi_initialize_hp_context(struct acpi_device *adev, struct acpi_hotplug_context *hp, - int (*notify)(struct acpi_device *, u32), - void (*uevent)(struct acpi_device *, u32)) + acpi_hp_notify notify, acpi_hp_uevent uevent) { acpi_lock_hp_context(); hp->notify = notify; @@ -428,7 +427,7 @@ void acpi_device_hotplug(struct acpi_device *adev, u32 src) } else if (adev->flags.hotplug_notify) { error = acpi_generic_hotplug_event(adev, src); } else { - int (*notify)(struct acpi_device *, u32); + acpi_hp_notify notify; acpi_lock_hp_context(); notify = adev->hp ? adev->hp->notify : NULL; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index a6ced88a08f3..6f8cc4cc61be 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -144,11 +144,15 @@ struct acpi_scan_handler { * -------------------- */ +typedef int (*acpi_hp_notify) (struct acpi_device *, u32); +typedef void (*acpi_hp_uevent) (struct acpi_device *, u32); +typedef void (*acpi_hp_fixup) (struct acpi_device *); + struct acpi_hotplug_context { struct acpi_device *self; - int (*notify)(struct acpi_device *, u32); - void (*uevent)(struct acpi_device *, u32); - void (*fixup)(struct acpi_device *); + acpi_hp_notify notify; + acpi_hp_uevent uevent; + acpi_hp_fixup fixup; }; /* @@ -583,8 +587,7 @@ static inline void acpi_set_hp_context(struct acpi_device *adev, void acpi_initialize_hp_context(struct acpi_device *adev, struct acpi_hotplug_context *hp, - int (*notify)(struct acpi_device *, u32), - void (*uevent)(struct acpi_device *, u32)); + acpi_hp_notify notify, acpi_hp_uevent uevent); /* acpi_device.dev.bus == &acpi_bus_type */ extern const struct bus_type acpi_bus_type; -- cgit v1.2.3 From d4aa921eb85a74bf0502eff64f0b9e06fe17081b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Apr 2024 18:02:20 +0200 Subject: ACPI: scan: Avoid enumerating devices with clearly invalid _STA values The return value of _STA with the "present" bit unset and the "enabled" bit set is clearly invalid as per the ACPI specification, Section 6.3.7 "_STA (Device Status)", so make the ACPI device enumeration code disregard devices with such _STA return values. Also, because this implies that status.enabled will only be set if status.present is set too, acpi_device_is_enabled() can be modified to simply return the value of the former. Link: https://uefi.org/specs/ACPI/6.5/06_Device_Configuration.html#sta-device-status Link: https://lore.kernel.org/linux-acpi/88179311a503493099028c12ca37d430@huawei.com/ Suggested-by: Salil Mehta Signed-off-by: Rafael J. Wysocki Reviewed-by: Jonathan Cameron Reviewed-by: Sudeep Holla --- drivers/acpi/bus.c | 11 +++++++++++ drivers/acpi/scan.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d9fa730416f1..18d50448ae1c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -112,6 +112,17 @@ int acpi_bus_get_status(struct acpi_device *device) if (ACPI_FAILURE(status)) return -ENODEV; + if (!device->status.present && device->status.enabled) { + pr_info(FW_BUG "Device [%s] status [%08x]: not present and enabled\n", + device->pnp.bus_id, (u32)sta); + device->status.enabled = 0; + /* + * The status is clearly invalid, so clear the functional bit as + * well to avoid attempting to use the device. + */ + device->status.functional = 0; + } + acpi_set_device_status(device, sta); if (device->status.functional && !device->status.present) { diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 68f101323f53..e41fb5716bc0 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1962,7 +1962,7 @@ bool acpi_device_is_present(const struct acpi_device *adev) bool acpi_device_is_enabled(const struct acpi_device *adev) { - return adev->status.present && adev->status.enabled; + return adev->status.enabled; } static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler, -- cgit v1.2.3