The diff below adds the hooks to disable and enable GPIO interrupts for amdgpio(4), aplgpio(4), bytgpio(4), chvgpio(4), glkgpio(4) and pchgpio(4). This is similar to what I did for qcgpio(4) a few weeks ago. This should fix potential interrupt storms related to level-triggered interrupts.
I can't really test this myself. But if you have a machine with a line like this: ihidev0 at iic7 addr 0x2c gpio 18, vendor 0x6cb product 0x8253, SYNA2B43 ^^^^ that contains the string "gpio", please give this a shot and check whether your keyboard and touchpad still work with it and report back with a fullk dmesg. Thanks, Mark Index: dev/acpi/amdgpio.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/amdgpio.c,v retrieving revision 1.9 diff -u -p -r1.9 amdgpio.c --- dev/acpi/amdgpio.c 27 Jun 2022 08:00:31 -0000 1.9 +++ dev/acpi/amdgpio.c 3 Oct 2022 19:10:03 -0000 @@ -92,6 +92,8 @@ 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_enable(void *, int); +void amdgpio_intr_disable(void *, int); int amdgpio_pin_intr(struct amdgpio_softc *, int); int amdgpio_intr(void *); void amdgpio_save_pin(struct amdgpio_softc *, int pin); @@ -163,6 +165,8 @@ amdgpio_attach(struct device *parent, st sc->sc_gpio.read_pin = amdgpio_read_pin; sc->sc_gpio.write_pin = amdgpio_write_pin; sc->sc_gpio.intr_establish = amdgpio_intr_establish; + sc->sc_gpio.intr_enable = amdgpio_intr_enable; + sc->sc_gpio.intr_disable = amdgpio_intr_disable; sc->sc_node->gpio = &sc->sc_gpio; printf(", %d pins\n", sc->sc_npins); @@ -275,6 +279,32 @@ amdgpio_intr_establish(void *cookie, int if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH) 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); +} + +void +amdgpio_intr_enable(void *cookie, int pin) +{ + struct amdgpio_softc *sc = cookie; + uint32_t reg; + + KASSERT(pin >= 0 && pin != 63 && pin < sc->sc_npins); + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4); + reg |= (AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN); + bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg); +} + +void +amdgpio_intr_disable(void *cookie, int pin) +{ + struct amdgpio_softc *sc = cookie; + uint32_t reg; + + KASSERT(pin >= 0 && pin != 63 && pin < sc->sc_npins); + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4); + reg &= ~(AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN); bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg); } Index: dev/acpi/aplgpio.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/aplgpio.c,v retrieving revision 1.5 diff -u -p -r1.5 aplgpio.c --- dev/acpi/aplgpio.c 6 Apr 2022 18:59:27 -0000 1.5 +++ dev/acpi/aplgpio.c 3 Oct 2022 19:10:03 -0000 @@ -76,6 +76,8 @@ 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_enable(void *, int); +void aplgpio_intr_disable(void *, int); int aplgpio_intr(void *); int @@ -150,6 +152,8 @@ aplgpio_attach(struct device *parent, st sc->sc_gpio.read_pin = aplgpio_read_pin; sc->sc_gpio.write_pin = aplgpio_write_pin; sc->sc_gpio.intr_establish = aplgpio_intr_establish; + sc->sc_gpio.intr_enable = aplgpio_intr_enable; + sc->sc_gpio.intr_disable = aplgpio_intr_disable; sc->sc_node->gpio = &sc->sc_gpio; /* Mask and clear all interrupts. */ @@ -227,6 +231,36 @@ aplgpio_intr_establish(void *cookie, int reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, APLGPIO_IRQ_EN + (pin / 32) * 4); reg |= (1 << (pin % 32)); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + APLGPIO_IRQ_EN + (pin / 32) * 4, reg); +} + +void +aplgpio_intr_enable(void *cookie, int pin) +{ + struct aplgpio_softc *sc = cookie; + uint32_t reg; + + KASSERT(pin >= 0 && pin < sc->sc_npins); + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, + APLGPIO_IRQ_EN + (pin / 32) * 4); + reg |= (1 << (pin % 32)); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + APLGPIO_IRQ_EN + (pin / 32) * 4, reg); +} + +void +aplgpio_intr_disable(void *cookie, int pin) +{ + struct aplgpio_softc *sc = cookie; + uint32_t reg; + + KASSERT(pin >= 0 && pin < sc->sc_npins); + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, + APLGPIO_IRQ_EN + (pin / 32) * 4); + reg &= ~(1 << (pin % 32)); bus_space_write_4(sc->sc_memt, sc->sc_memh, APLGPIO_IRQ_EN + (pin / 32) * 4, reg); } Index: dev/acpi/bytgpio.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/bytgpio.c,v retrieving revision 1.17 diff -u -p -r1.17 bytgpio.c --- dev/acpi/bytgpio.c 6 Apr 2022 18:59:27 -0000 1.17 +++ dev/acpi/bytgpio.c 3 Oct 2022 19:10:03 -0000 @@ -40,6 +40,7 @@ struct bytgpio_intrhand { int (*ih_func)(void *); void *ih_arg; + int ih_tflags; }; struct bytgpio_softc { @@ -102,6 +103,8 @@ 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_enable(void *, int); +void bytgpio_intr_disable(void *, int); int bytgpio_intr(void *); int @@ -177,6 +180,8 @@ bytgpio_attach(struct device *parent, st sc->sc_gpio.read_pin = bytgpio_read_pin; sc->sc_gpio.write_pin = bytgpio_write_pin; sc->sc_gpio.intr_establish = bytgpio_intr_establish; + sc->sc_gpio.intr_enable = bytgpio_intr_enable; + sc->sc_gpio.intr_disable = bytgpio_intr_disable; sc->sc_node->gpio = &sc->sc_gpio; /* Mask all interrupts. */ @@ -233,12 +238,26 @@ bytgpio_intr_establish(void *cookie, int int (*func)(void *), void *arg) { struct bytgpio_softc *sc = cookie; - uint32_t reg; KASSERT(pin >= 0 && pin < sc->sc_npins); sc->sc_pin_ih[pin].ih_func = func; sc->sc_pin_ih[pin].ih_arg = arg; + sc->sc_pin_ih[pin].ih_tflags = flags; + + bytgpio_intr_enable(cookie, pin); +} + +void +bytgpio_intr_enable(void *cookie, int pin) +{ + struct bytgpio_softc *sc = cookie; + uint32_t reg; + int flags; + + KASSERT(pin >= 0 && pin < sc->sc_npins); + + flags = sc->sc_pin_ih[pin].ih_tflags; reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16); reg &= ~BYTGPIO_CONF_GD_MASK; @@ -250,6 +269,19 @@ bytgpio_intr_establish(void *cookie, int reg |= BYTGPIO_CONF_GD_TPE; if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH) reg |= BYTGPIO_CONF_GD_TNE | BYTGPIO_CONF_GD_TPE; + bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16, reg); +} + +void +bytgpio_intr_disable(void *cookie, int pin) +{ + struct bytgpio_softc *sc = cookie; + uint32_t reg; + + KASSERT(pin >= 0 && pin < sc->sc_npins); + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16); + reg &= ~BYTGPIO_CONF_GD_MASK; bus_space_write_4(sc->sc_memt, sc->sc_memh, sc->sc_pins[pin] * 16, reg); } Index: dev/acpi/chvgpio.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/chvgpio.c,v retrieving revision 1.12 diff -u -p -r1.12 chvgpio.c --- dev/acpi/chvgpio.c 6 Apr 2022 18:59:27 -0000 1.12 +++ dev/acpi/chvgpio.c 3 Oct 2022 19:10:03 -0000 @@ -146,6 +146,8 @@ int chvgpio_check_pin(struct chvgpio_sof 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_enable(void *, int); +void chvgpio_intr_disable(void *, int); int chvgpio_intr(void *); int chvgpio_opreg_handler(void *, int, uint64_t, int, uint64_t *); @@ -224,6 +226,8 @@ chvgpio_attach(struct device *parent, st sc->sc_gpio.read_pin = chvgpio_read_pin; sc->sc_gpio.write_pin = chvgpio_write_pin; sc->sc_gpio.intr_establish = chvgpio_intr_establish; + sc->sc_gpio.intr_enable = chvgpio_intr_enable; + sc->sc_gpio.intr_disable = chvgpio_intr_disable; sc->sc_node->gpio = &sc->sc_gpio; /* Mask and ack all interrupts. */ @@ -334,6 +338,44 @@ chvgpio_intr_establish(void *cookie, int bus_space_write_4(sc->sc_memt, sc->sc_memh, CHVGPIO_INTERRUPT_MASK, reg | (1 << line)); } + +void +chvgpio_intr_enable(void *cookie, int pin) +{ + struct chvgpio_softc *sc = cookie; + uint32_t reg; + int line; + + KASSERT(chvgpio_check_pin(sc, pin) == 0); + + reg = chvgpio_read_pad_cfg0(sc, pin); + reg &= CHVGPIO_PAD_CFG0_INTSEL_MASK; + line = reg >> CHVGPIO_PAD_CFG0_INTSEL_SHIFT; + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, + CHVGPIO_INTERRUPT_MASK); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + CHVGPIO_INTERRUPT_MASK, reg | (1 << line)); +} + +void +chvgpio_intr_disable(void *cookie, int pin) +{ + struct chvgpio_softc *sc = cookie; + uint32_t reg; + int line; + + KASSERT(chvgpio_check_pin(sc, pin) == 0); + + reg = chvgpio_read_pad_cfg0(sc, pin); + reg &= CHVGPIO_PAD_CFG0_INTSEL_MASK; + line = reg >> CHVGPIO_PAD_CFG0_INTSEL_SHIFT; + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, + CHVGPIO_INTERRUPT_MASK); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + CHVGPIO_INTERRUPT_MASK, reg & ~(1 << line)); +} int chvgpio_intr(void *arg) Index: dev/acpi/glkgpio.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/glkgpio.c,v retrieving revision 1.5 diff -u -p -r1.5 glkgpio.c --- dev/acpi/glkgpio.c 6 Apr 2022 18:59:27 -0000 1.5 +++ dev/acpi/glkgpio.c 3 Oct 2022 19:10:03 -0000 @@ -77,6 +77,8 @@ int glkgpio_parse_resources(int, union a 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_enable(void *, int); +void glkgpio_intr_disable(void *, int); int glkgpio_intr(void *); int @@ -151,6 +153,8 @@ glkgpio_attach(struct device *parent, st sc->sc_gpio.read_pin = glkgpio_read_pin; sc->sc_gpio.write_pin = glkgpio_write_pin; sc->sc_gpio.intr_establish = glkgpio_intr_establish; + sc->sc_gpio.intr_enable = glkgpio_intr_enable; + sc->sc_gpio.intr_disable = glkgpio_intr_disable; sc->sc_node->gpio = &sc->sc_gpio; /* Mask and clear all interrupts. */ @@ -228,6 +232,36 @@ glkgpio_intr_establish(void *cookie, int reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, GLKGPIO_IRQ_EN + (pin / 32) * 4); reg |= (1 << (pin % 32)); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + GLKGPIO_IRQ_EN + (pin / 32) * 4, reg); +} + +void +glkgpio_intr_enable(void *cookie, int pin) +{ + struct glkgpio_softc *sc = cookie; + uint32_t reg; + + KASSERT(pin >= 0 && pin < sc->sc_npins); + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, + GLKGPIO_IRQ_EN + (pin / 32) * 4); + reg |= (1 << (pin % 32)); + bus_space_write_4(sc->sc_memt, sc->sc_memh, + GLKGPIO_IRQ_EN + (pin / 32) * 4, reg); +} + +void +glkgpio_intr_disable(void *cookie, int pin) +{ + struct glkgpio_softc *sc = cookie; + uint32_t reg; + + KASSERT(pin >= 0 && pin < sc->sc_npins); + + reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, + GLKGPIO_IRQ_EN + (pin / 32) * 4); + reg &= ~(1 << (pin % 32)); bus_space_write_4(sc->sc_memt, sc->sc_memh, GLKGPIO_IRQ_EN + (pin / 32) * 4, reg); } Index: dev/acpi/pchgpio.c =================================================================== RCS file: /cvs/src/sys/dev/acpi/pchgpio.c,v retrieving revision 1.13 diff -u -p -r1.13 pchgpio.c --- dev/acpi/pchgpio.c 29 Jun 2022 01:05:18 -0000 1.13 +++ dev/acpi/pchgpio.c 3 Oct 2022 19:10:03 -0000 @@ -325,6 +325,8 @@ 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_enable(void *, int); +void pchgpio_intr_disable(void *, int); int pchgpio_intr(void *); void pchgpio_save(struct pchgpio_softc *); void pchgpio_restore(struct pchgpio_softc *); @@ -406,6 +408,8 @@ pchgpio_attach(struct device *parent, st sc->sc_gpio.read_pin = pchgpio_read_pin; sc->sc_gpio.write_pin = pchgpio_write_pin; sc->sc_gpio.intr_establish = pchgpio_intr_establish; + sc->sc_gpio.intr_enable = pchgpio_intr_enable; + sc->sc_gpio.intr_disable = pchgpio_intr_disable; sc->sc_node->gpio = &sc->sc_gpio; printf(", %d pins\n", sc->sc_npins); @@ -534,6 +538,58 @@ pchgpio_intr_establish(void *cookie, int reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar], sc->sc_device->gpi_ie + bank * 4); reg |= (1 << (pin - group->gpiobase)); + bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar], + sc->sc_device->gpi_ie + bank * 4, reg); +} + +void +pchgpio_intr_enable(void *cookie, int pin) +{ + struct pchgpio_softc *sc = cookie; + const struct pchgpio_group *group; + uint32_t reg; + uint16_t pad; + uint8_t bank, bar; + + KASSERT(pin >= 0); + + group = pchgpio_find_group(sc, pin); + if (group == NULL) + return; + + bar = group->bar; + bank = group->bank; + pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar]; + + reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar], + sc->sc_device->gpi_ie + bank * 4); + reg |= (1 << (pin - group->gpiobase)); + bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar], + sc->sc_device->gpi_ie + bank * 4, reg); +} + +void +pchgpio_intr_disable(void *cookie, int pin) +{ + struct pchgpio_softc *sc = cookie; + const struct pchgpio_group *group; + uint32_t reg; + uint16_t pad; + uint8_t bank, bar; + + KASSERT(pin >= 0); + + group = pchgpio_find_group(sc, pin); + if (group == NULL) + return; + + bar = group->bar; + bank = group->bank; + pad = group->base + (pin - group->gpiobase) - sc->sc_padbase[bar]; + + reg = bus_space_read_4(sc->sc_memt[bar], sc->sc_memh[bar], + sc->sc_device->gpi_ie + bank * 4); + reg &= ~(1 << (pin - group->gpiobase)); bus_space_write_4(sc->sc_memt[bar], sc->sc_memh[bar], sc->sc_device->gpi_ie + bank * 4, reg); }