home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-mips / delay.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  2.4 KB  |  96 lines

  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.  
  17. static 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.  
  51. static 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[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.