diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-10-19 07:54:24 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-10-19 07:55:09 -0700 |
commit | 4533d86270d7986e00594495dde9a109d6be27ae (patch) | |
tree | c2473cac653f7b98e5bd5e6475e63734be4b7644 /arch/arm/lib/delay.c | |
parent | 21c5e50e15b1abd797e62f18fd7f90b9cc004cbd (diff) | |
parent | 5bc66170dc486556a1e36fd384463536573f4b82 (diff) |
Merge commit '5bc66170dc486556a1e36fd384463536573f4b82' into x86/urgent
From Borislav Petkov <bp@amd64.org>:
Below is a RAS fix which reverts the addition of a sysfs attribute
which we agreed is not needed, post-factum. And this should go in now
because that sysfs attribute is going to end up in 3.7 otherwise and
thus exposed to userspace; removing it then would be a lot harder.
This is done as a merge rather than a simple patch/cherry-pick since
the baseline for this patch was not in the previous x86/urgent.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/arm/lib/delay.c')
-rw-r--r-- | arch/arm/lib/delay.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c index d6dacc69254..9d0a30032d7 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,17 +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; - 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 |