patch-2.4.0-test3 linux/arch/mips/kernel/time.c
Next file: linux/arch/mips/kernel/traps.c
Previous file: linux/arch/mips/kernel/sysmips.c
Back to the patch index
Back to the overall index
- Lines: 161
- Date:
Sun Jul 9 22:18:15 2000
- Orig file:
v2.4.0-test2/linux/arch/mips/kernel/time.c
- Orig date:
Thu Mar 2 14:36:22 2000
diff -u --recursive --new-file v2.4.0-test2/linux/arch/mips/kernel/time.c linux/arch/mips/kernel/time.c
@@ -1,7 +1,6 @@
-/* $Id: time.c,v 1.14 2000/01/26 00:07:44 ralf Exp $
- *
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
- * Copyright (C) 1996, 1997, 1998 Ralf Baechle
+/*
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ * Copyright (C) 1996 - 2000 Ralf Baechle
*
* This file contains the time handling details for PC-style clocks as
* found in some MIPS systems.
@@ -15,6 +14,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
#include <asm/bootinfo.h>
#include <asm/mipsregs.h>
@@ -26,6 +26,8 @@
#include <linux/timex.h>
extern volatile unsigned long lost_ticks;
+unsigned long r4k_interval = 0;
+extern rwlock_t xtime_lock;
/*
* Change this if you have some constant time drift
@@ -219,7 +221,7 @@
{
unsigned long flags;
- save_and_cli(flags);
+ read_lock_irqsave (&xtime_lock, flags);
*tv = xtime;
tv->tv_usec += do_gettimeoffset();
@@ -230,7 +232,7 @@
if (lost_ticks)
tv->tv_usec += USECS_PER_JIFFY;
- restore_flags(flags);
+ read_unlock_irqrestore (&xtime_lock, flags);
if (tv->tv_usec >= 1000000) {
tv->tv_usec -= 1000000;
@@ -240,7 +242,7 @@
void do_settimeofday(struct timeval *tv)
{
- cli();
+ write_lock_irq (&xtime_lock);
/* This is revolting. We need to set the xtime.tv_usec
* correctly. However, the value in this location is
* is value at the last tick.
@@ -259,7 +261,7 @@
time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
- sti();
+ write_unlock_irq (&xtime_lock);
}
/*
@@ -355,7 +357,6 @@
dist = period / 4;
}
#endif
-#ifdef CONFIG_PROFILE
if(!user_mode(regs)) {
if (prof_buffer && current->pid) {
extern int _stext;
@@ -373,7 +374,6 @@
atomic_inc((atomic_t *)&prof_buffer[pc]);
}
}
-#endif
do_timer(regs);
/*
@@ -381,22 +381,26 @@
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
+ read_lock (&xtime_lock);
if ((time_status & STA_UNSYNC) == 0 &&
xtime.tv_sec > last_rtc_update + 660 &&
xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
- xtime.tv_usec <= 500000 + ((unsigned) tick) / 2)
+ xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
if (set_rtc_mmss(xtime.tv_sec) == 0)
last_rtc_update = xtime.tv_sec;
else
last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+ }
/* As we return to user mode fire off the other CPU schedulers.. this is
basically because we don't yet share IRQ's around. This message is
rigged to be safe on the 386 - basically it's a hack, so don't look
closely for now.. */
/*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
+ read_unlock (&xtime_lock);
}
-static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static inline void
+r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
{
unsigned int count;
@@ -408,6 +412,18 @@
timerhi += (count < timerlo); /* Wrap around */
timerlo = count;
+#ifdef CONFIG_SGI_IP22
+ /* Since we don't get anything but r4k timer interrupts, we need to
+ * set this up so that we'll get one next time. Fortunately since we
+ * have timerhi/timerlo, we don't care so much if we miss one. So
+ * we need only ask for the next in r4k_interval counts. On other
+ * archs we have a real timer, so we don't want this.
+ */
+ write_32bit_cp0_register (CP0_COMPARE,
+ (unsigned long) (count + r4k_interval));
+ kstat.irqs[0][irq]++;
+#endif
+
timer_interrupt(irq, dev_id, regs);
if (!jiffies)
@@ -421,6 +437,12 @@
}
}
+void indy_r4k_timer_interrupt (struct pt_regs *regs)
+{
+ static const int INDY_R4K_TIMER_IRQ = 7;
+ r4k_timer_interrupt (INDY_R4K_TIMER_IRQ, NULL, regs);
+}
+
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
@@ -500,7 +522,7 @@
void __init time_init(void)
{
- unsigned int epoch, year, mon, day, hour, min, sec;
+ unsigned int epoch = 0, year, mon, day, hour, min, sec;
int i;
/* The Linux interpretation of the CMOS clock register contents:
@@ -543,8 +565,10 @@
}
year += epoch;
+ write_lock_irq (&xtime_lock);
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_usec = 0;
+ write_unlock_irq (&xtime_lock);
init_cycle_counter();
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)