diff options
author | Mike J. Chen <mjchen@google.com> | 2012-03-01 18:48:33 -0800 |
---|---|---|
committer | Mike J. Chen <mjchen@google.com> | 2012-03-03 17:29:38 -0800 |
commit | 4ae13cf1682ea5a56ef1a40123d539c3b2868962 (patch) | |
tree | c46008465414bd01c4316dd2b72c6cd20778429e | |
parent | b984d88ea4c4a45fe4f73525ca237c02f1b8d0c6 (diff) | |
download | uboot-4ae13cf1682ea5a56ef1a40123d539c3b2868962.tar.gz |
ARMV7: omap: Make udelay handle large values properly
The current implemention of __udelay() for omap didn't
check for overflow so large values would wrap and not
delay he time requested. Using similar logic to
lib/time.c, break down large requests into smaller ones.
Change-Id: I391e43a45068d4d3725d852f6b86ccec7e97b491
Signed-off-by: Mike J. Chen <mjchen@google.com>
-rw-r--r-- | arch/arm/cpu/armv7/omap-common/timer.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/arch/arm/cpu/armv7/omap-common/timer.c b/arch/arm/cpu/armv7/omap-common/timer.c index 843a71105..858327037 100644 --- a/arch/arm/cpu/armv7/omap-common/timer.c +++ b/arch/arm/cpu/armv7/omap-common/timer.c @@ -70,8 +70,9 @@ ulong get_timer(ulong base) return get_timer_masked() - base; } -/* delay x useconds */ -void __udelay(unsigned long usec) +/* delay x useconds. + */ +static void __udelay_internal(unsigned long usec) { long tmo = usec * (TIMER_CLOCK / 1000) / 1000; unsigned long now, last = readl(&timer_base->tcrr); @@ -86,6 +87,23 @@ void __udelay(unsigned long usec) } } +/* we're limited to 32-bit because SPL doesn't have 64-bit libraries + * so for large values, call again. modeled after time.c udelay(). */ + +#ifndef CONFIG_MAX_UDELAY +#define CONFIG_MAX_UDELAY 100000 +#endif + +void __udelay(unsigned long usec) +{ + ulong kv; + do { + kv = usec > CONFIG_MAX_UDELAY ? CONFIG_MAX_UDELAY : usec; + __udelay_internal(kv); + usec -= kv; + } while(usec); +} + ulong get_timer_masked(void) { /* current tick value */ |