time.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 void itimer_set_mode(enum clock_event_mode mode,
  22. struct clock_event_device *evt)
  23. {
  24. switch (mode) {
  25. case CLOCK_EVT_MODE_PERIODIC:
  26. set_interval();
  27. break;
  28. case CLOCK_EVT_MODE_SHUTDOWN:
  29. case CLOCK_EVT_MODE_UNUSED:
  30. case CLOCK_EVT_MODE_ONESHOT:
  31. disable_timer();
  32. break;
  33. case CLOCK_EVT_MODE_RESUME:
  34. break;
  35. }
  36. }
  37. static int itimer_next_event(unsigned long delta,
  38. struct clock_event_device *evt)
  39. {
  40. return timer_one_shot(delta + 1);
  41. }
  42. static struct clock_event_device itimer_clockevent = {
  43. .name = "itimer",
  44. .rating = 250,
  45. .cpumask = cpu_all_mask,
  46. .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
  47. .set_mode = itimer_set_mode,
  48. .set_next_event = itimer_next_event,
  49. .shift = 32,
  50. .irq = 0,
  51. };
  52. static irqreturn_t um_timer(int irq, void *dev)
  53. {
  54. (*itimer_clockevent.event_handler)(&itimer_clockevent);
  55. return IRQ_HANDLED;
  56. }
  57. static cycle_t itimer_read(struct clocksource *cs)
  58. {
  59. return os_nsecs() / 1000;
  60. }
  61. static struct clocksource itimer_clocksource = {
  62. .name = "itimer",
  63. .rating = 300,
  64. .read = itimer_read,
  65. .mask = CLOCKSOURCE_MASK(64),
  66. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  67. };
  68. static void __init setup_itimer(void)
  69. {
  70. int err;
  71. err = request_irq(TIMER_IRQ, um_timer, 0, "timer", NULL);
  72. if (err != 0)
  73. printk(KERN_ERR "register_timer : request_irq failed - "
  74. "errno = %d\n", -err);
  75. itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32);
  76. itimer_clockevent.max_delta_ns =
  77. clockevent_delta2ns(60 * HZ, &itimer_clockevent);
  78. itimer_clockevent.min_delta_ns =
  79. clockevent_delta2ns(1, &itimer_clockevent);
  80. err = clocksource_register_hz(&itimer_clocksource, USEC_PER_SEC);
  81. if (err) {
  82. printk(KERN_ERR "clocksource_register_hz returned %d\n", err);
  83. return;
  84. }
  85. clockevents_register_device(&itimer_clockevent);
  86. }
  87. void read_persistent_clock(struct timespec *ts)
  88. {
  89. long long nsecs = os_nsecs();
  90. set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
  91. nsecs % NSEC_PER_SEC);
  92. }
  93. void __init time_init(void)
  94. {
  95. timer_init();
  96. late_time_init = setup_itimer;
  97. }