Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Apr 2016 14:28:34 +0000 (UTC)
From:      Andrew Turner <andrew@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r298054 - head/sys/arm/arm
Message-ID:  <201604151428.u3FESYjh059099@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: andrew
Date: Fri Apr 15 14:28:34 2016
New Revision: 298054
URL: https://svnweb.freebsd.org/changeset/base/298054

Log:
  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

Modified:
  head/sys/arm/arm/gic.c

Modified: head/sys/arm/arm/gic.c
==============================================================================
--- head/sys/arm/arm/gic.c	Fri Apr 15 14:26:24 2016	(r298053)
+++ head/sys/arm/arm/gic.c	Fri Apr 15 14:28:34 2016	(r298054)
@@ -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 
 
 	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
 	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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604151428.u3FESYjh059099>