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