Commit 31ade306 authored by Feng Tang's avatar Feng Tang Committed by John Stultz

timekeeping: Add persistent_clock_exist flag

In current kernel, there are several places which need to check
whether there is a persistent clock for the platform. Current check
is done by calling the read_persistent_clock() and validating its
return value.

So one optimization is to do the check only once in timekeeping_init(),
and use a flag persistent_clock_exist to record it.

v2: Add a has_persistent_clock() helper function, as suggested by John.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Stultz <john.stultz@linaro.org>
Signed-off-by: default avatarFeng Tang <feng.tang@intel.com>
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
parent f0dbe81f
...@@ -115,6 +115,12 @@ static inline bool timespec_valid_strict(const struct timespec *ts) ...@@ -115,6 +115,12 @@ static inline bool timespec_valid_strict(const struct timespec *ts)
return true; 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_persistent_clock(struct timespec *ts);
extern void read_boot_clock(struct timespec *ts); extern void read_boot_clock(struct timespec *ts);
extern int update_persistent_clock(struct timespec now); extern int update_persistent_clock(struct timespec now);
......
...@@ -28,6 +28,9 @@ static struct timekeeper timekeeper; ...@@ -28,6 +28,9 @@ static struct timekeeper timekeeper;
/* flag for if timekeeping is suspended */ /* flag for if timekeeping is suspended */
int __read_mostly timekeeping_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) static inline void tk_normalize_xtime(struct timekeeper *tk)
{ {
while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) { while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) {
...@@ -609,12 +612,14 @@ void __init timekeeping_init(void) ...@@ -609,12 +612,14 @@ void __init timekeeping_init(void)
struct timespec now, boot, tmp; struct timespec now, boot, tmp;
read_persistent_clock(&now); read_persistent_clock(&now);
if (!timespec_valid_strict(&now)) { if (!timespec_valid_strict(&now)) {
pr_warn("WARNING: Persistent clock returned invalid value!\n" pr_warn("WARNING: Persistent clock returned invalid value!\n"
" Check your CMOS/BIOS settings.\n"); " Check your CMOS/BIOS settings.\n");
now.tv_sec = 0; now.tv_sec = 0;
now.tv_nsec = 0; now.tv_nsec = 0;
} } else if (now.tv_sec || now.tv_nsec)
persistent_clock_exist = true;
read_boot_clock(&boot); read_boot_clock(&boot);
if (!timespec_valid_strict(&boot)) { if (!timespec_valid_strict(&boot)) {
...@@ -687,11 +692,12 @@ void timekeeping_inject_sleeptime(struct timespec *delta) ...@@ -687,11 +692,12 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
{ {
struct timekeeper *tk = &timekeeper; struct timekeeper *tk = &timekeeper;
unsigned long flags; unsigned long flags;
struct timespec ts;
/* Make sure we don't set the clock twice */ /*
read_persistent_clock(&ts); * Make sure we don't set the clock twice, as timekeeping_resume()
if (!(ts.tv_sec == 0 && ts.tv_nsec == 0)) * already did it
*/
if (has_persistent_clock())
return; return;
write_seqlock_irqsave(&tk->lock, flags); write_seqlock_irqsave(&tk->lock, flags);
......
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