delay.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. * delay.h - delay functions
  3. *
  4. * Copyright (c) 2004-2007 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #ifndef __ASM_DELAY_H__
  9. #define __ASM_DELAY_H__
  10. #include <mach/anomaly.h>
  11. static inline void __delay(unsigned long loops)
  12. {
  13. if (ANOMALY_05000312) {
  14. /* Interrupted loads to loop registers -> bad */
  15. unsigned long tmp;
  16. __asm__ __volatile__(
  17. "[--SP] = LC0;"
  18. "[--SP] = LT0;"
  19. "[--SP] = LB0;"
  20. "LSETUP (1f,1f) LC0 = %1;"
  21. "1: NOP;"
  22. /* We take advantage of the fact that LC0 is 0 at
  23. * the end of the loop. Otherwise we'd need some
  24. * NOPs after the CLI here.
  25. */
  26. "CLI %0;"
  27. "LB0 = [SP++];"
  28. "LT0 = [SP++];"
  29. "LC0 = [SP++];"
  30. "STI %0;"
  31. : "=d" (tmp)
  32. : "a" (loops)
  33. );
  34. } else
  35. __asm__ __volatile__ (
  36. "LSETUP(1f, 1f) LC0 = %0;"
  37. "1: NOP;"
  38. :
  39. : "a" (loops)
  40. : "LT0", "LB0", "LC0"
  41. );
  42. }
  43. #include <linux/param.h> /* needed for HZ */
  44. /*
  45. * Use only for very small delays ( < 1 msec). Should probably use a
  46. * lookup table, really, as the multiplications take much too long with
  47. * short delays. This is a "reasonable" implementation, though (and the
  48. * first constant multiplications gets optimized away if the delay is
  49. * a constant)
  50. */
  51. static inline void udelay(unsigned long usecs)
  52. {
  53. extern unsigned long loops_per_jiffy;
  54. __delay(usecs * loops_per_jiffy / (1000000 / HZ));
  55. }
  56. #endif