aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorXunlei Pang <pang.xunlei@linaro.org>2015-04-01 23:34:38 -0400
committerIngo Molnar <mingo@kernel.org>2015-04-03 02:18:34 -0400
commit0fa88cb4b82b5cf7429bc1cef9db006ca035754e (patch)
treeb3800f619ee137e6914e56bf803968642bd389af /kernel
parent264bb3f79f2a465477cdcd2f0554e21aedc443a3 (diff)
time, drivers/rtc: Don't bother with rtc_resume() for the nonstop clocksource
If a system does not provide a persistent_clock(), the time will be updated on resume by rtc_resume(). With the addition of the non-stop clocksources for suspend timing, those systems set the time on resume in timekeeping_resume(), but may not provide a valid persistent_clock(). This results in the rtc_resume() logic thinking no one has set the time and it then will over-write the suspend time again, which is not necessary and only increases clock error. So, fix this for rtc_resume(). This patch also improves the name of persistent_clock_exist to make it more grammatical. Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org> Signed-off-by: John Stultz <john.stultz@linaro.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1427945681-29972-19-git-send-email-john.stultz@linaro.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/timekeeping.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b7db4916415b..79b9bc6e7876 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -64,9 +64,6 @@ static struct tk_fast tk_fast_raw ____cacheline_aligned;
64/* flag for if timekeeping is suspended */ 64/* flag for if timekeeping is suspended */
65int __read_mostly timekeeping_suspended; 65int __read_mostly timekeeping_suspended;
66 66
67/* Flag for if there is a persistent clock on this platform */
68bool __read_mostly persistent_clock_exist = false;
69
70static inline void tk_normalize_xtime(struct timekeeper *tk) 67static inline void tk_normalize_xtime(struct timekeeper *tk)
71{ 68{
72 while (tk->tkr_mono.xtime_nsec >= ((u64)NSEC_PER_SEC << tk->tkr_mono.shift)) { 69 while (tk->tkr_mono.xtime_nsec >= ((u64)NSEC_PER_SEC << tk->tkr_mono.shift)) {
@@ -1204,6 +1201,12 @@ void __weak read_boot_clock64(struct timespec64 *ts64)
1204 *ts64 = timespec_to_timespec64(ts); 1201 *ts64 = timespec_to_timespec64(ts);
1205} 1202}
1206 1203
1204/* Flag for if timekeeping_resume() has injected sleeptime */
1205static bool sleeptime_injected;
1206
1207/* Flag for if there is a persistent clock on this platform */
1208static bool persistent_clock_exists;
1209
1207/* 1210/*
1208 * timekeeping_init - Initializes the clocksource and common timekeeping values 1211 * timekeeping_init - Initializes the clocksource and common timekeeping values
1209 */ 1212 */
@@ -1221,7 +1224,7 @@ void __init timekeeping_init(void)
1221 now.tv_sec = 0; 1224 now.tv_sec = 0;
1222 now.tv_nsec = 0; 1225 now.tv_nsec = 0;
1223 } else if (now.tv_sec || now.tv_nsec) 1226 } else if (now.tv_sec || now.tv_nsec)
1224 persistent_clock_exist = true; 1227 persistent_clock_exists = true;
1225 1228
1226 read_boot_clock64(&boot); 1229 read_boot_clock64(&boot);
1227 if (!timespec64_valid_strict(&boot)) { 1230 if (!timespec64_valid_strict(&boot)) {
@@ -1282,11 +1285,47 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
1282 1285
1283#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE) 1286#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
1284/** 1287/**
1288 * We have three kinds of time sources to use for sleep time
1289 * injection, the preference order is:
1290 * 1) non-stop clocksource
1291 * 2) persistent clock (ie: RTC accessible when irqs are off)
1292 * 3) RTC
1293 *
1294 * 1) and 2) are used by timekeeping, 3) by RTC subsystem.
1295 * If system has neither 1) nor 2), 3) will be used finally.
1296 *
1297 *
1298 * If timekeeping has injected sleeptime via either 1) or 2),
1299 * 3) becomes needless, so in this case we don't need to call
1300 * rtc_resume(), and this is what timekeeping_rtc_skipresume()
1301 * means.
1302 */
1303bool timekeeping_rtc_skipresume(void)
1304{
1305 return sleeptime_injected;
1306}
1307
1308/**
1309 * 1) can be determined whether to use or not only when doing
1310 * timekeeping_resume() which is invoked after rtc_suspend(),
1311 * so we can't skip rtc_suspend() surely if system has 1).
1312 *
1313 * But if system has 2), 2) will definitely be used, so in this
1314 * case we don't need to call rtc_suspend(), and this is what
1315 * timekeeping_rtc_skipsuspend() means.
1316 */
1317bool timekeeping_rtc_skipsuspend(void)
1318{
1319 return persistent_clock_exists;
1320}
1321
1322/**
1285 * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values 1323 * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
1286 * @delta: pointer to a timespec64 delta value 1324 * @delta: pointer to a timespec64 delta value
1287 * 1325 *
1288 * This hook is for architectures that cannot support read_persistent_clock64 1326 * This hook is for architectures that cannot support read_persistent_clock64
1289 * because their RTC/persistent clock is only accessible when irqs are enabled. 1327 * because their RTC/persistent clock is only accessible when irqs are enabled.
1328 * and also don't have an effective nonstop clocksource.
1290 * 1329 *
1291 * This function should only be called by rtc_resume(), and allows 1330 * This function should only be called by rtc_resume(), and allows
1292 * a suspend offset to be injected into the timekeeping values. 1331 * a suspend offset to be injected into the timekeeping values.
@@ -1296,13 +1335,6 @@ void timekeeping_inject_sleeptime64(struct timespec64 *delta)
1296 struct timekeeper *tk = &tk_core.timekeeper; 1335 struct timekeeper *tk = &tk_core.timekeeper;
1297 unsigned long flags; 1336 unsigned long flags;
1298 1337
1299 /*
1300 * Make sure we don't set the clock twice, as timekeeping_resume()
1301 * already did it
1302 */
1303 if (has_persistent_clock())
1304 return;
1305
1306 raw_spin_lock_irqsave(&timekeeper_lock, flags); 1338 raw_spin_lock_irqsave(&timekeeper_lock, flags);
1307 write_seqcount_begin(&tk_core.seq); 1339 write_seqcount_begin(&tk_core.seq);
1308 1340
@@ -1334,8 +1366,8 @@ void timekeeping_resume(void)
1334 unsigned long flags; 1366 unsigned long flags;
1335 struct timespec64 ts_new, ts_delta; 1367 struct timespec64 ts_new, ts_delta;
1336 cycle_t cycle_now, cycle_delta; 1368 cycle_t cycle_now, cycle_delta;
1337 bool suspendtime_found = false;
1338 1369
1370 sleeptime_injected = false;
1339 read_persistent_clock64(&ts_new); 1371 read_persistent_clock64(&ts_new);
1340 1372
1341 clockevents_resume(); 1373 clockevents_resume();
@@ -1381,13 +1413,13 @@ void timekeeping_resume(void)
1381 nsec += ((u64) cycle_delta * mult) >> shift; 1413 nsec += ((u64) cycle_delta * mult) >> shift;
1382 1414
1383 ts_delta = ns_to_timespec64(nsec); 1415 ts_delta = ns_to_timespec64(nsec);
1384 suspendtime_found = true; 1416 sleeptime_injected = true;
1385 } else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) { 1417 } else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) {
1386 ts_delta = timespec64_sub(ts_new, timekeeping_suspend_time); 1418 ts_delta = timespec64_sub(ts_new, timekeeping_suspend_time);
1387 suspendtime_found = true; 1419 sleeptime_injected = true;
1388 } 1420 }
1389 1421
1390 if (suspendtime_found) 1422 if (sleeptime_injected)
1391 __timekeeping_inject_sleeptime(tk, &ts_delta); 1423 __timekeeping_inject_sleeptime(tk, &ts_delta);
1392 1424
1393 /* Re-base the last cycle value */ 1425 /* Re-base the last cycle value */
@@ -1421,14 +1453,14 @@ int timekeeping_suspend(void)
1421 * value returned, update the persistent_clock_exists flag. 1453 * value returned, update the persistent_clock_exists flag.
1422 */ 1454 */
1423 if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec) 1455 if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec)
1424 persistent_clock_exist = true; 1456 persistent_clock_exists = true;
1425 1457
1426 raw_spin_lock_irqsave(&timekeeper_lock, flags); 1458 raw_spin_lock_irqsave(&timekeeper_lock, flags);
1427 write_seqcount_begin(&tk_core.seq); 1459 write_seqcount_begin(&tk_core.seq);
1428 timekeeping_forward_now(tk); 1460 timekeeping_forward_now(tk);
1429 timekeeping_suspended = 1; 1461 timekeeping_suspended = 1;
1430 1462
1431 if (has_persistent_clock()) { 1463 if (persistent_clock_exists) {
1432 /* 1464 /*
1433 * To avoid drift caused by repeated suspend/resumes, 1465 * To avoid drift caused by repeated suspend/resumes,
1434 * which each can add ~1 second drift error, 1466 * which each can add ~1 second drift error,