On Wed, Apr 20, 2022 at 11:39:00AM +0200, Mark Kettenis wrote: > > Date: Tue, 19 Apr 2022 22:02:00 -0700 > > From: Mike Larkin <mlar...@nested.page> > > > > 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. > > I think it might make sense to structure this a bit more like > pchgpio(4). There we only restore the configuration for pins that are > "in use" by OpenBSD. > > > 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. > > Well, using amdgpio_read_pin() for the purpose of saving the pin > configuration doesn't make sense. That function returns the pin input > state. > > What you need to do is to read the register using bus_space_read_4() > and restore that value. Again take a look at pchgpio(4). > > > Note 2: In xxx_activate() functions, we usually call > > config_activate_children > > but since amdgpio doesn't have any children, I left that out. > > I think that's fine. But you should do the save/restore in > DVACT_SUSPEND/DVACT_RESUME. You want to restore the state as early as > possible such that you don't get spurious interrupts when the BIOS > leaves GPIO pins misconfigured. Again, look at pchgpio(4). >
Will take a look, thanks! -ml > > > > 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 > > > > >