Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hrtimer: Add hrtimer support for CLOCK_TAI

Add hrtimer support for CLOCK_TAI, as well as posix timer interfaces.

Signed-off-by: John Stultz <john.stultz@linaro.org>

+44 -3
+4 -1
include/linux/hrtimer.h
··· 157 157 HRTIMER_BASE_MONOTONIC, 158 158 HRTIMER_BASE_REALTIME, 159 159 HRTIMER_BASE_BOOTTIME, 160 + HRTIMER_BASE_TAI, 160 161 HRTIMER_MAX_CLOCK_BASES, 161 162 }; 162 163 ··· 328 327 extern ktime_t ktime_get_real(void); 329 328 extern ktime_t ktime_get_boottime(void); 330 329 extern ktime_t ktime_get_monotonic_offset(void); 331 - extern ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot); 330 + extern ktime_t ktime_get_clocktai(void); 331 + extern ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot, 332 + ktime_t *offs_tai); 332 333 333 334 DECLARE_PER_CPU(struct tick_device, tick_cpu_device); 334 335
+2
include/linux/timekeeper_internal.h
··· 64 64 struct timespec raw_time; 65 65 /* The current UTC to TAI offset in seconds */ 66 66 s32 tai_offset; 67 + /* Offset clock monotonic -> clock tai */ 68 + ktime_t offs_tai; 67 69 68 70 /* Seqlock for all timekeeper values */ 69 71 seqlock_t lock;
+13 -1
kernel/hrtimer.c
··· 83 83 .get_time = &ktime_get_boottime, 84 84 .resolution = KTIME_LOW_RES, 85 85 }, 86 + { 87 + .index = HRTIMER_BASE_TAI, 88 + .clockid = CLOCK_TAI, 89 + .get_time = &ktime_get_clocktai, 90 + .resolution = KTIME_LOW_RES, 91 + }, 86 92 } 87 93 }; 88 94 ··· 96 90 [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, 97 91 [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, 98 92 [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, 93 + [CLOCK_TAI] = HRTIMER_BASE_TAI, 99 94 }; 100 95 101 96 static inline int hrtimer_clockid_to_base(clockid_t clock_id) ··· 113 106 { 114 107 ktime_t xtim, mono, boot; 115 108 struct timespec xts, tom, slp; 109 + s32 tai_offset; 116 110 117 111 get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &slp); 112 + tai_offset = timekeeping_get_tai_offset(); 118 113 119 114 xtim = timespec_to_ktime(xts); 120 115 mono = ktime_add(xtim, timespec_to_ktime(tom)); ··· 124 115 base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim; 125 116 base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono; 126 117 base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; 118 + base->clock_base[HRTIMER_BASE_TAI].softirq_time = 119 + ktime_add(xtim, ktime_set(tai_offset, 0)); 127 120 } 128 121 129 122 /* ··· 662 651 { 663 652 ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset; 664 653 ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; 654 + ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset; 665 655 666 - return ktime_get_update_offsets(offs_real, offs_boot); 656 + return ktime_get_update_offsets(offs_real, offs_boot, offs_tai); 667 657 } 668 658 669 659 /*
+6
kernel/posix-timers.c
··· 269 269 struct k_clock clock_tai = { 270 270 .clock_getres = hrtimer_get_res, 271 271 .clock_get = posix_get_tai, 272 + .nsleep = common_nsleep, 273 + .nsleep_restart = hrtimer_nanosleep_restart, 274 + .timer_create = common_timer_create, 275 + .timer_set = common_timer_set, 276 + .timer_get = common_timer_get, 277 + .timer_del = common_timer_del, 272 278 }; 273 279 struct k_clock clock_boottime = { 274 280 .clock_getres = hrtimer_get_res,
+19 -1
kernel/time/timekeeping.c
··· 67 67 tk->wall_to_monotonic = wtm; 68 68 set_normalized_timespec(&tmp, -wtm.tv_sec, -wtm.tv_nsec); 69 69 tk->offs_real = timespec_to_ktime(tmp); 70 + tk->offs_tai = ktime_sub(tk->offs_real, ktime_set(tk->tai_offset, 0)); 70 71 } 71 72 72 73 static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t) ··· 410 409 EXPORT_SYMBOL(timekeeping_clocktai); 411 410 412 411 412 + /** 413 + * ktime_get_clocktai - Returns the TAI time of day in a ktime 414 + * 415 + * Returns the time of day in a ktime. 416 + */ 417 + ktime_t ktime_get_clocktai(void) 418 + { 419 + struct timespec ts; 420 + 421 + timekeeping_clocktai(&ts); 422 + return timespec_to_ktime(ts); 423 + } 424 + EXPORT_SYMBOL(ktime_get_clocktai); 425 + 413 426 #ifdef CONFIG_NTP_PPS 414 427 415 428 /** ··· 584 569 void __timekeeping_set_tai_offset(struct timekeeper *tk, s32 tai_offset) 585 570 { 586 571 tk->tai_offset = tai_offset; 572 + tk->offs_tai = ktime_sub(tk->offs_real, ktime_set(tai_offset, 0)); 587 573 } 588 574 589 575 /** ··· 1555 1539 * Returns current monotonic time and updates the offsets 1556 1540 * Called from hrtimer_interupt() or retrigger_next_event() 1557 1541 */ 1558 - ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) 1542 + ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot, 1543 + ktime_t *offs_tai) 1559 1544 { 1560 1545 struct timekeeper *tk = &timekeeper; 1561 1546 ktime_t now; ··· 1571 1554 1572 1555 *offs_real = tk->offs_real; 1573 1556 *offs_boot = tk->offs_boot; 1557 + *offs_tai = tk->offs_tai; 1574 1558 } while (read_seqretry(&tk->lock, seq)); 1575 1559 1576 1560 now = ktime_add_ns(ktime_set(secs, 0), nsecs);