xref: /linux/kernel/time/tick-internal.h (revision bfb83b27519aa7ed9510f601a8f825a2c1484bc2)
1 /*
2  * tick internal variable and functions used by low/high res code
3  */
4 #include <linux/hrtimer.h>
5 #include <linux/tick.h>
6 
7 #include "timekeeping.h"
8 
9 #ifdef CONFIG_GENERIC_CLOCKEVENTS
10 
11 #define TICK_DO_TIMER_NONE	-1
12 #define TICK_DO_TIMER_BOOT	-2
13 
14 DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
15 extern ktime_t tick_next_period;
16 extern ktime_t tick_period;
17 extern int tick_do_timer_cpu __read_mostly;
18 
19 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
20 extern void tick_handle_periodic(struct clock_event_device *dev);
21 extern void tick_check_new_device(struct clock_event_device *dev);
22 extern void tick_handover_do_timer(int *cpup);
23 extern void tick_shutdown(unsigned int *cpup);
24 extern void tick_suspend(void);
25 extern void tick_resume(void);
26 extern bool tick_check_replacement(struct clock_event_device *curdev,
27 				   struct clock_event_device *newdev);
28 extern void tick_install_replacement(struct clock_event_device *dev);
29 
30 extern void clockevents_shutdown(struct clock_event_device *dev);
31 extern int clockevents_tick_resume(struct clock_event_device *dev);
32 
33 extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
34 
35 /*
36  * NO_HZ / high resolution timer shared code
37  */
38 #ifdef CONFIG_TICK_ONESHOT
39 extern void tick_setup_oneshot(struct clock_event_device *newdev,
40 			       void (*handler)(struct clock_event_device *),
41 			       ktime_t nextevt);
42 extern int tick_program_event(ktime_t expires, int force);
43 extern void tick_oneshot_notify(void);
44 extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
45 extern void tick_resume_oneshot(void);
46 # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
47 extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
48 extern int tick_broadcast_oneshot_control(unsigned long reason);
49 extern void tick_broadcast_switch_to_oneshot(void);
50 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
51 extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
52 extern int tick_broadcast_oneshot_active(void);
53 extern void tick_check_oneshot_broadcast_this_cpu(void);
54 bool tick_broadcast_oneshot_available(void);
55 # else /* BROADCAST */
56 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
57 {
58 	BUG();
59 }
60 static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; }
61 static inline void tick_broadcast_switch_to_oneshot(void) { }
62 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
63 static inline int tick_broadcast_oneshot_active(void) { return 0; }
64 static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
65 static inline bool tick_broadcast_oneshot_available(void) { return true; }
66 # endif /* !BROADCAST */
67 
68 #else /* !ONESHOT */
69 static inline
70 void tick_setup_oneshot(struct clock_event_device *newdev,
71 			void (*handler)(struct clock_event_device *),
72 			ktime_t nextevt)
73 {
74 	BUG();
75 }
76 static inline void tick_resume_oneshot(void)
77 {
78 	BUG();
79 }
80 static inline int tick_program_event(ktime_t expires, int force)
81 {
82 	return 0;
83 }
84 static inline void tick_oneshot_notify(void) { }
85 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
86 {
87 	BUG();
88 }
89 static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; }
90 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
91 static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
92 {
93 	return 0;
94 }
95 static inline int tick_broadcast_oneshot_active(void) { return 0; }
96 static inline bool tick_broadcast_oneshot_available(void) { return false; }
97 #endif /* !TICK_ONESHOT */
98 
99 /* NO_HZ_FULL internal */
100 #ifdef CONFIG_NO_HZ_FULL
101 extern void tick_nohz_init(void);
102 # else
103 static inline void tick_nohz_init(void) { }
104 #endif
105 
106 /*
107  * Broadcasting support
108  */
109 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
110 extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
111 extern void tick_install_broadcast_device(struct clock_event_device *dev);
112 extern int tick_is_broadcast_device(struct clock_event_device *dev);
113 extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
114 extern void tick_shutdown_broadcast(unsigned int *cpup);
115 extern void tick_suspend_broadcast(void);
116 extern int tick_resume_broadcast(void);
117 extern void tick_broadcast_init(void);
118 extern void
119 tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
120 int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq);
121 
122 #else /* !BROADCAST */
123 
124 static inline void tick_install_broadcast_device(struct clock_event_device *dev)
125 {
126 }
127 
128 static inline int tick_is_broadcast_device(struct clock_event_device *dev)
129 {
130 	return 0;
131 }
132 static inline int tick_device_uses_broadcast(struct clock_event_device *dev,
133 					     int cpu)
134 {
135 	return 0;
136 }
137 static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
138 static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
139 static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
140 static inline void tick_suspend_broadcast(void) { }
141 static inline int tick_resume_broadcast(void) { return 0; }
142 static inline void tick_broadcast_init(void) { }
143 static inline int tick_broadcast_update_freq(struct clock_event_device *dev,
144 					     u32 freq) { return -ENODEV; }
145 
146 /*
147  * Set the periodic handler in non broadcast mode
148  */
149 static inline void tick_set_periodic_handler(struct clock_event_device *dev,
150 					     int broadcast)
151 {
152 	dev->event_handler = tick_handle_periodic;
153 }
154 #endif /* !BROADCAST */
155 
156 /*
157  * Check, if the device is functional or a dummy for broadcast
158  */
159 static inline int tick_device_is_functional(struct clock_event_device *dev)
160 {
161 	return !(dev->features & CLOCK_EVT_FEAT_DUMMY);
162 }
163 
164 int __clockevents_update_freq(struct clock_event_device *dev, u32 freq);
165 
166 #endif /* GENERIC_CLOCKEVENTS */
167 
168