/* SPDX-License-Identifier: GPL-2.0 */


#ifndef _LINUX_TIMEKEEPER_INTERNAL_H
#define _LINUX_TIMEKEEPER_INTERNAL_H

#include <linux/clocksource.h>
#include <linux/jiffies.h>
#include <linux/time.h>


enum timekeeper_ids {
	TIMEKEEPER_CORE,
#ifdef CONFIG_POSIX_AUX_CLOCKS
	TIMEKEEPER_AUX_FIRST,
	TIMEKEEPER_AUX_LAST = TIMEKEEPER_AUX_FIRST + MAX_AUX_CLOCKS - 1,
#endif
	TIMEKEEPERS_MAX,
};


struct tk_read_base {
	struct clocksource	*clock;
	u64			mask;
	u64			cycle_last;
	u32			mult;
	u32			shift;
	u64			xtime_nsec;
	ktime_t			base;
	u64			base_real;
};


struct timekeeper {
	
	struct tk_read_base	tkr_mono;

	
	u64			xtime_sec;
	unsigned long		ktime_sec;
	struct timespec64	wall_to_monotonic;
	ktime_t			offs_real;
	ktime_t			offs_boot;
	union {
		ktime_t		offs_tai;
		ktime_t		offs_aux;
	};
	u32			coarse_nsec;
	enum timekeeper_ids	id;

	
	struct tk_read_base	tkr_raw;
	u64			raw_sec;

	
	unsigned int		clock_was_set_seq;
	u8			cs_was_changed_seq;
	u8			clock_valid;

	union {
		struct timespec64	monotonic_to_boot;
		struct timespec64	monotonic_to_aux;
	};

	u64			cycle_interval;
	u64			xtime_interval;
	s64			xtime_remainder;
	u64			raw_interval;

	ktime_t			next_leap_ktime;
	u64			ntp_tick;
	s64			ntp_error;
	u32			ntp_error_shift;
	u32			ntp_err_mult;
	u32			skip_second_overflow;
	s32			tai_offset;
};

#ifdef CONFIG_GENERIC_TIME_VSYSCALL

extern void update_vsyscall(struct timekeeper *tk);
extern void update_vsyscall_tz(void);

#else

static inline void update_vsyscall(struct timekeeper *tk)
{
}
static inline void update_vsyscall_tz(void)
{
}
#endif

#if defined(CONFIG_GENERIC_GETTIMEOFDAY) && defined(CONFIG_POSIX_AUX_CLOCKS)
extern void vdso_time_update_aux(struct timekeeper *tk);
#else
static inline void vdso_time_update_aux(struct timekeeper *tk) { }
#endif

#endif 
