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