delay.c 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /*
  2. * Precise Delay Loops for SuperH
  3. *
  4. * Copyright (C) 1999 Niibe Yutaka & Kaz Kojima
  5. */
  6. #include <linux/sched.h>
  7. #include <linux/delay.h>
  8. void __delay(unsigned long loops)
  9. {
  10. __asm__ __volatile__(
  11. /*
  12. * ST40-300 appears to have an issue with this code,
  13. * normally taking two cycles each loop, as with all
  14. * other SH variants. If however the branch and the
  15. * delay slot straddle an 8 byte boundary, this increases
  16. * to 3 cycles.
  17. * This align directive ensures this doesn't occur.
  18. */
  19. ".balign 8\n\t"
  20. "tst %0, %0\n\t"
  21. "1:\t"
  22. "bf/s 1b\n\t"
  23. " dt %0"
  24. : "=r" (loops)
  25. : "0" (loops)
  26. : "t");
  27. }
  28. inline void __const_udelay(unsigned long xloops)
  29. {
  30. xloops *= 4;
  31. __asm__("dmulu.l %0, %2\n\t"
  32. "sts mach, %0"
  33. : "=r" (xloops)
  34. : "0" (xloops),
  35. "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))
  36. : "macl", "mach");
  37. __delay(++xloops);
  38. }
  39. void __udelay(unsigned long usecs)
  40. {
  41. __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
  42. }
  43. void __ndelay(unsigned long nsecs)
  44. {
  45. __const_udelay(nsecs * 0x00000005);
  46. }