Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162881227
D58227.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D58227.diff
View Options
diff --git a/sys/arm64/rockchip/rk_gpio.c b/sys/arm64/rockchip/rk_gpio.c
--- a/sys/arm64/rockchip/rk_gpio.c
+++ b/sys/arm64/rockchip/rk_gpio.c
@@ -219,13 +219,30 @@
RK_GPIO_LOCK(sc);
status = rk_gpio_read_4(sc, RK_GPIO_INT_STATUS);
- rk_gpio_write_4(sc, RK_GPIO_PORTA_EOI, status);
RK_GPIO_UNLOCK(sc);
while (status) {
int pin = ffs(status) - 1;
+ bool is_level;
status &= ~(1 << pin);
+
+ /*
+ * Edge-triggered latches must be cleared before dispatch so a
+ * new edge during the handler still registers a new IRQ.
+ * Level-triggered latches must be cleared AFTER the consumer
+ * has deasserted the source line, otherwise the latch
+ * immediately re-arms and we storm. Edge EOI here; level EOI
+ * is deferred to pic_post_filter or pic_pre_ithread.
+ */
+ is_level = (sc->isrcs[pin].mode &
+ (GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH)) != 0;
+ if (!is_level) {
+ RK_GPIO_LOCK(sc);
+ rk_gpio_write_4(sc, RK_GPIO_PORTA_EOI, 1u << pin);
+ RK_GPIO_UNLOCK(sc);
+ }
+
if (intr_isrc_dispatch(RK_GPIO_ISRC(sc, pin), tf)) {
/*
* Pin asserted but no consumer is registered for it
@@ -235,14 +252,19 @@
* messages per second. Mask the pin's IRQ at the
* controller and disable further dispatches; if a
* consumer attaches later it will re-enable through
- * pic_enable_intr / rk_gpio_pic_enable_intr.
+ * pic_enable_intr / rk_gpio_pic_enable_intr. For
+ * level pins also EOI now -- there is no consumer
+ * to drive the source low.
*/
RK_GPIO_LOCK(sc);
rk_gpio_write_bit(sc, RK_GPIO_INTMASK, pin, 1);
rk_gpio_write_bit(sc, RK_GPIO_INTEN, pin, 0);
+ if (is_level)
+ rk_gpio_write_4(sc, RK_GPIO_PORTA_EOI,
+ 1u << pin);
RK_GPIO_UNLOCK(sc);
device_printf(sc->sc_dev,
- "Interrupt pin=%d unhandled — masked\n", pin);
+ "Interrupt pin=%d unhandled -- masked\n", pin);
continue;
}
@@ -906,21 +928,39 @@
RK_GPIO_UNLOCK(sc);
}
-/*
- * Called by INTRNG before delivering to the ithread. Mask the source
- * so it cannot re-fire during the ithread window -- without this,
- * level-low IRQs (e.g. FUSB302 INT_N) re-trigger continuously and
- * starve the ithread (~210 kHz storm observed via dtrace).
- * Re-unmasked in pic_post_ithread() once the ithread acks the source.
- */
+static void
+rk_pic_post_filter(device_t dev, struct intr_irqsrc *isrc)
+{
+ struct rk_gpio_softc *sc = device_get_softc(dev);
+ struct rk_pin_irqsrc *rkisrc = (struct rk_pin_irqsrc *)isrc;
+
+ /*
+ * Edge-triggered interrupts were cleared in rk_gpio_intr(); nothing
+ * further to do.
+ */
+ if ((rkisrc->mode & (GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH)) == 0)
+ return;
+
+ /* Ack/clear the interrupt. */
+ RK_GPIO_LOCK(sc);
+ rk_gpio_write_4(sc, RK_GPIO_PORTA_EOI, 1u << rkisrc->irq);
+ RK_GPIO_UNLOCK(sc);
+}
+
static void
rk_pic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
{
struct rk_gpio_softc *sc = device_get_softc(dev);
struct rk_pin_irqsrc *rkisrc = (struct rk_pin_irqsrc *)isrc;
+ /*
+ * Prepare to run the threaded handler -- first, mask the interrupt;
+ * then, ack/clear the (level-triggered) source.
+ */
RK_GPIO_LOCK(sc);
rk_gpio_write_bit(sc, RK_GPIO_INTMASK, rkisrc->irq, 1);
+ if ((rkisrc->mode & (GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH)) != 0)
+ rk_gpio_write_4(sc, RK_GPIO_PORTA_EOI, 1u << rkisrc->irq);
RK_GPIO_UNLOCK(sc);
}
@@ -930,6 +970,10 @@
struct rk_gpio_softc *sc = device_get_softc(dev);
struct rk_pin_irqsrc *rkisrc = (struct rk_pin_irqsrc *)isrc;
+ /*
+ * Execution of the threaded handler is complete -- unmask the
+ * interrupt.
+ */
RK_GPIO_LOCK(sc);
rk_gpio_write_bit(sc, RK_GPIO_INTMASK, rkisrc->irq, 0);
RK_GPIO_UNLOCK(sc);
@@ -965,6 +1009,7 @@
DEVMETHOD(pic_teardown_intr, rk_pic_teardown_intr),
DEVMETHOD(pic_disable_intr, rk_pic_disable_intr),
DEVMETHOD(pic_enable_intr, rk_pic_enable_intr),
+ DEVMETHOD(pic_post_filter, rk_pic_post_filter),
DEVMETHOD(pic_pre_ithread, rk_pic_pre_ithread),
DEVMETHOD(pic_post_ithread, rk_pic_post_ithread),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jul 18, 11:13 PM (7 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35105245
Default Alt Text
D58227.diff (3 KB)
Attached To
Mode
D58227: rk_gpio: improve EOI handling
Attached
Detach File
Event Timeline
Log In to Comment