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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * time.c: Baget/MIPS specific time handling details
  3.  *
  4.  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
  5.  */
  6. #include <linux/errno.h>
  7. #include <linux/init.h>
  8. #include <linux/sched.h>
  9. #include <linux/kernel.h>
  10. #include <linux/param.h>
  11. #include <linux/string.h>
  12. #include <linux/mm.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/timex.h>
  15. #include <linux/spinlock.h>
  16. #include <asm/bootinfo.h>
  17. #include <asm/io.h>
  18. #include <asm/irq.h>
  19. #include <asm/ptrace.h>
  20. #include <asm/system.h>  
  21. #include <asm/baget/baget.h>
  22. extern rwlock_t xtime_lock;
  23. /* 
  24.  *  To have precision clock, we need to fix available clock frequency
  25.  */
  26. #define FREQ_NOM  79125  /* Baget frequency ratio */
  27. #define FREQ_DEN  10000
  28. static inline int timer_intr_valid(void) 
  29. {
  30. static unsigned long long ticks, valid_ticks;
  31. if (ticks++ * FREQ_DEN >= valid_ticks * FREQ_NOM) {
  32. /* 
  33.  *  We need no overflow checks, 
  34.  *  due baget unable to work 3000 years...
  35.  *  At least without reboot...
  36.  */
  37. valid_ticks++;
  38. return 1;
  39. }
  40. return 0;
  41. }
  42. void static timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
  43. {
  44. if (timer_intr_valid()) {
  45. sti();
  46. do_timer(regs);
  47. }
  48. }
  49. static void __init timer_enable(void)
  50. {
  51. unsigned char ss0cr0 = vic_inb(VIC_SS0CR0);
  52. ss0cr0 &= ~VIC_SS0CR0_TIMER_FREQ_MASK;
  53. ss0cr0 |= VIC_SS0CR0_TIMER_FREQ_1000HZ;
  54. vic_outb(ss0cr0, VIC_SS0CR0);
  55. vic_outb(VIC_INT_IPL(6)|VIC_INT_NOAUTO|VIC_INT_EDGE|
  56.  VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); 
  57. }
  58. static struct irqaction timer_irq  = 
  59. { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
  60. void __init time_init(void)
  61. {
  62. if (setup_baget_irq(BAGET_VIC_TIMER_IRQ, &timer_irq) < 0)
  63. printk("time_init: unable request irq for system timern");
  64. timer_enable();
  65. /* We don't call sti() here, because it is too early for baget */
  66. }
  67. void do_gettimeofday(struct timeval *tv)
  68. {
  69. unsigned long flags;
  70. read_lock_irqsave (&xtime_lock, flags);
  71. *tv = xtime;
  72. read_unlock_irqrestore (&xtime_lock, flags);
  73. }
  74. void do_settimeofday(struct timeval *tv)
  75. {
  76. write_lock_irq (&xtime_lock);
  77. xtime = *tv;
  78. time_adjust = 0; /* stop active adjtime() */
  79. time_status |= STA_UNSYNC;
  80. time_maxerror = NTP_PHASE_LIMIT;
  81. time_esterror = NTP_PHASE_LIMIT;
  82. write_unlock_irq (&xtime_lock);
  83. }