


 25-akpm/arch/sparc/kernel/pcic.c  |   21 ++++++++++++---------
 25-akpm/arch/sparc/kernel/time.c  |   28 +++++++++++++++++-----------
 25-akpm/include/asm-sparc/timer.h |    2 +-
 3 files changed, 30 insertions(+), 21 deletions(-)

diff -puN arch/sparc/kernel/time.c~sparc-do_settimeofday-update arch/sparc/kernel/time.c
--- 25/arch/sparc/kernel/time.c~sparc-do_settimeofday-update	Wed Jun 11 15:21:51 2003
+++ 25-akpm/arch/sparc/kernel/time.c	Wed Jun 11 15:23:45 2003
@@ -53,7 +53,7 @@ spinlock_t mostek_lock = SPIN_LOCK_UNLOC
 unsigned long mstk48t02_regs = 0UL;
 static struct mostek48t08 *mstk48t08_regs = 0;
 static int set_rtc_mmss(unsigned long);
-static void sbus_do_settimeofday(struct timeval *tv);
+static int sbus_do_settimeofday(struct timespec *tv);
 
 #ifdef CONFIG_SUN4
 struct intersil *intersil_clock;
@@ -500,32 +500,37 @@ void do_gettimeofday(struct timeval *tv)
 	tv->tv_usec = usec;
 }
 
-void do_settimeofday(struct timeval *tv)
+int do_settimeofday(struct timespec *tv)
 {
+	int ret;
+
 	write_seqlock_irq(&xtime_lock);
-	bus_do_settimeofday(tv);
+	ret = bus_do_settimeofday(tv);
 	write_sequnlock_irq(&xtime_lock);
+	return ret;
 }
 
-static void sbus_do_settimeofday(struct timeval *tv)
+static int sbus_do_settimeofday(struct timespec *tv)
 {
+	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+		return -EINVAL;
+
 	/*
 	 * This is revolting. We need to set "xtime" correctly. However, the
 	 * value in this location is the value at the most recent update of
 	 * wall time.  Discover what correction gettimeofday() would have
 	 * made, and then undo it!
 	 */
-	tv->tv_usec -= do_gettimeoffset();
-	tv->tv_usec -= (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ);
+	tv->tv_nsec -= 1000 * (do_gettimeoffset() +
+			(jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
 
-	while (tv->tv_usec < 0) {
-		tv->tv_usec += USEC_PER_SEC;
+	while (tv->tv_nsec < 0) {
+		tv->tv_nsec += NSEC_PER_SEC;
 		tv->tv_sec--;
 	}
-	tv->tv_usec *= NSEC_PER_USEC;
 
 	wall_to_monotonic.tv_sec += xtime.tv_sec - tv->tv_sec;
-	wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_usec;
+	wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_nsec;
 
 	if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) {
 		wall_to_monotonic.tv_nsec -= NSEC_PER_SEC;
@@ -537,11 +542,12 @@ static void sbus_do_settimeofday(struct 
 	}
 
 	xtime.tv_sec = tv->tv_sec;
-	xtime.tv_nsec = tv->tv_usec;
+	xtime.tv_nsec = tv->tv_nsec;
 	time_adjust = 0;		/* stop active adjtime() */
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
+	return 0;
 }
 
 /*
diff -puN arch/sparc/kernel/pcic.c~sparc-do_settimeofday-update arch/sparc/kernel/pcic.c
--- 25/arch/sparc/kernel/pcic.c~sparc-do_settimeofday-update	Wed Jun 11 15:49:10 2003
+++ 25-akpm/arch/sparc/kernel/pcic.c	Wed Jun 11 15:52:06 2003
@@ -191,7 +191,7 @@ volatile int pcic_speculative;
 volatile int pcic_trapped;
 
 static void pci_do_gettimeofday(struct timeval *tv);
-static void pci_do_settimeofday(struct timeval *tv);
+static int pci_do_settimeofday(struct timespec *tv);
 
 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
 
@@ -819,24 +819,26 @@ static void pci_do_gettimeofday(struct t
 	tv->tv_usec = usec;
 }
 
-static void pci_do_settimeofday(struct timeval *tv)
+static int pci_do_settimeofday(struct timespec *tv)
 {
+	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+		return -EINVAL;
+
 	/*
 	 * This is revolting. We need to set "xtime" correctly. However, the
 	 * value in this location is the value at the most recent update of
 	 * wall time.  Discover what correction gettimeofday() would have
 	 * made, and then undo it!
 	 */
-	tv->tv_usec -= do_gettimeoffset();
-	tv->tv_usec -= (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ);
-	while (tv->tv_usec < 0) {
-		tv->tv_usec += USEC_PER_SEC;
+	tv->tv_nsec -= 1000 * (do_gettimeoffset() + 
+				(jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
+	while (tv->tv_nsec < 0) {
+		tv->tv_nsec += NSEC_PER_SEC;
 		tv->tv_sec--;
 	}
-	tv->tv_usec *= NSEC_PER_USEC;
 
 	wall_to_monotonic.tv_sec += xtime.tv_sec - tv->tv_sec;
-	wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_usec;
+	wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_nsec;
 
 	if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) {
 		wall_to_monotonic.tv_nsec -= NSEC_PER_SEC;
@@ -848,11 +850,12 @@ static void pci_do_settimeofday(struct t
 	}
 
 	xtime.tv_sec = tv->tv_sec;
-	xtime.tv_nsec = tv->tv_usec;
+	xtime.tv_nsec = tv->tv_nsec;
 	time_adjust = 0;		/* stop active adjtime() */
 	time_status |= STA_UNSYNC;
 	time_maxerror = NTP_PHASE_LIMIT;
 	time_esterror = NTP_PHASE_LIMIT;
+	return 0;
 }
 
 #if 0
diff -puN include/asm-sparc/timer.h~sparc-do_settimeofday-update include/asm-sparc/timer.h
--- 25/include/asm-sparc/timer.h~sparc-do_settimeofday-update	Wed Jun 11 15:50:54 2003
+++ 25-akpm/include/asm-sparc/timer.h	Wed Jun 11 15:51:05 2003
@@ -104,7 +104,7 @@ extern __volatile__ unsigned int *master
 extern __volatile__ unsigned int *master_l10_limit;
 
 /* FIXME: Make do_[gs]ettimeofday btfixup calls */
-BTFIXUPDEF_CALL(void, bus_do_settimeofday, struct timeval *tv)
+BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv)
 #define bus_do_settimeofday(tv) BTFIXUP_CALL(bus_do_settimeofday)(tv)
 
 #endif /* !(_SPARC_TIMER_H) */

_
