From: Yan Wang yan.wang@linux.intel.com
Before the 1st rollover, timer->hitimeout = 0, it will cause platform_timer_64_handler() set timeout = 1. So the time irq is forced to be fired at the beginning of rollover. And the timeout of platform_timer_set() will be invalid and work queue cannot be fired.
Just set the new hitimeout to timer->hitimeout. timer->hitime will be added in the next rollover. It is unnecessary to check timer->hitimout > 0.
Signed-off-by: Yan Wang yan.wang@linux.intel.com --- src/platform/baytrail/timer.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/src/platform/baytrail/timer.c b/src/platform/baytrail/timer.c index 9256dd9..3397ef0 100644 --- a/src/platform/baytrail/timer.c +++ b/src/platform/baytrail/timer.c @@ -66,7 +66,7 @@ static void platform_timer_64_handler(void *arg) }
/* get next timeout value */ - if (timer->hitimeout > 0 && timer->hitimeout == timer->hitime) { + if (timer->hitimeout == timer->hitime) { /* timeout is in this 32 bit period */ timeout = timer->lowtimeout; } else { @@ -108,17 +108,13 @@ int platform_timer_set(struct timer *timer, uint64_t ticks) flags = arch_interrupt_global_disable();
/* same hi 64 bit context as ticks ? */ - if (hitimeout == timer->hitime) { - /* yes, then set the value for next timeout */ - time = ticks; - timer->lowtimeout = 0; - timer->hitimeout = 0; - } else if (hitimeout < timer->hitime) { + if (hitimeout < timer->hitime) { /* cant be in the past */ arch_interrupt_global_enable(flags); return -EINVAL; } else { /* set for checking at next timeout */ + time = ticks; timer->hitimeout = hitimeout; timer->lowtimeout = ticks; }