patch-2.3.48 linux/arch/mips/sgi/kernel/indy_timer.c

Next file: linux/arch/mips/sgi/kernel/reset.c
Previous file: linux/arch/mips/sgi/kernel/indy_sc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.47/linux/arch/mips/sgi/kernel/indy_timer.c linux/arch/mips/sgi/kernel/indy_timer.c
@@ -1,4 +1,4 @@
-/* $Id: indy_timer.c,v 1.12 1999/06/13 16:30:36 ralf Exp $
+/* $Id: indy_timer.c,v 1.18 2000/02/04 07:40:23 ralf Exp $
  *
  * indy_timer.c: Setting up the clock on the INDY 8254 controller.
  *
@@ -21,10 +21,10 @@
 #include <asm/irq.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
-#include <asm/sgi.h>
 #include <asm/sgialib.h>
-#include <asm/sgihpc.h>
-#include <asm/sgint23.h>
+#include <asm/sgi/sgi.h>
+#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/sgint23.h>
 
 
 /* Because of a bug in the i8254 timer we need to use the onchip r4k
@@ -33,6 +33,8 @@
 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
 static unsigned long r4k_cur;    /* What counter should be at next timer irq */
 
+extern rwlock_t xtime_lock;
+
 static inline void ack_r4ktimer(unsigned long newval)
 {
 	write_32bit_cp0_register(CP0_COMPARE, newval);
@@ -85,6 +87,7 @@
 	unsigned long count;
 	int irq = 7;
 
+	write_lock(&xtime_lock);
 	/* Ack timer and compute new compare. */
 	count = read_32bit_cp0_register(CP0_COUNT);
 	/* This has races.  */
@@ -107,11 +110,14 @@
 	if ((time_status & STA_UNSYNC) == 0 &&
 	    xtime.tv_sec > last_rtc_update + 660 &&
 	    xtime.tv_usec >= 500000 - (tick >> 1) &&
-	    xtime.tv_usec <= 500000 + (tick >> 1))
-	  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 */
+	    xtime.tv_usec <= 500000 + (tick >> 1)) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			/* do it again in 60 s */
+			last_rtc_update = xtime.tv_sec - 600;
+	}
+	write_unlock(&xtime_lock);
 }
 
 static unsigned long dosample(volatile unsigned char *tcwp,
@@ -252,9 +258,10 @@
 	set_cp0_status(ST0_IM, ALLINTS);
 	sti();
 
-	/* Read time from the dallas chipset. */
-	xtime.tv_sec = get_indy_time();
+	write_lock_irq(&xtime_lock);
+	xtime.tv_sec = get_indy_time();		/* Read time from RTC. */
 	xtime.tv_usec = 0;
+	write_unlock_irq(&xtime_lock);
 }
 
 void indy_8254timer_irq(void)
@@ -262,29 +269,29 @@
 	int cpu = smp_processor_id();
 	int irq = 4;
 
-	hardirq_enter(cpu);
+	irq_enter(cpu);
 	kstat.irqs[0][irq]++;
 	printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
 	prom_getchar();
 	prom_imode();
-	hardirq_exit(cpu);
+	irq_exit(cpu);
 }
 
 void do_gettimeofday(struct timeval *tv)
 {
 	unsigned long flags;
 
-	save_and_cli(flags);
+	read_lock_irqsave(&xtime_lock, flags);
 	*tv = xtime;
-	restore_flags(flags);
+	read_unlock_irqrestore(&xtime_lock, flags);
 }
 
 void do_settimeofday(struct timeval *tv)
 {
-	cli();
+	write_lock_irq(&xtime_lock);
 	xtime = *tv;
 	time_state = TIME_BAD;
 	time_maxerror = MAXPHASE;
 	time_esterror = MAXPHASE;
-	sti();
+	write_unlock_irq(&xtime_lock);
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)