summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-01-10 12:03:35 +0400
committerMax Filippov <jcmvbkbc@gmail.com>2014-01-15 00:28:11 +0400
commit9ed82c6866e2ab671935a75ea454047e8bddb177 (patch)
tree821e8d51935476350c2c5ab308931c7efc00676e /arch
parent58f60c222e8d4503a4be654cbd6d4e190dc1a7d8 (diff)
downloadlinux-9ed82c6866e2ab671935a75ea454047e8bddb177.tar.gz
linux-9ed82c6866e2ab671935a75ea454047e8bddb177.tar.bz2
linux-9ed82c6866e2ab671935a75ea454047e8bddb177.zip
xtensa: implement ndelay
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/xtensa/include/asm/delay.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/xtensa/include/asm/delay.h b/arch/xtensa/include/asm/delay.h
index 69ba4629bed0..24304b39a5c7 100644
--- a/arch/xtensa/include/asm/delay.h
+++ b/arch/xtensa/include/asm/delay.h
@@ -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