aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2013-01-15 11:09:47 -0500
committerJohn Stultz <john.stultz@linaro.org>2013-01-15 21:16:07 -0500
commit31ade30692dc9680bfc95700d794818fa3f754ac (patch)
treecb436c839b890d04f589b49f75cb0df59315158e
parentf0dbe81f0e7c39783ad25d9084bbcda131508993 (diff)
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: Feng Tang <feng.tang@intel.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
-rw-r--r--include/linux/time.h6
-rw-r--r--kernel/time/timekeeping.c16
2 files changed, 17 insertions, 5 deletions
diff --git a/include/linux/time.h b/include/linux/time.h
index 0015aea4c4a7..dfbc4e82e8ba 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -115,6 +115,12 @@ static inline bool timespec_valid_strict(const struct timespec *ts)
115 return true; 115 return true;
116} 116}
117 117
118extern bool persistent_clock_exist;
119static inline bool has_persistent_clock(void)
120{
121 return persistent_clock_exist;
122}
123
118extern void read_persistent_clock(struct timespec *ts); 124extern void read_persistent_clock(struct timespec *ts);
119extern void read_boot_clock(struct timespec *ts); 125extern void read_boot_clock(struct timespec *ts);
120extern int update_persistent_clock(struct timespec now); 126extern int update_persistent_clock(struct timespec now);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index dfc7f87eb332..b7a584177618 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -28,6 +28,9 @@ static struct timekeeper timekeeper;
28/* flag for if timekeeping is suspended */ 28/* flag for if timekeeping is suspended */
29int __read_mostly timekeeping_suspended; 29int __read_mostly timekeeping_suspended;
30 30
31/* Flag for if there is a persistent clock on this platform */
32bool __read_mostly persistent_clock_exist = false;
33
31static inline void tk_normalize_xtime(struct timekeeper *tk) 34static inline void tk_normalize_xtime(struct timekeeper *tk)
32{ 35{
33 while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) { 36 while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) {
@@ -609,12 +612,14 @@ void __init timekeeping_init(void)
609 struct timespec now, boot, tmp; 612 struct timespec now, boot, tmp;
610 613
611 read_persistent_clock(&now); 614 read_persistent_clock(&now);
615
612 if (!timespec_valid_strict(&now)) { 616 if (!timespec_valid_strict(&now)) {
613 pr_warn("WARNING: Persistent clock returned invalid value!\n" 617 pr_warn("WARNING: Persistent clock returned invalid value!\n"
614 " Check your CMOS/BIOS settings.\n"); 618 " Check your CMOS/BIOS settings.\n");
615 now.tv_sec = 0; 619 now.tv_sec = 0;
616 now.tv_nsec = 0; 620 now.tv_nsec = 0;
617 } 621 } else if (now.tv_sec || now.tv_nsec)
622 persistent_clock_exist = true;
618 623
619 read_boot_clock(&boot); 624 read_boot_clock(&boot);
620 if (!timespec_valid_strict(&boot)) { 625 if (!timespec_valid_strict(&boot)) {
@@ -687,11 +692,12 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
687{ 692{
688 struct timekeeper *tk = &timekeeper; 693 struct timekeeper *tk = &timekeeper;
689 unsigned long flags; 694 unsigned long flags;
690 struct timespec ts;
691 695
692 /* Make sure we don't set the clock twice */ 696 /*
693 read_persistent_clock(&ts); 697 * Make sure we don't set the clock twice, as timekeeping_resume()
694 if (!(ts.tv_sec == 0 && ts.tv_nsec == 0)) 698 * already did it
699 */
700 if (has_persistent_clock())
695 return; 701 return;
696 702
697 write_seqlock_irqsave(&tk->lock, flags); 703 write_seqlock_irqsave(&tk->lock, flags);