aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike J. Chen <mjchen@google.com>2012-03-01 18:48:33 -0800
committerMike J. Chen <mjchen@google.com>2012-03-03 17:29:38 -0800
commit4ae13cf1682ea5a56ef1a40123d539c3b2868962 (patch)
treec46008465414bd01c4316dd2b72c6cd20778429e
parentb984d88ea4c4a45fe4f73525ca237c02f1b8d0c6 (diff)
downloaduboot-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.c22
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 */