blob: e2bced59b6dda1a7322eb6c35c575e1959aed971 [file] [log] [blame]
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -08001/*
2 * tick internal variable and functions used by low/high res code
3 */
Torben Hohne2830b52011-01-27 16:00:32 +01004#include <linux/hrtimer.h>
5#include <linux/tick.h>
Thomas Gleixner64414022008-09-22 18:46:37 +02006
Thomas Gleixnereb93e4d2013-02-21 22:51:36 +00007extern seqlock_t jiffies_lock;
8
Thomas Gleixnerc7e99fc2013-05-28 09:28:02 +02009#define CS_NAME_LEN 32
10
Thomas Gleixner7cf37e82011-02-01 09:34:58 +010011#ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD
Thomas Gleixner64414022008-09-22 18:46:37 +020012
13#define TICK_DO_TIMER_NONE -1
14#define TICK_DO_TIMER_BOOT -2
15
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -080016DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -080017extern ktime_t tick_next_period;
18extern ktime_t tick_period;
Thomas Gleixnerd3ed7822007-05-08 00:30:03 -070019extern int tick_do_timer_cpu __read_mostly;
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -080020
21extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
22extern void tick_handle_periodic(struct clock_event_device *dev);
Thomas Gleixner7172a282013-04-25 20:31:47 +000023extern void tick_check_new_device(struct clock_event_device *dev);
Thomas Gleixner8c53daf2013-04-25 20:31:48 +000024extern void tick_handover_do_timer(int *cpup);
25extern void tick_shutdown(unsigned int *cpup);
26extern void tick_suspend(void);
27extern void tick_resume(void);
Thomas Gleixner03e13cf2013-04-25 20:31:50 +000028extern bool tick_check_replacement(struct clock_event_device *curdev,
29 struct clock_event_device *newdev);
30extern void tick_install_replacement(struct clock_event_device *dev);
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -080031
Thomas Gleixner2344abb2008-09-16 11:32:50 -070032extern void clockevents_shutdown(struct clock_event_device *dev);
33
Patrick Palka891292a2013-10-11 13:11:55 -040034extern ssize_t sysfs_get_uname(const char *buf, char *dst, size_t cnt);
Thomas Gleixner03e13cf2013-04-25 20:31:50 +000035
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -080036/*
Thomas Gleixner79bf2bb2007-02-16 01:28:03 -080037 * NO_HZ / high resolution timer shared code
38 */
39#ifdef CONFIG_TICK_ONESHOT
40extern void tick_setup_oneshot(struct clock_event_device *newdev,
41 void (*handler)(struct clock_event_device *),
42 ktime_t nextevt);
43extern int tick_program_event(ktime_t expires, int force);
44extern void tick_oneshot_notify(void);
45extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
Thomas Gleixnercd05a1f2007-03-17 00:25:52 +010046extern void tick_resume_oneshot(void);
Thomas Gleixner79bf2bb2007-02-16 01:28:03 -080047# ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
48extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
49extern void tick_broadcast_oneshot_control(unsigned long reason);
50extern void tick_broadcast_switch_to_oneshot(void);
51extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
Thomas Gleixnercd05a1f2007-03-17 00:25:52 +010052extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
Thomas Gleixner27ce4cb2008-09-22 19:04:02 +020053extern int tick_broadcast_oneshot_active(void);
Frederic Weisbeckere8fcaa52013-08-07 22:28:01 +020054extern void tick_check_oneshot_broadcast_this_cpu(void);
Thomas Gleixner3a142a02011-02-25 22:34:23 +010055bool tick_broadcast_oneshot_available(void);
Thomas Gleixner79bf2bb2007-02-16 01:28:03 -080056# else /* BROADCAST */
57static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
58{
59 BUG();
60}
61static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
62static inline void tick_broadcast_switch_to_oneshot(void) { }
63static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
Thomas Gleixner27ce4cb2008-09-22 19:04:02 +020064static inline int tick_broadcast_oneshot_active(void) { return 0; }
Frederic Weisbeckere8fcaa52013-08-07 22:28:01 +020065static inline void tick_check_oneshot_broadcast_this_cpu(void) { }
Thomas Gleixner3a142a02011-02-25 22:34:23 +010066static inline bool tick_broadcast_oneshot_available(void) { return true; }
Thomas Gleixner79bf2bb2007-02-16 01:28:03 -080067# endif /* !BROADCAST */
68
69#else /* !ONESHOT */
70static inline
71void tick_setup_oneshot(struct clock_event_device *newdev,
72 void (*handler)(struct clock_event_device *),
73 ktime_t nextevt)
74{
75 BUG();
76}
Thomas Gleixnercd05a1f2007-03-17 00:25:52 +010077static inline void tick_resume_oneshot(void)
78{
79 BUG();
80}
Thomas Gleixner79bf2bb2007-02-16 01:28:03 -080081static inline int tick_program_event(ktime_t expires, int force)
82{
83 return 0;
84}
85static inline void tick_oneshot_notify(void) { }
86static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
87{
88 BUG();
89}
90static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
91static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
Thomas Gleixnercd05a1f2007-03-17 00:25:52 +010092static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
93{
94 return 0;
95}
Ingo Molnarf8e256c2008-09-23 13:00:57 +020096static inline int tick_broadcast_oneshot_active(void) { return 0; }
Thomas Gleixner3a142a02011-02-25 22:34:23 +010097static inline bool tick_broadcast_oneshot_available(void) { return false; }
Thomas Gleixner79bf2bb2007-02-16 01:28:03 -080098#endif /* !TICK_ONESHOT */
99
100/*
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -0800101 * Broadcasting support
102 */
103#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -0800104extern int tick_device_uses_broadcast(struct clock_event_device *dev, int cpu);
Thomas Gleixner7172a282013-04-25 20:31:47 +0000105extern void tick_install_broadcast_device(struct clock_event_device *dev);
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -0800106extern int tick_is_broadcast_device(struct clock_event_device *dev);
107extern void tick_broadcast_on_off(unsigned long reason, int *oncpu);
108extern void tick_shutdown_broadcast(unsigned int *cpup);
Thomas Gleixner6321dd62007-03-06 08:25:42 +0100109extern void tick_suspend_broadcast(void);
110extern int tick_resume_broadcast(void);
Thomas Gleixnerb352bc12013-03-05 14:25:32 +0100111extern void tick_broadcast_init(void);
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -0800112extern void
113tick_set_periodic_handler(struct clock_event_device *dev, int broadcast);
114
115#else /* !BROADCAST */
116
Thomas Gleixner7172a282013-04-25 20:31:47 +0000117static inline void tick_install_broadcast_device(struct clock_event_device *dev)
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -0800118{
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -0800119}
120
121static inline int tick_is_broadcast_device(struct clock_event_device *dev)
122{
123 return 0;
124}
125static inline int tick_device_uses_broadcast(struct clock_event_device *dev,
126 int cpu)
127{
128 return 0;
129}
130static inline void tick_do_periodic_broadcast(struct clock_event_device *d) { }
131static inline void tick_broadcast_on_off(unsigned long reason, int *oncpu) { }
132static inline void tick_shutdown_broadcast(unsigned int *cpup) { }
Thomas Gleixner6321dd62007-03-06 08:25:42 +0100133static inline void tick_suspend_broadcast(void) { }
134static inline int tick_resume_broadcast(void) { return 0; }
Thomas Gleixnerb352bc12013-03-05 14:25:32 +0100135static inline void tick_broadcast_init(void) { }
Thomas Gleixnerf8381cb2007-02-16 01:28:02 -0800136
137/*
138 * Set the periodic handler in non broadcast mode
139 */
140static inline void tick_set_periodic_handler(struct clock_event_device *dev,
141 int broadcast)
142{
143 dev->event_handler = tick_handle_periodic;
144}
145#endif /* !BROADCAST */
146
147/*
148 * Check, if the device is functional or a dummy for broadcast
149 */
150static inline int tick_device_is_functional(struct clock_event_device *dev)
151{
152 return !(dev->features & CLOCK_EVT_FEAT_DUMMY);
153}
Torben Hohne2830b52011-01-27 16:00:32 +0100154
Thomas Gleixner7cf37e82011-02-01 09:34:58 +0100155#endif
156
Torben Hohne2830b52011-01-27 16:00:32 +0100157extern void do_timer(unsigned long ticks);