ARM: ensure delay timer has sufficient accuracy for delays
authorRussell King <rmk+kernel@arm.linux.org.uk>
Mon, 13 Apr 2015 09:36:04 +0000 (10:36 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 14 Apr 2015 21:28:07 +0000 (22:28 +0100)
We have recently had an example of someone wanting to use a 90kHz timer
for the software delay loop.

udelay() needs to have at least microsecond resolution to allow drivers
access to a delay mechanism with a reasonable chance of delaying the
period they requested within at least a 50% marging of error, especially
for small delays.

Discussion about the udelay() accuracy can be found at:
https://lkml.org/lkml/2011/1/9/37

Reject timers which are unable to supply this level of resolution.

Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/lib/delay.c

index 312d43eb686a0254543258efdc3185c340bde82c..8044591dca729b74f805094e1f5a39f8deb153f8 100644 (file)
@@ -83,6 +83,12 @@ void __init register_current_timer_delay(const struct delay_timer *timer)
                               NSEC_PER_SEC, 3600);
        res = cyc_to_ns(1ULL, new_mult, new_shift);
 
+       if (res > 1000) {
+               pr_err("Ignoring delay timer %ps, which has insufficient resolution of %lluns\n",
+                       timer, res);
+               return;
+       }
+
        if (!delay_calibrated && (!delay_res || (res < delay_res))) {
                pr_info("Switching to timer-based delay loop, resolution %lluns\n", res);
                delay_timer                     = timer;