Import changeset
[opensuse:kernel.git] / include / asm-arm / arch-sa1100 / time.h
1 /*
2  * linux/include/asm-arm/arch-sa1100/time.h
3  *
4  * Copyright (C) 1998 Deborah Wallach.
5  * Twiddles  (C) 1999   Hugo Fiennes <hugo@empeg.com>
6  * 
7  * 2000/03/29 (C) Nicolas Pitre <nico@cam.org>
8  *      Rewritten: big cleanup, much simpler, better HZ acuracy.
9  *
10  */
11
12
13 /* IRQs are disabled before entering here from do_gettimeofday() */
14 static unsigned long sa1100_gettimeoffset (void)
15 {
16         unsigned long ticks_to_match, elapsed, usec;
17
18         /* Get ticks before next timer match */
19         ticks_to_match = OSMR0 - OSCR;
20
21         /* We need elapsed ticks since last match */
22         elapsed = LATCH - ticks_to_match;
23
24         /* Now convert them to usec */
25         usec = (unsigned long)(elapsed*tick)/LATCH;
26
27         return usec;
28 }
29
30
31 static void sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
32 {
33         long flags;
34         int next_match;
35
36         /* Loop until we get ahead of the free running timer.
37          * This ensures an exact clock tick count and time acuracy.
38          * IRQs are disabled inside the loop to ensure coherence between
39          * lost_ticks (updated in do_timer()) and the match reg value, so we
40          * can use do_gettimeofday() from interrupt handlers.
41          */
42         do {
43                 do_leds();
44                 save_flags_cli( flags );
45                 do_timer(regs);
46                 OSSR = OSSR_M0;  /* Clear match on timer 0 */
47                 next_match = (OSMR0 += LATCH);
48                 restore_flags( flags );
49         } while( (signed long)(next_match - OSCR) <= 0 );
50 }
51
52
53 extern inline void setup_timer (void)
54 {
55         gettimeoffset = sa1100_gettimeoffset;
56         timer_irq.handler = sa1100_timer_interrupt;
57         OSMR0 = 0;              /* set initial match at 0 */
58         OSSR = 0xf;             /* clear status on all timers */
59         setup_arm_irq(IRQ_OST0, &timer_irq);
60         OIER |= OIER_E0;        /* enable match on timer 0 to cause interrupts */
61         OSCR = 0;               /* initialize free-running timer, force first match */
62 }
63