Commit b82db9f3 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] sparc: fix do_settimeofday() for new API

parent 2e508205
...@@ -191,7 +191,7 @@ volatile int pcic_speculative; ...@@ -191,7 +191,7 @@ volatile int pcic_speculative;
volatile int pcic_trapped; volatile int pcic_trapped;
static void pci_do_gettimeofday(struct timeval *tv); 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)) #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 timeval *tv) ...@@ -819,24 +819,26 @@ static void pci_do_gettimeofday(struct timeval *tv)
tv->tv_usec = usec; 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 * This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of * value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have * wall time. Discover what correction gettimeofday() would have
* made, and then undo it! * made, and then undo it!
*/ */
tv->tv_usec -= do_gettimeoffset(); tv->tv_nsec -= 1000 * (do_gettimeoffset() +
tv->tv_usec -= (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ); (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
while (tv->tv_usec < 0) { while (tv->tv_nsec < 0) {
tv->tv_usec += USEC_PER_SEC; tv->tv_nsec += NSEC_PER_SEC;
tv->tv_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_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) { if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) {
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 timeval *tv) ...@@ -848,11 +850,12 @@ static void pci_do_settimeofday(struct timeval *tv)
} }
xtime.tv_sec = tv->tv_sec; 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_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC; time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT; time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT;
return 0;
} }
#if 0 #if 0
......
...@@ -53,7 +53,7 @@ spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED; ...@@ -53,7 +53,7 @@ spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED;
unsigned long mstk48t02_regs = 0UL; unsigned long mstk48t02_regs = 0UL;
static struct mostek48t08 *mstk48t08_regs = 0; static struct mostek48t08 *mstk48t08_regs = 0;
static int set_rtc_mmss(unsigned long); 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 #ifdef CONFIG_SUN4
struct intersil *intersil_clock; struct intersil *intersil_clock;
...@@ -500,32 +500,37 @@ void do_gettimeofday(struct timeval *tv) ...@@ -500,32 +500,37 @@ void do_gettimeofday(struct timeval *tv)
tv->tv_usec = usec; tv->tv_usec = usec;
} }
void do_settimeofday(struct timeval *tv) int do_settimeofday(struct timespec *tv)
{ {
int ret;
write_seqlock_irq(&xtime_lock); write_seqlock_irq(&xtime_lock);
bus_do_settimeofday(tv); ret = bus_do_settimeofday(tv);
write_sequnlock_irq(&xtime_lock); 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 * This is revolting. We need to set "xtime" correctly. However, the
* value in this location is the value at the most recent update of * value in this location is the value at the most recent update of
* wall time. Discover what correction gettimeofday() would have * wall time. Discover what correction gettimeofday() would have
* made, and then undo it! * made, and then undo it!
*/ */
tv->tv_usec -= do_gettimeoffset(); tv->tv_nsec -= 1000 * (do_gettimeoffset() +
tv->tv_usec -= (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ); (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ));
while (tv->tv_usec < 0) { while (tv->tv_nsec < 0) {
tv->tv_usec += USEC_PER_SEC; tv->tv_nsec += NSEC_PER_SEC;
tv->tv_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_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) { if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) {
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 timeval *tv) ...@@ -537,11 +542,12 @@ static void sbus_do_settimeofday(struct timeval *tv)
} }
xtime.tv_sec = tv->tv_sec; 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_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC; time_status |= STA_UNSYNC;
time_maxerror = NTP_PHASE_LIMIT; time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT;
return 0;
} }
/* /*
......
...@@ -104,7 +104,7 @@ extern __volatile__ unsigned int *master_l10_counter; ...@@ -104,7 +104,7 @@ extern __volatile__ unsigned int *master_l10_counter;
extern __volatile__ unsigned int *master_l10_limit; extern __volatile__ unsigned int *master_l10_limit;
/* FIXME: Make do_[gs]ettimeofday btfixup calls */ /* 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) #define bus_do_settimeofday(tv) BTFIXUP_CALL(bus_do_settimeofday)(tv)
#endif /* !(_SPARC_TIMER_H) */ #endif /* !(_SPARC_TIMER_H) */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment