diff options
Diffstat (limited to 'arch/mips/lib/delay.c')
| -rw-r--r-- | arch/mips/lib/delay.c | 18 | 
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 5995969e8c4..21d27c6819a 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -6,25 +6,33 @@   * Copyright (C) 1994 by Waldorf Electronics   * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle   * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - * Copyright (C) 2007  Maciej W. Rozycki + * Copyright (C) 2007, 2014 Maciej W. Rozycki   */  #include <linux/module.h>  #include <linux/param.h>  #include <linux/smp.h> +#include <linux/stringify.h> +#include <asm/asm.h>  #include <asm/compiler.h>  #include <asm/war.h> -inline void __delay(unsigned int loops) +#ifndef CONFIG_CPU_DADDI_WORKAROUNDS +#define GCC_DADDI_IMM_ASM() "I" +#else +#define GCC_DADDI_IMM_ASM() "r" +#endif + +void __delay(unsigned long loops)  {  	__asm__ __volatile__ (  	"	.set	noreorder				\n"  	"	.align	3					\n"  	"1:	bnez	%0, 1b					\n" -	"	subu	%0, 1					\n" +	"	 " __stringify(LONG_SUBU) "	%0, %1		\n"  	"	.set	reorder					\n"  	: "=r" (loops) -	: "0" (loops)); +	: GCC_DADDI_IMM_ASM() (1), "0" (loops));  }  EXPORT_SYMBOL(__delay); @@ -32,7 +40,7 @@ EXPORT_SYMBOL(__delay);   * Division by multiplication: you don't have to worry about   * loss of precision.   * - * Use only for very small delays ( < 1 msec).  Should probably use a + * Use only for very small delays ( < 1 msec).	Should probably use a   * lookup table, really, as the multiplications take much too long with   * short delays.  This is a "reasonable" implementation, though (and the   * first constant multiplications gets optimized away if the delay is  | 
