|
@@ -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);
|