162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _TICK_SCHED_H
362306a36Sopenharmony_ci#define _TICK_SCHED_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/hrtimer.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_cienum tick_device_mode {
862306a36Sopenharmony_ci	TICKDEV_MODE_PERIODIC,
962306a36Sopenharmony_ci	TICKDEV_MODE_ONESHOT,
1062306a36Sopenharmony_ci};
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct tick_device {
1362306a36Sopenharmony_ci	struct clock_event_device *evtdev;
1462306a36Sopenharmony_ci	enum tick_device_mode mode;
1562306a36Sopenharmony_ci};
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cienum tick_nohz_mode {
1862306a36Sopenharmony_ci	NOHZ_MODE_INACTIVE,
1962306a36Sopenharmony_ci	NOHZ_MODE_LOWRES,
2062306a36Sopenharmony_ci	NOHZ_MODE_HIGHRES,
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/**
2462306a36Sopenharmony_ci * struct tick_sched - sched tick emulation and no idle tick control/stats
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci * @inidle:		Indicator that the CPU is in the tick idle mode
2762306a36Sopenharmony_ci * @tick_stopped:	Indicator that the idle tick has been stopped
2862306a36Sopenharmony_ci * @idle_active:	Indicator that the CPU is actively in the tick idle mode;
2962306a36Sopenharmony_ci *			it is reset during irq handling phases.
3062306a36Sopenharmony_ci * @do_timer_last:	CPU was the last one doing do_timer before going idle
3162306a36Sopenharmony_ci * @got_idle_tick:	Tick timer function has run with @inidle set
3262306a36Sopenharmony_ci * @stalled_jiffies:	Number of stalled jiffies detected across ticks
3362306a36Sopenharmony_ci * @last_tick_jiffies:	Value of jiffies seen on last tick
3462306a36Sopenharmony_ci * @sched_timer:	hrtimer to schedule the periodic tick in high
3562306a36Sopenharmony_ci *			resolution mode
3662306a36Sopenharmony_ci * @last_tick:		Store the last tick expiry time when the tick
3762306a36Sopenharmony_ci *			timer is modified for nohz sleeps. This is necessary
3862306a36Sopenharmony_ci *			to resume the tick timer operation in the timeline
3962306a36Sopenharmony_ci *			when the CPU returns from nohz sleep.
4062306a36Sopenharmony_ci * @next_tick:		Next tick to be fired when in dynticks mode.
4162306a36Sopenharmony_ci * @idle_jiffies:	jiffies at the entry to idle for idle time accounting
4262306a36Sopenharmony_ci * @idle_waketime:	Time when the idle was interrupted
4362306a36Sopenharmony_ci * @idle_entrytime:	Time when the idle call was entered
4462306a36Sopenharmony_ci * @nohz_mode:		Mode - one state of tick_nohz_mode
4562306a36Sopenharmony_ci * @last_jiffies:	Base jiffies snapshot when next event was last computed
4662306a36Sopenharmony_ci * @timer_expires_base:	Base time clock monotonic for @timer_expires
4762306a36Sopenharmony_ci * @timer_expires:	Anticipated timer expiration time (in case sched tick is stopped)
4862306a36Sopenharmony_ci * @next_timer:		Expiry time of next expiring timer for debugging purpose only
4962306a36Sopenharmony_ci * @idle_expires:	Next tick in idle, for debugging purpose only
5062306a36Sopenharmony_ci * @idle_calls:		Total number of idle calls
5162306a36Sopenharmony_ci * @idle_sleeps:	Number of idle calls, where the sched tick was stopped
5262306a36Sopenharmony_ci * @idle_exittime:	Time when the idle state was left
5362306a36Sopenharmony_ci * @idle_sleeptime:	Sum of the time slept in idle with sched tick stopped
5462306a36Sopenharmony_ci * @iowait_sleeptime:	Sum of the time slept in idle with sched tick stopped, with IO outstanding
5562306a36Sopenharmony_ci * @tick_dep_mask:	Tick dependency mask - is set, if someone needs the tick
5662306a36Sopenharmony_ci * @check_clocks:	Notification mechanism about clocksource changes
5762306a36Sopenharmony_ci */
5862306a36Sopenharmony_cistruct tick_sched {
5962306a36Sopenharmony_ci	/* Common flags */
6062306a36Sopenharmony_ci	unsigned int			inidle		: 1;
6162306a36Sopenharmony_ci	unsigned int			tick_stopped	: 1;
6262306a36Sopenharmony_ci	unsigned int			idle_active	: 1;
6362306a36Sopenharmony_ci	unsigned int			do_timer_last	: 1;
6462306a36Sopenharmony_ci	unsigned int			got_idle_tick	: 1;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	/* Tick handling: jiffies stall check */
6762306a36Sopenharmony_ci	unsigned int			stalled_jiffies;
6862306a36Sopenharmony_ci	unsigned long			last_tick_jiffies;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	/* Tick handling */
7162306a36Sopenharmony_ci	struct hrtimer			sched_timer;
7262306a36Sopenharmony_ci	ktime_t				last_tick;
7362306a36Sopenharmony_ci	ktime_t				next_tick;
7462306a36Sopenharmony_ci	unsigned long			idle_jiffies;
7562306a36Sopenharmony_ci	ktime_t				idle_waketime;
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	/* Idle entry */
7862306a36Sopenharmony_ci	seqcount_t			idle_sleeptime_seq;
7962306a36Sopenharmony_ci	ktime_t				idle_entrytime;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	/* Tick stop */
8262306a36Sopenharmony_ci	enum tick_nohz_mode		nohz_mode;
8362306a36Sopenharmony_ci	unsigned long			last_jiffies;
8462306a36Sopenharmony_ci	u64				timer_expires_base;
8562306a36Sopenharmony_ci	u64				timer_expires;
8662306a36Sopenharmony_ci	u64				next_timer;
8762306a36Sopenharmony_ci	ktime_t				idle_expires;
8862306a36Sopenharmony_ci	unsigned long			idle_calls;
8962306a36Sopenharmony_ci	unsigned long			idle_sleeps;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	/* Idle exit */
9262306a36Sopenharmony_ci	ktime_t				idle_exittime;
9362306a36Sopenharmony_ci	ktime_t				idle_sleeptime;
9462306a36Sopenharmony_ci	ktime_t				iowait_sleeptime;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	/* Full dynticks handling */
9762306a36Sopenharmony_ci	atomic_t			tick_dep_mask;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	/* Clocksource changes */
10062306a36Sopenharmony_ci	unsigned long			check_clocks;
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciextern struct tick_sched *tick_get_tick_sched(int cpu);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ciextern void tick_setup_sched_timer(void);
10662306a36Sopenharmony_ci#if defined CONFIG_NO_HZ_COMMON || defined CONFIG_HIGH_RES_TIMERS
10762306a36Sopenharmony_ciextern void tick_cancel_sched_timer(int cpu);
10862306a36Sopenharmony_ci#else
10962306a36Sopenharmony_cistatic inline void tick_cancel_sched_timer(int cpu) { }
11062306a36Sopenharmony_ci#endif
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
11362306a36Sopenharmony_ciextern int __tick_broadcast_oneshot_control(enum tick_broadcast_state state);
11462306a36Sopenharmony_ci#else
11562306a36Sopenharmony_cistatic inline int
11662306a36Sopenharmony_ci__tick_broadcast_oneshot_control(enum tick_broadcast_state state)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	return -EBUSY;
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci#endif
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#endif
123