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 <linux/stringify.h>
15 #include <linux/clocksource.h>
17 #include <asm/arch-ns9xxx/regs-sys.h>
18 #include <asm/arch-ns9xxx/clock.h>
19 #include <asm/arch-ns9xxx/irqs.h>
20 #include <asm/arch/system.h>
23 #define TIMERCLOCKSELECT 64
24 #define TIMER_CLOCKSOURCE 1
27 ns9xxx_timer_interrupt(int irq
, void *dev_id
)
29 int timerno
= irq
- IRQ_TIMER0
;
32 write_seqlock(&xtime_lock
);
34 write_sequnlock(&xtime_lock
);
38 if (REGGET(tc
, SYS_TCx
, REN
) == SYS_TCx_REN_DIS
) {
39 REGSET(tc
, SYS_TCx
, TEN
, DIS
);
42 REGSET(tc
, SYS_TCx
, INTC
, SET
);
44 REGSET(tc
, SYS_TCx
, INTC
, UNSET
);
50 static struct irqaction ns9xxx_timer_irq
= {
51 .name
= "NS9xxx Timer Tick",
52 .flags
= IRQF_DISABLED
| IRQF_TIMER
| IRQF_IRQPOLL
,
53 .handler
= ns9xxx_timer_interrupt
,
56 static cycle_t
ns9xxx_clocksource_read(void)
58 return SYS_TR(TIMER_CLOCKSOURCE
);
61 static struct clocksource ns9xxx_clocksource
= {
62 .name
= "ns9xxx-timer" __stringify(TIMER_CLOCKSOURCE
),
64 .read
= ns9xxx_clocksource_read
,
65 .mask
= CLOCKSOURCE_MASK(32),
67 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
70 static void __init
ns9xxx_timer_init(void)
75 if ((tc
= SYS_TC(0)) & SYS_TCx_TEN
)
76 SYS_TC(0) = tc
& ~SYS_TCx_TEN
;
78 SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT
* HZ
), 0);
80 REGSET(tc
, SYS_TCx
, TEN
, EN
);
81 REGSET(tc
, SYS_TCx
, TLCS
, DIV64
); /* This must match TIMERCLOCKSELECT */
82 REGSET(tc
, SYS_TCx
, INTS
, EN
);
83 REGSET(tc
, SYS_TCx
, UDS
, DOWN
);
84 REGSET(tc
, SYS_TCx
, TDBG
, STOP
);
85 REGSET(tc
, SYS_TCx
, TSZ
, 32);
86 REGSET(tc
, SYS_TCx
, REN
, EN
);
89 setup_irq(IRQ_TIMER0
, &ns9xxx_timer_irq
);
91 tc
= SYS_TC(TIMER_CLOCKSOURCE
);
92 if (REGGET(tc
, SYS_TCx
, TEN
)) {
93 REGSET(tc
, SYS_TCx
, TEN
, DIS
);
94 SYS_TC(TIMER_CLOCKSOURCE
) = tc
;
97 SYS_TRC(TIMER_CLOCKSOURCE
) = 0;
99 REGSET(tc
, SYS_TCx
, TEN
, EN
);
100 REGSET(tc
, SYS_TCx
, TDBG
, STOP
);
101 REGSET(tc
, SYS_TCx
, TLCS
, CPU
);
102 REGSET(tc
, SYS_TCx
, TM
, IEE
);
103 REGSET(tc
, SYS_TCx
, INTS
, DIS
);
104 REGSET(tc
, SYS_TCx
, UDS
, UP
);
105 REGSET(tc
, SYS_TCx
, TSZ
, 32);
106 REGSET(tc
, SYS_TCx
, REN
, EN
);
108 SYS_TC(TIMER_CLOCKSOURCE
) = tc
;
110 ns9xxx_clocksource
.mult
= clocksource_hz2mult(ns9xxx_cpuclock(),
111 ns9xxx_clocksource
.shift
);
113 clocksource_register(&ns9xxx_clocksource
);
116 struct sys_timer ns9xxx_timer
= {
117 .init
= ns9xxx_timer_init
,