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) */ _