summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2016-04-15 14:28:34 +0000
committerandrew <andrew@FreeBSD.org>2016-04-15 14:28:34 +0000
commit09cc69da94ad26d463004506b1bb2db36973a6da (patch)
treea51f907b6ec9ce281fd3fa9279bab6378f1775f3
parentbb82d4608439d25802860305a6457ab0db4f1fd2 (diff)
downloadFreeBSD-src-09cc69da94ad26d463004506b1bb2db36973a6da.zip
FreeBSD-src-09cc69da94ad26d463004506b1bb2db36973a6da.tar.gz
Add a flag field to struct gic_irqsrc and use it to mark when we should
write to the End of Interrupt (EOI) register before handling the interrupt. This should be a noop as it will be set for all edge triggered interrupts, however this will not be the case for MSI interrupts. These are also edge triggered, however we should not write to the EOI register until later in arm_gic_pre_ithread. Obtained from: ABT Systems Ltd Sponsored by: The FreeBSD Foundation
-rw-r--r--sys/arm/arm/gic.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index ced66d5..0d201fd 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -122,6 +122,8 @@ struct gic_irqsrc {
uint32_t gi_irq;
enum intr_polarity gi_pol;
enum intr_trigger gi_trig;
+#define GI_FLAG_EARLY_EOI (1 << 0)
+ u_int gi_flags;
};
static u_int gic_irq_cpu;
@@ -853,12 +855,12 @@ dispatch_irq:
#ifdef GIC_DEBUG_SPURIOUS
sc->last_irq[PCPU_GET(cpuid)] = irq;
#endif
- if (gi->gi_trig == INTR_TRIGGER_EDGE)
+ if ((gi->gi_flags & GI_FLAG_EARLY_EOI) == GI_FLAG_EARLY_EOI)
gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
if (intr_isrc_dispatch(&gi->gi_isrc, tf) != 0) {
gic_irq_mask(sc, irq);
- if (gi->gi_trig != INTR_TRIGGER_EDGE)
+ if ((gi->gi_flags & GI_FLAG_EARLY_EOI) != GI_FLAG_EARLY_EOI)
gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
device_printf(sc->gic_dev, "Stray irq %u disabled\n", irq);
}
@@ -1087,6 +1089,9 @@ arm_gic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
gi->gi_pol = pol;
gi->gi_trig = trig;
+ /* Edge triggered interrupts need an early EOI sent */
+ if (gi->gi_pol == INTR_TRIGGER_EDGE)
+ gi->gi_flags |= GI_FLAG_EARLY_EOI;
/*
* XXX - In case that per CPU interrupt is going to be enabled in time
@@ -1160,7 +1165,7 @@ arm_gic_post_filter(device_t dev, struct intr_irqsrc *isrc)
struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
/* EOI for edge-triggered done earlier. */
- if (gi->gi_trig == INTR_TRIGGER_EDGE)
+ if ((gi->gi_flags & GI_FLAG_EARLY_EOI) == GI_FLAG_EARLY_EOI)
return;
arm_irq_memory_barrier(0);
OpenPOWER on IntegriCloud