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 <[email protected]>
---
 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

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to