git: 6bd543f7a82a - main - acpi_spmc(4): Check DSMs only on attach, do not return 0 on probe

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Wed, 13 May 2026 12:39:49 UTC
The branch main has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=6bd543f7a82a3cbb10db3a79590d5179be403660

commit 6bd543f7a82a3cbb10db3a79590d5179be403660
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2026-05-04 12:40:44 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2026-05-13 12:38:21 +0000

    acpi_spmc(4): Check DSMs only on attach, do not return 0 on probe
    
    Once we have recognized a device by PNP ID, declare support
    unconditionally on probe, and only check for DSMs in attach.
    
    We do this for these reasons:
    1. PNP0D80 is de-facto a device supposed to hold DSMs related to
       suspend-to-idle, so we assume it cannot be used for other purposes.
       And if that changes, we need another architecture anyway (e.g., have
       a new driver claiming those devices and behaving like a bus, to which
       this driver would be a sub-driver).
    2. If there are no DSMs that we support on such a device, then a new DSM
       was added that the driver does not know about and which "replaces"
       (in terms of functionality) the known ones, or the firmware is buggy.
       In both cases, failing the attach instead of the probe is reasonable,
       as that leads to printing some error which we (and probably users
       too) would like to know about.
    3. This is a step to enable multiple instances of this driver (just to
       be a good citizen, and also to be future proof against weird
       firmwares that would, e.g., implement the Microsoft DSM on another
       device than the Intel one).
    
    Reviewed by:    imp (older version), obiwac
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D56810
---
 sys/dev/acpica/acpi_spmc.c | 56 ++++++++++++++++++++++------------------------
 1 file changed, 27 insertions(+), 29 deletions(-)

diff --git a/sys/dev/acpica/acpi_spmc.c b/sys/dev/acpica/acpi_spmc.c
index 58197242ff92..939f254fbf7f 100644
--- a/sys/dev/acpica/acpi_spmc.c
+++ b/sys/dev/acpica/acpi_spmc.c
@@ -340,10 +340,7 @@ static void	acpi_spmc_resume(device_t dev, enum power_stype stype);
 static int
 acpi_spmc_probe(device_t dev)
 {
-	char			*name;
-	ACPI_HANDLE		 handle;
-	struct acpi_spmc_softc	*sc;
-	char			 buf[32];
+	char *name;
 
 	/* Check that this is an enabled device. */
 	if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("spmc"))
@@ -357,41 +354,42 @@ acpi_spmc_probe(device_t dev)
 		return (ENXIO);
 	}
 
-	handle = acpi_get_handle(dev);
-	/* ACPI_ID_PROBE() above cannot succeed without a handle. */
+	device_set_desc(dev, "System Power Management Controller");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+acpi_spmc_attach(device_t dev)
+{
+	struct acpi_spmc_softc *const sc = device_get_softc(dev);
+	const ACPI_HANDLE handle = acpi_get_handle(dev);
+	char buf[32];
+
+	/*
+	 * ACPI_ID_PROBE() in acpi_spmc_probe() cannot succeed without a handle.
+	 */
 	MPASS(handle != NULL);
 
-	sc = device_get_softc(dev);
 	sc->dev = dev;
+	sc->handle = handle;
 
-	/* Check which DSMs are supported. */
-	sc->dsms = 0;
+	for (int i = 0; i < nitems(dsms); ++i) {
+		KASSERT(dsms[i] != NULL, ("%s: Sparse dsms[]!", __func__));
+		KASSERT(dsms[i]->index == i,
+		    ("%s: Inconsistent indices for DSM %s", __func__,
+		    dsms[i]->name));
 
-	for (int i = 0; i < nitems(dsms); ++i)
 		acpi_spmc_check_dsm(sc, handle, dsms[i]);
+	}
 
-	if (sc->dsms == 0)
+	if (sc->dsms == 0) {
+		device_printf(dev, "No DSM supported!");
 		return (ENXIO);
+	}
 
 	print_bit_field(buf, sizeof(buf), sc->dsms, "DSM", pbf_dsm_name, NULL);
-	device_set_descf(dev, "System Power Management Controller (DSMs %s)",
-	    buf);
-
-	return (0);
-}
-
-static int
-acpi_spmc_attach(device_t dev)
-{
-	struct acpi_spmc_softc *sc = device_get_softc(dev);
-
-	sc->handle = acpi_get_handle(dev);
-	if (sc->handle == NULL)
-		return (ENXIO);
-
-	sc->constraints_populated = false;
-	sc->constraint_count = 0;
-	sc->constraints = NULL;
+	device_printf(dev, "DSMs supported: %s\n", buf);
 
 	/* Get device constraints. We can only call this once so do this now. */
 	acpi_spmc_get_constraints(dev);