On at least the Asus ROG Zephyrus 14 (2020), the trackpad fails to generate any interrupts after resume. I tracked this down to amdgpio(4) not generating interrupts after resume, and started looking at missing soft state.
This diff preserves the interrupt pin configurations and restores them after resume. This makes the device function properly post-zzz and post-ZZZ. Note: amdgpio_read_pin does not return the value that was previously written during amdgpio_intr_establish (it always just returns 0x1 if the pin is in use), so I'm just saving the actual value we write during amdgpio_intr_establish and restoring that during resume. Note 2: In xxx_activate() functions, we usually call config_activate_children but since amdgpio doesn't have any children, I left that out. ok? -ml diff a82721d2c9ea32a8f6043a3e06b2a7f8280ef68b /export/bin/src/OpenBSD/g14 blob - 1d0cd5fcede71f0495a271a9d06fc9c0ecb16412 file + sys/dev/acpi/amdgpio.c --- sys/dev/acpi/amdgpio.c +++ sys/dev/acpi/amdgpio.c @@ -62,13 +62,17 @@ struct amdgpio_softc { struct amdgpio_intrhand *sc_pin_ih; struct acpi_gpio sc_gpio; + + uint32_t *sc_pincfg; }; int amdgpio_match(struct device *, void *, void *); void amdgpio_attach(struct device *, struct device *, void *); +int amdgpio_activate(struct device *, int); const struct cfattach amdgpio_ca = { - sizeof(struct amdgpio_softc), amdgpio_match, amdgpio_attach + sizeof(struct amdgpio_softc), amdgpio_match, amdgpio_attach, NULL, + amdgpio_activate }; struct cfdriver amdgpio_cd = { @@ -98,6 +102,24 @@ amdgpio_match(struct device *parent, void *match, void return acpi_matchhids(aaa, amdgpio_hids, cf->cf_driver->cd_name); } +int +amdgpio_activate(struct device *self, int act) +{ + struct amdgpio_softc *sc = (struct amdgpio_softc *)self; + int rv = 0, i; + + switch (act) { + case DVACT_WAKEUP: + for (i = 0; i < sc->sc_npins; i++) { + if (sc->sc_pincfg[i]) + bus_space_write_4(sc->sc_memt, sc->sc_memh, + i * 4, sc->sc_pincfg[i]); + } + } + + return (rv); +} + void amdgpio_attach(struct device *parent, struct device *self, void *aux) { @@ -152,6 +174,8 @@ amdgpio_attach(struct device *parent, struct device *s sc->sc_node->gpio = &sc->sc_gpio; printf(", %d pins\n", sc->sc_npins); + sc->sc_pincfg = malloc(sc->sc_npins * sizeof(uint32_t), M_DEVBUF, + M_WAITOK | M_ZERO); acpi_register_gpio(sc->sc_acpi, sc->sc_node); return; @@ -210,6 +234,8 @@ amdgpio_intr_establish(void *cookie, int pin, int flag 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); + + sc->sc_pincfg[pin] = reg; } int