1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1994 by Waldorf Electronics 7 * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 9 */ 10#ifndef _ASM_DELAY_H 11#define _ASM_DELAY_H 12 13#include <linux/param.h> 14#include <linux/smp.h> 15#include <asm/compiler.h> 16 17static inline void __delay(unsigned long loops) 18{ 19 if (sizeof(long) == 4) 20 __asm__ __volatile__ ( 21 " .set noreorder \n" 22 " .align 3 \n" 23 "1: bnez %0, 1b \n" 24 " subu %0, 1 \n" 25 " .set reorder \n" 26 : "=r" (loops) 27 : "0" (loops)); 28 else if (sizeof(long) == 8) 29 __asm__ __volatile__ ( 30 " .set noreorder \n" 31 " .align 3 \n" 32 "1: bnez %0, 1b \n" 33 " dsubu %0, 1 \n" 34 " .set reorder \n" 35 : "=r" (loops) 36 : "0" (loops)); 37} 38 39 40/* 41 * Division by multiplication: you don't have to worry about 42 * loss of precision. 43 * 44 * Use only for very small delays ( < 1 msec). Should probably use a 45 * lookup table, really, as the multiplications take much too long with 46 * short delays. This is a "reasonable" implementation, though (and the 47 * first constant multiplications gets optimized away if the delay is 48 * a constant) 49 */ 50 51static inline void __udelay(unsigned long usecs, unsigned long lpj) 52{ 53 unsigned long lo; 54 55 /* 56 * The rates of 128 is rounded wrongly by the catchall case 57 * for 64-bit. Excessive precission? Probably ... 58 */ 59#if defined(CONFIG_64BIT) && (HZ == 128) 60 usecs *= 0x0008637bd05af6c7UL; /* 2**64 / (1000000 / HZ) */ 61#elif defined(CONFIG_64BIT) 62 usecs *= (0x8000000000000000UL / (500000 / HZ)); 63#else /* 32-bit junk follows here */ 64 usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + 65 0x80000000ULL) >> 32); 66#endif 67 68 if (sizeof(long) == 4) 69 __asm__("multu\t%2, %3" 70 : "=h" (usecs), "=l" (lo) 71 : "r" (usecs), "r" (lpj) 72 : GCC_REG_ACCUM); 73 else if (sizeof(long) == 8) 74 __asm__("dmultu\t%2, %3" 75 : "=h" (usecs), "=l" (lo) 76 : "r" (usecs), "r" (lpj) 77 : GCC_REG_ACCUM); 78 79 __delay(usecs); 80} 81 82#define __udelay_val cpu_data[raw_smp_processor_id()].udelay_val 83 84#define udelay(usecs) __udelay((usecs),__udelay_val) 85 86/* make sure "usecs *= ..." in udelay do not overflow. */ 87#if HZ >= 1000 88#define MAX_UDELAY_MS 1 89#elif HZ <= 200 90#define MAX_UDELAY_MS 5 91#else 92#define MAX_UDELAY_MS (1000 / HZ) 93#endif 94 95#endif /* _ASM_DELAY_H */ 96