xref: /openbmc/linux/kernel/time/tick-internal.h (revision b7475eb5)
1f8381cbaSThomas Gleixner /*
2f8381cbaSThomas Gleixner  * tick internal variable and functions used by low/high res code
3f8381cbaSThomas Gleixner  */
4e2830b5cSTorben Hohn #include <linux/hrtimer.h>
5e2830b5cSTorben Hohn #include <linux/tick.h>
66441402bSThomas Gleixner 
78b094cd0SThomas Gleixner #include "timekeeping.h"
88b094cd0SThomas Gleixner 
99f083b74SThomas Gleixner #ifdef CONFIG_GENERIC_CLOCKEVENTS
106441402bSThomas Gleixner 
116441402bSThomas Gleixner #define TICK_DO_TIMER_NONE	-1
126441402bSThomas Gleixner #define TICK_DO_TIMER_BOOT	-2
136441402bSThomas Gleixner 
14f8381cbaSThomas Gleixner DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
15f8381cbaSThomas Gleixner extern ktime_t tick_next_period;
16f8381cbaSThomas Gleixner extern ktime_t tick_period;
17d3ed7824SThomas Gleixner extern int tick_do_timer_cpu __read_mostly;
18f8381cbaSThomas Gleixner 
19f8381cbaSThomas Gleixner extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
20f8381cbaSThomas Gleixner extern void tick_handle_periodic(struct clock_event_device *dev);
217172a286SThomas Gleixner extern void tick_check_new_device(struct clock_event_device *dev);
228c53daf6SThomas Gleixner extern void tick_handover_do_timer(int *cpup);
238c53daf6SThomas Gleixner extern void tick_shutdown(unsigned int *cpup);
248c53daf6SThomas Gleixner extern void tick_suspend(void);
258c53daf6SThomas Gleixner extern void tick_resume(void);
2603e13cf5SThomas Gleixner extern bool tick_check_replacement(struct clock_event_device *curdev,
2703e13cf5SThomas Gleixner 				   struct clock_event_device *newdev);
2803e13cf5SThomas Gleixner extern void tick_install_replacement(struct clock_event_device *dev);
29f8381cbaSThomas Gleixner 
30554ef387SViresh Kumar extern int clockevents_tick_resume(struct clock_event_device *dev);
31b7475eb5SThomas Gleixner /* Check, if the device is functional or a dummy for broadcast */
32b7475eb5SThomas Gleixner static inline int tick_device_is_functional(struct clock_event_device *dev)
33b7475eb5SThomas Gleixner {
34b7475eb5SThomas Gleixner 	return !(dev->features & CLOCK_EVT_FEAT_DUMMY);
35b7475eb5SThomas Gleixner }
362344abbcSThomas Gleixner 
37b7475eb5SThomas Gleixner extern void clockevents_shutdown(struct clock_event_device *dev);
38b7475eb5SThomas Gleixner extern int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
39891292a7SPatrick Palka extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
40b7475eb5SThomas Gleixner #endif /* GENERIC_CLOCKEVENTS */
4103e13cf5SThomas Gleixner 
42b7475eb5SThomas Gleixner /* Oneshot related functions */
4379bf2bb3SThomas Gleixner #ifdef CONFIG_TICK_ONESHOT
4479bf2bb3SThomas Gleixner extern void tick_setup_oneshot(struct clock_event_device *newdev,
4579bf2bb3SThomas Gleixner 			       void (*handler)(struct clock_event_device *),
4679bf2bb3SThomas Gleixner 			       ktime_t nextevt);
4779bf2bb3SThomas Gleixner extern int tick_program_event(ktime_t expires, int force);
4879bf2bb3SThomas Gleixner extern void tick_oneshot_notify(void);
4979bf2bb3SThomas Gleixner extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
50cd05a1f8SThomas Gleixner extern void tick_resume_oneshot(void);
51b7475eb5SThomas Gleixner static inline bool tick_oneshot_possible(void) { return true; }
5279bf2bb3SThomas Gleixner #else /* !ONESHOT */
5379bf2bb3SThomas Gleixner static inline
5479bf2bb3SThomas Gleixner void tick_setup_oneshot(struct clock_event_device *newdev,
5579bf2bb3SThomas Gleixner 			void (*handler)(struct clock_event_device *),
56b7475eb5SThomas Gleixner 			ktime_t nextevt) { BUG(); }
57b7475eb5SThomas Gleixner static inline void tick_resume_oneshot(void) { BUG(); }
58b7475eb5SThomas Gleixner static inline int tick_program_event(ktime_t expires, int force) { return 0; }
5979bf2bb3SThomas Gleixner static inline void tick_oneshot_notify(void) { }
60b7475eb5SThomas Gleixner static inline bool tick_oneshot_possible(void) { return false; }
6179bf2bb3SThomas Gleixner #endif /* !TICK_ONESHOT */
6279bf2bb3SThomas Gleixner 
63b7475eb5SThomas Gleixner /* Broadcasting support */
64f8381cbaSThomas Gleixner #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
65f8381cbaSThomas Gleixner extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
667172a286SThomas Gleixner extern void tick_install_broadcast_device(struct clock_event_device *dev);
67f8381cbaSThomas Gleixner extern int tick_is_broadcast_device(struct clock_event_device *dev);
68f8381cbaSThomas Gleixner extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
69f8381cbaSThomas Gleixner extern void tick_shutdown_broadcast(unsigned int *cpup);
706321dd60SThomas Gleixner extern void tick_suspend_broadcast(void);
716321dd60SThomas Gleixner extern int tick_resume_broadcast(void);
72b352bc1cSThomas Gleixner extern void tick_broadcast_init(void);
73b7475eb5SThomas Gleixner extern void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
74b7475eb5SThomas Gleixner extern int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq);
75f8381cbaSThomas Gleixner #else /* !BROADCAST */
76b7475eb5SThomas Gleixner static inline void tick_install_broadcast_device(struct clock_event_device *dev) { }
77b7475eb5SThomas Gleixner static inline int tick_is_broadcast_device(struct clock_event_device *dev) { return 0; }
78b7475eb5SThomas Gleixner static inline int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu) { return 0; }
79f8381cbaSThomas Gleixner static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
80f8381cbaSThomas Gleixner static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
81f8381cbaSThomas Gleixner static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
826321dd60SThomas Gleixner static inline void tick_suspend_broadcast(void) { }
836321dd60SThomas Gleixner static inline int tick_resume_broadcast(void) { return 0; }
84b352bc1cSThomas Gleixner static inline void tick_broadcast_init(void) { }
85b7475eb5SThomas Gleixner static inline int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq) { return -ENODEV; }
86f8381cbaSThomas Gleixner 
87b7475eb5SThomas Gleixner /* Set the periodic handler in non broadcast mode */
88b7475eb5SThomas Gleixner static inline void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast)
89f8381cbaSThomas Gleixner {
90f8381cbaSThomas Gleixner 	dev->event_handler = tick_handle_periodic;
91f8381cbaSThomas Gleixner }
92f8381cbaSThomas Gleixner #endif /* !BROADCAST */
93f8381cbaSThomas Gleixner 
94b7475eb5SThomas Gleixner /* Functions related to oneshot broadcasting */
95b7475eb5SThomas Gleixner #if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
96b7475eb5SThomas Gleixner extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
97b7475eb5SThomas Gleixner extern int tick_broadcast_oneshot_control(unsigned long reason);
98b7475eb5SThomas Gleixner extern void tick_broadcast_switch_to_oneshot(void);
99b7475eb5SThomas Gleixner extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
100b7475eb5SThomas Gleixner extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
101b7475eb5SThomas Gleixner extern int tick_broadcast_oneshot_active(void);
102b7475eb5SThomas Gleixner extern void tick_check_oneshot_broadcast_this_cpu(void);
103b7475eb5SThomas Gleixner bool tick_broadcast_oneshot_available(void);
104b7475eb5SThomas Gleixner #else /* BROADCAST && ONESHOT */
105b7475eb5SThomas Gleixner static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
106b7475eb5SThomas Gleixner static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; }
107b7475eb5SThomas Gleixner static inline void tick_broadcast_switch_to_oneshot(void) { }
108b7475eb5SThomas Gleixner static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
109b7475eb5SThomas Gleixner static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) { return 0; }
110b7475eb5SThomas Gleixner static inline int tick_broadcast_oneshot_active(void) { return 0; }
111b7475eb5SThomas Gleixner static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
112b7475eb5SThomas Gleixner static inline bool tick_broadcast_oneshot_available(void) { return tick_oneshot_possible(); }
113b7475eb5SThomas Gleixner #endif /* !BROADCAST && ONESHOT */
114e2830b5cSTorben Hohn 
115b7475eb5SThomas Gleixner /* NO_HZ_FULL internal */
116b7475eb5SThomas Gleixner #ifdef CONFIG_NO_HZ_FULL
117b7475eb5SThomas Gleixner extern void tick_nohz_init(void);
118b7475eb5SThomas Gleixner # else
119b7475eb5SThomas Gleixner static inline void tick_nohz_init(void) { }
120b7475eb5SThomas Gleixner #endif
121