Blame view

arch/arm/mach-sa1100/time.c 3.04 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /*
   * linux/arch/arm/mach-sa1100/time.c
   *
   * Copyright (C) 1998 Deborah Wallach.
93982535a   Kristoffer Ericson   [ARM] 5336/1: For...
5
6
   * Twiddles  (C) 1999 Hugo Fiennes <hugo@empeg.com>
   *
2f82af08f   Nicolas Pitre   Nicolas Pitre has...
7
   * 2000/03/29 (C) Nicolas Pitre <nico@fluxnic.net>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
10
11
12
13
   *	Rewritten: big cleanup, much simpler, better HZ accuracy.
   *
   */
  #include <linux/init.h>
  #include <linux/errno.h>
  #include <linux/interrupt.h>
119c641c9   Thomas Gleixner   [ARM] 3698/1: ARM...
14
  #include <linux/irq.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include <linux/timex.h>
3e238be2f   Russell King   [ARM] sa1100: add...
16
  #include <linux/clockchips.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
  
  #include <asm/mach/time.h>
5094b92f1   Russell King   ARM: sa1100: conv...
19
  #include <asm/sched_clock.h>
a09e64fbc   Russell King   [ARM] Move includ...
20
  #include <mach/hardware.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21

ef3a0bf5b   Linus Walleij   ARM: 7269/1: mach...
22
  static u32 notrace sa1100_read_sched_clock(void)
5094b92f1   Russell King   ARM: sa1100: conv...
23
  {
2f0778afa   Marc Zyngier   ARM: 7205/2: sche...
24
  	return OSCR;
5094b92f1   Russell King   ARM: sa1100: conv...
25
  }
3e238be2f   Russell King   [ARM] sa1100: add...
26
  #define MIN_OSCR_DELTA 2
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27

3e238be2f   Russell King   [ARM] sa1100: add...
28
  static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
  {
3e238be2f   Russell King   [ARM] sa1100: add...
30
  	struct clock_event_device *c = dev_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31

3e238be2f   Russell King   [ARM] sa1100: add...
32
33
34
35
  	/* Disarm the compare/match, signal the event. */
  	OIER &= ~OIER_E0;
  	OSSR = OSSR_M0;
  	c->event_handler(c);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36

3e238be2f   Russell King   [ARM] sa1100: add...
37
38
  	return IRQ_HANDLED;
  }
569d2c34d   Nicolas Pitre   [ARM] 2864/1: VST...
39

3e238be2f   Russell King   [ARM] sa1100: add...
40
41
  static int
  sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
  {
a602f0f2f   Uwe Kleine-König   arm/{pxa,sa1100,n...
43
  	unsigned long next, oscr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

3e238be2f   Russell King   [ARM] sa1100: add...
45
46
47
48
  	OIER |= OIER_E0;
  	next = OSCR + delta;
  	OSMR0 = next;
  	oscr = OSCR;
569d2c34d   Nicolas Pitre   [ARM] 2864/1: VST...
49

3e238be2f   Russell King   [ARM] sa1100: add...
50
51
  	return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52

3e238be2f   Russell King   [ARM] sa1100: add...
53
54
55
  static void
  sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
  {
3e238be2f   Russell King   [ARM] sa1100: add...
56
57
58
59
  	switch (mode) {
  	case CLOCK_EVT_MODE_ONESHOT:
  	case CLOCK_EVT_MODE_UNUSED:
  	case CLOCK_EVT_MODE_SHUTDOWN:
3e238be2f   Russell King   [ARM] sa1100: add...
60
61
  		OIER &= ~OIER_E0;
  		OSSR = OSSR_M0;
3e238be2f   Russell King   [ARM] sa1100: add...
62
63
64
65
66
67
  		break;
  
  	case CLOCK_EVT_MODE_RESUME:
  	case CLOCK_EVT_MODE_PERIODIC:
  		break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
  }
3e238be2f   Russell King   [ARM] sa1100: add...
69
70
71
  static struct clock_event_device ckevt_sa1100_osmr0 = {
  	.name		= "osmr0",
  	.features	= CLOCK_EVT_FEAT_ONESHOT,
3e238be2f   Russell King   [ARM] sa1100: add...
72
  	.rating		= 200,
3e238be2f   Russell King   [ARM] sa1100: add...
73
74
  	.set_next_event	= sa1100_osmr0_set_next_event,
  	.set_mode	= sa1100_osmr0_set_mode,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  };
3e238be2f   Russell King   [ARM] sa1100: add...
76
77
78
79
80
81
  static struct irqaction sa1100_timer_irq = {
  	.name		= "ost0",
  	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
  	.handler	= sa1100_ost0_interrupt,
  	.dev_id		= &ckevt_sa1100_osmr0,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
83
  static void __init sa1100_timer_init(void)
  {
1ba4c3cb1   Russell King   ARM: update sa110...
84
85
  	OIER = 0;
  	OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
3e238be2f   Russell King   [ARM] sa1100: add...
86

2f0778afa   Marc Zyngier   ARM: 7205/2: sche...
87
  	setup_sched_clock(sa1100_read_sched_clock, 32, 3686400);
5094b92f1   Russell King   ARM: sa1100: conv...
88

1ba4c3cb1   Russell King   ARM: update sa110...
89
  	clockevents_calc_mult_shift(&ckevt_sa1100_osmr0, 3686400, 4);
3e238be2f   Russell King   [ARM] sa1100: add...
90
91
92
93
  	ckevt_sa1100_osmr0.max_delta_ns =
  		clockevent_delta2ns(0x7fffffff, &ckevt_sa1100_osmr0);
  	ckevt_sa1100_osmr0.min_delta_ns =
  		clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1;
320ab2b0b   Rusty Russell   cpumask: convert ...
94
  	ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
d142b6e77   Russell King   [ARM] sa1100: add...
95

3e238be2f   Russell King   [ARM] sa1100: add...
96
  	setup_irq(IRQ_OST0, &sa1100_timer_irq);
569d2c34d   Nicolas Pitre   [ARM] 2864/1: VST...
97

234b6cedd   Russell King   clocksource: conv...
98
99
  	clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32,
  		clocksource_mmio_readl_up);
3e238be2f   Russell King   [ARM] sa1100: add...
100
  	clockevents_register_device(&ckevt_sa1100_osmr0);
569d2c34d   Nicolas Pitre   [ARM] 2864/1: VST...
101
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  #ifdef CONFIG_PM
  unsigned long osmr[4], oier;
  
  static void sa1100_timer_suspend(void)
  {
  	osmr[0] = OSMR0;
  	osmr[1] = OSMR1;
  	osmr[2] = OSMR2;
  	osmr[3] = OSMR3;
  	oier = OIER;
  }
  
  static void sa1100_timer_resume(void)
  {
  	OSSR = 0x0f;
  	OSMR0 = osmr[0];
  	OSMR1 = osmr[1];
  	OSMR2 = osmr[2];
  	OSMR3 = osmr[3];
  	OIER = oier;
  
  	/*
  	 * OSMR0 is the system timer: make sure OSCR is sufficiently behind
  	 */
  	OSCR = OSMR0 - LATCH;
  }
  #else
  #define sa1100_timer_suspend NULL
  #define sa1100_timer_resume NULL
  #endif
  
  struct sys_timer sa1100_timer = {
  	.init		= sa1100_timer_init,
  	.suspend	= sa1100_timer_suspend,
  	.resume		= sa1100_timer_resume,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
  };