diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-10-05 02:02:26 +0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-10-05 02:02:26 +0400 |
commit | ceaa1a13c0e53242555fa45887d82339a3f93c78 (patch) | |
tree | 665bebcd325c68a1424a49baf9be52512b2d8aa1 /arch/arm/lib | |
parent | ba4a63f89c8f8a014450e45fd96a06a5e078e52f (diff) | |
parent | 56942fec06efa0e17df0f4c3b438332c923b9014 (diff) | |
download | linux-ceaa1a13c0e53242555fa45887d82339a3f93c78.tar.xz |
Merge branch 'arch-timers' into for-linus
Conflicts:
arch/arm/include/asm/timex.h
arch/arm/lib/delay.c
Diffstat (limited to 'arch/arm/lib')
-rw-r--r-- | arch/arm/lib/delay.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c index 395d5fbb8fa2..9d0a30032d7f 100644 --- a/arch/arm/lib/delay.c +++ b/arch/arm/lib/delay.c @@ -34,7 +34,18 @@ struct arm_delay_ops arm_delay_ops = { .udelay = __loop_udelay, }; -#ifdef ARCH_HAS_READ_CURRENT_TIMER +static const struct delay_timer *delay_timer; +static bool delay_calibrated; + +int read_current_timer(unsigned long *timer_val) +{ + if (!delay_timer) + return -ENXIO; + + *timer_val = delay_timer->read_current_timer(); + return 0; +} + static void __timer_delay(unsigned long cycles) { cycles_t start = get_cycles(); @@ -55,18 +66,24 @@ static void __timer_udelay(unsigned long usecs) __timer_const_udelay(usecs * UDELAY_MULT); } -void __init init_current_timer_delay(unsigned long freq) +void __init register_current_timer_delay(const struct delay_timer *timer) { - pr_info("Switching to timer-based delay loop\n"); - lpj_fine = freq / HZ; - loops_per_jiffy = lpj_fine; - arm_delay_ops.delay = __timer_delay; - arm_delay_ops.const_udelay = __timer_const_udelay; - arm_delay_ops.udelay = __timer_udelay; + if (!delay_calibrated) { + pr_info("Switching to timer-based delay loop\n"); + delay_timer = timer; + lpj_fine = timer->freq / HZ; + loops_per_jiffy = lpj_fine; + arm_delay_ops.delay = __timer_delay; + arm_delay_ops.const_udelay = __timer_const_udelay; + arm_delay_ops.udelay = __timer_udelay; + delay_calibrated = true; + } else { + pr_info("Ignoring duplicate/late registration of read_current_timer delay\n"); + } } unsigned long __cpuinit calibrate_delay_is_known(void) { + delay_calibrated = true; return lpj_fine; } -#endif |