git: ba1904937d9a - main - acpica: Extract _OSC parsing to a common file

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Thu, 12 Dec 2024 18:19:01 UTC
The branch main has been updated by andrew:

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

commit ba1904937d9ae0539e39001467a1519b17177118
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-12-12 16:29:45 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-12-12 18:00:22 +0000

    acpica: Extract _OSC parsing to a common file
    
    This will be used by pci_host_generic_acpi.c so needs to be in a
    common location.
    
    Reviewed by:    imp, jhb
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D48044
---
 sys/dev/acpica/acpi_pcib.c      | 59 ++++++++++++++++++++++++++++++++++++++++
 sys/dev/acpica/acpi_pcib_acpi.c | 60 ++---------------------------------------
 sys/dev/acpica/acpi_pcibvar.h   |  1 +
 3 files changed, 62 insertions(+), 58 deletions(-)

diff --git a/sys/dev/acpica/acpi_pcib.c b/sys/dev/acpica/acpi_pcib.c
index b16457ec853d..dfb4f143d5c4 100644
--- a/sys/dev/acpica/acpi_pcib.c
+++ b/sys/dev/acpica/acpi_pcib.c
@@ -38,6 +38,7 @@
 #include <dev/acpica/acpivar.h>
 #include <dev/acpica/acpi_pcibvar.h>
 
+#include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 #include "pcib_if.h"
 
@@ -277,3 +278,61 @@ acpi_pcib_get_cpus(device_t pcib, device_t dev, enum cpu_sets op,
 
 	return (bus_get_cpus(pcib, op, setsize, cpuset));
 }
+
+int
+acpi_pcib_osc(device_t pcib, uint32_t *ap_osc_ctl, uint32_t osc_ctl)
+{
+	ACPI_STATUS status;
+	ACPI_HANDLE handle;
+	uint32_t cap_set[3];
+
+	static uint8_t pci_host_bridge_uuid[ACPI_UUID_LENGTH] = {
+		0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40,
+		0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66
+	};
+
+	/*
+	 * Don't invoke _OSC if a control is already granted.
+	 * However, always invoke _OSC during attach when 0 is passed.
+	 */
+	if (osc_ctl != 0 && (*ap_osc_ctl & osc_ctl) == osc_ctl)
+		return (0);
+
+	/* Support Field: Extended PCI Config Space, PCI Segment Groups, MSI */
+	cap_set[PCI_OSC_SUPPORT] = PCIM_OSC_SUPPORT_EXT_PCI_CONF |
+	    PCIM_OSC_SUPPORT_SEG_GROUP | PCIM_OSC_SUPPORT_MSI;
+	/* Active State Power Management, Clock Power Management Capability */
+	if (pci_enable_aspm)
+		cap_set[PCI_OSC_SUPPORT] |= PCIM_OSC_SUPPORT_ASPM |
+		    PCIM_OSC_SUPPORT_CPMC;
+
+	/* Control Field */
+	cap_set[PCI_OSC_CTL] = *ap_osc_ctl | osc_ctl;
+
+	handle = acpi_get_handle(pcib);
+	status = acpi_EvaluateOSC(handle, pci_host_bridge_uuid, 1,
+	    nitems(cap_set), cap_set, cap_set, false);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_NOT_FOUND) {
+			*ap_osc_ctl |= osc_ctl;
+			return (0);
+		}
+		device_printf(pcib, "_OSC failed: %s\n",
+		    AcpiFormatException(status));
+		return (EIO);
+	}
+
+	/*
+	 * _OSC may return an error in the status word, but will
+	 * update the control mask always.  _OSC should not revoke
+	 * previously-granted controls.
+	 */
+	if ((cap_set[PCI_OSC_CTL] & *ap_osc_ctl) != *ap_osc_ctl)
+		device_printf(pcib, "_OSC revoked %#x\n",
+		    (cap_set[PCI_OSC_CTL] & *ap_osc_ctl) ^ *ap_osc_ctl);
+	*ap_osc_ctl = cap_set[PCI_OSC_CTL];
+	if ((*ap_osc_ctl & osc_ctl) != osc_ctl)
+		return (EIO);
+
+	return (0);
+}
diff --git a/sys/dev/acpica/acpi_pcib_acpi.c b/sys/dev/acpica/acpi_pcib_acpi.c
index bd005aed8fdc..e4cff4639a93 100644
--- a/sys/dev/acpica/acpi_pcib_acpi.c
+++ b/sys/dev/acpica/acpi_pcib_acpi.c
@@ -286,62 +286,6 @@ get_decoded_bus_range(struct acpi_hpcib_softc *sc, rman_res_t *startp,
 	return (true);
 }
 
-static int
-acpi_pcib_osc(struct acpi_hpcib_softc *sc, uint32_t osc_ctl)
-{
-	ACPI_STATUS status;
-	uint32_t cap_set[3];
-
-	static uint8_t pci_host_bridge_uuid[ACPI_UUID_LENGTH] = {
-		0x5b, 0x4d, 0xdb, 0x33, 0xf7, 0x1f, 0x1c, 0x40,
-		0x96, 0x57, 0x74, 0x41, 0xc0, 0x3d, 0xd7, 0x66
-	};
-
-	/*
-	 * Don't invoke _OSC if a control is already granted.
-	 * However, always invoke _OSC during attach when 0 is passed.
-	 */
-	if (osc_ctl != 0 && (sc->ap_osc_ctl & osc_ctl) == osc_ctl)
-		return (0);
-
-	/* Support Field: Extended PCI Config Space, PCI Segment Groups, MSI */
-	cap_set[PCI_OSC_SUPPORT] = PCIM_OSC_SUPPORT_EXT_PCI_CONF |
-	    PCIM_OSC_SUPPORT_SEG_GROUP | PCIM_OSC_SUPPORT_MSI;
-	/* Active State Power Management, Clock Power Management Capability */
-	if (pci_enable_aspm)
-		cap_set[PCI_OSC_SUPPORT] |= PCIM_OSC_SUPPORT_ASPM |
-		    PCIM_OSC_SUPPORT_CPMC;
-
-	/* Control Field */
-	cap_set[PCI_OSC_CTL] = sc->ap_osc_ctl | osc_ctl;
-
-	status = acpi_EvaluateOSC(sc->ap_handle, pci_host_bridge_uuid, 1,
-	    nitems(cap_set), cap_set, cap_set, false);
-	if (ACPI_FAILURE(status)) {
-		if (status == AE_NOT_FOUND) {
-			sc->ap_osc_ctl |= osc_ctl;
-			return (0);
-		}
-		device_printf(sc->ap_dev, "_OSC failed: %s\n",
-		    AcpiFormatException(status));
-		return (EIO);
-	}
-
-	/*
-	 * _OSC may return an error in the status word, but will
-	 * update the control mask always.  _OSC should not revoke
-	 * previously-granted controls.
-	 */
-	if ((cap_set[PCI_OSC_CTL] & sc->ap_osc_ctl) != sc->ap_osc_ctl)
-		device_printf(sc->ap_dev, "_OSC revoked %#x\n",
-		    (cap_set[PCI_OSC_CTL] & sc->ap_osc_ctl) ^ sc->ap_osc_ctl);
-	sc->ap_osc_ctl = cap_set[PCI_OSC_CTL];
-	if ((sc->ap_osc_ctl & osc_ctl) != osc_ctl)
-		return (EIO);
-
-	return (0);
-}
-
 static int
 acpi_pcib_acpi_attach(device_t dev)
 {
@@ -367,7 +311,7 @@ acpi_pcib_acpi_attach(device_t dev)
     if (!acpi_DeviceIsPresent(dev))
 	return (ENXIO);
 
-    acpi_pcib_osc(sc, 0);
+    acpi_pcib_osc(dev, &sc->ap_osc_ctl, 0);
 
     /*
      * Get our segment number by evaluating _SEG.
@@ -759,7 +703,7 @@ acpi_pcib_request_feature(device_t pcib, device_t dev, enum pci_feature feature)
 		return (EINVAL);
 	}
 
-	return (acpi_pcib_osc(sc, osc_ctl));
+	return (acpi_pcib_osc(dev, &sc->ap_osc_ctl, osc_ctl));
 }
 
 static bus_dma_tag_t
diff --git a/sys/dev/acpica/acpi_pcibvar.h b/sys/dev/acpica/acpi_pcibvar.h
index 2b75c276f9d1..c763eeea1941 100644
--- a/sys/dev/acpica/acpi_pcibvar.h
+++ b/sys/dev/acpica/acpi_pcibvar.h
@@ -40,6 +40,7 @@ int	acpi_pcib_route_interrupt(device_t pcib, device_t dev, int pin,
     ACPI_BUFFER *prtbuf);
 int	acpi_pcib_power_for_sleep(device_t pcib, device_t dev,
     int *pstate);
+int	acpi_pcib_osc(device_t pcib, uint32_t *ap_osc_ctl, uint32_t osc_ctl);
 
 #endif /* _KERNEL */