Let's bail out of the wait loop if we see the expected state to save about seven seconds of run time. Make sure we wait a bit before reading the registers, though, to somewhat mitigate the chance of the expected state being stale. Signed-off-by: Andrew Jones <drjones@xxxxxxxxxx> --- arm/timer.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/arm/timer.c b/arm/timer.c index f5cf775ce50f..c2262c112c09 100644 --- a/arm/timer.c +++ b/arm/timer.c @@ -183,7 +183,8 @@ static bool timer_pending(struct timer_info *info) (info->read_ctl() & ARCH_TIMER_CTL_ISTATUS); } -static enum gic_state gic_timer_state(struct timer_info *info) +static bool gic_timer_check_state(struct timer_info *info, + enum gic_state expected_state) { enum gic_state state = GIC_STATE_INACTIVE; int i; @@ -191,6 +192,7 @@ static enum gic_state gic_timer_state(struct timer_info *info) /* Wait for up to 1s for the GIC to sample the interrupt. */ for (i = 0; i < 10; i++) { + mdelay(100); pending = readl(gic_ispendr) & (1 << PPI(info->irq)); active = readl(gic_isactiver) & (1 << PPI(info->irq)); if (!active && !pending) @@ -201,10 +203,11 @@ static enum gic_state gic_timer_state(struct timer_info *info) state = GIC_STATE_ACTIVE; if (active && pending) state = GIC_STATE_ACTIVE_PENDING; - mdelay(100); + if (state == expected_state) + return true; } - return state; + return false; } static bool test_cval_10msec(struct timer_info *info) @@ -253,11 +256,11 @@ static void test_timer(struct timer_info *info) /* Enable the timer, but schedule it for much later */ info->write_cval(later); info->write_ctl(ARCH_TIMER_CTL_ENABLE); - report(!timer_pending(info) && gic_timer_state(info) == GIC_STATE_INACTIVE, + report(!timer_pending(info) && gic_timer_check_state(info, GIC_STATE_INACTIVE), "not pending before"); info->write_cval(now - 1); - report(timer_pending(info) && gic_timer_state(info) == GIC_STATE_PENDING, + report(timer_pending(info) && gic_timer_check_state(info, GIC_STATE_PENDING), "interrupt signal pending"); /* Disable the timer again and prepare to take interrupts */ @@ -265,12 +268,12 @@ static void test_timer(struct timer_info *info) info->irq_received = false; set_timer_irq_enabled(info, true); report(!info->irq_received, "no interrupt when timer is disabled"); - report(!timer_pending(info) && gic_timer_state(info) == GIC_STATE_INACTIVE, + report(!timer_pending(info) && gic_timer_check_state(info, GIC_STATE_INACTIVE), "interrupt signal no longer pending"); info->write_cval(now - 1); info->write_ctl(ARCH_TIMER_CTL_ENABLE | ARCH_TIMER_CTL_IMASK); - report(timer_pending(info) && gic_timer_state(info) == GIC_STATE_INACTIVE, + report(timer_pending(info) && gic_timer_check_state(info, GIC_STATE_INACTIVE), "interrupt signal not pending"); report(test_cval_10msec(info), "latency within 10 ms"); -- 2.21.1