From 585ca7254cdf4d6604ed726e0305524cfa5e3f4d Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Wed, 16 Jan 2013 00:09:47 +0800 Subject: [PATCH] --- yaml --- r: 350163 b: refs/heads/master c: 31ade30692dc9680bfc95700d794818fa3f754ac h: refs/heads/master i: 350161: 9f8d94c7a37638fa4ff6ebacbe9d603a526fcdb9 350159: 85f24f6c85435326b896987a9a9237bd86c1b22e v: v3 --- [refs] | 2 +- trunk/include/linux/time.h | 6 ++++++ trunk/kernel/time/timekeeping.c | 16 +++++++++++----- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 92abb9d4c8bb..2f00fc384075 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f0dbe81f0e7c39783ad25d9084bbcda131508993 +refs/heads/master: 31ade30692dc9680bfc95700d794818fa3f754ac diff --git a/trunk/include/linux/time.h b/trunk/include/linux/time.h index 0015aea4c4a7..dfbc4e82e8ba 100644 --- a/trunk/include/linux/time.h +++ b/trunk/include/linux/time.h @@ -115,6 +115,12 @@ static inline bool timespec_valid_strict(const struct timespec *ts) return true; } +extern bool persistent_clock_exist; +static inline bool has_persistent_clock(void) +{ + return persistent_clock_exist; +} + extern void read_persistent_clock(struct timespec *ts); extern void read_boot_clock(struct timespec *ts); extern int update_persistent_clock(struct timespec now); diff --git a/trunk/kernel/time/timekeeping.c b/trunk/kernel/time/timekeeping.c index dfc7f87eb332..b7a584177618 100644 --- a/trunk/kernel/time/timekeeping.c +++ b/trunk/kernel/time/timekeeping.c @@ -28,6 +28,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)) { @@ -609,12 +612,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)) { @@ -687,11 +692,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);