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

Commit 97ac984d authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

Merge branch 'fortglx/3.4/time' of git://git.linaro.org/people/jstultz/linux into timers/core

parents 8682df25 cc06268c
Loading
Loading
Loading
Loading
+1 −16
Original line number Diff line number Diff line
@@ -234,23 +234,9 @@ struct timex {
extern unsigned long tick_usec;		/* USER_HZ period (usec) */
extern unsigned long tick_nsec;		/* ACTHZ          period (nsec) */

/*
 * phase-lock loop variables
 */
extern int time_status;		/* clock synchronization status bits */

extern void ntp_init(void);
extern void ntp_clear(void);

/**
 * ntp_synced - Returns 1 if the NTP status is not UNSYNC
 *
 */
static inline int ntp_synced(void)
{
	return !(time_status & STA_UNSYNC);
}

/* Required to safely shift negative values */
#define shift_right(x, s) ({	\
	__typeof__(x) __x = (x);	\
@@ -264,10 +250,9 @@ static inline int ntp_synced(void)
#define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ)

/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */
extern u64 tick_length;
extern u64 ntp_tick_length(void);

extern void second_overflow(void);
extern void update_ntp_one_tick(void);
extern int do_adjtimex(struct timex *);
extern void hardpps(const struct timespec *, const struct timespec *);

+63 −20
Original line number Diff line number Diff line
@@ -22,13 +22,16 @@
 * NTP timekeeping variables:
 */

DEFINE_SPINLOCK(ntp_lock);


/* USER_HZ period (usecs): */
unsigned long			tick_usec = TICK_USEC;

/* ACTHZ period (nsecs): */
unsigned long			tick_nsec;

u64				tick_length;
static u64			tick_length;
static u64			tick_length_base;

static struct hrtimer		leap_timer;
@@ -49,7 +52,7 @@ static struct hrtimer leap_timer;
static int			time_state = TIME_OK;

/* clock status bits:							*/
int				time_status = STA_UNSYNC;
static int			time_status = STA_UNSYNC;

/* TAI offset (secs):							*/
static long			time_tai;
@@ -133,7 +136,7 @@ static inline void pps_reset_freq_interval(void)
/**
 * pps_clear - Clears the PPS state variables
 *
 * Must be called while holding a write on the xtime_lock
 * Must be called while holding a write on the ntp_lock
 */
static inline void pps_clear(void)
{
@@ -149,7 +152,7 @@ static inline void pps_clear(void)
 * the last PPS signal. When it reaches 0, indicate that PPS signal is
 * missing.
 *
 * Must be called while holding a write on the xtime_lock
 * Must be called while holding a write on the ntp_lock
 */
static inline void pps_dec_valid(void)
{
@@ -233,6 +236,17 @@ static inline void pps_fill_timex(struct timex *txc)

#endif /* CONFIG_NTP_PPS */


/**
 * ntp_synced - Returns 1 if the NTP status is not UNSYNC
 *
 */
static inline int ntp_synced(void)
{
	return !(time_status & STA_UNSYNC);
}


/*
 * NTP methods:
 */
@@ -330,11 +344,13 @@ static void ntp_update_offset(long offset)

/**
 * ntp_clear - Clears the NTP state variables
 *
 * Must be called while holding a write on the xtime_lock
 */
void ntp_clear(void)
{
	unsigned long flags;

	spin_lock_irqsave(&ntp_lock, flags);

	time_adjust	= 0;		/* stop active adjtime() */
	time_status	|= STA_UNSYNC;
	time_maxerror	= NTP_PHASE_LIMIT;
@@ -347,8 +363,23 @@ void ntp_clear(void)

	/* Clear PPS state variables */
	pps_clear();
	spin_unlock_irqrestore(&ntp_lock, flags);

}


u64 ntp_tick_length(void)
{
	unsigned long flags;
	s64 ret;

	spin_lock_irqsave(&ntp_lock, flags);
	ret = tick_length;
	spin_unlock_irqrestore(&ntp_lock, flags);
	return ret;
}


/*
 * Leap second processing. If in leap-insert state at the end of the
 * day, the system clock is set back one second; if in leap-delete
@@ -357,14 +388,15 @@ void ntp_clear(void)
static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
{
	enum hrtimer_restart res = HRTIMER_NORESTART;
	unsigned long flags;
	int leap = 0;

	write_seqlock(&xtime_lock);

	spin_lock_irqsave(&ntp_lock, flags);
	switch (time_state) {
	case TIME_OK:
		break;
	case TIME_INS:
		timekeeping_leap_insert(-1);
		leap = -1;
		time_state = TIME_OOP;
		printk(KERN_NOTICE
			"Clock: inserting leap second 23:59:60 UTC\n");
@@ -372,7 +404,7 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
		res = HRTIMER_RESTART;
		break;
	case TIME_DEL:
		timekeeping_leap_insert(1);
		leap = 1;
		time_tai--;
		time_state = TIME_WAIT;
		printk(KERN_NOTICE
@@ -387,8 +419,14 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
			time_state = TIME_OK;
		break;
	}
	spin_unlock_irqrestore(&ntp_lock, flags);

	write_sequnlock(&xtime_lock);
	/*
	 * We have to call this outside of the ntp_lock to keep
	 * the proper locking hierarchy
	 */
	if (leap)
		timekeeping_leap_insert(leap);

	return res;
}
@@ -404,6 +442,9 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
void second_overflow(void)
{
	s64 delta;
	unsigned long flags;

	spin_lock_irqsave(&ntp_lock, flags);

	/* Bump the maxerror field */
	time_maxerror += MAXFREQ / NSEC_PER_USEC;
@@ -423,23 +464,25 @@ void second_overflow(void)
	pps_dec_valid();

	if (!time_adjust)
		return;
		goto out;

	if (time_adjust > MAX_TICKADJ) {
		time_adjust -= MAX_TICKADJ;
		tick_length += MAX_TICKADJ_SCALED;
		return;
		goto out;
	}

	if (time_adjust < -MAX_TICKADJ) {
		time_adjust += MAX_TICKADJ;
		tick_length -= MAX_TICKADJ_SCALED;
		return;
		goto out;
	}

	tick_length += (s64)(time_adjust * NSEC_PER_USEC / NTP_INTERVAL_FREQ)
							 << NTP_SCALE_SHIFT;
	time_adjust = 0;
out:
	spin_unlock_irqrestore(&ntp_lock, flags);
}

#ifdef CONFIG_GENERIC_CMOS_UPDATE
@@ -663,7 +706,7 @@ int do_adjtimex(struct timex *txc)

	getnstimeofday(&ts);

	write_seqlock_irq(&xtime_lock);
	spin_lock_irq(&ntp_lock);

	if (txc->modes & ADJ_ADJTIME) {
		long save_adjust = time_adjust;
@@ -705,7 +748,7 @@ int do_adjtimex(struct timex *txc)
	/* fill PPS status fields */
	pps_fill_timex(txc);

	write_sequnlock_irq(&xtime_lock);
	spin_unlock_irq(&ntp_lock);

	txc->time.tv_sec = ts.tv_sec;
	txc->time.tv_usec = ts.tv_nsec;
@@ -903,7 +946,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)

	pts_norm = pps_normalize_ts(*phase_ts);

	write_seqlock_irqsave(&xtime_lock, flags);
	spin_lock_irqsave(&ntp_lock, flags);

	/* clear the error bits, they will be set again if needed */
	time_status &= ~(STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR);
@@ -916,7 +959,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
	 * just start the frequency interval */
	if (unlikely(pps_fbase.tv_sec == 0)) {
		pps_fbase = *raw_ts;
		write_sequnlock_irqrestore(&xtime_lock, flags);
		spin_unlock_irqrestore(&ntp_lock, flags);
		return;
	}

@@ -931,7 +974,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
		time_status |= STA_PPSJITTER;
		/* restart the frequency calibration interval */
		pps_fbase = *raw_ts;
		write_sequnlock_irqrestore(&xtime_lock, flags);
		spin_unlock_irqrestore(&ntp_lock, flags);
		pr_err("hardpps: PPSJITTER: bad pulse\n");
		return;
	}
@@ -948,7 +991,7 @@ void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)

	hardpps_update_phase(pts_norm.nsec);

	write_sequnlock_irqrestore(&xtime_lock, flags);
	spin_unlock_irqrestore(&ntp_lock, flags);
}
EXPORT_SYMBOL(hardpps);

+184 −154

File changed.

Preview size limit exceeded, changes collapsed.