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); 352344abbcSThomas Gleixner 36891292a7SPatrick Palka extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt); 3703e13cf5SThomas Gleixner 38f8381cbaSThomas Gleixner /* 3979bf2bb3SThomas Gleixner * NO_HZ / high resolution timer shared code 4079bf2bb3SThomas Gleixner */ 4179bf2bb3SThomas Gleixner #ifdef CONFIG_TICK_ONESHOT 4279bf2bb3SThomas Gleixner extern void tick_setup_oneshot(struct clock_event_device *newdev, 4379bf2bb3SThomas Gleixner void (*handler)(struct clock_event_device *), 4479bf2bb3SThomas Gleixner ktime_t nextevt); 4579bf2bb3SThomas Gleixner extern int tick_program_event(ktime_t expires, int force); 4679bf2bb3SThomas Gleixner extern void tick_oneshot_notify(void); 4779bf2bb3SThomas Gleixner extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)); 48cd05a1f8SThomas Gleixner extern void tick_resume_oneshot(void); 4979bf2bb3SThomas Gleixner # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 5079bf2bb3SThomas Gleixner extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc); 51da7e6f45SPreeti U Murthy extern int tick_broadcast_oneshot_control(unsigned long reason); 5279bf2bb3SThomas Gleixner extern void tick_broadcast_switch_to_oneshot(void); 5379bf2bb3SThomas Gleixner extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); 54cd05a1f8SThomas Gleixner extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); 5527ce4cb4SThomas Gleixner extern int tick_broadcast_oneshot_active(void); 56e8fcaa5cSFrederic Weisbecker extern void tick_check_oneshot_broadcast_this_cpu(void); 573a142a06SThomas Gleixner bool tick_broadcast_oneshot_available(void); 5879bf2bb3SThomas Gleixner # else /* BROADCAST */ 5979bf2bb3SThomas Gleixner static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) 6079bf2bb3SThomas Gleixner { 6179bf2bb3SThomas Gleixner BUG(); 6279bf2bb3SThomas Gleixner } 63da7e6f45SPreeti U Murthy static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; } 6479bf2bb3SThomas Gleixner static inline void tick_broadcast_switch_to_oneshot(void) { } 6579bf2bb3SThomas Gleixner static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } 6627ce4cb4SThomas Gleixner static inline int tick_broadcast_oneshot_active(void) { return 0; } 67e8fcaa5cSFrederic Weisbecker static inline void tick_check_oneshot_broadcast_this_cpu(void) { } 683a142a06SThomas Gleixner static inline bool tick_broadcast_oneshot_available(void) { return true; } 6979bf2bb3SThomas Gleixner # endif /* !BROADCAST */ 7079bf2bb3SThomas Gleixner 7179bf2bb3SThomas Gleixner #else /* !ONESHOT */ 7279bf2bb3SThomas Gleixner static inline 7379bf2bb3SThomas Gleixner void tick_setup_oneshot(struct clock_event_device *newdev, 7479bf2bb3SThomas Gleixner void (*handler)(struct clock_event_device *), 7579bf2bb3SThomas Gleixner ktime_t nextevt) 7679bf2bb3SThomas Gleixner { 7779bf2bb3SThomas Gleixner BUG(); 7879bf2bb3SThomas Gleixner } 79cd05a1f8SThomas Gleixner static inline void tick_resume_oneshot(void) 80cd05a1f8SThomas Gleixner { 81cd05a1f8SThomas Gleixner BUG(); 82cd05a1f8SThomas Gleixner } 8379bf2bb3SThomas Gleixner static inline int tick_program_event(ktime_t expires, int force) 8479bf2bb3SThomas Gleixner { 8579bf2bb3SThomas Gleixner return 0; 8679bf2bb3SThomas Gleixner } 8779bf2bb3SThomas Gleixner static inline void tick_oneshot_notify(void) { } 8879bf2bb3SThomas Gleixner static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) 8979bf2bb3SThomas Gleixner { 9079bf2bb3SThomas Gleixner BUG(); 9179bf2bb3SThomas Gleixner } 92da7e6f45SPreeti U Murthy static inline int tick_broadcast_oneshot_control(unsigned long reason) { return 0; } 9379bf2bb3SThomas Gleixner static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } 94cd05a1f8SThomas Gleixner static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) 95cd05a1f8SThomas Gleixner { 96cd05a1f8SThomas Gleixner return 0; 97cd05a1f8SThomas Gleixner } 98f8e256c6SIngo Molnar static inline int tick_broadcast_oneshot_active(void) { return 0; } 993a142a06SThomas Gleixner static inline bool tick_broadcast_oneshot_available(void) { return false; } 10079bf2bb3SThomas Gleixner #endif /* !TICK_ONESHOT */ 10179bf2bb3SThomas Gleixner 10279bf2bb3SThomas Gleixner /* 103f8381cbaSThomas Gleixner * Broadcasting support 104f8381cbaSThomas Gleixner */ 105f8381cbaSThomas Gleixner #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 106f8381cbaSThomas Gleixner extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu); 1077172a286SThomas Gleixner extern void tick_install_broadcast_device(struct clock_event_device *dev); 108f8381cbaSThomas Gleixner extern int tick_is_broadcast_device(struct clock_event_device *dev); 109f8381cbaSThomas Gleixner extern void tick_broadcast_on_off(unsigned long reason, int *oncpu); 110f8381cbaSThomas Gleixner extern void tick_shutdown_broadcast(unsigned int *cpup); 1116321dd60SThomas Gleixner extern void tick_suspend_broadcast(void); 1126321dd60SThomas Gleixner extern int tick_resume_broadcast(void); 113b352bc1cSThomas Gleixner extern void tick_broadcast_init(void); 114f8381cbaSThomas Gleixner extern void 115f8381cbaSThomas Gleixner tick_set_periodic_handler(struct clock_event_device *dev, int broadcast); 116627ee794SThomas Gleixner int tick_broadcast_update_freq(struct clock_event_device *dev, u32 freq); 117f8381cbaSThomas Gleixner 118f8381cbaSThomas Gleixner #else /* !BROADCAST */ 119f8381cbaSThomas Gleixner 1207172a286SThomas Gleixner static inline void tick_install_broadcast_device(struct clock_event_device *dev) 121f8381cbaSThomas Gleixner { 122f8381cbaSThomas Gleixner } 123f8381cbaSThomas Gleixner 124f8381cbaSThomas Gleixner static inline int tick_is_broadcast_device(struct clock_event_device *dev) 125f8381cbaSThomas Gleixner { 126f8381cbaSThomas Gleixner return 0; 127f8381cbaSThomas Gleixner } 128f8381cbaSThomas Gleixner static inline int tick_device_uses_broadcast(struct clock_event_device *dev, 129f8381cbaSThomas Gleixner int cpu) 130f8381cbaSThomas Gleixner { 131f8381cbaSThomas Gleixner return 0; 132f8381cbaSThomas Gleixner } 133f8381cbaSThomas Gleixner static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { } 134f8381cbaSThomas Gleixner static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { } 135f8381cbaSThomas Gleixner static inline void tick_shutdown_broadcast(unsigned int *cpup) { } 1366321dd60SThomas Gleixner static inline void tick_suspend_broadcast(void) { } 1376321dd60SThomas Gleixner static inline int tick_resume_broadcast(void) { return 0; } 138b352bc1cSThomas Gleixner static inline void tick_broadcast_init(void) { } 139627ee794SThomas Gleixner static inline int tick_broadcast_update_freq(struct clock_event_device *dev, 140627ee794SThomas Gleixner u32 freq) { return -ENODEV; } 141f8381cbaSThomas Gleixner 142f8381cbaSThomas Gleixner /* 143f8381cbaSThomas Gleixner * Set the periodic handler in non broadcast mode 144f8381cbaSThomas Gleixner */ 145f8381cbaSThomas Gleixner static inline void tick_set_periodic_handler(struct clock_event_device *dev, 146f8381cbaSThomas Gleixner int broadcast) 147f8381cbaSThomas Gleixner { 148f8381cbaSThomas Gleixner dev->event_handler = tick_handle_periodic; 149f8381cbaSThomas Gleixner } 150f8381cbaSThomas Gleixner #endif /* !BROADCAST */ 151f8381cbaSThomas Gleixner 152f8381cbaSThomas Gleixner /* 153f8381cbaSThomas Gleixner * Check, if the device is functional or a dummy for broadcast 154f8381cbaSThomas Gleixner */ 155f8381cbaSThomas Gleixner static inline int tick_device_is_functional(struct clock_event_device *dev) 156f8381cbaSThomas Gleixner { 157f8381cbaSThomas Gleixner return !(dev->features & CLOCK_EVT_FEAT_DUMMY); 158f8381cbaSThomas Gleixner } 159e2830b5cSTorben Hohn 160f1689bb7SThomas Gleixner int __clockevents_update_freq(struct clock_event_device *dev, u32 freq); 161f1689bb7SThomas Gleixner 1627cf37e87SThomas Gleixner #endif 1637cf37e87SThomas Gleixner 164e2830b5cSTorben Hohn extern void do_timer(unsigned long ticks); 16547a1b796SJohn Stultz extern void update_wall_time(void); 166