If the host decrements the counter register that results in a negative
delta. This is then passed to muldiv64 which only handles unsigned
numbers resulting in bogus results.
This fix ensures the delta being operated on is positive.
Test case: kexec a kernel using aspeed_timer and it will freeze on the
second bootup when the kernel initializes the timer. With this patch
that no longer happens and the timer appears to run OK.
Signed-off-by: Christian Svensson <[email protected]>
Signed-off-by: Cédric Le Goater <[email protected]>
Reviewed-by: Joel Stanley <[email protected]>
Reviewed-by: Andrew Jeffery <[email protected]>
Message-id:
20190618165311[email protected]
Signed-off-by: Peter Maydell <[email protected]>
int64_t delta = (int64_t) value - (int64_t) calculate_ticks(t, now);
uint32_t rate = calculate_rate(t);
- t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
+ if (delta >= 0) {
+ t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
+ } else {
+ t->start -= muldiv64(-delta, NANOSECONDS_PER_SECOND, rate);
+ }
aspeed_timer_mod(t);
}
break;