Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 1994 by Waldorf Electronics
0007  * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle
0008  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
0009  * Copyright (C) 2007, 2014 Maciej W. Rozycki
0010  */
0011 #include <linux/delay.h>
0012 #include <linux/export.h>
0013 #include <linux/param.h>
0014 #include <linux/smp.h>
0015 #include <linux/stringify.h>
0016 
0017 #include <asm/asm.h>
0018 #include <asm/compiler.h>
0019 
0020 #ifndef CONFIG_CPU_DADDI_WORKAROUNDS
0021 #define GCC_DADDI_IMM_ASM() "I"
0022 #else
0023 #define GCC_DADDI_IMM_ASM() "r"
0024 #endif
0025 
0026 #ifndef CONFIG_HAVE_PLAT_DELAY
0027 
0028 void __delay(unsigned long loops)
0029 {
0030     __asm__ __volatile__ (
0031     "   .set    noreorder               \n"
0032     "   .align  3                   \n"
0033     "1: bnez    %0, 1b                  \n"
0034     "    " __stringify(LONG_SUBU) " %0, %1      \n"
0035     "   .set    reorder                 \n"
0036     : "=r" (loops)
0037     : GCC_DADDI_IMM_ASM() (1), "0" (loops));
0038 }
0039 EXPORT_SYMBOL(__delay);
0040 
0041 /*
0042  * Division by multiplication: you don't have to worry about
0043  * loss of precision.
0044  *
0045  * Use only for very small delays ( < 1 msec).  Should probably use a
0046  * lookup table, really, as the multiplications take much too long with
0047  * short delays.  This is a "reasonable" implementation, though (and the
0048  * first constant multiplications gets optimized away if the delay is
0049  * a constant)
0050  */
0051 
0052 void __udelay(unsigned long us)
0053 {
0054     unsigned int lpj = raw_current_cpu_data.udelay_val;
0055 
0056     __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
0057 }
0058 EXPORT_SYMBOL(__udelay);
0059 
0060 void __ndelay(unsigned long ns)
0061 {
0062     unsigned int lpj = raw_current_cpu_data.udelay_val;
0063 
0064     __delay((ns * 0x00000005ull * HZ * lpj) >> 32);
0065 }
0066 EXPORT_SYMBOL(__ndelay);
0067 
0068 #endif