diff options
author | Feng Tang <feng.tang@intel.com> | 2013-01-15 11:09:47 -0500 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2013-01-15 21:16:07 -0500 |
commit | 31ade30692dc9680bfc95700d794818fa3f754ac (patch) | |
tree | cb436c839b890d04f589b49f75cb0df59315158e | |
parent | f0dbe81f0e7c39783ad25d9084bbcda131508993 (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.h | 6 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 16 |
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 | ||
118 | extern bool persistent_clock_exist; | ||
119 | static inline bool has_persistent_clock(void) | ||
120 | { | ||
121 | return persistent_clock_exist; | ||
122 | } | ||
123 | |||
118 | extern void read_persistent_clock(struct timespec *ts); | 124 | extern void read_persistent_clock(struct timespec *ts); |
119 | extern void read_boot_clock(struct timespec *ts); | 125 | extern void read_boot_clock(struct timespec *ts); |
120 | extern int update_persistent_clock(struct timespec now); | 126 | extern 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 */ |
29 | int __read_mostly timekeeping_suspended; | 29 | int __read_mostly timekeeping_suspended; |
30 | 30 | ||
31 | /* Flag for if there is a persistent clock on this platform */ | ||
32 | bool __read_mostly persistent_clock_exist = false; | ||
33 | |||
31 | static inline void tk_normalize_xtime(struct timekeeper *tk) | 34 | static 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); |