2 * arch/arm/mach-ns9xxx/time.c
4 * Copyright (C) 2006 by Digi International Inc.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
11 #include <linux/jiffies.h>
12 #include <linux/interrupt.h>
13 #include <linux/irq.h>
14 #include <asm/arch-ns9xxx/regs-sys.h>
15 #include <asm/arch-ns9xxx/clock.h>
16 #include <asm/arch-ns9xxx/irqs.h>
17 #include <asm/arch/system.h>
20 #define TIMERCLOCKSELECT 64
22 static u32 usecs_per_tick
;
25 ns9xxx_timer_interrupt(int irq
, void *dev_id
)
27 write_seqlock(&xtime_lock
);
29 write_sequnlock(&xtime_lock
);
34 static unsigned long ns9xxx_timer_gettimeoffset(void)
36 /* return the microseconds which have passed since the last interrupt
37 * was _serviced_. That is, if an interrupt is pending or the counter
38 * reloads, return one period more. */
40 u32 counter1
= SYS_TR(0);
41 int pending
= SYS_ISR
& (1 << IRQ_TIMER0
);
42 u32 counter2
= SYS_TR(0);
45 if (pending
|| counter2
> counter1
)
46 elapsed
= 2 * SYS_TRC(0) - counter2
;
48 elapsed
= SYS_TRC(0) - counter1
;
50 return (elapsed
* usecs_per_tick
) >> 16;
54 static struct irqaction ns9xxx_timer_irq
= {
55 .name
= "NS9xxx Timer Tick",
56 .flags
= IRQF_DISABLED
| IRQF_TIMER
| IRQF_IRQPOLL
,
57 .handler
= ns9xxx_timer_interrupt
,
60 static void __init
ns9xxx_timer_init(void)
65 SH_DIV(1000000 * TIMERCLOCKSELECT
, ns9xxx_cpuclock(), 16);
68 if ((tc
= SYS_TC(0)) & SYS_TCx_TEN
)
69 SYS_TC(0) = tc
& ~SYS_TCx_TEN
;
71 SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT
* HZ
), 0);
73 REGSET(tc
, SYS_TCx
, TEN
, EN
);
74 REGSET(tc
, SYS_TCx
, TLCS
, DIV64
); /* This must match TIMERCLOCKSELECT */
75 REGSET(tc
, SYS_TCx
, INTS
, EN
);
76 REGSET(tc
, SYS_TCx
, UDS
, DOWN
);
77 REGSET(tc
, SYS_TCx
, TDBG
, STOP
);
78 REGSET(tc
, SYS_TCx
, TSZ
, 32);
79 REGSET(tc
, SYS_TCx
, REN
, EN
);
82 setup_irq(IRQ_TIMER0
, &ns9xxx_timer_irq
);
85 struct sys_timer ns9xxx_timer
= {
86 .init
= ns9xxx_timer_init
,
87 .offset
= ns9xxx_timer_gettimeoffset
,