Index | Thread | Search

From:
James Hastings <moosetek4@gmail.com>
Subject:
amdgpio(4): add wakeup support
To:
tech@openbsd.org,moosetek4@gmail.com
Date:
Mon, 2 Jun 2025 18:37:39 -0400

Download raw body.

Thread
Diff below does two things:

(1) Teach acpi(4) about gpio wakeup resources.

(2) Add gpio wakeup support to amdgpio(4).

At suspend time the driver saves the pin configuration as before but now
disables all non-wakeup interrupts.

ok?


Index: dev/acpi/dsdt.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.h,v
retrieving revision 1.82
diff -u -p -r1.82 dsdt.h
--- dev/acpi/dsdt.h	13 May 2024 01:15:50 -0000	1.82
+++ dev/acpi/dsdt.h	2 Jun 2025 22:04:02 -0000
@@ -243,6 +243,9 @@ union acpi_resource {
 		uint16_t	flags;
 		uint16_t	tflags;
 #define LR_GPIO_SHR		(3L << 3)
+#define  LR_GPIO_EXCLUSIVE	(0L << 3)
+#define  LR_GPIO_SHARED		(1L << 3)
+#define  LR_GPIO_WAKE		(2L << 3)
 #define LR_GPIO_POLARITY	(3L << 1)
 #define  LR_GPIO_ACTHI		(0L << 1)
 #define  LR_GPIO_ACTLO		(1L << 1)
Index: dev/acpi/amdgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/amdgpio.c,v
retrieving revision 1.10
diff -u -p -r1.10 amdgpio.c
--- dev/acpi/amdgpio.c	20 Oct 2022 20:40:57 -0000	1.10
+++ dev/acpi/amdgpio.c	2 Jun 2025 22:04:02 -0000
@@ -32,10 +32,15 @@
 #define AMDGPIO_CONF_MASK		0x00000600
 #define AMDGPIO_CONF_INT_EN		0x00000800
 #define AMDGPIO_CONF_INT_MASK		0x00001000
+#define AMDGPIO_CONF_WAKE_S0		0x00002000
+#define AMDGPIO_CONF_WAKE_S3		0x00004000
+#define AMDGPIO_CONF_WAKE_S4		0x00008000
+#define AMDGPIO_CONF_WAKE_MASK		0x0000e000
 #define AMDGPIO_CONF_RXSTATE		0x00010000
 #define AMDGPIO_CONF_TXSTATE		0x00400000
 #define AMDGPIO_CONF_TXSTATE_EN		0x00800000
 #define AMDGPIO_CONF_INT_STS		0x10000000
+#define AMDGPIO_CONF_WAKE_STS		0x20000000
 #define AMDGPIO_IRQ_MASTER_EOI		0x20000000
 #define AMDGPIO_IRQ_BITS		46
 #define AMDGPIO_IRQ_PINS		4
@@ -155,7 +160,7 @@ amdgpio_attach(struct device *parent, st
 	    M_DEVBUF, M_WAITOK | M_ZERO);
 
 	sc->sc_ih = acpi_intr_establish(aaa->aaa_irq[0], aaa->aaa_irq_flags[0],
-	    IPL_BIO, amdgpio_intr, sc, sc->sc_dev.dv_xname);
+	    IPL_BIO | IPL_WAKEUP, amdgpio_intr, sc, sc->sc_dev.dv_xname);
 	if (sc->sc_ih == NULL) {
 		printf(": can't establish interrupt\n");
 		goto unmap;
@@ -201,6 +206,10 @@ amdgpio_save_pin(struct amdgpio_softc *s
 {
 	sc->sc_pin_cfg[pin].pin_cfg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
 	    pin * 4);
+
+	if (sc->sc_pin_ih[pin].ih_func &&
+	    (sc->sc_pin_cfg[pin].pin_cfg & AMDGPIO_CONF_WAKE_MASK) == 0)
+		amdgpio_intr_disable(sc, pin);
 }
 
 void
@@ -271,13 +280,15 @@ amdgpio_intr_establish(void *cookie, int
 
 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
 	reg &= ~(AMDGPIO_CONF_MASK | AMDGPIO_CONF_LEVEL |
-	    AMDGPIO_CONF_TXSTATE_EN);
+	    AMDGPIO_CONF_TXSTATE_EN | AMDGPIO_CONF_WAKE_MASK);
 	if ((flags & LR_GPIO_MODE) == 0)
 		reg |= AMDGPIO_CONF_LEVEL;
 	if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO)
 		reg |= AMDGPIO_CONF_ACTLO;
 	if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH)
 		reg |= AMDGPIO_CONF_ACTBOTH;
+	if ((flags & LR_GPIO_WAKE) == LR_GPIO_WAKE)
+		reg |= AMDGPIO_CONF_WAKE_S0;
 	reg |= (AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN);
 	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg);
 }