Blame view

arch/um/kernel/time.c 2.48 KB
cff65c4f0   Gennady Sharapov   [PATCH] uml: move...
1
  /*
ba180fd43   Jeff Dike   uml: style fixes ...
2
   * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
   * Licensed under the GPL
   */
c5d4bb171   Jeff Dike   uml: style fixes ...
5
  #include <linux/clockchips.h>
7d195a540   Adrian Bunk   proper extern for...
6
  #include <linux/init.h>
c5d4bb171   Jeff Dike   uml: style fixes ...
7
8
9
10
11
  #include <linux/interrupt.h>
  #include <linux/jiffies.h>
  #include <linux/threads.h>
  #include <asm/irq.h>
  #include <asm/param.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
  #include "kern_util.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
  #include "os.h"
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
14
  void timer_handler(int sig, struct uml_pt_regs *regs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  {
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
16
  	unsigned long flags;
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
17
18
  
  	local_irq_save(flags);
d2753a6d1   Jeff Dike   uml: tickless sup...
19
  	do_IRQ(TIMER_IRQ, regs);
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
20
  	local_irq_restore(flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  }
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
22
23
  static void itimer_set_mode(enum clock_event_mode mode,
  			    struct clock_event_device *evt)
cff65c4f0   Gennady Sharapov   [PATCH] uml: move...
24
  {
c5d4bb171   Jeff Dike   uml: style fixes ...
25
  	switch (mode) {
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
26
27
28
29
30
31
  	case CLOCK_EVT_MODE_PERIODIC:
  		set_interval();
  		break;
  
  	case CLOCK_EVT_MODE_SHUTDOWN:
  	case CLOCK_EVT_MODE_UNUSED:
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
32
  	case CLOCK_EVT_MODE_ONESHOT:
d2753a6d1   Jeff Dike   uml: tickless sup...
33
  		disable_timer();
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
34
35
36
37
38
  		break;
  
  	case CLOCK_EVT_MODE_RESUME:
  		break;
  	}
cff65c4f0   Gennady Sharapov   [PATCH] uml: move...
39
  }
d2753a6d1   Jeff Dike   uml: tickless sup...
40
41
42
43
44
  static int itimer_next_event(unsigned long delta,
  			     struct clock_event_device *evt)
  {
  	return timer_one_shot(delta + 1);
  }
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
45
46
47
  static struct clock_event_device itimer_clockevent = {
  	.name		= "itimer",
  	.rating		= 250,
320ab2b0b   Rusty Russell   cpumask: convert ...
48
  	.cpumask	= cpu_all_mask,
d2753a6d1   Jeff Dike   uml: tickless sup...
49
  	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
50
  	.set_mode	= itimer_set_mode,
d2753a6d1   Jeff Dike   uml: tickless sup...
51
  	.set_next_event = itimer_next_event,
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
52
53
54
55
56
  	.shift		= 32,
  	.irq		= 0,
  };
  
  static irqreturn_t um_timer(int irq, void *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
  {
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
58
  	(*itimer_clockevent.event_handler)(&itimer_clockevent);
cff65c4f0   Gennady Sharapov   [PATCH] uml: move...
59

572e61475   Jeff Dike   [PATCH] uml: add ...
60
  	return IRQ_HANDLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  }
8e19608e8   Magnus Damm   clocksource: pass...
62
  static cycle_t itimer_read(struct clocksource *cs)
791a644a8   Jeff Dike   uml: clocksource ...
63
  {
cfd28f669   Jeff Dike   uml: fix bad NTP ...
64
  	return os_nsecs() / 1000;
791a644a8   Jeff Dike   uml: clocksource ...
65
66
67
68
69
70
71
  }
  
  static struct clocksource itimer_clocksource = {
  	.name		= "itimer",
  	.rating		= 300,
  	.read		= itimer_read,
  	.mask		= CLOCKSOURCE_MASK(64),
791a644a8   Jeff Dike   uml: clocksource ...
72
73
  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
  };
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
74
  static void __init setup_itimer(void)
aceb34346   Jeff Dike   [PATCH] uml: time...
75
76
77
78
  {
  	int err;
  
  	err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
ba180fd43   Jeff Dike   uml: style fixes ...
79
  	if (err != 0)
537ae946e   Jeff Dike   [PATCH] uml: time...
80
  		printk(KERN_ERR "register_timer : request_irq failed - "
aceb34346   Jeff Dike   [PATCH] uml: time...
81
82
  		       "errno = %d
  ", -err);
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
83
84
85
86
87
  	itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32);
  	itimer_clockevent.max_delta_ns =
  		clockevent_delta2ns(60 * HZ, &itimer_clockevent);
  	itimer_clockevent.min_delta_ns =
  		clockevent_delta2ns(1, &itimer_clockevent);
60d687e7d   John Stultz   clocksource: um: ...
88
  	err = clocksource_register_hz(&itimer_clocksource, USEC_PER_SEC);
791a644a8   Jeff Dike   uml: clocksource ...
89
  	if (err) {
60d687e7d   John Stultz   clocksource: um: ...
90
91
  		printk(KERN_ERR "clocksource_register_hz returned %d
  ", err);
791a644a8   Jeff Dike   uml: clocksource ...
92
93
  		return;
  	}
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
94
  	clockevents_register_device(&itimer_clockevent);
aceb34346   Jeff Dike   [PATCH] uml: time...
95
  }
9f31f5774   John Stultz   um: Convert to us...
96
97
  void read_persistent_clock(struct timespec *ts)
  {
b29230769   Thomas Gleixner   um: Fix read_pers...
98
  	long long nsecs = os_nsecs();
9f31f5774   John Stultz   um: Convert to us...
99
100
101
  	set_normalized_timespec(ts, nsecs / NSEC_PER_SEC,
  				nsecs % NSEC_PER_SEC);
  }
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
102
  void __init time_init(void)
aceb34346   Jeff Dike   [PATCH] uml: time...
103
  {
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
104
  	timer_init();
31ccc1f52   Jeff Dike   uml: GENERIC_CLOC...
105
  	late_time_init = setup_itimer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
  }