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