@@ -1100,8 +1100,8 @@ void __init timekeeping_init(void)
raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
}
-/* time in seconds when suspend began */
-static struct timespec64 timekeeping_suspend_time;
+/* time in seconds when suspend began for persistent clock */
+static struct timespec64 persistent_clock_suspendtime;
/**
* __timekeeping_inject_sleeptime - Internal function to add sleep interval
@@ -1229,8 +1229,9 @@ static void timekeeping_resume(void)
ts_delta = ns_to_timespec64(nsec);
suspendtime_found = true;
- } else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) {
- ts_delta = timespec64_sub(ts_new, timekeeping_suspend_time);
+ } else if (timespec64_compare(&ts_new,
+ &persistent_clock_suspendtime) > 0) {
+ ts_delta = timespec64_sub(ts_new, persistent_clock_suspendtime);
suspendtime_found = true;
}
@@ -1262,14 +1263,15 @@ static int timekeeping_suspend(void)
struct timespec tmp;
read_persistent_clock(&tmp);
- timekeeping_suspend_time = timespec_to_timespec64(tmp);
+ persistent_clock_suspendtime = timespec_to_timespec64(tmp);
/*
* On some systems the persistent_clock can not be detected at
* timekeeping_init by its return value, so if we see a valid
* value returned, update the persistent_clock_exists flag.
*/
- if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec)
+ if (persistent_clock_suspendtime.tv_sec ||
+ persistent_clock_suspendtime.tv_nsec)
persistent_clock_exist = true;
raw_spin_lock_irqsave(&timekeeper_lock, flags);
@@ -1277,24 +1279,28 @@ static int timekeeping_suspend(void)
timekeeping_forward_now(tk);
timekeeping_suspended = 1;
- /*
- * To avoid drift caused by repeated suspend/resumes,
- * which each can add ~1 second drift error,
- * try to compensate so the difference in system time
- * and persistent_clock time stays close to constant.
- */
- delta = timespec64_sub(tk_xtime(tk), timekeeping_suspend_time);
- delta_delta = timespec64_sub(delta, old_delta);
- if (abs(delta_delta.tv_sec) >= 2) {
+ if (has_persistent_clock()) {
/*
- * if delta_delta is too large, assume time correction
- * has occured and set old_delta to the current delta.
+ * To avoid drift caused by repeated suspend/resumes,
+ * which each can add ~1 second drift error,
+ * try to compensate so the difference in system time
+ * and persistent_clock time stays close to constant.
*/
- old_delta = delta;
- } else {
- /* Otherwise try to adjust old_system to compensate */
- timekeeping_suspend_time =
- timespec64_add(timekeeping_suspend_time, delta_delta);
+ delta = timespec64_sub(tk_xtime(tk),
+ persistent_clock_suspendtime);
+ delta_delta = timespec64_sub(delta, old_delta);
+ if (abs(delta_delta.tv_sec) >= 2) {
+ /*
+ * if delta_delta is too large, assume time correction
+ * has occurred and set old_delta to the current delta.
+ */
+ old_delta = delta;
+ } else {
+ /* Otherwise try to adjust old_system to compensate */
+ persistent_clock_suspendtime =
+ timespec64_add(persistent_clock_suspendtime,
+ delta_delta);
+ }
}
timekeeping_update(tk, TK_MIRROR);