Page MenuHomeFreeBSD

D48735.id170347.diff
No OneTemporary

D48735.id170347.diff

diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -777,6 +777,7 @@
dev/acpica/acpi_video.c optional acpi_video acpi
dev/acpica/acpi_dock.c optional acpi_dock acpi
dev/acpica/acpi_spmc.c optional acpi
+dev/acpica/acpi_pmc_if.m optional acpi
dev/adlink/adlink.c optional adlink
dev/ae/if_ae.c optional ae pci
dev/age/if_age.c optional age pci
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -56,6 +56,8 @@
#include <sys/timetc.h>
#include <sys/uuid.h>
+#include "acpi_pmc_if.h"
+
#if defined(__i386__) || defined(__amd64__)
#include <machine/clock.h>
#include <machine/intr_machdep.h>
@@ -3436,11 +3438,12 @@
}
enum acpi_sleep_state {
- ACPI_SS_NONE = 0,
- ACPI_SS_GPE_SET = 1 << 0,
- ACPI_SS_DEV_SUSPEND = 1 << 1,
- ACPI_SS_SLP_PREP = 1 << 2,
- ACPI_SS_SLEPT = 1 << 3,
+ ACPI_SS_NONE = 0,
+ ACPI_SS_GPE_SET = 1 << 0,
+ ACPI_SS_DEV_SUSPEND = 1 << 1,
+ ACPI_SS_SPMC_SUSPEND = 1 << 2,
+ ACPI_SS_SLP_PREP = 1 << 3,
+ ACPI_SS_SLEPT = 1 << 4,
};
static void
@@ -3559,10 +3562,12 @@
static ACPI_STATUS
acpi_EnterSleepState(struct acpi_softc *sc, enum power_stype stype)
{
- register_t intr;
- ACPI_STATUS status;
- enum acpi_sleep_state slp_state;
- int acpi_sstate;
+ register_t intr;
+ ACPI_STATUS status;
+ enum acpi_sleep_state slp_state;
+ int acpi_sstate;
+ devclass_t spmc_dc;
+ device_t spmc = NULL;
ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, stype);
@@ -3638,6 +3643,16 @@
}
slp_state |= ACPI_SS_DEV_SUSPEND;
+ spmc_dc = devclass_find("acpi_spmc");
+ if (spmc_dc != NULL)
+ spmc = devclass_get_device(spmc_dc, 0);
+ if (spmc != NULL) {
+ if (ACPI_PMC_SUSPEND(spmc) != 0)
+ device_printf(sc->acpi_dev, "failed to run SPMC suspend\n");
+ else
+ slp_state |= ACPI_SS_SPMC_SUSPEND;
+ }
+
if (stype != POWER_STYPE_SUSPEND_TO_IDLE) {
status = AcpiEnterSleepStatePrep(acpi_sstate);
if (ACPI_FAILURE(status)) {
@@ -3684,6 +3699,12 @@
sc->acpi_stype = POWER_STYPE_AWAKE;
slp_state &= ~ACPI_SS_GPE_SET;
}
+ if ((slp_state & ACPI_SS_SPMC_SUSPEND) != 0) {
+ MPASS(spmc != NULL);
+ if (ACPI_PMC_RESUME(spmc) != 0)
+ device_printf(sc->acpi_dev, "failed to run SPMC resume\n");
+ slp_state &= ~ACPI_SS_SPMC_SUSPEND;
+ }
if ((slp_state & ACPI_SS_DEV_SUSPEND) != 0) {
DEVICE_RESUME(root_bus);
slp_state &= ~ACPI_SS_DEV_SUSPEND;
diff --git a/sys/dev/acpica/acpi_pmc_if.m b/sys/dev/acpica/acpi_pmc_if.m
new file mode 100644
--- /dev/null
+++ b/sys/dev/acpica/acpi_pmc_if.m
@@ -0,0 +1,44 @@
+#-
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2026 The FreeBSD Foundation
+#
+# This software was developed by Aymeric Wibo <obiwac@freebsd.org>
+# under sponsorship from the FreeBSD Foundation.
+#
+
+#include <sys/types.h>
+
+/**
+ * @defgroup ACPI_PMC acpi_pmc - KObj methods for all ACPI PMC (power
+ * management controller) drivers
+ * @brief Late suspend and early resume methods required for ACPI PMCs.
+ *
+ * PMCs such as the x86 SPMC (implemented by the acpi_spmc driver) often need
+ * to run late suspend after all other devices have already been suspended and
+ * early resume methods before all other devices have been resumed. This
+ * provides an interface to do that which will be called at those points in the
+ * acpi_EnterSleepState() function.
+ * @{
+ */
+INTERFACE acpi_pmc;
+
+CODE {
+ static int null_suspend(device_t dev)
+ {
+ return (0);
+ }
+
+ static int null_resume(device_t dev)
+ {
+ return (0);
+ }
+};
+
+METHOD int suspend {
+ device_t dev;
+} DEFAULT null_suspend;
+
+METHOD int resume {
+ device_t dev;
+} DEFAULT null_resume;
diff --git a/sys/dev/acpica/acpi_spmc.c b/sys/dev/acpica/acpi_spmc.c
--- a/sys/dev/acpica/acpi_spmc.c
+++ b/sys/dev/acpica/acpi_spmc.c
@@ -15,6 +15,8 @@
#include <sys/uuid.h>
#include <sys/kdb.h>
+#include "acpi_pmc_if.h"
+
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
@@ -605,6 +607,9 @@
DEVMETHOD(device_probe, acpi_spmc_probe),
DEVMETHOD(device_attach, acpi_spmc_attach),
DEVMETHOD(device_detach, acpi_spmc_detach),
+
+ DEVMETHOD(acpi_pmc_suspend, acpi_spmc_suspend),
+ DEVMETHOD(acpi_pmc_resume, acpi_spmc_resume),
DEVMETHOD_END
};

File Metadata

Mime Type
text/plain
Expires
Fri, Jun 12, 4:06 AM (5 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33899154
Default Alt Text
D48735.id170347.diff (4 KB)

Event Timeline