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).
>
I reworked this diff and made it look just like pchgpio. But it's a little
simpler than pchgpio since there is less to save/restore.
ok?
-ml
Index: amdgpio.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/amdgpio.c,v
retrieving revision 1.7
diff -u -p -a -u -r1.7 amdgpio.c
--- amdgpio.c 6 Apr 2022 18:59:27 -0000 1.7
+++ amdgpio.c 26 Jun 2022 13:53:19 -0000
@@ -48,6 +48,11 @@ struct amdgpio_intrhand {
void *ih_arg;
};
+struct amdgpio_pincfg {
+ /* Modeled after pchgpio but we only have one value to save/restore */
+ uint32_t pin_cfg;
+};
+
struct amdgpio_softc {
struct device sc_dev;
struct acpi_softc *sc_acpi;
@@ -59,6 +64,7 @@ struct amdgpio_softc {
void *sc_ih;
int sc_npins;
+ struct amdgpio_pincfg *sc_pin_cfg;
struct amdgpio_intrhand *sc_pin_ih;
struct acpi_gpio sc_gpio;
@@ -66,9 +72,11 @@ struct amdgpio_softc {
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 = {
@@ -86,6 +94,10 @@ void amdgpio_write_pin(void *, int, int)
void amdgpio_intr_establish(void *, int, int, int (*)(void *), void *);
int amdgpio_pin_intr(struct amdgpio_softc *, int);
int amdgpio_intr(void *);
+void amdgpio_save_pin(struct amdgpio_softc *, int pin);
+void amdgpio_save(struct amdgpio_softc *);
+void amdgpio_restore_pin(struct amdgpio_softc *, int pin);
+void amdgpio_restore(struct amdgpio_softc *);
int
amdgpio_match(struct device *parent, void *match, void *aux)
@@ -135,6 +147,8 @@ amdgpio_attach(struct device *parent, st
return;
}
+ sc->sc_pin_cfg = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_cfg),
+ M_DEVBUF, M_WAITOK);
sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih),
M_DEVBUF, M_WAITOK | M_ZERO);
@@ -159,6 +173,58 @@ amdgpio_attach(struct device *parent, st
unmap:
free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
bus_space_unmap(sc->sc_memt, sc->sc_memh, aaa->aaa_size[0]);
+}
+
+int
+amdgpio_activate(struct device *self, int act)
+{
+ struct amdgpio_softc *sc = (struct amdgpio_softc *)self;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ amdgpio_save(sc);
+ break;
+ case DVACT_RESUME:
+ amdgpio_restore(sc);
+ break;
+ }
+
+ return 0;
+}
+
+void
+amdgpio_save_pin(struct amdgpio_softc *sc, int pin)
+{
+ sc->sc_pin_cfg[pin].pin_cfg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
+ pin * 4);
+}
+
+void
+amdgpio_save(struct amdgpio_softc *sc)
+{
+ int pin;
+
+ for (pin = 0 ; pin < sc->sc_npins; pin++)
+ amdgpio_save_pin(sc, pin);
+}
+
+void
+amdgpio_restore_pin(struct amdgpio_softc *sc, int pin)
+{
+ if (!sc->sc_pin_ih[pin].ih_func)
+ return;
+
+ bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4,
+ sc->sc_pin_cfg[pin].pin_cfg);
+}
+
+void
+amdgpio_restore(struct amdgpio_softc *sc)
+{
+ int pin;
+
+ for (pin = 0; pin < sc->sc_npins; pin++)
+ amdgpio_restore_pin(sc, pin);
}
int