ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / arm / kernel / time-acorn.c
1 /*
2  *  linux/arch/arm/kernel/time-acorn.c
3  *
4  *  Copyright (c) 1996-2000 Russell King.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  *  Changelog:
11  *   24-Sep-1996        RMK     Created
12  *   10-Oct-1996        RMK     Brought up to date with arch-sa110eval
13  *   04-Dec-1997        RMK     Updated for new arch/arm/time.c
14  */
15 #include <linux/timex.h>
16 #include <linux/init.h>
17
18 #include <asm/hardware.h>
19 #include <asm/io.h>
20 #include <asm/hardware/ioc.h>
21
22 extern unsigned long (*gettimeoffset)(void);
23
24 static unsigned long ioctime_gettimeoffset(void)
25 {
26         unsigned int count1, count2, status;
27         long offset;
28
29         ioc_writeb (0, IOC_T0LATCH);
30         barrier ();
31         count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
32         barrier ();
33         status = ioc_readb(IOC_IRQREQA);
34         barrier ();
35         ioc_writeb (0, IOC_T0LATCH);
36         barrier ();
37         count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
38
39         offset = count2;
40         if (count2 < count1) {
41                 /*
42                  * We have not had an interrupt between reading count1
43                  * and count2.
44                  */
45                 if (status & (1 << 5))
46                         offset -= LATCH;
47         } else if (count2 > count1) {
48                 /*
49                  * We have just had another interrupt between reading
50                  * count1 and count2.
51                  */
52                 offset -= LATCH;
53         }
54
55         offset = (LATCH - offset) * (tick_nsec / 1000);
56         return (offset + LATCH/2) / LATCH;
57 }
58
59 void __init ioctime_init(void)
60 {
61         ioc_writeb(LATCH & 255, IOC_T0LTCHL);
62         ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
63         ioc_writeb(0, IOC_T0GO);
64
65         gettimeoffset = ioctime_gettimeoffset;
66 }