Blame view
arch/arm/mach-sa1100/time.c
3.04 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 |
/* * linux/arch/arm/mach-sa1100/time.c * * Copyright (C) 1998 Deborah Wallach. |
93982535a [ARM] 5336/1: For... |
5 6 |
* Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com> * |
2f82af08f Nicolas Pitre has... |
7 |
* 2000/03/29 (C) Nicolas Pitre <nico@fluxnic.net> |
1da177e4c 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 [ARM] 3698/1: ARM... |
14 |
#include <linux/irq.h> |
1da177e4c Linux-2.6.12-rc2 |
15 |
#include <linux/timex.h> |
3e238be2f [ARM] sa1100: add... |
16 |
#include <linux/clockchips.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 |
#include <asm/mach/time.h> |
5094b92f1 ARM: sa1100: conv... |
19 |
#include <asm/sched_clock.h> |
a09e64fbc [ARM] Move includ... |
20 |
#include <mach/hardware.h> |
1da177e4c Linux-2.6.12-rc2 |
21 |
|
ef3a0bf5b ARM: 7269/1: mach... |
22 |
static u32 notrace sa1100_read_sched_clock(void) |
5094b92f1 ARM: sa1100: conv... |
23 |
{ |
2f0778afa ARM: 7205/2: sche... |
24 |
return OSCR; |
5094b92f1 ARM: sa1100: conv... |
25 |
} |
3e238be2f [ARM] sa1100: add... |
26 |
#define MIN_OSCR_DELTA 2 |
1da177e4c Linux-2.6.12-rc2 |
27 |
|
3e238be2f [ARM] sa1100: add... |
28 |
static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id) |
1da177e4c Linux-2.6.12-rc2 |
29 |
{ |
3e238be2f [ARM] sa1100: add... |
30 |
struct clock_event_device *c = dev_id; |
1da177e4c Linux-2.6.12-rc2 |
31 |
|
3e238be2f [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 Linux-2.6.12-rc2 |
36 |
|
3e238be2f [ARM] sa1100: add... |
37 38 |
return IRQ_HANDLED; } |
569d2c34d [ARM] 2864/1: VST... |
39 |
|
3e238be2f [ARM] sa1100: add... |
40 41 |
static int sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c) |
1da177e4c Linux-2.6.12-rc2 |
42 |
{ |
a602f0f2f arm/{pxa,sa1100,n... |
43 |
unsigned long next, oscr; |
1da177e4c Linux-2.6.12-rc2 |
44 |
|
3e238be2f [ARM] sa1100: add... |
45 46 47 48 |
OIER |= OIER_E0; next = OSCR + delta; OSMR0 = next; oscr = OSCR; |
569d2c34d [ARM] 2864/1: VST... |
49 |
|
3e238be2f [ARM] sa1100: add... |
50 51 |
return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0; } |
1da177e4c Linux-2.6.12-rc2 |
52 |
|
3e238be2f [ARM] sa1100: add... |
53 54 55 |
static void sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c) { |
3e238be2f [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 [ARM] sa1100: add... |
60 61 |
OIER &= ~OIER_E0; OSSR = OSSR_M0; |
3e238be2f [ARM] sa1100: add... |
62 63 64 65 66 67 |
break; case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_PERIODIC: break; } |
1da177e4c Linux-2.6.12-rc2 |
68 |
} |
3e238be2f [ARM] sa1100: add... |
69 70 71 |
static struct clock_event_device ckevt_sa1100_osmr0 = { .name = "osmr0", .features = CLOCK_EVT_FEAT_ONESHOT, |
3e238be2f [ARM] sa1100: add... |
72 |
.rating = 200, |
3e238be2f [ARM] sa1100: add... |
73 74 |
.set_next_event = sa1100_osmr0_set_next_event, .set_mode = sa1100_osmr0_set_mode, |
1da177e4c Linux-2.6.12-rc2 |
75 |
}; |
3e238be2f [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 Linux-2.6.12-rc2 |
82 83 |
static void __init sa1100_timer_init(void) { |
1ba4c3cb1 ARM: update sa110... |
84 85 |
OIER = 0; OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3; |
3e238be2f [ARM] sa1100: add... |
86 |
|
2f0778afa ARM: 7205/2: sche... |
87 |
setup_sched_clock(sa1100_read_sched_clock, 32, 3686400); |
5094b92f1 ARM: sa1100: conv... |
88 |
|
1ba4c3cb1 ARM: update sa110... |
89 |
clockevents_calc_mult_shift(&ckevt_sa1100_osmr0, 3686400, 4); |
3e238be2f [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 cpumask: convert ... |
94 |
ckevt_sa1100_osmr0.cpumask = cpumask_of(0); |
d142b6e77 [ARM] sa1100: add... |
95 |
|
3e238be2f [ARM] sa1100: add... |
96 |
setup_irq(IRQ_OST0, &sa1100_timer_irq); |
569d2c34d [ARM] 2864/1: VST... |
97 |
|
234b6cedd clocksource: conv... |
98 99 |
clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32, clocksource_mmio_readl_up); |
3e238be2f [ARM] sa1100: add... |
100 |
clockevents_register_device(&ckevt_sa1100_osmr0); |
569d2c34d [ARM] 2864/1: VST... |
101 |
} |
1da177e4c 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 Linux-2.6.12-rc2 |
137 |
}; |