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 <[email protected]>
> >
> > 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
> >
> >
>