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