aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/clockchips.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/clockchips.h')
-rw-r--r--include/linux/clockchips.h154
1 files changed, 79 insertions, 75 deletions
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 2e4cb67f6e56..96c280b2c263 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -8,33 +8,19 @@
8#ifndef _LINUX_CLOCKCHIPS_H 8#ifndef _LINUX_CLOCKCHIPS_H
9#define _LINUX_CLOCKCHIPS_H 9#define _LINUX_CLOCKCHIPS_H
10 10
11/* Clock event notification values */ 11#ifdef CONFIG_GENERIC_CLOCKEVENTS
12enum clock_event_nofitiers {
13 CLOCK_EVT_NOTIFY_ADD,
14 CLOCK_EVT_NOTIFY_BROADCAST_ON,
15 CLOCK_EVT_NOTIFY_BROADCAST_OFF,
16 CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
17 CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
18 CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
19 CLOCK_EVT_NOTIFY_SUSPEND,
20 CLOCK_EVT_NOTIFY_RESUME,
21 CLOCK_EVT_NOTIFY_CPU_DYING,
22 CLOCK_EVT_NOTIFY_CPU_DEAD,
23};
24
25#ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD
26 12
27#include <linux/clocksource.h> 13# include <linux/clocksource.h>
28#include <linux/cpumask.h> 14# include <linux/cpumask.h>
29#include <linux/ktime.h> 15# include <linux/ktime.h>
30#include <linux/notifier.h> 16# include <linux/notifier.h>
31 17
32struct clock_event_device; 18struct clock_event_device;
33struct module; 19struct module;
34 20
35/* Clock event mode commands */ 21/* Clock event mode commands for legacy ->set_mode(): OBSOLETE */
36enum clock_event_mode { 22enum clock_event_mode {
37 CLOCK_EVT_MODE_UNUSED = 0, 23 CLOCK_EVT_MODE_UNUSED,
38 CLOCK_EVT_MODE_SHUTDOWN, 24 CLOCK_EVT_MODE_SHUTDOWN,
39 CLOCK_EVT_MODE_PERIODIC, 25 CLOCK_EVT_MODE_PERIODIC,
40 CLOCK_EVT_MODE_ONESHOT, 26 CLOCK_EVT_MODE_ONESHOT,
@@ -42,30 +28,49 @@ enum clock_event_mode {
42}; 28};
43 29
44/* 30/*
31 * Possible states of a clock event device.
32 *
33 * DETACHED: Device is not used by clockevents core. Initial state or can be
34 * reached from SHUTDOWN.
35 * SHUTDOWN: Device is powered-off. Can be reached from PERIODIC or ONESHOT.
36 * PERIODIC: Device is programmed to generate events periodically. Can be
37 * reached from DETACHED or SHUTDOWN.
38 * ONESHOT: Device is programmed to generate event only once. Can be reached
39 * from DETACHED or SHUTDOWN.
40 */
41enum clock_event_state {
42 CLOCK_EVT_STATE_DETACHED,
43 CLOCK_EVT_STATE_SHUTDOWN,
44 CLOCK_EVT_STATE_PERIODIC,
45 CLOCK_EVT_STATE_ONESHOT,
46};
47
48/*
45 * Clock event features 49 * Clock event features
46 */ 50 */
47#define CLOCK_EVT_FEAT_PERIODIC 0x000001 51# define CLOCK_EVT_FEAT_PERIODIC 0x000001
48#define CLOCK_EVT_FEAT_ONESHOT 0x000002 52# define CLOCK_EVT_FEAT_ONESHOT 0x000002
49#define CLOCK_EVT_FEAT_KTIME 0x000004 53# define CLOCK_EVT_FEAT_KTIME 0x000004
54
50/* 55/*
51 * x86(64) specific misfeatures: 56 * x86(64) specific (mis)features:
52 * 57 *
53 * - Clockevent source stops in C3 State and needs broadcast support. 58 * - Clockevent source stops in C3 State and needs broadcast support.
54 * - Local APIC timer is used as a dummy device. 59 * - Local APIC timer is used as a dummy device.
55 */ 60 */
56#define CLOCK_EVT_FEAT_C3STOP 0x000008 61# define CLOCK_EVT_FEAT_C3STOP 0x000008
57#define CLOCK_EVT_FEAT_DUMMY 0x000010 62# define CLOCK_EVT_FEAT_DUMMY 0x000010
58 63
59/* 64/*
60 * Core shall set the interrupt affinity dynamically in broadcast mode 65 * Core shall set the interrupt affinity dynamically in broadcast mode
61 */ 66 */
62#define CLOCK_EVT_FEAT_DYNIRQ 0x000020 67# define CLOCK_EVT_FEAT_DYNIRQ 0x000020
63#define CLOCK_EVT_FEAT_PERCPU 0x000040 68# define CLOCK_EVT_FEAT_PERCPU 0x000040
64 69
65/* 70/*
66 * Clockevent device is based on a hrtimer for broadcast 71 * Clockevent device is based on a hrtimer for broadcast
67 */ 72 */
68#define CLOCK_EVT_FEAT_HRTIMER 0x000080 73# define CLOCK_EVT_FEAT_HRTIMER 0x000080
69 74
70/** 75/**
71 * struct clock_event_device - clock event device descriptor 76 * struct clock_event_device - clock event device descriptor
@@ -78,10 +83,15 @@ enum clock_event_mode {
78 * @min_delta_ns: minimum delta value in ns 83 * @min_delta_ns: minimum delta value in ns
79 * @mult: nanosecond to cycles multiplier 84 * @mult: nanosecond to cycles multiplier
80 * @shift: nanoseconds to cycles divisor (power of two) 85 * @shift: nanoseconds to cycles divisor (power of two)
81 * @mode: operating mode assigned by the management code 86 * @mode: operating mode, relevant only to ->set_mode(), OBSOLETE
87 * @state: current state of the device, assigned by the core code
82 * @features: features 88 * @features: features
83 * @retries: number of forced programming retries 89 * @retries: number of forced programming retries
84 * @set_mode: set mode function 90 * @set_mode: legacy set mode function, only for modes <= CLOCK_EVT_MODE_RESUME.
91 * @set_state_periodic: switch state to periodic, if !set_mode
92 * @set_state_oneshot: switch state to oneshot, if !set_mode
93 * @set_state_shutdown: switch state to shutdown, if !set_mode
94 * @tick_resume: resume clkevt device, if !set_mode
85 * @broadcast: function to broadcast events 95 * @broadcast: function to broadcast events
86 * @min_delta_ticks: minimum delta value in ticks stored for reconfiguration 96 * @min_delta_ticks: minimum delta value in ticks stored for reconfiguration
87 * @max_delta_ticks: maximum delta value in ticks stored for reconfiguration 97 * @max_delta_ticks: maximum delta value in ticks stored for reconfiguration
@@ -95,22 +105,31 @@ enum clock_event_mode {
95 */ 105 */
96struct clock_event_device { 106struct clock_event_device {
97 void (*event_handler)(struct clock_event_device *); 107 void (*event_handler)(struct clock_event_device *);
98 int (*set_next_event)(unsigned long evt, 108 int (*set_next_event)(unsigned long evt, struct clock_event_device *);
99 struct clock_event_device *); 109 int (*set_next_ktime)(ktime_t expires, struct clock_event_device *);
100 int (*set_next_ktime)(ktime_t expires,
101 struct clock_event_device *);
102 ktime_t next_event; 110 ktime_t next_event;
103 u64 max_delta_ns; 111 u64 max_delta_ns;
104 u64 min_delta_ns; 112 u64 min_delta_ns;
105 u32 mult; 113 u32 mult;
106 u32 shift; 114 u32 shift;
107 enum clock_event_mode mode; 115 enum clock_event_mode mode;
116 enum clock_event_state state;
108 unsigned int features; 117 unsigned int features;
109 unsigned long retries; 118 unsigned long retries;
110 119
120 /*
121 * State transition callback(s): Only one of the two groups should be
122 * defined:
123 * - set_mode(), only for modes <= CLOCK_EVT_MODE_RESUME.
124 * - set_state_{shutdown|periodic|oneshot}(), tick_resume().
125 */
126 void (*set_mode)(enum clock_event_mode mode, struct clock_event_device *);
127 int (*set_state_periodic)(struct clock_event_device *);
128 int (*set_state_oneshot)(struct clock_event_device *);
129 int (*set_state_shutdown)(struct clock_event_device *);
130 int (*tick_resume)(struct clock_event_device *);
131
111 void (*broadcast)(const struct cpumask *mask); 132 void (*broadcast)(const struct cpumask *mask);
112 void (*set_mode)(enum clock_event_mode mode,
113 struct clock_event_device *);
114 void (*suspend)(struct clock_event_device *); 133 void (*suspend)(struct clock_event_device *);
115 void (*resume)(struct clock_event_device *); 134 void (*resume)(struct clock_event_device *);
116 unsigned long min_delta_ticks; 135 unsigned long min_delta_ticks;
@@ -136,18 +155,18 @@ struct clock_event_device {
136 * 155 *
137 * factor = (clock_ticks << shift) / nanoseconds 156 * factor = (clock_ticks << shift) / nanoseconds
138 */ 157 */
139static inline unsigned long div_sc(unsigned long ticks, unsigned long nsec, 158static inline unsigned long
140 int shift) 159div_sc(unsigned long ticks, unsigned long nsec, int shift)
141{ 160{
142 uint64_t tmp = ((uint64_t)ticks) << shift; 161 u64 tmp = ((u64)ticks) << shift;
143 162
144 do_div(tmp, nsec); 163 do_div(tmp, nsec);
164
145 return (unsigned long) tmp; 165 return (unsigned long) tmp;
146} 166}
147 167
148/* Clock event layer functions */ 168/* Clock event layer functions */
149extern u64 clockevent_delta2ns(unsigned long latch, 169extern u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *evt);
150 struct clock_event_device *evt);
151extern void clockevents_register_device(struct clock_event_device *dev); 170extern void clockevents_register_device(struct clock_event_device *dev);
152extern int clockevents_unbind_device(struct clock_event_device *ced, int cpu); 171extern int clockevents_unbind_device(struct clock_event_device *ced, int cpu);
153 172
@@ -158,57 +177,42 @@ extern void clockevents_config_and_register(struct clock_event_device *dev,
158 177
159extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq); 178extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq);
160 179
161extern void clockevents_exchange_device(struct clock_event_device *old,
162 struct clock_event_device *new);
163extern void clockevents_set_mode(struct clock_event_device *dev,
164 enum clock_event_mode mode);
165extern int clockevents_program_event(struct clock_event_device *dev,
166 ktime_t expires, bool force);
167
168extern void clockevents_handle_noop(struct clock_event_device *dev);
169
170static inline void 180static inline void
171clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec) 181clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 minsec)
172{ 182{
173 return clocks_calc_mult_shift(&ce->mult, &ce->shift, NSEC_PER_SEC, 183 return clocks_calc_mult_shift(&ce->mult, &ce->shift, NSEC_PER_SEC, freq, minsec);
174 freq, minsec);
175} 184}
176 185
177extern void clockevents_suspend(void); 186extern void clockevents_suspend(void);
178extern void clockevents_resume(void); 187extern void clockevents_resume(void);
179 188
180#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 189# ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
181#ifdef CONFIG_ARCH_HAS_TICK_BROADCAST 190# ifdef CONFIG_ARCH_HAS_TICK_BROADCAST
182extern void tick_broadcast(const struct cpumask *mask); 191extern void tick_broadcast(const struct cpumask *mask);
183#else 192# else
184#define tick_broadcast NULL 193# define tick_broadcast NULL
185#endif 194# endif
186extern int tick_receive_broadcast(void); 195extern int tick_receive_broadcast(void);
187#endif 196# endif
188 197
189#if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT) 198# if defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) && defined(CONFIG_TICK_ONESHOT)
190extern void tick_setup_hrtimer_broadcast(void); 199extern void tick_setup_hrtimer_broadcast(void);
191extern int tick_check_broadcast_expired(void); 200extern int tick_check_broadcast_expired(void);
192#else 201# else
193static inline int tick_check_broadcast_expired(void) { return 0; } 202static inline int tick_check_broadcast_expired(void) { return 0; }
194static inline void tick_setup_hrtimer_broadcast(void) {}; 203static inline void tick_setup_hrtimer_broadcast(void) { }
195#endif 204# endif
196 205
197#ifdef CONFIG_GENERIC_CLOCKEVENTS
198extern int clockevents_notify(unsigned long reason, void *arg); 206extern int clockevents_notify(unsigned long reason, void *arg);
199#else
200static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; }
201#endif
202
203#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
204 207
205static inline void clockevents_suspend(void) {} 208#else /* !CONFIG_GENERIC_CLOCKEVENTS: */
206static inline void clockevents_resume(void) {}
207 209
210static inline void clockevents_suspend(void) { }
211static inline void clockevents_resume(void) { }
208static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; } 212static inline int clockevents_notify(unsigned long reason, void *arg) { return 0; }
209static inline int tick_check_broadcast_expired(void) { return 0; } 213static inline int tick_check_broadcast_expired(void) { return 0; }
210static inline void tick_setup_hrtimer_broadcast(void) {}; 214static inline void tick_setup_hrtimer_broadcast(void) { }
211 215
212#endif 216#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
213 217
214#endif 218#endif /* _LINUX_CLOCKCHIPS_H */