From: James Hastings Subject: Re: amdgpio(4): add wakeup support To: Mark Kettenis Cc: tech@openbsd.org Date: Wed, 4 Jun 2025 05:53:35 -0400 On Tue, Jun 3, 2025 at 3:41 PM Mark Kettenis wrote: > > > From: James Hastings > > Date: Mon, 2 Jun 2025 18:37:39 -0400 (EDT) > > Hi James, > > > 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? > > I don't think this is enough to actually wake the machine up as the > acpi code will send the machine straight back to sleep as you don't > set sc_wakeup in the acpi(4) softc. > > Also, my understanding is that the LR_GPIO_WAKE flag marks a GPIO as > wakeup *capable*. But we don't necessarily want to configure all > wakeup capable GPIOs to actually wake up the system. That will just > result in spurious wakeups. > > I sent out the diff below that handles the upper layers and passes > down IPL_WAKEUP to the GPIO drivers. But some of your bits make me > suspect that I'm missing some stuff in my code. > > I haven't had any test reports for my diff yet, but I'd like to find > if it works or not. And if it doesn't I'd like to roll in some of the > bits from your diff to see if they help. Is that ok with you? > That is ok with me. I tested your diff by itself and the machine did not wake. Further testing and a printf in amdgpio_pin_intr() combined with ddb.suspend=1 confirmed gpio interrupts are working. Pressing the power button triggers interrupt on pin 0 with config reg 0x1005f800 each press. Hard shutdown still required. > > 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); > > } > > > > > > Index: arch/amd64/amd64/intr.c > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/amd64/intr.c,v > diff -u -p -r1.62 intr.c > --- arch/amd64/amd64/intr.c 23 Apr 2025 15:08:05 -0000 1.62 > +++ arch/amd64/amd64/intr.c 31 May 2025 20:15:47 -0000 > @@ -712,6 +712,13 @@ intr_barrier(void *cookie) > sched_barrier(ih->ih_cpu); > } > > +void > +intr_set_wakeup(void *cookie) > +{ > + struct intrhand *ih = cookie; > + ih->ih_flags |= IPL_WAKEUP; > +} > + > #ifdef SUSPEND > > void > Index: arch/amd64/include/intr.h > =================================================================== > RCS file: /cvs/src/sys/arch/amd64/include/intr.h,v > diff -u -p -r1.35 intr.h > --- arch/amd64/include/intr.h 23 Apr 2025 15:08:05 -0000 1.35 > +++ arch/amd64/include/intr.h 31 May 2025 20:15:47 -0000 > @@ -210,6 +210,7 @@ int intr_handler(struct intrframe *, str > void cpu_intr_init(struct cpu_info *); > void intr_printconfig(void); > void intr_barrier(void *); > +void intr_set_wakeup(void *); > void intr_enable_wakeup(void); > void intr_disable_wakeup(void); > > Index: dev/acpi/acpi.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/acpi.c,v > diff -u -p -r1.447 acpi.c > --- dev/acpi/acpi.c 28 May 2025 09:53:53 -0000 1.447 > +++ dev/acpi/acpi.c 31 May 2025 20:15:47 -0000 > @@ -945,7 +945,8 @@ acpi_gpio_parse_events(int crsidx, union > ev->tflags = crs->lr_gpio.tflags; > ev->pin = pin; > gpio->intr_establish(gpio->cookie, pin, > - crs->lr_gpio.tflags, acpi_gpio_event, ev); > + crs->lr_gpio.tflags, IPL_BIO | IPL_WAKEUP, > + acpi_gpio_event, ev); > } > break; > default: > Index: dev/acpi/amdgpio.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/amdgpio.c,v > diff -u -p -r1.10 amdgpio.c > --- dev/acpi/amdgpio.c 20 Oct 2022 20:40:57 -0000 1.10 > +++ dev/acpi/amdgpio.c 31 May 2025 20:15:47 -0000 > @@ -46,6 +46,7 @@ > struct amdgpio_intrhand { > int (*ih_func)(void *); > void *ih_arg; > + int ih_wakeup; > }; > > struct amdgpio_pincfg { > @@ -91,7 +92,7 @@ const char *amdgpio_hids[] = { > > int amdgpio_read_pin(void *, int); > void amdgpio_write_pin(void *, int, int); > -void amdgpio_intr_establish(void *, int, int, int (*)(void *), void *); > +void amdgpio_intr_establish(void *, int, int, int, int (*)(void *), void *); > void amdgpio_intr_enable(void *, int); > void amdgpio_intr_disable(void *, int); > int amdgpio_pin_intr(struct amdgpio_softc *, int); > @@ -258,7 +259,7 @@ amdgpio_write_pin(void *cookie, int pin, > } > > void > -amdgpio_intr_establish(void *cookie, int pin, int flags, > +amdgpio_intr_establish(void *cookie, int pin, int flags, int level, > int (*func)(void *), void *arg) > { > struct amdgpio_softc *sc = cookie; > @@ -268,6 +269,7 @@ amdgpio_intr_establish(void *cookie, int > > sc->sc_pin_ih[pin].ih_func = func; > sc->sc_pin_ih[pin].ih_arg = arg; > + sc->sc_pin_ih[pin].ih_wakeup = level & IPL_WAKEUP; > > reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4); > reg &= ~(AMDGPIO_CONF_MASK | AMDGPIO_CONF_LEVEL | > @@ -280,6 +282,9 @@ amdgpio_intr_establish(void *cookie, int > reg |= AMDGPIO_CONF_ACTBOTH; > reg |= (AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN); > bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg); > + > + if (sc->sc_pin_ih[pin].ih_wakeup) > + intr_set_wakeup(sc->sc_ih); > } > > void > Index: dev/acpi/amltypes.h > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/amltypes.h,v > diff -u -p -r1.50 amltypes.h > --- dev/acpi/amltypes.h 2 Jun 2024 11:08:41 -0000 1.50 > +++ dev/acpi/amltypes.h 31 May 2025 20:15:47 -0000 > @@ -369,7 +369,8 @@ struct acpi_gpio { > void *cookie; > int (*read_pin)(void *, int); > void (*write_pin)(void *, int, int); > - void (*intr_establish)(void *, int, int, int (*)(void *), void *); > + void (*intr_establish)(void *, int, int, int, > + int (*)(void *), void *); > void (*intr_enable)(void *, int); > void (*intr_disable)(void *, int); > }; > Index: dev/acpi/aplgpio.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/aplgpio.c,v > diff -u -p -r1.6 aplgpio.c > --- dev/acpi/aplgpio.c 20 Oct 2022 20:40:57 -0000 1.6 > +++ dev/acpi/aplgpio.c 31 May 2025 20:15:47 -0000 > @@ -75,7 +75,7 @@ const char *aplgpio_hids[] = { > > int aplgpio_read_pin(void *, int); > void aplgpio_write_pin(void *, int, int); > -void aplgpio_intr_establish(void *, int, int, int (*)(void *), void *); > +void aplgpio_intr_establish(void *, int, int, int, int (*)(void *), void *); > void aplgpio_intr_enable(void *, int); > void aplgpio_intr_disable(void *, int); > int aplgpio_intr(void *); > @@ -205,7 +205,7 @@ aplgpio_write_pin(void *cookie, int pin, > } > > void > -aplgpio_intr_establish(void *cookie, int pin, int flags, > +aplgpio_intr_establish(void *cookie, int pin, int flags, int level, > int (*func)(void *), void *arg) > { > struct aplgpio_softc *sc = cookie; > Index: dev/acpi/bytgpio.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/bytgpio.c,v > diff -u -p -r1.18 bytgpio.c > --- dev/acpi/bytgpio.c 20 Oct 2022 20:40:57 -0000 1.18 > +++ dev/acpi/bytgpio.c 31 May 2025 20:15:47 -0000 > @@ -102,7 +102,7 @@ const int byt_sus_pins[] = { > > int bytgpio_read_pin(void *, int); > void bytgpio_write_pin(void *, int, int); > -void bytgpio_intr_establish(void *, int, int, int (*)(void *), void *); > +void bytgpio_intr_establish(void *, int, int, int, int (*)(void *), void *); > void bytgpio_intr_enable(void *, int); > void bytgpio_intr_disable(void *, int); > int bytgpio_intr(void *); > @@ -234,7 +234,7 @@ bytgpio_write_pin(void *cookie, int pin, > } > > void > -bytgpio_intr_establish(void *cookie, int pin, int flags, > +bytgpio_intr_establish(void *cookie, int pin, int flags, int level, > int (*func)(void *), void *arg) > { > struct bytgpio_softc *sc = cookie; > Index: dev/acpi/chvgpio.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/chvgpio.c,v > diff -u -p -r1.13 chvgpio.c > --- dev/acpi/chvgpio.c 20 Oct 2022 20:40:57 -0000 1.13 > +++ dev/acpi/chvgpio.c 31 May 2025 20:15:47 -0000 > @@ -145,7 +145,7 @@ const int chv_southeast_pins[] = { > int chvgpio_check_pin(struct chvgpio_softc *, int); > int chvgpio_read_pin(void *, int); > void chvgpio_write_pin(void *, int, int); > -void chvgpio_intr_establish(void *, int, int, int (*)(void *), void *); > +void chvgpio_intr_establish(void *, int, int, int, int (*)(void *), void *); > void chvgpio_intr_enable(void *, int); > void chvgpio_intr_disable(void *, int); > int chvgpio_intr(void *); > @@ -291,7 +291,7 @@ chvgpio_write_pin(void *cookie, int pin, > } > > void > -chvgpio_intr_establish(void *cookie, int pin, int flags, > +chvgpio_intr_establish(void *cookie, int pin, int flags, int level, > int (*func)(void *), void *arg) > { > struct chvgpio_softc *sc = cookie; > Index: dev/acpi/dwgpio.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/dwgpio.c,v > diff -u -p -r1.8 dwgpio.c > --- dev/acpi/dwgpio.c 13 May 2024 01:15:50 -0000 1.8 > +++ dev/acpi/dwgpio.c 31 May 2025 20:15:47 -0000 > @@ -90,7 +90,7 @@ const char *dwgpio_hids[] = { > int dwgpio_found_hid(struct aml_node *, void *); > int dwgpio_read_pin(void *, int); > void dwgpio_write_pin(void *, int, int); > -void dwgpio_intr_establish(void *, int, int, int (*)(void *), void *); > +void dwgpio_intr_establish(void *, int, int, int, int (*)(void *), void *); > int dwgpio_intr(void *); > > int > @@ -228,7 +228,7 @@ dwgpio_write_pin(void *cookie, int pin, > } > > void > -dwgpio_intr_establish(void *cookie, int pin, int flags, > +dwgpio_intr_establish(void *cookie, int pin, int flags, int level, > int (*func)(void *), void *arg) > { > struct dwgpio_softc *sc = cookie; > Index: dev/acpi/dwiic_acpi.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/dwiic_acpi.c,v > diff -u -p -r1.22 dwiic_acpi.c > --- dev/acpi/dwiic_acpi.c 8 Jul 2023 02:43:02 -0000 1.22 > +++ dev/acpi/dwiic_acpi.c 31 May 2025 20:15:47 -0000 > @@ -387,7 +387,7 @@ dwiic_i2c_intr_establish(void *cookie, v > > struct acpi_gpio *gpio = crs->gpio_int_node->gpio; > gpio->intr_establish(gpio->cookie, crs->gpio_int_pin, > - crs->gpio_int_flags, func, arg); > + crs->gpio_int_flags, level, func, arg); > return ih; > } > > Index: dev/acpi/glkgpio.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/glkgpio.c,v > diff -u -p -r1.7 glkgpio.c > --- dev/acpi/glkgpio.c 13 May 2024 01:15:50 -0000 1.7 > +++ dev/acpi/glkgpio.c 31 May 2025 20:15:47 -0000 > @@ -75,7 +75,7 @@ const char *glkgpio_hids[] = { > > int glkgpio_read_pin(void *, int); > void glkgpio_write_pin(void *, int, int); > -void glkgpio_intr_establish(void *, int, int, int (*)(void *), void *); > +void glkgpio_intr_establish(void *, int, int, int, int (*)(void *), void *); > void glkgpio_intr_enable(void *, int); > void glkgpio_intr_disable(void *, int); > int glkgpio_intr(void *); > @@ -205,7 +205,7 @@ glkgpio_write_pin(void *cookie, int pin, > } > > void > -glkgpio_intr_establish(void *cookie, int pin, int flags, > +glkgpio_intr_establish(void *cookie, int pin, int flags, int level, > int (*func)(void *), void *arg) > { > struct glkgpio_softc *sc = cookie; > Index: dev/acpi/pchgpio.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/pchgpio.c,v > diff -u -p -r1.16 pchgpio.c > --- dev/acpi/pchgpio.c 18 Aug 2024 11:10:10 -0000 1.16 > +++ dev/acpi/pchgpio.c 31 May 2025 20:15:47 -0000 > @@ -463,7 +463,7 @@ struct pchgpio_match pchgpio_devices[] = > > int pchgpio_read_pin(void *, int); > void pchgpio_write_pin(void *, int, int); > -void pchgpio_intr_establish(void *, int, int, int (*)(void *), void *); > +void pchgpio_intr_establish(void *, int, int, int, int (*)(void *), void *); > void pchgpio_intr_enable(void *, int); > void pchgpio_intr_disable(void *, int); > int pchgpio_intr(void *); > @@ -640,7 +640,7 @@ pchgpio_write_pin(void *cookie, int pin, > } > > void > -pchgpio_intr_establish(void *cookie, int pin, int flags, > +pchgpio_intr_establish(void *cookie, int pin, int flags, int level, > int (*func)(void *), void *arg) > { > struct pchgpio_softc *sc = cookie; > Index: dev/acpi/pckbc_acpi.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/pckbc_acpi.c,v > diff -u -p -r1.4 pckbc_acpi.c > --- dev/acpi/pckbc_acpi.c 28 May 2025 07:04:27 -0000 1.4 > +++ dev/acpi/pckbc_acpi.c 31 May 2025 20:15:47 -0000 > @@ -290,8 +290,8 @@ pckbc_acpi_attach_kbd(struct device *par > if (pasc->sc_nints == nitems(pasc->sc_ih)) > break; > pasc->sc_ih[pasc->sc_nints] = acpi_intr_establish( > - aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], IPL_TTY, > - pckbcintr, pasc, self->dv_xname); > + aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], > + IPL_TTY, pckbcintr, pasc, self->dv_xname); > if (pasc->sc_ih[pasc->sc_nints] == NULL) { > printf("%s: can't establish interrupt %d\n", > self->dv_xname, aaa->aaa_irq[irq]); > @@ -392,8 +392,8 @@ pckbc_acpi_attach_mouse(struct device *p > if (pasc->sc_nints == nitems(pasc->sc_ih)) > break; > pasc->sc_ih[pasc->sc_nints] = acpi_intr_establish( > - aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], IPL_TTY, > - pckbcintr, pasc, self->dv_xname); > + aaa->aaa_irq[irq], aaa->aaa_irq_flags[irq], > + IPL_TTY, pckbcintr, pasc, self->dv_xname); > if (pasc->sc_ih[pasc->sc_nints] == NULL) { > printf("%s: can't establish interrupt %d\n", > self->dv_xname, aaa->aaa_irq[irq]); > @@ -433,7 +433,7 @@ pckbc_acpi_register_gpio_intrs(struct de > } > gpio->intr_establish(gpio->cookie, > sc->sc_gpioint[irq].pin, sc->sc_gpioint[irq].flags, > - pckbc_acpi_gpio_intr_wrapper, sc); > + IPL_TTY, pckbc_acpi_gpio_intr_wrapper, sc); > } > } > > Index: dev/acpi/sdhc_acpi.c > =================================================================== > RCS file: /cvs/src/sys/dev/acpi/sdhc_acpi.c,v > diff -u -p -r1.23 sdhc_acpi.c > --- dev/acpi/sdhc_acpi.c 9 Oct 2024 00:38:25 -0000 1.23 > +++ dev/acpi/sdhc_acpi.c 31 May 2025 20:15:47 -0000 > @@ -131,7 +131,8 @@ sdhc_acpi_attach(struct device *parent, > struct acpi_gpio *gpio = sc->sc_gpio_int_node->gpio; > > gpio->intr_establish(gpio->cookie, sc->sc_gpio_int_pin, > - sc->sc_gpio_int_flags, sdhc_acpi_card_detect_intr, sc); > + sc->sc_gpio_int_flags, IPL_BIO, > + sdhc_acpi_card_detect_intr, sc); > } > > sdhc_acpi_power_on(sc, sc->sc_node); >