static int apb_intr(void *arg) { struct apb_softc *sc = arg; struct intr_event *event; uint32_t reg, irq; reg = ATH_READ_REG(AR71XX_MISC_INTR_STATUS); for (irq = 0; irq < APB_NIRQS; irq++) { if (reg & (1 << irq)) { switch (ar71xx_soc) { case AR71XX_SOC_AR7240: case AR71XX_SOC_AR7241: case AR71XX_SOC_AR7242: /* Ack/clear the irq on status register for AR724x */ ATH_WRITE_REG(AR71XX_MISC_INTR_STATUS, reg & ~(1 << irq)); break; default: /* fallthrough */ break; } event = sc->sc_eventstab[irq]; if (!event || TAILQ_EMPTY(&event->ie_handlers)) { /* Ignore timer interrupts */ if (irq != 0) printf("Stray APB IRQ %d\n", irq); continue; } /* TODO: frame instead of NULL? */ intr_event_handle(event, NULL); mips_intrcnt_inc(sc->sc_intr_counter[irq]); } } return (FILTER_HANDLED); }
static int obio_intr(void *arg) { struct obio_softc *sc = arg; struct intr_event *event; uint32_t irqstat, ipend, imask, xpend; int irq, thread, group, i; irqstat = 0; irq = 0; for (group = 2; group <= 6; group++) { ipend = ICU_REG_READ(ICU_GROUP_IPEND_REG(group)); imask = ICU_REG_READ(ICU_GROUP_MASK_REG(group)); xpend = ipend; ipend &= ~imask; while ((i = fls(xpend)) != 0) { xpend &= ~(1 << (i - 1)); irq = IP_IRQ(group, i - 1); } while ((i = fls(ipend)) != 0) { ipend &= ~(1 << (i - 1)); irq = IP_IRQ(group, i - 1); event = sc->sc_eventstab[irq]; thread = 0; if (!event || TAILQ_EMPTY(&event->ie_handlers)) { /* TODO: Log stray IRQs */ continue; } /* TODO: frame instead of NULL? */ intr_event_handle(event, NULL); /* XXX: Log stray IRQs */ } } #if 0 ipend = ICU_REG_READ(ICU_IPEND2); printf("ipend2 = %08x!\n", ipend); ipend = ICU_REG_READ(ICU_IPEND3); printf("ipend3 = %08x!\n", ipend); ipend = ICU_REG_READ(ICU_IPEND4); printf("ipend4 = %08x!\n", ipend); ipend = ICU_REG_READ(ICU_IPEND5); printf("ipend5 = %08x!\n", ipend); ipend = ICU_REG_READ(ICU_IPEND6); printf("ipend6 = %08x!\n", ipend); #endif while (irqstat != 0) { if ((irqstat & 1) == 1) { } irq++; irqstat >>= 1; } return (FILTER_HANDLED); }