Due to the removal of the 'h' asm constraint in GCC-4.4, we need to
adjust the computation in delay.h
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
Tested on 64-bit kernel (Cavium Octeon).
arch/mips/include/asm/compiler.h | 7 +++++++
arch/mips/include/asm/delay.h | 10 +++++++++-
2 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h
index 71f5c5c..1f0954d 100644
--- a/arch/mips/include/asm/compiler.h
+++ b/arch/mips/include/asm/compiler.h
@@ -16,4 +16,11 @@
#define GCC_REG_ACCUM "accum"
#endif
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+#define GCC_NO_H_CONSTRAINT
+#ifdef CONFIG_64BIT
+typedef unsigned int uint128_t __attribute__((mode(TI)));
+#endif
+#endif
+
#endif /* _ASM_COMPILER_H */
diff --git a/arch/mips/include/asm/delay.h b/arch/mips/include/asm/delay.h
index b0bccd2..9be0ba7 100644
--- a/arch/mips/include/asm/delay.h
+++ b/arch/mips/include/asm/delay.h
@@ -62,8 +62,9 @@ static inline void __delay(unsigned long loops)
static inline void __udelay(unsigned long usecs, unsigned long lpj)
{
+#ifndef GCC_NO_H_CONSTRAINT
unsigned long hi, lo;
-
+#endif
/*
* The rates of 128 is rounded wrongly by the catchall case
* for 64-bit. Excessive precission? Probably ...
@@ -77,6 +78,12 @@ static inline void __udelay(unsigned long usecs, unsigned
long lpj)
0x80000000ULL) >> 32);
#endif
+#ifdef GCC_NO_H_CONSTRAINT
+ if (sizeof(long) == 4)
+ usecs = ((u64)usecs * lpj) >> 32;
+ else
+ usecs = ((uint128_t)usecs * lpj) >> 64;
+#else
if (sizeof(long) == 4)
__asm__("multu\t%2, %3"
: "=h" (usecs), "=l" (lo)
@@ -92,6 +99,7 @@ static inline void __udelay(unsigned long usecs, unsigned
long lpj)
: "=r" (usecs), "=h" (hi), "=l" (lo)
: "r" (usecs), "r" (lpj)
: GCC_REG_ACCUM);
+#endif
__delay(usecs);
}
--
1.5.6.6
|