diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -104,6 +104,10 @@ struct resource *res; void *ihl; struct arm_tmr_softc *sc; + u_int flags; +#define TMR_IRQ_PHYS (1 << 0) +#define TMR_IRQ_ET (1 << 1) +#define TMR_IRQ_CHILD (1 << 2) }; struct arm_tmr_softc { @@ -360,17 +364,23 @@ struct arm_tmr_softc *sc; struct arm_tmr_irq *irq; int ctrl; + bool physical; irq = (struct arm_tmr_irq *)arg; - sc = irq->sc; - ctrl = get_ctrl(sc->physical); + + physical = (irq->flags & TMR_IRQ_PHYS) != 0; + + ctrl = get_ctrl(physical); if (ctrl & GT_CTRL_INT_STAT) { ctrl |= GT_CTRL_INT_MASK; - set_ctrl(ctrl, sc->physical); + set_ctrl(ctrl, physical); } - if (sc->et.et_active) - sc->et.et_event_cb(&sc->et, sc->et.et_arg); + if ((irq->flags & TMR_IRQ_ET) != 0) { + sc = irq->sc; + if (sc->et.et_active) + sc->et.et_event_cb(&sc->et, sc->et.et_arg); + } return (FILTER_HANDLED); } @@ -457,7 +467,7 @@ pcell_t clock; #endif int error; - int i, first_timer, last_timer; + int i; sc = device_get_softc(dev); if (arm_tmr_sc) @@ -505,21 +515,25 @@ /* Use the virtual timer if we have one. */ if (sc->irqs[GT_VIRT].res != NULL) { sc->physical = false; - first_timer = GT_VIRT; - last_timer = GT_VIRT; } else #endif /* Otherwise set up the secure and non-secure physical timers. */ { sc->physical = true; - first_timer = GT_PHYS_SECURE; - last_timer = GT_PHYS_NONSECURE; } arm_tmr_sc = sc; + sc->irqs[GT_PHYS_SECURE].flags |= TMR_IRQ_PHYS; + sc->irqs[GT_PHYS_NONSECURE].flags |= TMR_IRQ_PHYS; + + if (sc->physical) + sc->irqs[GT_PHYS_NONSECURE].flags |= TMR_IRQ_ET; + else + sc->irqs[GT_VIRT].flags |= TMR_IRQ_ET; + /* Setup secure, non-secure and virtual IRQs handler */ - for (i = first_timer; i <= last_timer; i++) { + for (i = 0; i < GT_IRQ_COUNT; i++) { /* If we do not have the interrupt, skip it. */ if (sc->irqs[i].res == NULL) continue;