interrupt storms related to level-triggered interrupts.
ok mglocker@
-/* $OpenBSD: amdgpio.c,v 1.9 2022/06/27 08:00:31 mlarkin Exp $ */
+/* $OpenBSD: amdgpio.c,v 1.10 2022/10/20 20:40:57 kettenis Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
* Copyright (c) 2019 James Hastings
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);
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);
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);
+}
+
int
amdgpio_pin_intr(struct amdgpio_softc *sc, int pin)
{
-/* $OpenBSD: aplgpio.c,v 1.5 2022/04/06 18:59:27 naddy Exp $ */
+/* $OpenBSD: aplgpio.c,v 1.6 2022/10/20 20:40:57 kettenis Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
* Copyright (c) 2019 James Hastings
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
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. */
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);
+}
+
int
aplgpio_intr(void *arg)
{
-/* $OpenBSD: bytgpio.c,v 1.17 2022/04/06 18:59:27 naddy Exp $ */
+/* $OpenBSD: bytgpio.c,v 1.18 2022/10/20 20:40:57 kettenis Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
*
struct bytgpio_intrhand {
int (*ih_func)(void *);
void *ih_arg;
+ int ih_tflags;
};
struct bytgpio_softc {
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
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. */
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;
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);
+}
+
int
bytgpio_intr(void *arg)
{
-/* $OpenBSD: chvgpio.c,v 1.12 2022/04/06 18:59:27 naddy Exp $ */
+/* $OpenBSD: chvgpio.c,v 1.13 2022/10/20 20:40:57 kettenis Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
*
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 *);
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. */
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)
{
-/* $OpenBSD: glkgpio.c,v 1.5 2022/04/06 18:59:27 naddy Exp $ */
+/* $OpenBSD: glkgpio.c,v 1.6 2022/10/20 20:40:57 kettenis Exp $ */
/*
* Copyright (c) 2016 Mark Kettenis
* Copyright (c) 2019 James Hastings
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
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. */
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);
+}
+
int
glkgpio_intr(void *arg)
{
-/* $OpenBSD: pchgpio.c,v 1.13 2022/06/29 01:05:18 jsg Exp $ */
+/* $OpenBSD: pchgpio.c,v 1.14 2022/10/20 20:40:57 kettenis Exp $ */
/*
* Copyright (c) 2020 Mark Kettenis
* Copyright (c) 2020 James Hastings
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 *);
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);
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);
+}
+
int
pchgpio_intr_handle(struct pchgpio_softc *sc, int group, int bit)
{