2 * time.c: Baget/MIPS specific time handling details
4 * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
7 #include <linux/errno.h>
8 #include <linux/init.h>
9 #include <linux/module.h>
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/param.h>
13 #include <linux/string.h>
15 #include <linux/time.h>
16 #include <linux/interrupt.h>
17 #include <linux/timex.h>
18 #include <linux/spinlock.h>
20 #include <asm/bootinfo.h>
23 #include <asm/ptrace.h>
24 #include <asm/system.h>
26 #include <asm/baget/baget.h>
29 * To have precision clock, we need to fix available clock frequency
31 #define FREQ_NOM 79125 /* Baget frequency ratio */
32 #define FREQ_DEN 10000
34 static inline int timer_intr_valid(void)
36 static unsigned long long ticks, valid_ticks;
38 if (ticks++ * FREQ_DEN >= valid_ticks * FREQ_NOM) {
40 * We need no overflow checks,
41 * due baget unable to work 3000 years...
42 * At least without reboot...
50 void static timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
52 if (timer_intr_valid()) {
58 static void __init timer_enable(void)
60 unsigned char ss0cr0 = vic_inb(VIC_SS0CR0);
61 ss0cr0 &= ~VIC_SS0CR0_TIMER_FREQ_MASK;
62 ss0cr0 |= VIC_SS0CR0_TIMER_FREQ_1000HZ;
63 vic_outb(ss0cr0, VIC_SS0CR0);
65 vic_outb(VIC_INT_IPL(6)|VIC_INT_NOAUTO|VIC_INT_EDGE|
66 VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2);
69 static struct irqaction timer_irq =
70 { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
72 void __init time_init(void)
74 if (setup_baget_irq(BAGET_VIC_TIMER_IRQ, &timer_irq) < 0)
75 printk("time_init: unable request irq for system timer\n");
77 /* We don't call sti() here, because it is too early for baget */
80 void do_gettimeofday(struct timeval *tv)
85 seq = read_seqbegin(&xtime_lock);
86 tv->tv_sec = xtime.tv_sec;
87 tv->tv_usec = xtime.tv_nsec / 1000;
88 } while (read_seqretry(&xtime_lock, seq));
91 EXPORT_SYMBOL(do_gettimeofday);
93 void do_settimeofday(struct timeval *tv)
95 write_seqlock_irq(&xtime_lock);
96 xtime.tv_usec = tv->tv_sec;
97 xtime.tv_nsec = tv->tv_usec;
98 time_adjust = 0; /* stop active adjtime() */
99 time_status |= STA_UNSYNC;
100 time_maxerror = NTP_PHASE_LIMIT;
101 time_esterror = NTP_PHASE_LIMIT;
102 write_sequnlock_irq(&xtime_lock);
105 EXPORT_SYMBOL(do_settimeofday);