time.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  3. * Licensed under the GPL
  4. */
  5. #include <linux/clockchips.h>
  6. #include <linux/init.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/jiffies.h>
  9. #include <linux/threads.h>
  10. #include <asm/irq.h>
  11. #include <asm/param.h>
  12. #include <kern_util.h>
  13. #include <os.h>
  14. void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
  15. {
  16. unsigned long flags;
  17. local_irq_save(flags);
  18. do_IRQ(TIMER_IRQ, regs);
  19. local_irq_restore(flags);
  20. }
  21. static int itimer_shutdown(struct clock_event_device *evt)
  22. {
  23. disable_timer();
  24. return 0;
  25. }
  26. static int itimer_set_periodic(struct clock_event_device *evt)
  27. {
  28. set_interval();
  29. return 0;
  30. }
  31. static int itimer_next_event(unsigned long delta,
  32. struct clock_event_device *evt)
  33. {
  34. return timer_one_shot(delta + 1);
  35. }
  36. static struct clock_event_device itimer_clockevent = {
  37. .name = "itimer",
  38. .rating = 250,
  39. .cpumask = cpu_all_mask,
  40. .features = CLOCK_EVT_FEAT_PERIODIC |
  41. CLOCK_EVT_FEAT_ONESHOT,
  42. .set_state_shutdown = itimer_shutdown,
  43. .set_state_periodic = itimer_set_periodic,
  44. .set_state_oneshot = itimer_shutdown,
  45. .set_next_event = itimer_next_event,
  46. .shift = 32,
  47. .irq = 0,
  48. };
  49. static irqreturn_t um_timer(int irq, void *dev)
  50. {
  51. (*itimer_clockevent.event_handler)(&itimer_clockevent);
  52. return IRQ_HANDLED;
  53. }
  54. static cycle_t itimer_read(struct clocksource *cs)
  55. {
  56. return os_nsecs() / 1000;
  57. }
  58. static struct clocksource itimer_clocksource = {
  59. .name = "itimer",
  60. .rating = 300,
  61. .read = itimer_read,
  62. .mask = CLOCKSOURCE_MASK(64),
  63. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  64. };
  65. static void __init setup_itimer(void)
  66. {
  67. int err;
  68. err = request_irq(TIMER_IRQ, um_timer, 0, "timer", NULL);
  69. if (err != 0)
  70. printk(KERN_ERR "register_timer : request_irq failed - "
  71. "errno = %d\n", -err);
  72. itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32);
  73. itimer_clockevent.max_delta_ns =
  74. clockevent_delta2ns(60 * HZ, &itimer_clockevent);
  75. itimer_clockevent.min_delta_ns =
  76. clockevent_delta2ns(1, &itimer_clockevent);
  77. err = clocksource_register_hz(&itimer_clocksource, USEC_PER_SEC);
  78. if (err) {
  79. printk(KERN_ERR "clocksource_register_hz returned %d\n", err);
  80. return;
  81. }
  82. clockevents_register_device(&itimer_clockevent);
  83. }
  84. void read_persistent_clock(struct timespec *ts)
  85. {
  86. long long nsecs = os_nsecs();
  87. set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
  88. nsecs % NSEC_PER_SEC);
  89. }
  90. void __init time_init(void)
  91. {
  92. timer_init();
  93. late_time_init = setup_itimer;
  94. }