Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f564ad6 authored by Bob Picco's avatar Bob Picco Committed by Tony Luck
Browse files

[IA64] remove time interpolator



Remove time_interpolator code (This is generic code, but
only user was ia64.  It has been superseded by the
CONFIG_GENERIC_TIME code).

Signed-off-by: default avatarBob Picco <bob.picco@hp.com>
Signed-off-by: default avatarJohn Stultz <johnstul@us.ibm.com>
Signed-off-by: default avatarPeter Keilty <peter.keilty@hp.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 0aa366f3
Loading
Loading
Loading
Loading
+0 −41
Original line number Diff line number Diff line
Time Interpolators
------------------

Time interpolators are a base of time calculation between timer ticks and
allow an accurate determination of time down to the accuracy of the time
source in nanoseconds.

The architecture specific code typically provides gettimeofday and
settimeofday under Linux. The time interpolator provides both if an arch
defines CONFIG_TIME_INTERPOLATION. The arch still must set up timer tick
operations and call the necessary functions to advance the clock.

With the time interpolator a standardized interface exists for time
interpolation between ticks. The provided logic is highly scalable
and has been tested in SMP situations of up to 512 CPUs.

If CONFIG_TIME_INTERPOLATION is defined then the architecture specific code
(or the device drivers - like HPET) may register time interpolators.
These are typically defined in the following way:

static struct time_interpolator my_interpolator {
	.frequency = MY_FREQUENCY,
	.source = TIME_SOURCE_MMIO32,
	.shift = 8,		/* scaling for higher accuracy */
	.drift = -1,		/* Unknown drift */
	.jitter = 0		/* time source is stable */
};

void time_init(void)
{
	....
	/* Initialization of the timer *.
	my_interpolator.address = &my_timer;
	register_time_interpolator(&my_interpolator);
	....
}

For more details see include/linux/timex.h and kernel/timer.c.

Christoph Lameter <christoph@lameter.com>, October 31, 2004
+0 −60
Original line number Diff line number Diff line
@@ -224,66 +224,6 @@ static inline int ntp_synced(void)
	__x < 0 ? -(-__x >> __s) : __x >> __s;	\
})


#ifdef CONFIG_TIME_INTERPOLATION

#define TIME_SOURCE_CPU 0
#define TIME_SOURCE_MMIO64 1
#define TIME_SOURCE_MMIO32 2
#define TIME_SOURCE_FUNCTION 3

/* For proper operations time_interpolator clocks must run slightly slower
 * than the standard clock since the interpolator may only correct by having
 * time jump forward during a tick. A slower clock is usually a side effect
 * of the integer divide of the nanoseconds in a second by the frequency.
 * The accuracy of the division can be increased by specifying a shift.
 * However, this may cause the clock not to be slow enough.
 * The interpolator will self-tune the clock by slowing down if no
 * resets occur or speeding up if the time jumps per analysis cycle
 * become too high.
 *
 * Setting jitter compensates for a fluctuating timesource by comparing
 * to the last value read from the timesource to insure that an earlier value
 * is not returned by a later call. The price to pay
 * for the compensation is that the timer routines are not as scalable anymore.
 */

struct time_interpolator {
	u16 source;			/* time source flags */
	u8 shift;			/* increases accuracy of multiply by shifting. */
				/* Note that bits may be lost if shift is set too high */
	u8 jitter;			/* if set compensate for fluctuations */
	u32 nsec_per_cyc;		/* set by register_time_interpolator() */
	void *addr;			/* address of counter or function */
	cycles_t mask;			/* mask the valid bits of the counter */
	unsigned long offset;		/* nsec offset at last update of interpolator */
	u64 last_counter;		/* counter value in units of the counter at last update */
	cycles_t last_cycle;		/* Last timer value if TIME_SOURCE_JITTER is set */
	u64 frequency;			/* frequency in counts/second */
	long drift;			/* drift in parts-per-million (or -1) */
	unsigned long skips;		/* skips forward */
	unsigned long ns_skipped;	/* nanoseconds skipped */
	struct time_interpolator *next;
};

extern void register_time_interpolator(struct time_interpolator *);
extern void unregister_time_interpolator(struct time_interpolator *);
extern void time_interpolator_reset(void);
extern unsigned long time_interpolator_get_offset(void);
extern void time_interpolator_update(long delta_nsec);

#else /* !CONFIG_TIME_INTERPOLATION */

static inline void time_interpolator_reset(void)
{
}

static inline void time_interpolator_update(long delta_nsec)
{
}

#endif /* !CONFIG_TIME_INTERPOLATION */

#define TICK_LENGTH_SHIFT	32

#ifdef CONFIG_NO_HZ
+0 −88
Original line number Diff line number Diff line
@@ -136,7 +136,6 @@ static inline void warp_clock(void)
	write_seqlock_irq(&xtime_lock);
	wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
	xtime.tv_sec += sys_tz.tz_minuteswest * 60;
	time_interpolator_reset();
	write_sequnlock_irq(&xtime_lock);
	clock_was_set();
}
@@ -309,92 +308,6 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran)
}
EXPORT_SYMBOL(timespec_trunc);

#ifdef CONFIG_TIME_INTERPOLATION
void getnstimeofday (struct timespec *tv)
{
	unsigned long seq,sec,nsec;

	do {
		seq = read_seqbegin(&xtime_lock);
		sec = xtime.tv_sec;
		nsec = xtime.tv_nsec+time_interpolator_get_offset();
	} while (unlikely(read_seqretry(&xtime_lock, seq)));

	while (unlikely(nsec >= NSEC_PER_SEC)) {
		nsec -= NSEC_PER_SEC;
		++sec;
	}
	tv->tv_sec = sec;
	tv->tv_nsec = nsec;
}
EXPORT_SYMBOL_GPL(getnstimeofday);

int do_settimeofday (struct timespec *tv)
{
	time_t wtm_sec, sec = tv->tv_sec;
	long wtm_nsec, nsec = tv->tv_nsec;

	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
		return -EINVAL;

	write_seqlock_irq(&xtime_lock);
	{
		wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
		wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);

		set_normalized_timespec(&xtime, sec, nsec);
		set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);

		time_adjust = 0;		/* stop active adjtime() */
		time_status |= STA_UNSYNC;
		time_maxerror = NTP_PHASE_LIMIT;
		time_esterror = NTP_PHASE_LIMIT;
		time_interpolator_reset();
	}
	write_sequnlock_irq(&xtime_lock);
	clock_was_set();
	return 0;
}
EXPORT_SYMBOL(do_settimeofday);

void do_gettimeofday (struct timeval *tv)
{
	unsigned long seq, nsec, usec, sec, offset;
	do {
		seq = read_seqbegin(&xtime_lock);
		offset = time_interpolator_get_offset();
		sec = xtime.tv_sec;
		nsec = xtime.tv_nsec;
	} while (unlikely(read_seqretry(&xtime_lock, seq)));

	usec = (nsec + offset) / 1000;

	while (unlikely(usec >= USEC_PER_SEC)) {
		usec -= USEC_PER_SEC;
		++sec;
	}

	tv->tv_sec = sec;
	tv->tv_usec = usec;

	/*
	 * Make sure xtime.tv_sec [returned by sys_time()] always
	 * follows the gettimeofday() result precisely. This
	 * condition is extremely unlikely, it can hit at most
	 * once per second:
	 */
	if (unlikely(xtime.tv_sec != tv->tv_sec)) {
		unsigned long flags;

		write_seqlock_irqsave(&xtime_lock, flags);
		update_wall_time();
		write_sequnlock_irqrestore(&xtime_lock, flags);
	}
}
EXPORT_SYMBOL(do_gettimeofday);

#else	/* CONFIG_TIME_INTERPOLATION */

#ifndef CONFIG_GENERIC_TIME
/*
 * Simulate gettimeofday using do_gettimeofday which only allows a timeval
@@ -410,7 +323,6 @@ void getnstimeofday(struct timespec *tv)
}
EXPORT_SYMBOL_GPL(getnstimeofday);
#endif
#endif	/* CONFIG_TIME_INTERPOLATION */

/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+0 −10
Original line number Diff line number Diff line
@@ -116,11 +116,6 @@ void second_overflow(void)
		if (xtime.tv_sec % 86400 == 0) {
			xtime.tv_sec--;
			wall_to_monotonic.tv_sec++;
			/*
			 * The timer interpolator will make time change
			 * gradually instead of an immediate jump by one second
			 */
			time_interpolator_update(-NSEC_PER_SEC);
			time_state = TIME_OOP;
			printk(KERN_NOTICE "Clock: inserting leap second "
					"23:59:60 UTC\n");
@@ -130,11 +125,6 @@ void second_overflow(void)
		if ((xtime.tv_sec + 1) % 86400 == 0) {
			xtime.tv_sec++;
			wall_to_monotonic.tv_sec--;
			/*
			 * Use of time interpolator for a gradual change of
			 * time
			 */
			time_interpolator_update(NSEC_PER_SEC);
			time_state = TIME_WAIT;
			printk(KERN_NOTICE "Clock: deleting leap second "
					"23:59:59 UTC\n");
+0 −4
Original line number Diff line number Diff line
@@ -466,10 +466,6 @@ void update_wall_time(void)
			second_overflow();
		}

		/* interpolator bits */
		time_interpolator_update(clock->xtime_interval
						>> clock->shift);

		/* accumulate error between NTP and clock interval */
		clock->error += current_tick_length();
		clock->error -= clock->xtime_interval << (TICK_LENGTH_SHIFT - clock->shift);
Loading