time.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/include/asm-arm/arch-sa1100/time.h
  3.  *
  4.  * Copyright (C) 1998 Deborah Wallach.
  5.  * Twiddles  (C) 1999  Hugo Fiennes <hugo@empeg.com>
  6.  * 
  7.  * 2000/03/29 (C) Nicolas Pitre <nico@cam.org>
  8.  * Rewritten: big cleanup, much simpler, better HZ accuracy.
  9.  *
  10.  */
  11. #define RTC_DEF_DIVIDER (32768 - 1)
  12. #define RTC_DEF_TRIM            0
  13. static unsigned long __init sa1100_get_rtc_time(void)
  14. {
  15. /*
  16.  * According to the manual we should be able to let RTTR be zero
  17.  * and then a default diviser for a 32.768KHz clock is used.
  18.  * Apparently this doesn't work, at least for my SA1110 rev 5.
  19.  * If the clock divider is uninitialized then reset it to the
  20.  * default value to get the 1Hz clock.
  21.  */
  22. if (RTTR == 0) {
  23. RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
  24. printk(KERN_WARNING "Warning: uninitialized Real Time Clockn");
  25. /* The current RTC value probably doesn't make sense either */
  26. RCNR = 0;
  27. return 0;
  28. }
  29. return RCNR;
  30. }
  31. static int sa1100_set_rtc(void)
  32. {
  33. unsigned long current_time = xtime.tv_sec;
  34. if (RTSR & RTSR_ALE) {
  35. /* make sure not to forward the clock over an alarm */
  36. unsigned long alarm = RTAR;
  37. if (current_time >= alarm && alarm >= RCNR)
  38. return -ERESTARTSYS;
  39. }
  40. RCNR = current_time;
  41. return 0;
  42. }
  43. /* IRQs are disabled before entering here from do_gettimeofday() */
  44. static unsigned long sa1100_gettimeoffset (void)
  45. {
  46. unsigned long ticks_to_match, elapsed, usec;
  47. /* Get ticks before next timer match */
  48. ticks_to_match = OSMR0 - OSCR;
  49. /* We need elapsed ticks since last match */
  50. elapsed = LATCH - ticks_to_match;
  51. /* Now convert them to usec */
  52. usec = (unsigned long)(elapsed*tick)/LATCH;
  53. return usec;
  54. }
  55. static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  56. {
  57. long flags;
  58. int next_match;
  59. /* Loop until we get ahead of the free running timer.
  60.  * This ensures an exact clock tick count and time acuracy.
  61.  * IRQs are disabled inside the loop to ensure coherence between
  62.  * lost_ticks (updated in do_timer()) and the match reg value, so we
  63.  * can use do_gettimeofday() from interrupt handlers.
  64.  */
  65. do {
  66. do_leds();
  67. do_set_rtc();
  68. save_flags_cli( flags );
  69. do_timer(regs);
  70. OSSR = OSSR_M0;  /* Clear match on timer 0 */
  71. next_match = (OSMR0 += LATCH);
  72. restore_flags( flags );
  73. } while( (signed long)(next_match - OSCR) <= 0 );
  74. do_profile(regs);
  75. }
  76. static inline void setup_timer (void)
  77. {
  78. gettimeoffset = sa1100_gettimeoffset;
  79. set_rtc = sa1100_set_rtc;
  80. xtime.tv_sec = sa1100_get_rtc_time();
  81. timer_irq.handler = sa1100_timer_interrupt;
  82. OSMR0 = 0; /* set initial match at 0 */
  83. OSSR = 0xf; /* clear status on all timers */
  84. setup_arm_irq(IRQ_OST0, &timer_irq);
  85. OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
  86. OSCR = 0; /* initialize free-running timer, force first match */
  87. }