1 /*
2 * linux/include/asm-arm/arch-shark/time.h
3 *
4 * by Alexander Schulz
5 *
6 * Uses the real time clock because you can't run
7 * the timer with level triggered interrupts and
8 * you can't run the shark with edge triggered
9 * inetrrupts (loses ints and hangs).
10 *
11 * derived from linux/drivers/char/rtc.c and:
12 * linux/include/asm-arm/arch-ebsa110/time.h
13 * Copyright (c) 1996,1997,1998 Russell King.
14 */
15
16 #include <asm/leds.h>
17 #include <linux/mc146818rtc.h>
18
19 #define IRQ_TIMER 8
20
21 extern void get_rtc_time(struct rtc_time *rtc_tm);
22 extern void set_rtc_irq_bit(unsigned char bit);
23 extern unsigned long epoch;
24
timer_interrupt(int irq,void * dev_id,struct pt_regs * regs)25 static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
26 {
27
28 CMOS_READ(RTC_INTR_FLAGS);
29
30 do_leds();
31
32 {
33 #ifdef DIVISOR
34 static unsigned int divisor;
35
36 if (divisor-- == 0) {
37 divisor = DIVISOR - 1;
38 #else
39 {
40 #endif
41 do_timer(regs);
42 }
43 }
44 }
45
46 /*
47 * Set up timer interrupt, and return the current time in seconds.
48 */
49 static inline void setup_timer(void)
50 {
51 struct rtc_time r_time;
52 unsigned long flags;
53 int tmp = 0;
54 unsigned char val;
55
56 /*
57 * Set the clock to 128 Hz, we already have a valid
58 * vector now:
59 */
60
61 while (HZ > (1<<tmp))
62 tmp++;
63
64 /*
65 * Check that the input was really a power of 2.
66 */
67 if (HZ != (1<<tmp))
68 panic("Please set HZ to a power of 2!");
69
70 save_flags(flags);
71 cli();
72 val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
73 val |= (16 - tmp);
74 CMOS_WRITE(val, RTC_FREQ_SELECT);
75 restore_flags(flags);
76 set_rtc_irq_bit(RTC_PIE);
77
78 get_rtc_time(&r_time);
79 xtime.tv_sec = mktime(r_time.tm_year+epoch, r_time.tm_mon+1, r_time.tm_mday,
80 r_time.tm_hour, r_time.tm_min, r_time.tm_sec);
81
82 timer_irq.handler = timer_interrupt;
83 setup_arm_irq(IRQ_TIMER, &timer_irq);
84 }
85