summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/xtensa/include/asm/delay.h21
1 files changed, 15 insertions, 6 deletions
diff --git a/arch/xtensa/include/asm/delay.h b/arch/xtensa/include/asm/delay.h
index 742b89f3ca2c..69ba4629bed0 100644
--- a/arch/xtensa/include/asm/delay.h
+++ b/arch/xtensa/include/asm/delay.h
@@ -27,18 +27,27 @@ static inline void __delay(unsigned long loops)
: "+r" (loops));
}
-/* For SMP/NUMA systems, change boot_cpu_data to something like
- * local_cpu_data->... where local_cpu_data points to the current
- * cpu. */
+/* Undefined function to get compile-time error */
+void __bad_udelay(void);
-static __inline__ void udelay (unsigned long usecs)
+#define __MAX_UDELAY 30000
+
+static inline void __udelay(unsigned long usecs)
{
unsigned long start = get_ccount();
- unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ));
+ unsigned long cycles = (usecs * (ccount_freq >> 15)) >> 5;
/* Note: all variables are unsigned (can wrap around)! */
while (((unsigned long)get_ccount()) - start < cycles)
- ;
+ cpu_relax();
+}
+
+static inline void udelay(unsigned long usec)
+{
+ if (__builtin_constant_p(usec) && usec >= __MAX_UDELAY)
+ __bad_udelay();
+ else
+ __udelay(usec);
}
#endif