Merge branch 'fortglx/3.9/time' of git://git.linaro.org/people/jstultz/linux into timers/core
Trivial conflict in arch/x86/Kconfig Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
@@ -12,6 +12,11 @@ config CLOCKSOURCE_WATCHDOG
|
||||
config ARCH_CLOCKSOURCE_DATA
|
||||
bool
|
||||
|
||||
# Platforms has a persistent clock
|
||||
config ALWAYS_USE_PERSISTENT_CLOCK
|
||||
bool
|
||||
default n
|
||||
|
||||
# Timekeeping vsyscall support
|
||||
config GENERIC_TIME_VSYSCALL
|
||||
bool
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include <linux/time.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#include "tick-internal.h"
|
||||
|
||||
@@ -483,8 +484,7 @@ out:
|
||||
return leap;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_CMOS_UPDATE
|
||||
|
||||
#if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC)
|
||||
static void sync_cmos_clock(struct work_struct *work);
|
||||
|
||||
static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
|
||||
@@ -510,14 +510,22 @@ static void sync_cmos_clock(struct work_struct *work)
|
||||
}
|
||||
|
||||
getnstimeofday(&now);
|
||||
if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
|
||||
if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) {
|
||||
fail = -ENODEV;
|
||||
#ifdef CONFIG_GENERIC_CMOS_UPDATE
|
||||
fail = update_persistent_clock(now);
|
||||
#endif
|
||||
#ifdef CONFIG_RTC_SYSTOHC
|
||||
if (fail == -ENODEV)
|
||||
fail = rtc_set_ntp_time(now);
|
||||
#endif
|
||||
}
|
||||
|
||||
next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
|
||||
if (next.tv_nsec <= 0)
|
||||
next.tv_nsec += NSEC_PER_SEC;
|
||||
|
||||
if (!fail)
|
||||
if (!fail || fail == -ENODEV)
|
||||
next.tv_sec = 659;
|
||||
else
|
||||
next.tv_sec = 0;
|
||||
|
@@ -29,6 +29,9 @@ static struct timekeeper timekeeper;
|
||||
/* flag for if timekeeping is suspended */
|
||||
int __read_mostly timekeeping_suspended;
|
||||
|
||||
/* Flag for if there is a persistent clock on this platform */
|
||||
bool __read_mostly persistent_clock_exist = false;
|
||||
|
||||
static inline void tk_normalize_xtime(struct timekeeper *tk)
|
||||
{
|
||||
while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) {
|
||||
@@ -264,19 +267,18 @@ static void timekeeping_forward_now(struct timekeeper *tk)
|
||||
}
|
||||
|
||||
/**
|
||||
* getnstimeofday - Returns the time of day in a timespec
|
||||
* __getnstimeofday - Returns the time of day in a timespec.
|
||||
* @ts: pointer to the timespec to be set
|
||||
*
|
||||
* Returns the time of day in a timespec.
|
||||
* Updates the time of day in the timespec.
|
||||
* Returns 0 on success, or -ve when suspended (timespec will be undefined).
|
||||
*/
|
||||
void getnstimeofday(struct timespec *ts)
|
||||
int __getnstimeofday(struct timespec *ts)
|
||||
{
|
||||
struct timekeeper *tk = &timekeeper;
|
||||
unsigned long seq;
|
||||
s64 nsecs = 0;
|
||||
|
||||
WARN_ON(timekeeping_suspended);
|
||||
|
||||
do {
|
||||
seq = read_seqbegin(&tk->lock);
|
||||
|
||||
@@ -287,6 +289,26 @@ void getnstimeofday(struct timespec *ts)
|
||||
|
||||
ts->tv_nsec = 0;
|
||||
timespec_add_ns(ts, nsecs);
|
||||
|
||||
/*
|
||||
* Do not bail out early, in case there were callers still using
|
||||
* the value, even in the face of the WARN_ON.
|
||||
*/
|
||||
if (unlikely(timekeeping_suspended))
|
||||
return -EAGAIN;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__getnstimeofday);
|
||||
|
||||
/**
|
||||
* getnstimeofday - Returns the time of day in a timespec.
|
||||
* @ts: pointer to the timespec to be set
|
||||
*
|
||||
* Returns the time of day in a timespec (WARN if suspended).
|
||||
*/
|
||||
void getnstimeofday(struct timespec *ts)
|
||||
{
|
||||
WARN_ON(__getnstimeofday(ts));
|
||||
}
|
||||
EXPORT_SYMBOL(getnstimeofday);
|
||||
|
||||
@@ -640,12 +662,14 @@ void __init timekeeping_init(void)
|
||||
struct timespec now, boot, tmp;
|
||||
|
||||
read_persistent_clock(&now);
|
||||
|
||||
if (!timespec_valid_strict(&now)) {
|
||||
pr_warn("WARNING: Persistent clock returned invalid value!\n"
|
||||
" Check your CMOS/BIOS settings.\n");
|
||||
now.tv_sec = 0;
|
||||
now.tv_nsec = 0;
|
||||
}
|
||||
} else if (now.tv_sec || now.tv_nsec)
|
||||
persistent_clock_exist = true;
|
||||
|
||||
read_boot_clock(&boot);
|
||||
if (!timespec_valid_strict(&boot)) {
|
||||
@@ -718,11 +742,12 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
|
||||
{
|
||||
struct timekeeper *tk = &timekeeper;
|
||||
unsigned long flags;
|
||||
struct timespec ts;
|
||||
|
||||
/* Make sure we don't set the clock twice */
|
||||
read_persistent_clock(&ts);
|
||||
if (!(ts.tv_sec == 0 && ts.tv_nsec == 0))
|
||||
/*
|
||||
* Make sure we don't set the clock twice, as timekeeping_resume()
|
||||
* already did it
|
||||
*/
|
||||
if (has_persistent_clock())
|
||||
return;
|
||||
|
||||
write_seqlock_irqsave(&tk->lock, flags);
|
||||
|
Reference in New Issue
Block a user