time.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 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. .mult = 1000,
  67. .shift = 0,
  68. .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  69. };
  70. static void __init setup_itimer(void)
  71. {
  72. int err;
  73. err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
  74. if (err != 0)
  75. printk(KERN_ERR "register_timer : request_irq failed - "
  76. "errno = %d\n", -err);
  77. itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32);
  78. itimer_clockevent.max_delta_ns =
  79. clockevent_delta2ns(60 * HZ, &itimer_clockevent);
  80. itimer_clockevent.min_delta_ns =
  81. clockevent_delta2ns(1, &itimer_clockevent);
  82. err = clocksource_register(&itimer_clocksource);
  83. if (err) {
  84. printk(KERN_ERR "clocksource_register returned %d\n", err);
  85. return;
  86. }
  87. clockevents_register_device(&itimer_clockevent);
  88. }
  89. void read_persistent_clock(struct timespec *ts)
  90. {
  91. long long nsecs = os_nsecs();
  92. set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
  93. nsecs % NSEC_PER_SEC);
  94. }
  95. void __init time_init(void)
  96. {
  97. timer_init();
  98. late_time_init = setup_itimer;
  99. }