From a0ae26518307fa1a02d94565f9866f6921efde68 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 19 Oct 2004 18:44:21 +0100 Subject: [PATCH] [ARM] Convert to constant-optimising udelay() implementation. This allows us to eliminate a multiplication when we have a constant delay value, as per x86. --- arch/arm/kernel/armksyms.c | 3 ++- arch/arm/lib/delay.S | 13 +++++++------ include/asm-arm/delay.h | 30 ++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index ae9203853a77d..1d0fcf411ec99 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -60,7 +60,8 @@ EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig); EXPORT_SYMBOL(__backtrace); /* platform dependent support */ -EXPORT_SYMBOL(udelay); +EXPORT_SYMBOL(__udelay); +EXPORT_SYMBOL(__const_udelay); /* networking */ EXPORT_SYMBOL(csum_partial); diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S index 67cbd8697bb76..3c7f7e675dd8c 100644 --- a/arch/arm/lib/delay.S +++ b/arch/arm/lib/delay.S @@ -16,15 +16,16 @@ LC0: .word loops_per_jiffy /* * 0 <= r0 <= 2000 */ -ENTRY(udelay) +ENTRY(__udelay) mov r2, #0x6800 orr r2, r2, #0x00db - mul r1, r0, r2 + mul r0, r2, r0 +ENTRY(__const_udelay) @ 0 <= r0 <= 0x01ffffff ldr r2, LC0 - ldr r2, [r2] - mov r1, r1, lsr #11 - mov r2, r2, lsr #11 - mul r0, r1, r2 + ldr r2, [r2] @ max = 0x0fffffff + mov r0, r0, lsr #11 @ max = 0x00003fff + mov r2, r2, lsr #11 @ max = 0x0003ffff + mul r0, r2, r0 @ max = 2^32-1 movs r0, r0, lsr #6 RETINSTR(moveq,pc,lr) diff --git a/include/asm-arm/delay.h b/include/asm-arm/delay.h index 4ebcea03406de..1704360e96996 100644 --- a/include/asm-arm/delay.h +++ b/include/asm-arm/delay.h @@ -1,14 +1,22 @@ -#ifndef __ASM_ARM_DELAY_H -#define __ASM_ARM_DELAY_H - /* - * Copyright (C) 1995 Russell King + * Copyright (C) 1995-2004 Russell King * * Delay routines, using a pre-computed "loops_per_second" value. */ +#ifndef __ASM_ARM_DELAY_H +#define __ASM_ARM_DELAY_H extern void __delay(int loops); +/* + * This function intentionally does not exist; if you see references to + * it, it means that you're calling udelay() with an out of range value. + * + * With currently imposed limits, this means that we support a max delay + * of 2000us and 671 bogomips + */ +extern void __bad_udelay(void); + /* * division by multiplication: you don't have to worry about * loss of precision. @@ -19,14 +27,16 @@ extern void __delay(int loops); * first constant multiplications gets optimized away if the delay is * a constant) */ -extern void udelay(unsigned long usecs); +extern void __udelay(unsigned long usecs); +extern void __const_udelay(unsigned long); -static inline unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c) -{ - return a * b / c; -} +#define MAX_UDELAY_MS 2 - +#define udelay(n) \ + (__builtin_constant_p(n) ? \ + ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \ + __const_udelay((n) * 0x68dbul)) : \ + __udelay(n)) #endif /* defined(_ARM_DELAY_H) */ -- 2.53.0