git: 5bd84c4f0d01 - main - acpi: Add a function to deregister all ioctl commands using the same function

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 15 Jan 2026 18:24:26 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=5bd84c4f0d016a2ca87ee115370ec1e7802e6d8a

commit 5bd84c4f0d016a2ca87ee115370ec1e7802e6d8a
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-01-15 18:24:08 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-01-15 18:24:08 +0000

    acpi: Add a function to deregister all ioctl commands using the same function
    
    This simplifies detach/cleanup for drivers that add multiple ACPI ioctls.
    
    Reviewed by:    imp
    Sponsored by:   Netflix
    Differential Revision:  https://reviews.freebsd.org/D54420
---
 sys/dev/acpica/acpi.c         | 15 +++++++++++++++
 sys/dev/acpica/acpi_battery.c |  8 +-------
 sys/dev/acpica/acpiio.h       |  1 +
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 9657938371f0..518cbce19e33 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -4334,6 +4334,21 @@ acpi_deregister_ioctl(u_long cmd, acpi_ioctl_fn fn)
     ACPI_UNLOCK(acpi);
 }
 
+void
+acpi_deregister_ioctls(acpi_ioctl_fn fn)
+{
+	struct acpi_ioctl_hook *hp, *thp;
+
+	ACPI_LOCK(acpi);
+	TAILQ_FOREACH_SAFE(hp, &acpi_ioctl_hooks, link, thp) {
+		if (hp->fn == fn) {
+			TAILQ_REMOVE(&acpi_ioctl_hooks, hp, link);
+			free(hp, M_ACPIDEV);
+		}
+	}
+	ACPI_UNLOCK(acpi);
+}
+
 static int
 acpiopen(struct cdev *dev, int flag, int fmt, struct thread *td)
 {
diff --git a/sys/dev/acpica/acpi_battery.c b/sys/dev/acpica/acpi_battery.c
index cfd8261d5eab..f1eebda705c1 100644
--- a/sys/dev/acpica/acpi_battery.c
+++ b/sys/dev/acpica/acpi_battery.c
@@ -531,13 +531,7 @@ acpi_battery_init(void)
 
 out:
     if (error) {
-	acpi_deregister_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl);
-	acpi_deregister_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl);
-	acpi_deregister_ioctl(ACPIIO_BATT_GET_BATTINFO_V1, acpi_battery_ioctl);
-	acpi_deregister_ioctl(ACPIIO_BATT_GET_BIF, acpi_battery_ioctl);
-	acpi_deregister_ioctl(ACPIIO_BATT_GET_BIX, acpi_battery_ioctl);
-	acpi_deregister_ioctl(ACPIIO_BATT_GET_BST, acpi_battery_ioctl);
-	acpi_deregister_ioctl(ACPIIO_BATT_GET_BST_V1, acpi_battery_ioctl);
+	acpi_deregister_ioctls(acpi_battery_ioctl);
     }
     return (error);
 }
diff --git a/sys/dev/acpica/acpiio.h b/sys/dev/acpica/acpiio.h
index 63779d309951..4df049ed196a 100644
--- a/sys/dev/acpica/acpiio.h
+++ b/sys/dev/acpica/acpiio.h
@@ -205,6 +205,7 @@ union acpi_battery_ioctl_arg {
 typedef int	(*acpi_ioctl_fn)(u_long cmd, caddr_t addr, void *arg);
 extern int	acpi_register_ioctl(u_long cmd, acpi_ioctl_fn fn, void *arg);
 extern void	acpi_deregister_ioctl(u_long cmd, acpi_ioctl_fn fn);
+extern void	acpi_deregister_ioctls(acpi_ioctl_fn fn);
 #endif
 
 #endif /* !_ACPIIO_H_ */