1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
28b094cd0SThomas Gleixner #ifndef _LINUX_TIMEKEEPING_H
38b094cd0SThomas Gleixner #define _LINUX_TIMEKEEPING_H
48b094cd0SThomas Gleixner
5b536fd58SChristoph Hellwig #include <linux/errno.h>
6b2c67cbeSThomas Gleixner #include <linux/clocksource_ids.h>
7b2fa8443SKent Overstreet #include <linux/ktime.h>
886d34732SBaolin Wang
98b094cd0SThomas Gleixner /* Included from linux/ktime.h */
108b094cd0SThomas Gleixner
118b094cd0SThomas Gleixner void timekeeping_init(void);
128b094cd0SThomas Gleixner extern int timekeeping_suspended;
138b094cd0SThomas Gleixner
1493b5a9a7SIngo Molnar /* Architecture timer tick functions: */
15b3550164SArnd Bergmann extern void legacy_timer_tick(unsigned long ticks);
1693b5a9a7SIngo Molnar
178b094cd0SThomas Gleixner /*
188b094cd0SThomas Gleixner * Get and set timeofday
198b094cd0SThomas Gleixner */
2021f7eca5Spang.xunlei extern int do_settimeofday64(const struct timespec64 *ts);
2186d34732SBaolin Wang extern int do_sys_settimeofday64(const struct timespec64 *tv,
228b094cd0SThomas Gleixner const struct timezone *tz);
238758a240SBaolin Wang
248b094cd0SThomas Gleixner /*
2576f788eeSRandy Dunlap * ktime_get() family - read the current time in a multitude of ways.
260e3fd810SArnd Bergmann *
270e3fd810SArnd Bergmann * The default time reference is CLOCK_MONOTONIC, starting at
280e3fd810SArnd Bergmann * boot time but not counting the time spent in suspend.
290e3fd810SArnd Bergmann * For other references, use the functions with "real", "clocktai",
300e3fd810SArnd Bergmann * "boottime" and "raw" suffixes.
310e3fd810SArnd Bergmann *
3276f788eeSRandy Dunlap * To get the time in a different format, use the ones with
330e3fd810SArnd Bergmann * "ns", "ts64" and "seconds" suffix.
340e3fd810SArnd Bergmann *
350e3fd810SArnd Bergmann * See Documentation/core-api/timekeeping.rst for more details.
360e3fd810SArnd Bergmann */
370e3fd810SArnd Bergmann
380e3fd810SArnd Bergmann
390e3fd810SArnd Bergmann /*
406546911eSArnd Bergmann * timespec64 based interfaces
418b094cd0SThomas Gleixner */
42fb7fcc96SArnd Bergmann extern void ktime_get_raw_ts64(struct timespec64 *ts);
43d6d29896SThomas Gleixner extern void ktime_get_ts64(struct timespec64 *ts);
44edca71feSArnd Bergmann extern void ktime_get_real_ts64(struct timespec64 *tv);
45fb7fcc96SArnd Bergmann extern void ktime_get_coarse_ts64(struct timespec64 *ts);
46fb7fcc96SArnd Bergmann extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
47fb7fcc96SArnd Bergmann
4870c8fd00SJeff Layton /* Multigrain timestamp interfaces */
4970c8fd00SJeff Layton extern void ktime_get_coarse_real_ts64_mg(struct timespec64 *ts);
5070c8fd00SJeff Layton extern void ktime_get_real_ts64_mg(struct timespec64 *ts);
51*96f9a366SJeff Layton extern unsigned long timekeeping_get_mg_floor_swaps(void);
5270c8fd00SJeff Layton
53fb7fcc96SArnd Bergmann void getboottime64(struct timespec64 *ts);
54fb7fcc96SArnd Bergmann
55fb7fcc96SArnd Bergmann /*
56fb7fcc96SArnd Bergmann * time64_t base interfaces
57fb7fcc96SArnd Bergmann */
589e3680b1SHeena Sirwani extern time64_t ktime_get_seconds(void);
596909e29fSArnd Bergmann extern time64_t __ktime_get_real_seconds(void);
60dbe7aa62SHeena Sirwani extern time64_t ktime_get_real_seconds(void);
618b094cd0SThomas Gleixner
628b094cd0SThomas Gleixner /*
638b094cd0SThomas Gleixner * ktime_t based interfaces
648b094cd0SThomas Gleixner */
65a3ed0e43SThomas Gleixner
660077dc60SThomas Gleixner enum tk_offsets {
670077dc60SThomas Gleixner TK_OFFS_REAL,
68a3ed0e43SThomas Gleixner TK_OFFS_BOOT,
690077dc60SThomas Gleixner TK_OFFS_TAI,
700077dc60SThomas Gleixner TK_OFFS_MAX,
710077dc60SThomas Gleixner };
720077dc60SThomas Gleixner
738b094cd0SThomas Gleixner extern ktime_t ktime_get(void);
740077dc60SThomas Gleixner extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
75b9ff604cSArnd Bergmann extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
769a6b5197SThomas Gleixner extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
77f519b1a2SThomas Gleixner extern ktime_t ktime_get_raw(void);
786374f912SHarald Geyer extern u32 ktime_get_resolution_ns(void);
798b094cd0SThomas Gleixner
80f5264d5dSThomas Gleixner /**
81f5264d5dSThomas Gleixner * ktime_get_real - get the real (wall-) time in ktime_t format
8276f788eeSRandy Dunlap *
8376f788eeSRandy Dunlap * Returns: real (wall) time in ktime_t format
84f5264d5dSThomas Gleixner */
ktime_get_real(void)85f5264d5dSThomas Gleixner static inline ktime_t ktime_get_real(void)
86f5264d5dSThomas Gleixner {
87f5264d5dSThomas Gleixner return ktime_get_with_offset(TK_OFFS_REAL);
88f5264d5dSThomas Gleixner }
89f5264d5dSThomas Gleixner
ktime_get_coarse_real(void)90b9ff604cSArnd Bergmann static inline ktime_t ktime_get_coarse_real(void)
91b9ff604cSArnd Bergmann {
92b9ff604cSArnd Bergmann return ktime_get_coarse_with_offset(TK_OFFS_REAL);
93b9ff604cSArnd Bergmann }
94b9ff604cSArnd Bergmann
95b82c817eSThomas Gleixner /**
9676f788eeSRandy Dunlap * ktime_get_boottime - Get monotonic time since boot in ktime_t format
97a3ed0e43SThomas Gleixner *
98a3ed0e43SThomas Gleixner * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
99a3ed0e43SThomas Gleixner * time spent in suspend.
10076f788eeSRandy Dunlap *
10176f788eeSRandy Dunlap * Returns: monotonic time since boot in ktime_t format
102a3ed0e43SThomas Gleixner */
ktime_get_boottime(void)103a3ed0e43SThomas Gleixner static inline ktime_t ktime_get_boottime(void)
104a3ed0e43SThomas Gleixner {
105a3ed0e43SThomas Gleixner return ktime_get_with_offset(TK_OFFS_BOOT);
106a3ed0e43SThomas Gleixner }
107a3ed0e43SThomas Gleixner
ktime_get_coarse_boottime(void)108b9ff604cSArnd Bergmann static inline ktime_t ktime_get_coarse_boottime(void)
109b9ff604cSArnd Bergmann {
110b9ff604cSArnd Bergmann return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
111b9ff604cSArnd Bergmann }
112b9ff604cSArnd Bergmann
113a3ed0e43SThomas Gleixner /**
11476f788eeSRandy Dunlap * ktime_get_clocktai - Get the TAI time of day in ktime_t format
11576f788eeSRandy Dunlap *
11676f788eeSRandy Dunlap * Returns: the TAI time of day in ktime_t format
117afab07c0SThomas Gleixner */
ktime_get_clocktai(void)118afab07c0SThomas Gleixner static inline ktime_t ktime_get_clocktai(void)
119afab07c0SThomas Gleixner {
120afab07c0SThomas Gleixner return ktime_get_with_offset(TK_OFFS_TAI);
121afab07c0SThomas Gleixner }
122afab07c0SThomas Gleixner
ktime_get_coarse_clocktai(void)123b9ff604cSArnd Bergmann static inline ktime_t ktime_get_coarse_clocktai(void)
124b9ff604cSArnd Bergmann {
125b9ff604cSArnd Bergmann return ktime_get_coarse_with_offset(TK_OFFS_TAI);
126b9ff604cSArnd Bergmann }
127b9ff604cSArnd Bergmann
ktime_get_coarse(void)1284c54294dSJason A. Donenfeld static inline ktime_t ktime_get_coarse(void)
1294c54294dSJason A. Donenfeld {
1304c54294dSJason A. Donenfeld struct timespec64 ts;
1314c54294dSJason A. Donenfeld
1324c54294dSJason A. Donenfeld ktime_get_coarse_ts64(&ts);
1334c54294dSJason A. Donenfeld return timespec64_to_ktime(ts);
1344c54294dSJason A. Donenfeld }
1354c54294dSJason A. Donenfeld
ktime_get_coarse_ns(void)1364c54294dSJason A. Donenfeld static inline u64 ktime_get_coarse_ns(void)
1374c54294dSJason A. Donenfeld {
1384c54294dSJason A. Donenfeld return ktime_to_ns(ktime_get_coarse());
1394c54294dSJason A. Donenfeld }
1404c54294dSJason A. Donenfeld
ktime_get_coarse_real_ns(void)1414c54294dSJason A. Donenfeld static inline u64 ktime_get_coarse_real_ns(void)
1424c54294dSJason A. Donenfeld {
1434c54294dSJason A. Donenfeld return ktime_to_ns(ktime_get_coarse_real());
1444c54294dSJason A. Donenfeld }
1454c54294dSJason A. Donenfeld
ktime_get_coarse_boottime_ns(void)146d48e0cd8SJason A. Donenfeld static inline u64 ktime_get_coarse_boottime_ns(void)
1474c54294dSJason A. Donenfeld {
1484c54294dSJason A. Donenfeld return ktime_to_ns(ktime_get_coarse_boottime());
1494c54294dSJason A. Donenfeld }
1504c54294dSJason A. Donenfeld
ktime_get_coarse_clocktai_ns(void)1514c54294dSJason A. Donenfeld static inline u64 ktime_get_coarse_clocktai_ns(void)
1524c54294dSJason A. Donenfeld {
1534c54294dSJason A. Donenfeld return ktime_to_ns(ktime_get_coarse_clocktai());
1544c54294dSJason A. Donenfeld }
1554c54294dSJason A. Donenfeld
1569a6b5197SThomas Gleixner /**
1579a6b5197SThomas Gleixner * ktime_mono_to_real - Convert monotonic time to clock realtime
15876f788eeSRandy Dunlap * @mono: monotonic time to convert
15976f788eeSRandy Dunlap *
16076f788eeSRandy Dunlap * Returns: time converted to realtime clock
1619a6b5197SThomas Gleixner */
ktime_mono_to_real(ktime_t mono)1629a6b5197SThomas Gleixner static inline ktime_t ktime_mono_to_real(ktime_t mono)
1639a6b5197SThomas Gleixner {
1649a6b5197SThomas Gleixner return ktime_mono_to_any(mono, TK_OFFS_REAL);
1659a6b5197SThomas Gleixner }
1669a6b5197SThomas Gleixner
16776f788eeSRandy Dunlap /**
16876f788eeSRandy Dunlap * ktime_get_ns - Get the current time in nanoseconds
16976f788eeSRandy Dunlap *
17076f788eeSRandy Dunlap * Returns: current time converted to nanoseconds
17176f788eeSRandy Dunlap */
ktime_get_ns(void)172897994e3SThomas Gleixner static inline u64 ktime_get_ns(void)
173897994e3SThomas Gleixner {
174897994e3SThomas Gleixner return ktime_to_ns(ktime_get());
175897994e3SThomas Gleixner }
176897994e3SThomas Gleixner
17776f788eeSRandy Dunlap /**
17876f788eeSRandy Dunlap * ktime_get_real_ns - Get the current real/wall time in nanoseconds
17976f788eeSRandy Dunlap *
18076f788eeSRandy Dunlap * Returns: current real time converted to nanoseconds
18176f788eeSRandy Dunlap */
ktime_get_real_ns(void)182897994e3SThomas Gleixner static inline u64 ktime_get_real_ns(void)
183897994e3SThomas Gleixner {
184897994e3SThomas Gleixner return ktime_to_ns(ktime_get_real());
185897994e3SThomas Gleixner }
186897994e3SThomas Gleixner
18776f788eeSRandy Dunlap /**
18876f788eeSRandy Dunlap * ktime_get_boottime_ns - Get the monotonic time since boot in nanoseconds
18976f788eeSRandy Dunlap *
19076f788eeSRandy Dunlap * Returns: current boottime converted to nanoseconds
19176f788eeSRandy Dunlap */
ktime_get_boottime_ns(void)1929285ec4cSJason A. Donenfeld static inline u64 ktime_get_boottime_ns(void)
193a3ed0e43SThomas Gleixner {
194a3ed0e43SThomas Gleixner return ktime_to_ns(ktime_get_boottime());
195a3ed0e43SThomas Gleixner }
196a3ed0e43SThomas Gleixner
19776f788eeSRandy Dunlap /**
19876f788eeSRandy Dunlap * ktime_get_clocktai_ns - Get the current TAI time of day in nanoseconds
19976f788eeSRandy Dunlap *
20076f788eeSRandy Dunlap * Returns: current TAI time converted to nanoseconds
20176f788eeSRandy Dunlap */
ktime_get_clocktai_ns(void)2029285ec4cSJason A. Donenfeld static inline u64 ktime_get_clocktai_ns(void)
203fe5fba05SPeter Zijlstra {
204fe5fba05SPeter Zijlstra return ktime_to_ns(ktime_get_clocktai());
205fe5fba05SPeter Zijlstra }
206fe5fba05SPeter Zijlstra
20776f788eeSRandy Dunlap /**
20876f788eeSRandy Dunlap * ktime_get_raw_ns - Get the raw monotonic time in nanoseconds
20976f788eeSRandy Dunlap *
21076f788eeSRandy Dunlap * Returns: current raw monotonic time converted to nanoseconds
21176f788eeSRandy Dunlap */
ktime_get_raw_ns(void)212f519b1a2SThomas Gleixner static inline u64 ktime_get_raw_ns(void)
213f519b1a2SThomas Gleixner {
214f519b1a2SThomas Gleixner return ktime_to_ns(ktime_get_raw());
215f519b1a2SThomas Gleixner }
216f519b1a2SThomas Gleixner
2174396e058SThomas Gleixner extern u64 ktime_get_mono_fast_ns(void);
218f09cb9a1SPeter Zijlstra extern u64 ktime_get_raw_fast_ns(void);
219a3ed0e43SThomas Gleixner extern u64 ktime_get_boot_fast_ns(void);
2203dc6ffaeSKurt Kanzenbach extern u64 ktime_get_tai_fast_ns(void);
2214c3711d7SThomas Gleixner extern u64 ktime_get_real_fast_ns(void);
2224396e058SThomas Gleixner
2238b094cd0SThomas Gleixner /*
22406aa3769SArnd Bergmann * timespec64/time64_t interfaces utilizing the ktime based ones
22506aa3769SArnd Bergmann * for API completeness, these could be implemented more efficiently
22606aa3769SArnd Bergmann * if needed.
22748f18fd6SThomas Gleixner */
ktime_get_boottime_ts64(struct timespec64 * ts)228fb7fcc96SArnd Bergmann static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
229a3ed0e43SThomas Gleixner {
230a3ed0e43SThomas Gleixner *ts = ktime_to_timespec64(ktime_get_boottime());
231a3ed0e43SThomas Gleixner }
232a3ed0e43SThomas Gleixner
ktime_get_coarse_boottime_ts64(struct timespec64 * ts)23306aa3769SArnd Bergmann static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
23406aa3769SArnd Bergmann {
23506aa3769SArnd Bergmann *ts = ktime_to_timespec64(ktime_get_coarse_boottime());
23606aa3769SArnd Bergmann }
23706aa3769SArnd Bergmann
ktime_get_boottime_seconds(void)23806aa3769SArnd Bergmann static inline time64_t ktime_get_boottime_seconds(void)
23906aa3769SArnd Bergmann {
24006aa3769SArnd Bergmann return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
24106aa3769SArnd Bergmann }
24206aa3769SArnd Bergmann
ktime_get_clocktai_ts64(struct timespec64 * ts)243fb7fcc96SArnd Bergmann static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
2443c9c12f4SDeepa Dinamani {
2453c9c12f4SDeepa Dinamani *ts = ktime_to_timespec64(ktime_get_clocktai());
2463c9c12f4SDeepa Dinamani }
2473c9c12f4SDeepa Dinamani
ktime_get_coarse_clocktai_ts64(struct timespec64 * ts)24806aa3769SArnd Bergmann static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
24906aa3769SArnd Bergmann {
25006aa3769SArnd Bergmann *ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
25106aa3769SArnd Bergmann }
25206aa3769SArnd Bergmann
ktime_get_clocktai_seconds(void)25306aa3769SArnd Bergmann static inline time64_t ktime_get_clocktai_seconds(void)
25406aa3769SArnd Bergmann {
25506aa3769SArnd Bergmann return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
25606aa3769SArnd Bergmann }
25706aa3769SArnd Bergmann
25848f18fd6SThomas Gleixner /*
2598b094cd0SThomas Gleixner * RTC specific
2608b094cd0SThomas Gleixner */
2610fa88cb4SXunlei Pang extern bool timekeeping_rtc_skipsuspend(void);
2620fa88cb4SXunlei Pang extern bool timekeeping_rtc_skipresume(void);
2630fa88cb4SXunlei Pang
264985e6950SOndrej Mosnacek extern void timekeeping_inject_sleeptime64(const struct timespec64 *delta);
26504d90890Spang.xunlei
26676f788eeSRandy Dunlap /**
2679da0f49cSChristopher S. Hall * struct system_time_snapshot - simultaneous raw/real time capture with
2689da0f49cSChristopher S. Hall * counter value
2699da0f49cSChristopher S. Hall * @cycles: Clocksource counter value to produce the system times
2709da0f49cSChristopher S. Hall * @real: Realtime system time
2718102c4daSVincent Donnefort * @boot: Boot time
2729da0f49cSChristopher S. Hall * @raw: Monotonic raw system time
27376f788eeSRandy Dunlap * @cs_id: Clocksource ID
27476f788eeSRandy Dunlap * @clock_was_set_seq: The sequence number of clock-was-set events
2752c756febSChristopher S. Hall * @cs_was_changed_seq: The sequence number of clocksource change events
2769da0f49cSChristopher S. Hall */
2779da0f49cSChristopher S. Hall struct system_time_snapshot {
278a5a1d1c2SThomas Gleixner u64 cycles;
2799da0f49cSChristopher S. Hall ktime_t real;
2808102c4daSVincent Donnefort ktime_t boot;
2819da0f49cSChristopher S. Hall ktime_t raw;
282b2c67cbeSThomas Gleixner enum clocksource_ids cs_id;
2832c756febSChristopher S. Hall unsigned int clock_was_set_seq;
2842c756febSChristopher S. Hall u8 cs_was_changed_seq;
2859da0f49cSChristopher S. Hall };
2869da0f49cSChristopher S. Hall
287f097eb38SKurt Kanzenbach /**
2888006c245SChristopher S. Hall * struct system_device_crosststamp - system/device cross-timestamp
289f097eb38SKurt Kanzenbach * (synchronized capture)
2908006c245SChristopher S. Hall * @device: Device time
2918006c245SChristopher S. Hall * @sys_realtime: Realtime simultaneous with device time
2928006c245SChristopher S. Hall * @sys_monoraw: Monotonic raw simultaneous with device time
2938006c245SChristopher S. Hall */
2948006c245SChristopher S. Hall struct system_device_crosststamp {
2958006c245SChristopher S. Hall ktime_t device;
2968006c245SChristopher S. Hall ktime_t sys_realtime;
2978006c245SChristopher S. Hall ktime_t sys_monoraw;
2988006c245SChristopher S. Hall };
2998006c245SChristopher S. Hall
300f097eb38SKurt Kanzenbach /**
3014b7f5212SPeter Hilber * struct system_counterval_t - system counter value with the ID of the
3028006c245SChristopher S. Hall * corresponding clocksource
3038006c245SChristopher S. Hall * @cycles: System counter value
3044b7f5212SPeter Hilber * @cs_id: Clocksource ID corresponding to system counter value. Used by
3054b7f5212SPeter Hilber * timekeeping code to verify comparability of two cycle values.
30693630d6dSPeter Hilber * The default ID, CSID_GENERIC, does not identify a specific
30793630d6dSPeter Hilber * clocksource.
3086b2e2997SLakshmi Sowjanya D * @use_nsecs: @cycles is in nanoseconds.
3098006c245SChristopher S. Hall */
3108006c245SChristopher S. Hall struct system_counterval_t {
311a5a1d1c2SThomas Gleixner u64 cycles;
31293630d6dSPeter Hilber enum clocksource_ids cs_id;
3136b2e2997SLakshmi Sowjanya D bool use_nsecs;
3148006c245SChristopher S. Hall };
3158006c245SChristopher S. Hall
31602ecee07SLakshmi Sowjanya D extern bool ktime_real_to_base_clock(ktime_t treal,
31702ecee07SLakshmi Sowjanya D enum clocksource_ids base_id, u64 *cycles);
31802ecee07SLakshmi Sowjanya D extern bool timekeeping_clocksource_has_base(enum clocksource_ids id);
31902ecee07SLakshmi Sowjanya D
3208006c245SChristopher S. Hall /*
3218006c245SChristopher S. Hall * Get cross timestamp between system clock and device clock
3228006c245SChristopher S. Hall */
3238006c245SChristopher S. Hall extern int get_device_system_crosststamp(
3248006c245SChristopher S. Hall int (*get_time_fn)(ktime_t *device_time,
3258006c245SChristopher S. Hall struct system_counterval_t *system_counterval,
3268006c245SChristopher S. Hall void *ctx),
3278006c245SChristopher S. Hall void *ctx,
3282c756febSChristopher S. Hall struct system_time_snapshot *history,
3298006c245SChristopher S. Hall struct system_device_crosststamp *xtstamp);
3308006c245SChristopher S. Hall
3318006c245SChristopher S. Hall /*
3329da0f49cSChristopher S. Hall * Simultaneously snapshot realtime and monotonic raw clocks
3339da0f49cSChristopher S. Hall */
3349da0f49cSChristopher S. Hall extern void ktime_get_snapshot(struct system_time_snapshot *systime_snapshot);
3359da0f49cSChristopher S. Hall
3369da0f49cSChristopher S. Hall /*
3378b094cd0SThomas Gleixner * Persistent clock related interfaces
3388b094cd0SThomas Gleixner */
3398b094cd0SThomas Gleixner extern int persistent_clock_is_local;
3408b094cd0SThomas Gleixner
3412ee96632SXunlei Pang extern void read_persistent_clock64(struct timespec64 *ts);
342c43c5e9fSChristian Borntraeger void read_persistent_wall_and_boot_offset(struct timespec64 *wall_clock,
3433eca9937SPavel Tatashin struct timespec64 *boot_offset);
3443cabca87SIngo Molnar #ifdef CONFIG_GENERIC_CMOS_UPDATE
3453c00a1feSXunlei Pang extern int update_persistent_clock64(struct timespec64 now);
3463cabca87SIngo Molnar #endif
3478b094cd0SThomas Gleixner
3488b094cd0SThomas Gleixner #endif
349