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
21extern void get_rtc_time(struct rtc_time *rtc_tm);
22extern void set_rtc_irq_bit(unsigned char bit);
23extern unsigned long epoch;
24
25static 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 */
49static 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	timer_irq.flags = SA_INTERRUPT;
84	setup_arm_irq(IRQ_TIMER, &timer_irq);
85}
86