diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-24 16:17:26 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-24 16:17:26 +0200 |
| commit | b62ed4c93ad71374b54d2c3a72cbc67b506f580c (patch) | |
| tree | 6ca6ab974bbce902fc9de300fea6aa056170850f /drivers/acpi/bus.c | |
| parent | 5895db67c12464003afd16c08049b73aa09e58ea (diff) | |
| parent | 221fc2f4d0eda59d02af2e751a9282fa013a8e97 (diff) | |
Merge v6.18.40linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/acpi/bus.c')
| -rw-r--r-- | drivers/acpi/bus.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index a984ccd4a2a0..222a6bc61644 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -622,6 +622,76 @@ void acpi_dev_remove_notify_handler(struct acpi_device *adev, } EXPORT_SYMBOL_GPL(acpi_dev_remove_notify_handler); +struct acpi_notify_handler_devres { + struct acpi_device *adev; + acpi_notify_handler handler; + u32 handler_type; +}; + +static void devm_acpi_notify_handler_release(struct device *dev, void *res) +{ + struct acpi_notify_handler_devres *dr = res; + + acpi_dev_remove_notify_handler(dr->adev, dr->handler_type, + dr->handler); +} + +/** + * devm_acpi_install_notify_handler - Install an ACPI notify handler for a + * managed device + * @dev: Device to install a notify handler for + * @handler_type: Type of the notify handler + * @handler: Handler function to install + * @context: Data passed back to the handler function + * + * This function performs the same function as acpi_dev_install_notify_handler() + * called for the ACPI companion of @dev with the same @handler_type, @handler, + * and @context arguments, but the ACPI notify handler installed by it will be + * automatically removed on driver detach. + * + * Callers should ensure that all resources used by @handler have been allocated + * prior to invoking this function, in which case those resources should be + * devres-managed so that they won't be released before the notify handler + * removal. Otherwise, special synchronization between @handler and the + * management of those resources is required. + * + * When the request fails, an error message is printed. Don't add extra error + * messages at the call sites. + * + * Return: 0 on success or a negative error number. + */ +int devm_acpi_install_notify_handler(struct device *dev, u32 handler_type, + acpi_notify_handler handler, void *context) +{ + struct acpi_notify_handler_devres *dr; + struct acpi_device *adev; + int ret; + + adev = ACPI_COMPANION(dev); + if (!adev && dev->bus == &acpi_bus_type) + adev = to_acpi_device(dev); + if (!adev) + return dev_err_probe(dev, -ENODEV, "No ACPI companion in %s()\n", __func__); + + dr = devres_alloc(devm_acpi_notify_handler_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + ret = acpi_dev_install_notify_handler(adev, handler_type, handler, context); + if (ret) { + devres_free(dr); + return dev_err_probe(dev, ret, "Failed to install an ACPI notify handler\n"); + } + + dr->adev = adev; + dr->handler = handler; + dr->handler_type = handler_type; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_acpi_install_notify_handler); + /* Handle events targeting \_SB device (at present only graceful shutdown) */ #define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81 |
