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 9eb93e4d9SThomas Gleixner extern seqlock_t jiffies_lock; 10eb93e4d9SThomas Gleixner 11c7e99fc7SThomas Gleixner #define CS_NAME_LEN 32 12c7e99fc7SThomas Gleixner 137cf37e87SThomas Gleixner #ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD 146441402bSThomas Gleixner 156441402bSThomas Gleixner #define TICK_DO_TIMER_NONE -1 166441402bSThomas Gleixner #define TICK_DO_TIMER_BOOT -2 176441402bSThomas Gleixner 18f8381cbaSThomas Gleixner DECLARE_PER_CPU(struct tick_device, tick_cpu_device); 19f8381cbaSThomas Gleixner extern ktime_t tick_next_period; 20f8381cbaSThomas Gleixner extern ktime_t tick_period; 21d3ed7824SThomas Gleixner extern int tick_do_timer_cpu __read_mostly; 22f8381cbaSThomas Gleixner 23f8381cbaSThomas Gleixner extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); 24f8381cbaSThomas Gleixner extern void tick_handle_periodic(struct clock_event_device *dev); 257172a286SThomas Gleixner extern void tick_check_new_device(struct clock_event_device *dev); 268c53daf6SThomas Gleixner extern void tick_handover_do_timer(int *cpup); 278c53daf6SThomas Gleixner extern void tick_shutdown(unsigned int *cpup); 288c53daf6SThomas Gleixner extern void tick_suspend(void); 298c53daf6SThomas Gleixner extern void tick_resume(void); 3003e13cf5SThomas Gleixner extern bool tick_check_replacement(struct clock_event_device *curdev, 3103e13cf5SThomas Gleixner struct clock_event_device *newdev); 3203e13cf5SThomas Gleixner extern void tick_install_replacement(struct clock_event_device *dev); 33f8381cbaSThomas Gleixner 342344abbcSThomas Gleixner extern void clockevents_shutdown(struct clock_event_device *dev); 35554ef387SViresh Kumar extern int clockevents_tick_resume(struct clock_event_device *dev); 362344abbcSThomas Gleixner 37891292a7SPatrick Palka extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt); 3803e13cf5SThomas Gleixner 39f8381cbaSThomas Gleixner /* 4079bf2bb3SThomas Gleixner * NO_HZ / high resolution timer shared code 4179bf2bb3SThomas Gleixner */ 4279bf2bb3SThomas Gleixner #ifdef CONFIG_TICK_ONESHOT 4379bf2bb3SThomas Gleixner extern void tick_setup_oneshot(struct clock_event_device *newdev, 4479bf2bb3SThomas Gleixner void (*handler)(struct clock_event_device *), 4579bf2bb3SThomas Gleixner ktime_t nextevt); 4679bf2bb3SThomas Gleixner extern int tick_program_event(ktime_t expires, int force); 4779bf2bb3SThomas Gleixner extern void tick_oneshot_notify(void); 4879bf2bb3SThomas Gleixner extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)); 49cd05a1f8SThomas Gleixner extern void tick_resume_oneshot(void); 5079bf2bb3SThomas Gleixner # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 5179bf2bb3SThomas Gleixner extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc); 52da7e6f45SPreeti U Murthy extern int tick_broadcast_oneshot_control(unsigned long reason); 5379bf2bb3SThomas Gleixner extern void tick_broadcast_switch_to_oneshot(void); 5479bf2bb3SThomas Gleixner extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); 55cd05a1f8SThomas Gleixner extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); 5627ce4cb4SThomas Gleixner extern int tick_broadcast_oneshot_active(void); 57e8fcaa5cSFrederic Weisbecker extern void tick_check_oneshot_broadcast_this_cpu(void); 583a142a06SThomas Gleixner bool tick_broadcast_oneshot_available(void); 5979bf2bb3SThomas Gleixner # else /* BROADCAST */ 6079bf2bb3SThomas Gleixner static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) 6179bf2bb3SThomas Gleixner { 6279bf2bb3SThomas Gleixner BUG(); 6379bf2bb3SThomas Gleixner } 64da7e6f45SPreeti U Murthy static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; } 6579bf2bb3SThomas Gleixner static inline void tick_broadcast_switch_to_oneshot(void) { } 6679bf2bb3SThomas Gleixner static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } 6727ce4cb4SThomas Gleixner static inline int tick_broadcast_oneshot_active(void) { return 0; } 68e8fcaa5cSFrederic Weisbecker static inline void tick_check_oneshot_broadcast_this_cpu(void) { } 693a142a06SThomas Gleixner static inline bool tick_broadcast_oneshot_available(void) { return true; } 7079bf2bb3SThomas Gleixner # endif /* !BROADCAST */ 7179bf2bb3SThomas Gleixner 7279bf2bb3SThomas Gleixner #else /* !ONESHOT */ 7379bf2bb3SThomas Gleixner static inline 7479bf2bb3SThomas Gleixner void tick_setup_oneshot(struct clock_event_device *newdev, 7579bf2bb3SThomas Gleixner void (*handler)(struct clock_event_device *), 7679bf2bb3SThomas Gleixner ktime_t nextevt) 7779bf2bb3SThomas Gleixner { 7879bf2bb3SThomas Gleixner BUG(); 7979bf2bb3SThomas Gleixner } 80cd05a1f8SThomas Gleixner static inline void tick_resume_oneshot(void) 81cd05a1f8SThomas Gleixner { 82cd05a1f8SThomas Gleixner BUG(); 83cd05a1f8SThomas Gleixner } 8479bf2bb3SThomas Gleixner static inline int tick_program_event(ktime_t expires, int force) 8579bf2bb3SThomas Gleixner { 8679bf2bb3SThomas Gleixner return 0; 8779bf2bb3SThomas Gleixner } 8879bf2bb3SThomas Gleixner static inline void tick_oneshot_notify(void) { } 8979bf2bb3SThomas Gleixner static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) 9079bf2bb3SThomas Gleixner { 9179bf2bb3SThomas Gleixner BUG(); 9279bf2bb3SThomas Gleixner } 93da7e6f45SPreeti U Murthy static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; } 9479bf2bb3SThomas Gleixner static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } 95cd05a1f8SThomas Gleixner static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) 96cd05a1f8SThomas Gleixner { 97cd05a1f8SThomas Gleixner return 0; 98cd05a1f8SThomas Gleixner } 99f8e256c6SIngo Molnar static inline int tick_broadcast_oneshot_active(void) { return 0; } 1003a142a06SThomas Gleixner static inline bool tick_broadcast_oneshot_available(void) { return false; } 10179bf2bb3SThomas Gleixner #endif /* !TICK_ONESHOT */ 10279bf2bb3SThomas Gleixner 103a80e49e2SFrederic Weisbecker /* NO_HZ_FULL internal */ 104a80e49e2SFrederic Weisbecker #ifdef CONFIG_NO_HZ_FULL 105a80e49e2SFrederic Weisbecker extern void tick_nohz_init(void); 106a80e49e2SFrederic Weisbecker # else 107a80e49e2SFrederic Weisbecker static inline void tick_nohz_init(void) { } 108a80e49e2SFrederic Weisbecker #endif 109a80e49e2SFrederic Weisbecker 11079bf2bb3SThomas Gleixner /* 111f8381cbaSThomas Gleixner * Broadcasting support 112f8381cbaSThomas Gleixner */ 113f8381cbaSThomas Gleixner #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 114f8381cbaSThomas Gleixner extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu); 1157172a286SThomas Gleixner extern void tick_install_broadcast_device(struct clock_event_device *dev); 116f8381cbaSThomas Gleixner extern int tick_is_broadcast_device(struct clock_event_device *dev); 117f8381cbaSThomas Gleixner extern void tick_broadcast_on_off(unsigned long reason, int *oncpu); 118f8381cbaSThomas Gleixner extern void tick_shutdown_broadcast(unsigned int *cpup); 1196321dd60SThomas Gleixner extern void tick_suspend_broadcast(void); 1206321dd60SThomas Gleixner extern int tick_resume_broadcast(void); 121b352bc1cSThomas Gleixner extern void tick_broadcast_init(void); 122f8381cbaSThomas Gleixner extern void 123f8381cbaSThomas Gleixner tick_set_periodic_handler(struct clock_event_device *dev, int broadcast); 124627ee794SThomas Gleixner int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq); 125f8381cbaSThomas Gleixner 126f8381cbaSThomas Gleixner #else /* !BROADCAST */ 127f8381cbaSThomas Gleixner 1287172a286SThomas Gleixner static inline void tick_install_broadcast_device(struct clock_event_device *dev) 129f8381cbaSThomas Gleixner { 130f8381cbaSThomas Gleixner } 131f8381cbaSThomas Gleixner 132f8381cbaSThomas Gleixner static inline int tick_is_broadcast_device(struct clock_event_device *dev) 133f8381cbaSThomas Gleixner { 134f8381cbaSThomas Gleixner return 0; 135f8381cbaSThomas Gleixner } 136f8381cbaSThomas Gleixner static inline int tick_device_uses_broadcast(struct clock_event_device *dev, 137f8381cbaSThomas Gleixner int cpu) 138f8381cbaSThomas Gleixner { 139f8381cbaSThomas Gleixner return 0; 140f8381cbaSThomas Gleixner } 141f8381cbaSThomas Gleixner static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { } 142f8381cbaSThomas Gleixner static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { } 143f8381cbaSThomas Gleixner static inline void tick_shutdown_broadcast(unsigned int *cpup) { } 1446321dd60SThomas Gleixner static inline void tick_suspend_broadcast(void) { } 1456321dd60SThomas Gleixner static inline int tick_resume_broadcast(void) { return 0; } 146b352bc1cSThomas Gleixner static inline void tick_broadcast_init(void) { } 147627ee794SThomas Gleixner static inline int tick_broadcast_update_freq(struct clock_event_device *dev, 148627ee794SThomas Gleixner u32 freq) { return -ENODEV; } 149f8381cbaSThomas Gleixner 150f8381cbaSThomas Gleixner /* 151f8381cbaSThomas Gleixner * Set the periodic handler in non broadcast mode 152f8381cbaSThomas Gleixner */ 153f8381cbaSThomas Gleixner static inline void tick_set_periodic_handler(struct clock_event_device *dev, 154f8381cbaSThomas Gleixner int broadcast) 155f8381cbaSThomas Gleixner { 156f8381cbaSThomas Gleixner dev->event_handler = tick_handle_periodic; 157f8381cbaSThomas Gleixner } 158f8381cbaSThomas Gleixner #endif /* !BROADCAST */ 159f8381cbaSThomas Gleixner 160f8381cbaSThomas Gleixner /* 161f8381cbaSThomas Gleixner * Check, if the device is functional or a dummy for broadcast 162f8381cbaSThomas Gleixner */ 163f8381cbaSThomas Gleixner static inline int tick_device_is_functional(struct clock_event_device *dev) 164f8381cbaSThomas Gleixner { 165f8381cbaSThomas Gleixner return !(dev->features & CLOCK_EVT_FEAT_DUMMY); 166f8381cbaSThomas Gleixner } 167e2830b5cSTorben Hohn 168f1689bb7SThomas Gleixner int __clockevents_update_freq(struct clock_event_device *dev, u32 freq); 169f1689bb7SThomas Gleixner 1707cf37e87SThomas Gleixner #endif 1717cf37e87SThomas Gleixner 172e2830b5cSTorben Hohn extern void do_timer(unsigned long ticks); 17347a1b796SJohn Stultz extern void update_wall_time(void); 174