patch-2.4.20 linux-2.4.20/arch/mips/kernel/time.c

Next file: linux-2.4.20/arch/mips/kernel/traps.c
Previous file: linux-2.4.20/arch/mips/kernel/sysmips.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/arch/mips/kernel/time.c linux-2.4.20/arch/mips/kernel/time.c
@@ -2,8 +2,8 @@
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
- * Common time service routines for MIPS machines. See 
- * Documents/MIPS/README.txt. 
+ * Common time service routines for MIPS machines. See
+ * Documents/MIPS/README.txt.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -289,9 +289,9 @@
 
 /*
  * local_timer_interrupt() does profiling and process accounting
- * on a per-CPU basis.  
+ * on a per-CPU basis.
  *
- * In UP mode, it is invoked from the (global) timer_interrupt.  
+ * In UP mode, it is invoked from the (global) timer_interrupt.
  *
  * In SMP mode, it might invoked by per-CPU timer interrupt, or
  * a broadcasted inter-processor interrupt which itself is triggered
@@ -368,7 +368,7 @@
 		if (rtc_set_time(xtime.tv_sec) == 0) {
 			last_rtc_update = xtime.tv_sec;
 		} else {
-			last_rtc_update = xtime.tv_sec - 600; 
+			last_rtc_update = xtime.tv_sec - 600;
 			/* do it again in 60 s */
 		}
 	}
@@ -384,9 +384,9 @@
 	}
 
 #if !defined(CONFIG_SMP)
-	/* 
+	/*
 	 * In UP mode, we call local_timer_interrupt() to do profiling
-	 * and process accouting.  
+	 * and process accouting.
 	 *
 	 * In SMP mode, local_timer_interrupt() is invoked by appropriate
 	 * low-level local timer interrupt handler.
@@ -396,7 +396,7 @@
 #else	/* CONFIG_SMP */
 
 	if (emulate_local_timer_interrupt) {
-		/* 
+		/*
 		 * this is the place where we send out inter-process
 		 * interrupts and let each CPU do its own profiling
 		 * and process accouting.
@@ -418,7 +418,7 @@
 
 	/* we keep interrupt disabled all the time */
 	timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -434,7 +434,7 @@
 
 	/* we keep interrupt disabled all the time */
 	local_timer_interrupt(irq, NULL, regs);
-	
+
 	irq_exit(cpu, irq);
 
 	if (softirq_pending(cpu))
@@ -444,19 +444,19 @@
 /*
  * time_init() - it does the following things.
  *
- * 1) board_time_init() - 
- * 	a) (optional) set up RTC routines, 
+ * 1) board_time_init() -
+ * 	a) (optional) set up RTC routines,
  *      b) (optional) calibrate and set the mips_counter_frequency
  *	    (only needed if you intended to use fixed_rate_gettimeoffset
  *	     or use cpu counter as timer interrupt source)
  * 2) setup xtime based on rtc_get_time().
  * 3) choose a appropriate gettimeoffset routine.
  * 4) calculate a couple of cached variables for later usage
- * 5) board_timer_setup() - 
+ * 5) board_timer_setup() -
  *	a) (optional) over-write any choices made above by time_init().
  *	b) machine specific code should setup the timer irqaction.
  *	c) enable the timer interrupt
- */ 
+ */
 
 void (*board_time_init)(void) = NULL;
 void (*board_timer_setup)(struct irqaction *irq) = NULL;
@@ -497,10 +497,12 @@
 		/* we need to calibrate the counter but we *do* have
 		 * 64-bit division. */
 		do_gettimeoffset = calibrate_div64_gettimeoffset;
-	}	
+	}
 
 	/* caclulate cache parameters */
 	if (mips_counter_frequency) {
+		u32 count;
+
 		cycles_per_jiffy = mips_counter_frequency / HZ;
 
 		/* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */
@@ -508,16 +510,24 @@
 		sll32_usecs_per_cycle = mips_counter_frequency / 100000;
 		sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle;
 		sll32_usecs_per_cycle *= 10;
+
+		/*
+		 * For those using cpu counter as timer,  this sets up the
+		 * first interrupt
+		 */
+		count = read_32bit_cp0_register(CP0_COUNT);
+		write_32bit_cp0_register (CP0_COMPARE,
+					  count + cycles_per_jiffy);
 	}
 
-	/* 
+	/*
 	 * Call board specific timer interrupt setup.
 	 *
-	 * this pointer must be setup in machine setup routine. 
+	 * this pointer must be setup in machine setup routine.
 	 *
 	 * Even if the machine choose to use low-level timer interrupt,
 	 * it still needs to setup the timer_irqaction.
-	 * In that case, it might be better to set timer_irqaction.handler 
+	 * In that case, it might be better to set timer_irqaction.handler
 	 * to be NULL function so that we are sure the high-level code
 	 * is not invoked accidentally.
 	 */

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