svn commit: r297674 - in head/sys: arm/arm arm/broadcom/bcm2835 kern sys

Svatopluk Kraus skra at FreeBSD.org
Thu Apr 7 15:00:27 UTC 2016


Author: skra
Date: Thu Apr  7 15:00:25 2016
New Revision: 297674
URL: https://svnweb.freebsd.org/changeset/base/297674

Log:
  Implement intr_isrc_init_on_cpu() and use it to replace very same
  code implemented in every interrupt controller driver running SMP.
  This function returns true, if provided ISRC should be enabled on
  given cpu.

Modified:
  head/sys/arm/arm/gic.c
  head/sys/arm/broadcom/bcm2835/bcm2836.c
  head/sys/kern/subr_intr.c
  head/sys/sys/intr.h

Modified: head/sys/arm/arm/gic.c
==============================================================================
--- head/sys/arm/arm/gic.c	Thu Apr  7 14:25:15 2016	(r297673)
+++ head/sys/arm/arm/gic.c	Thu Apr  7 15:00:25 2016	(r297674)
@@ -256,11 +256,11 @@ static void
 arm_gic_init_secondary(device_t dev)
 {
 	struct arm_gic_softc *sc = device_get_softc(dev);
-	struct intr_irqsrc *isrc;
-	u_int irq;
+	u_int irq, cpu;
 
 	/* Set the mask so we can find this CPU to send it IPIs */
-	arm_gic_map[PCPU_GET(cpuid)] = gic_cpu_mask(sc);
+	cpu = PCPU_GET(cpuid);
+	arm_gic_map[cpu] = gic_cpu_mask(sc);
 
 	for (irq = 0; irq < sc->nirqs; irq += 4)
 		gic_d_write_4(sc, GICD_IPRIORITYR(irq >> 2), 0);
@@ -280,27 +280,14 @@ arm_gic_init_secondary(device_t dev)
 	gic_d_write_4(sc, GICD_CTLR, 0x01);
 
 	/* Unmask attached SGI interrupts. */
-	for (irq = GIC_FIRST_SGI; irq <= GIC_LAST_SGI; irq++) {
-		isrc = GIC_INTR_ISRC(sc, irq);
-		if (isrc != NULL && isrc->isrc_handlers != 0) {
-			CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
+	for (irq = GIC_FIRST_SGI; irq <= GIC_LAST_SGI; irq++)
+		if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu))
 			gic_irq_unmask(sc, irq);
-		}
-	}
 
 	/* Unmask attached PPI interrupts. */
-	for (irq = GIC_FIRST_PPI; irq <= GIC_LAST_PPI; irq++) {
-		isrc = GIC_INTR_ISRC(sc, irq);
-		if (isrc == NULL || isrc->isrc_handlers == 0)
-			continue;
-		if (isrc->isrc_flags & INTR_ISRCF_BOUND) {
-			if (CPU_ISSET(PCPU_GET(cpuid), &isrc->isrc_cpu))
-				gic_irq_unmask(sc, irq);
-		} else {
-			CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
+	for (irq = GIC_FIRST_PPI; irq <= GIC_LAST_PPI; irq++)
+		if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu))
 			gic_irq_unmask(sc, irq);
-		}
-	}
 }
 #else
 static void

Modified: head/sys/arm/broadcom/bcm2835/bcm2836.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2836.c	Thu Apr  7 14:25:15 2016	(r297673)
+++ head/sys/arm/broadcom/bcm2835/bcm2836.c	Thu Apr  7 15:00:25 2016	(r297674)
@@ -525,40 +525,21 @@ bcm_lintc_setup_intr(device_t dev, struc
 }
 
 #ifdef SMP
-static bool
-bcm_lint_init_on_ap(struct bcm_lintc_softc *sc, struct bcm_lintc_irqsrc *bli,
-    u_int cpu)
-{
-	struct intr_irqsrc *isrc;
-
-	isrc = &bli->bli_isrc;
-
-	KASSERT(isrc->isrc_flags & INTR_ISRCF_PPI,
-	    ("%s: irq %d is not PPI", __func__, bli->bli_irq));
-
-	if (isrc->isrc_handlers == 0)
-		return (false);
-	if (isrc->isrc_flags & INTR_ISRCF_BOUND)
-		return (CPU_ISSET(cpu, &isrc->isrc_cpu));
-
-	CPU_SET(cpu, &isrc->isrc_cpu);
-	return (true);
-}
-
 static void
 bcm_lintc_init_rwreg_on_ap(struct bcm_lintc_softc *sc, u_int cpu, u_int irq,
     uint32_t reg, uint32_t mask)
 {
 
-	if (bcm_lint_init_on_ap(sc, &sc->bls_isrcs[irq], cpu))
+	if (intr_isrc_init_on_cpu(&sc->bls_isrcs[irq].bli_isrc, cpu))
 		bcm_lintc_rwreg_set(sc, reg, mask);
 }
 
 static void
 bcm_lintc_init_pmu_on_ap(struct bcm_lintc_softc *sc, u_int cpu)
 {
+	struct intr_irqsrc *isrc = &sc->bls_isrcs[BCM_LINTC_PMU_IRQ].bli_isrc;
 
-	if (bcm_lint_init_on_ap(sc, &sc->bls_isrcs[BCM_LINTC_PMU_IRQ], cpu)) {
+	if (intr_isrc_init_on_cpu(isrc, cpu)) {
 		/* Write-set register. */
 		bcm_lintc_write_4(sc, BCM_LINTC_PMU_ROUTING_SET_REG,
 		    BCM_LINTC_PIRR_IRQ_EN_CORE(cpu));

Modified: head/sys/kern/subr_intr.c
==============================================================================
--- head/sys/kern/subr_intr.c	Thu Apr  7 14:25:15 2016	(r297673)
+++ head/sys/kern/subr_intr.c	Thu Apr  7 15:00:25 2016	(r297674)
@@ -467,6 +467,32 @@ intr_isrc_deregister(struct intr_irqsrc 
 	return (error);
 }
 
+#ifdef SMP
+/*
+ *  A support function for a PIC to decide if provided ISRC should be inited
+ *  on given cpu. The logic of INTR_ISRCF_BOUND flag and isrc_cpu member of
+ *  struct intr_irqsrc is the following:
+ *
+ *     If INTR_ISRCF_BOUND is set, the ISRC should be inited only on cpus
+ *     set in isrc_cpu. If not, the ISRC should be inited on every cpu and
+ *     isrc_cpu is kept consistent with it. Thus isrc_cpu is always correct.
+ */
+bool
+intr_isrc_init_on_cpu(struct intr_irqsrc *isrc, u_int cpu)
+{
+
+	if (isrc->isrc_handlers == 0)
+		return (false);
+	if ((isrc->isrc_flags & (INTR_ISRCF_PPI | INTR_ISRCF_IPI)) == 0)
+		return (false);
+	if (isrc->isrc_flags & INTR_ISRCF_BOUND)
+		return (CPU_ISSET(cpu, &isrc->isrc_cpu));
+
+	CPU_SET(cpu, &isrc->isrc_cpu);
+	return (true);
+}
+#endif
+
 static struct intr_dev_data *
 intr_ddata_alloc(u_int extsize)
 {

Modified: head/sys/sys/intr.h
==============================================================================
--- head/sys/sys/intr.h	Thu Apr  7 14:25:15 2016	(r297673)
+++ head/sys/sys/intr.h	Thu Apr  7 15:00:25 2016	(r297674)
@@ -98,6 +98,10 @@ int intr_isrc_deregister(struct intr_irq
 int intr_isrc_register(struct intr_irqsrc *, device_t, u_int, const char *, ...)
     __printflike(4, 5);
 
+#ifdef SMP
+bool intr_isrc_init_on_cpu(struct intr_irqsrc *isrc, u_int cpu);
+#endif
+
 int intr_isrc_dispatch(struct intr_irqsrc *, struct trapframe *);
 u_int intr_irq_next_cpu(u_int current_cpu, cpuset_t *cpumask);
 


More information about the svn-src-all mailing list