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