xtensa: implement ndelay
authorMax Filippov <jcmvbkbc@gmail.com>
Fri, 10 Jan 2014 08:03:35 +0000 (12:03 +0400)
committerMax Filippov <jcmvbkbc@gmail.com>
Tue, 14 Jan 2014 20:28:11 +0000 (00:28 +0400)
Proper ndelay implementation allows for faster IO rate with drivers that
use ndelay to access their device registers, as otherwise ndelay is
emulated with udelay.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
arch/xtensa/include/asm/delay.h

index 69ba462..24304b3 100644 (file)
@@ -29,8 +29,10 @@ static inline void __delay(unsigned long loops)
 
 /* Undefined function to get compile-time error */
 void __bad_udelay(void);
+void __bad_ndelay(void);
 
 #define __MAX_UDELAY 30000
+#define __MAX_NDELAY 30000
 
 static inline void __udelay(unsigned long usecs)
 {
@@ -50,4 +52,24 @@ static inline void udelay(unsigned long usec)
                __udelay(usec);
 }
 
+static inline void __ndelay(unsigned long nsec)
+{
+       /*
+        * Inner shift makes sure multiplication doesn't overflow
+        * for legitimate nsec values
+        */
+       unsigned long cycles = (nsec * (ccount_freq >> 15)) >> 15;
+       __delay(cycles);
+}
+
+#define ndelay(n) ndelay(n)
+
+static inline void ndelay(unsigned long nsec)
+{
+       if (__builtin_constant_p(nsec) && nsec >= __MAX_NDELAY)
+               __bad_ndelay();
+       else
+               __ndelay(nsec);
+}
+
 #endif