git: 878856b7a109 - main - acpi: Remove support for /dev/apmctl and apmd(8) compatibility
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 30 Sep 2026 16:27:41 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=878856b7a1093d8b82903358f6104f6582910fdf
commit 878856b7a1093d8b82903358f6104f6582910fdf
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-09-30 16:22:00 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-09-30 16:22:00 +0000
acpi: Remove support for /dev/apmctl and apmd(8) compatibility
This simplifies the logic around ACKing suspend requests as there is
no longer the potential for multiple listeners, only devd and the
acknowledgement via acpiconf -k.
Reviewed by: imp
Differential Revision: https://reviews.freebsd.org/D59942
---
sys/dev/acpica/acpi.c | 58 ++++------------
sys/dev/acpica/acpivar.h | 20 ------
sys/x86/acpica/acpi_apm.c | 173 +---------------------------------------------
3 files changed, 14 insertions(+), 237 deletions(-)
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index e5f82b00135e..ed07ca62382c 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -3416,7 +3416,6 @@ int
acpi_ReqSleepState(struct acpi_softc *sc, enum power_stype stype)
{
#if defined(__amd64__) || defined(__i386__)
- struct apm_clone_data *clone;
ACPI_STATUS status;
if (stype < POWER_STYPE_AWAKE || stype >= POWER_STYPE_COUNT)
@@ -3448,15 +3447,6 @@ acpi_ReqSleepState(struct acpi_softc *sc, enum power_stype stype)
return (ACPI_SUCCESS(status) ? 0 : ENXIO);
}
- /* Record the pending state and notify all apm devices. */
- STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) {
- clone->notify_status = APM_EV_NONE;
- if ((clone->flags & ACPI_EVF_DEVD) == 0) {
- selwakeuppri(&clone->sel_read, PZERO);
- KNOTE_LOCKED(&clone->sel_read.si_note, 0);
- }
- }
-
/* If devd(8) is not running, immediately enter the sleep state. */
if (!devctl_process_running()) {
ACPI_UNLOCK(acpi);
@@ -3468,13 +3458,13 @@ acpi_ReqSleepState(struct acpi_softc *sc, enum power_stype stype)
* Set a timeout to fire if userland doesn't ack the suspend request
* in time. This way we still eventually go to sleep if we were
* overheating or running low on battery, even if userland is hung.
- * We cancel this timeout once all userland acks are in or the
- * suspend request is aborted.
+ * We cancel this timeout once userland acks or the suspend request
+ * is aborted.
*/
callout_reset(&sc->susp_force_to, 10 * hz, acpi_sleep_force, sc);
ACPI_UNLOCK(acpi);
- /* Now notify devd(8) also. */
+ /* Now notify devd(8). */
acpi_UserNotify("Suspend", ACPI_ROOT_OBJECT, stype);
return (0);
@@ -3489,16 +3479,13 @@ acpi_ReqSleepState(struct acpi_softc *sc, enum power_stype stype)
* Acknowledge (or reject) a pending sleep state. The caller has
* prepared for suspend and is now ready for it to proceed. If the
* error argument is non-zero, it indicates suspend should be cancelled
- * and gives an errno value describing why. Once all votes are in,
- * we suspend the system.
+ * and gives an errno value describing why.
*/
-int
-acpi_AckSleepState(struct apm_clone_data *clone, int error)
+static int
+acpi_AckSleepState(struct acpi_softc *sc, int error)
{
- struct acpi_softc *sc = clone->acpi_sc;
-
#if defined(__amd64__) || defined(__i386__)
- int ret, sleeping;
+ int ret;
/* If no pending sleep type, return an error. */
ACPI_LOCK(acpi);
@@ -3511,37 +3498,16 @@ acpi_AckSleepState(struct apm_clone_data *clone, int error)
if (error) {
sc->acpi_next_stype = POWER_STYPE_AWAKE;
callout_stop(&sc->susp_force_to);
- device_printf(sc->acpi_dev,
- "listener on %s cancelled the pending suspend\n",
- devtoname(clone->cdev));
+ device_printf(sc->acpi_dev, "pending suspend cancelled\n");
ACPI_UNLOCK(acpi);
return (0);
}
- /*
- * Mark this device as acking the suspend request. Then, walk through
- * all devices, seeing if they agree yet. We only count devices that
- * are writable since read-only devices couldn't ack the request.
- */
- sleeping = TRUE;
- clone->notify_status = APM_EV_ACKED;
- STAILQ_FOREACH(clone, &sc->apm_cdevs, entries) {
- if ((clone->flags & ACPI_EVF_WRITE) != 0 &&
- clone->notify_status != APM_EV_ACKED) {
- sleeping = FALSE;
- break;
- }
- }
-
- /* If all devices have voted "yes", we will suspend now. */
- if (sleeping)
- callout_stop(&sc->susp_force_to);
+ callout_stop(&sc->susp_force_to);
ACPI_UNLOCK(acpi);
ret = 0;
- if (sleeping) {
- if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_stype)))
- ret = ENODEV;
- }
+ if (ACPI_FAILURE(acpi_EnterSleepState(sc, sc->acpi_next_stype)))
+ ret = ENODEV;
return (ret);
#else
device_printf(sc->acpi_dev, "ACPI suspend not supported on this platform "
@@ -4604,7 +4570,7 @@ acpiioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *t
break;
case ACPIIO_ACKSLPSTATE:
error = *(int *)addr;
- error = acpi_AckSleepState(sc->acpi_clone, error);
+ error = acpi_AckSleepState(sc, error);
break;
case ACPIIO_SETSLPSTATE: /* DEPRECATED */
sstate = *(int *)addr;
diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h
index 550c6ceb9c97..2a2c4bcb0a7c 100644
--- a/sys/dev/acpica/acpivar.h
+++ b/sys/dev/acpica/acpivar.h
@@ -48,7 +48,6 @@
#include <machine/bus.h>
#include <machine/resource.h>
-struct apm_clone_data;
struct acpi_softc {
device_t acpi_dev;
struct cdev *acpi_dev_t;
@@ -80,8 +79,6 @@ struct acpi_softc {
vm_paddr_t acpi_wakephys;
enum power_stype acpi_next_stype; /* Next suspend sleep type. */
- struct apm_clone_data *acpi_clone; /* Pseudo-dev for devd(8). */
- STAILQ_HEAD(,apm_clone_data) apm_cdevs; /* All apm/apmctl/acpi cdevs. */
struct callout susp_force_to; /* Force suspend if no acks. */
/* System Resources */
@@ -113,22 +110,6 @@ struct intr_map_data_acpi {
#endif
-/* Track device (/dev/{apm,apmctl} and /dev/acpi) notification status. */
-struct apm_clone_data {
- STAILQ_ENTRY(apm_clone_data) entries;
- struct cdev *cdev;
- int flags;
-#define ACPI_EVF_NONE 0 /* /dev/apm semantics */
-#define ACPI_EVF_DEVD 1 /* /dev/acpi is handled via devd(8) */
-#define ACPI_EVF_WRITE 2 /* Device instance is opened writable. */
- int notify_status;
-#define APM_EV_NONE 0 /* Device not yet aware of pending sleep. */
-#define APM_EV_NOTIFIED 1 /* Device saw next sleep state. */
-#define APM_EV_ACKED 2 /* Device agreed sleep can occur. */
- struct acpi_softc *acpi_sc;
- struct selinfo sel_read;
-};
-
#define ACPI_PRW_MAX_POWERRES 8
struct acpi_prw_data {
@@ -398,7 +379,6 @@ ACPI_STATUS acpi_EvaluateOSC(ACPI_HANDLE handle, uint8_t *uuid,
ACPI_STATUS acpi_OverrideInterruptLevel(UINT32 InterruptNumber);
ACPI_STATUS acpi_SetIntrModel(int model);
int acpi_ReqSleepState(struct acpi_softc *sc, enum power_stype stype);
-int acpi_AckSleepState(struct apm_clone_data *clone, int error);
ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state);
int acpi_wake_set_enable(device_t dev, int enable);
int acpi_parse_prw(ACPI_HANDLE h, struct acpi_prw_data *prw);
diff --git a/sys/x86/acpica/acpi_apm.c b/sys/x86/acpica/acpi_apm.c
index e1addc46c38c..ad94bd1296d7 100644
--- a/sys/x86/acpica/acpi_apm.c
+++ b/sys/x86/acpica/acpi_apm.c
@@ -28,13 +28,10 @@
#include <sys/param.h>
#include <sys/bus.h>
-#include <sys/condvar.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
-#include <sys/poll.h>
-#include <sys/uio.h>
#include <contrib/dev/acpica/include/acpi.h>
@@ -53,28 +50,12 @@ static int apm_active;
static MALLOC_DEFINE(M_APMDEV, "apmdev", "APM device emulation");
-static d_open_t apmopen;
-static d_write_t apmwrite;
static d_ioctl_t apmioctl;
-static d_poll_t apmpoll;
-static d_kqfilter_t apmkqfilter;
-static void apmreadfiltdetach(struct knote *kn);
-static int apmreadfilt(struct knote *kn, long hint);
-static const struct filterops apm_readfiltops = {
- .f_isfd = 1,
- .f_detach = apmreadfiltdetach,
- .f_event = apmreadfilt,
- .f_copy = knote_triv_copy,
-};
static struct cdevsw apm_cdevsw = {
.d_version = D_VERSION,
- .d_open = apmopen,
- .d_write = apmwrite,
.d_ioctl = apmioctl,
- .d_poll = apmpoll,
.d_name = "apm",
- .d_kqfilter = apmkqfilter
};
static int
@@ -198,85 +179,15 @@ acpi_capm_get_pwstatus(apm_pwstatus_t app)
return (0);
}
-/* Create a struct for tracking per-device suspend notification. */
-static struct apm_clone_data *
-apm_create_clone(struct cdev *dev, struct acpi_softc *acpi_sc)
-{
- struct apm_clone_data *clone;
-
- clone = malloc(sizeof(*clone), M_APMDEV, M_WAITOK);
- clone->cdev = dev;
- clone->acpi_sc = acpi_sc;
- clone->notify_status = APM_EV_NONE;
- bzero(&clone->sel_read, sizeof(clone->sel_read));
- knlist_init_mtx(&clone->sel_read.si_note, &acpi_mutex);
-
- /*
- * The acpi device is always managed by devd(8) and is considered
- * writable (i.e., ack is required to allow suspend to proceed.)
- */
- if (strcmp("acpi", devtoname(dev)) == 0)
- clone->flags = ACPI_EVF_DEVD | ACPI_EVF_WRITE;
- else
- clone->flags = ACPI_EVF_NONE;
-
- ACPI_LOCK(acpi);
- STAILQ_INSERT_TAIL(&acpi_sc->apm_cdevs, clone, entries);
- ACPI_UNLOCK(acpi);
- return (clone);
-}
-
-static void
-apmdtor(void *data)
-{
- struct apm_clone_data *clone;
- struct acpi_softc *acpi_sc;
-
- clone = data;
- acpi_sc = clone->acpi_sc;
-
- /* We are about to lose a reference so check if suspend should occur */
- if (acpi_sc->acpi_next_stype != POWER_STYPE_AWAKE &&
- clone->notify_status != APM_EV_ACKED)
- acpi_AckSleepState(clone, 0);
-
- /* Remove this clone's data from the list and free it. */
- ACPI_LOCK(acpi);
- STAILQ_REMOVE(&acpi_sc->apm_cdevs, clone, apm_clone_data, entries);
- ACPI_UNLOCK(acpi);
- seldrain(&clone->sel_read);
- knlist_destroy(&clone->sel_read.si_note);
- free(clone, M_APMDEV);
-}
-
-static int
-apmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
-{
- struct acpi_softc *acpi_sc = dev->si_drv1;
- struct apm_clone_data *clone;
-
- clone = apm_create_clone(dev, acpi_sc);
- devfs_set_cdevpriv(clone, apmdtor);
-
- /* If the device is opened for write, record that. */
- if ((flag & FWRITE) != 0)
- clone->flags |= ACPI_EVF_WRITE;
-
- return (0);
-}
-
static int
apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
{
int error;
- struct apm_clone_data *clone;
struct acpi_softc *acpi_sc = dev->si_drv1;
struct apm_info info;
- struct apm_event_info *ev_info;
apm_info_old_t aiop;
error = 0;
- devfs_get_cdevpriv((void **)&clone);
switch (cmd) {
case APMIO_SUSPEND:
@@ -291,8 +202,7 @@ apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td
"power off via apm suspend not supported\n");
error = ENXIO;
}
- } else
- error = acpi_AckSleepState(clone, 0);
+ }
break;
case APMIO_STANDBY:
if ((flag & FWRITE) == 0)
@@ -306,26 +216,7 @@ apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td
"power off via apm standby not supported\n");
error = ENXIO;
}
- } else
- error = acpi_AckSleepState(clone, 0);
- break;
- case APMIO_NEXTEVENT:
- printf("apm nextevent start\n");
- ACPI_LOCK(acpi);
- if (acpi_sc->acpi_next_stype != POWER_STYPE_AWAKE &&
- clone->notify_status == APM_EV_NONE) {
- ev_info = (struct apm_event_info *)addr;
- /* XXX Check this. */
- if (acpi_sc->acpi_next_stype == POWER_STYPE_STANDBY)
- ev_info->type = PMEV_STANDBYREQ;
- else
- ev_info->type = PMEV_SUSPENDREQ;
- ev_info->index = 0;
- clone->notify_status = APM_EV_NOTIFIED;
- printf("apm event returning %d\n", ev_info->type);
- } else
- error = EAGAIN;
- ACPI_UNLOCK(acpi);
+ }
break;
case APMIO_GETINFO_OLD:
if (acpi_capm_get_info(&info))
@@ -376,71 +267,12 @@ apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td
return (error);
}
-static int
-apmwrite(struct cdev *dev, struct uio *uio, int ioflag)
-{
- return (uio->uio_resid);
-}
-
-static int
-apmpoll(struct cdev *dev, int events, struct thread *td)
-{
- struct apm_clone_data *clone;
- int revents;
-
- revents = 0;
- devfs_get_cdevpriv((void **)&clone);
- ACPI_LOCK(acpi);
- if (clone->acpi_sc->acpi_next_stype != POWER_STYPE_AWAKE)
- revents |= events & (POLLIN | POLLRDNORM);
- else
- selrecord(td, &clone->sel_read);
- ACPI_UNLOCK(acpi);
- return (revents);
-}
-
-static int
-apmkqfilter(struct cdev *dev, struct knote *kn)
-{
- struct apm_clone_data *clone;
-
- devfs_get_cdevpriv((void **)&clone);
- kn->kn_hook = clone;
- kn->kn_fop = &apm_readfiltops;
- knlist_add(&clone->sel_read.si_note, kn, 0);
- return (0);
-}
-
-static void
-apmreadfiltdetach(struct knote *kn)
-{
- struct apm_clone_data *clone;
-
- clone = kn->kn_hook;
- knlist_remove(&clone->sel_read.si_note, kn, 0);
-}
-
-static int
-apmreadfilt(struct knote *kn, long hint)
-{
- struct apm_clone_data *clone;
- int sleeping;
-
- clone = kn->kn_hook;
- sleeping = clone->acpi_sc->acpi_next_stype != POWER_STYPE_AWAKE;
- return (sleeping);
-}
-
void
acpi_apm_init(struct acpi_softc *sc)
{
struct make_dev_args args;
struct cdev *dev;
- /* Create a clone for /dev/acpi also. */
- STAILQ_INIT(&sc->apm_cdevs);
- sc->acpi_clone = apm_create_clone(sc->acpi_dev_t, sc);
-
make_dev_args_init(&args);
args.mda_devsw = &apm_cdevsw;
args.mda_uid = UID_ROOT;
@@ -448,6 +280,5 @@ acpi_apm_init(struct acpi_softc *sc)
args.mda_mode = 0664;
args.mda_si_drv1 = sc;
args.mda_flags = MAKEDEV_ETERNAL;
- make_dev_s(&args, &dev, "apmctl");
make_dev_s(&args, &dev, "apm");
}