blob: 96cdf5bdc375dba803a331af0da630e0d9500c00 [file] [log] [blame]
Nicholas Flintham1e3d3112013-04-10 10:48:38 +01001#ifndef _LINUX_CLOCKSOURCE_H
2#define _LINUX_CLOCKSOURCE_H
3
4#include <linux/types.h>
5#include <linux/timex.h>
6#include <linux/time.h>
7#include <linux/list.h>
8#include <linux/cache.h>
9#include <linux/timer.h>
10#include <linux/init.h>
11#include <asm/div64.h>
12#include <asm/io.h>
13
14typedef u64 cycle_t;
15struct clocksource;
16
17#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
18#include <asm/clocksource.h>
19#endif
20
21struct cyclecounter {
22 cycle_t (*read)(const struct cyclecounter *cc);
23 cycle_t mask;
24 u32 mult;
25 u32 shift;
26};
27
28struct timecounter {
29 const struct cyclecounter *cc;
30 cycle_t cycle_last;
31 u64 nsec;
32};
33
34static inline u64 cyclecounter_cyc2ns(const struct cyclecounter *cc,
35 cycle_t cycles)
36{
37 u64 ret = (u64)cycles;
38 ret = (ret * cc->mult) >> cc->shift;
39 return ret;
40}
41
42extern void timecounter_init(struct timecounter *tc,
43 const struct cyclecounter *cc,
44 u64 start_tstamp);
45
46extern u64 timecounter_read(struct timecounter *tc);
47
48extern u64 timecounter_cyc2time(struct timecounter *tc,
49 cycle_t cycle_tstamp);
50
51struct clocksource {
52 cycle_t (*read)(struct clocksource *cs);
53 cycle_t cycle_last;
54 cycle_t mask;
55 u32 mult;
56 u32 shift;
57 u64 max_idle_ns;
58 u32 maxadj;
59#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
60 struct arch_clocksource_data archdata;
61#endif
62
63 const char *name;
64 struct list_head list;
65 int rating;
66 int (*enable)(struct clocksource *cs);
67 void (*disable)(struct clocksource *cs);
68 unsigned long flags;
69 void (*suspend)(struct clocksource *cs);
70 void (*resume)(struct clocksource *cs);
71
72
73#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
74
75 struct list_head wd_list;
76 cycle_t cs_last;
77 cycle_t wd_last;
78#endif
79} ____cacheline_aligned;
80
81#define CLOCK_SOURCE_IS_CONTINUOUS 0x01
82#define CLOCK_SOURCE_MUST_VERIFY 0x02
83
84#define CLOCK_SOURCE_WATCHDOG 0x10
85#define CLOCK_SOURCE_VALID_FOR_HRES 0x20
86#define CLOCK_SOURCE_UNSTABLE 0x40
87
88#define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
89
90static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
91{
92 u64 tmp = ((u64)1000000) << shift_constant;
93
94 tmp += khz/2;
95 do_div(tmp, khz);
96
97 return (u32)tmp;
98}
99
100static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
101{
102 u64 tmp = ((u64)1000000000) << shift_constant;
103
104 tmp += hz/2;
105 do_div(tmp, hz);
106
107 return (u32)tmp;
108}
109
110static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
111{
112 return ((u64) cycles * mult) >> shift;
113}
114
115
116extern int clocksource_register(struct clocksource*);
117extern void clocksource_unregister(struct clocksource*);
118extern void clocksource_touch_watchdog(void);
119extern struct clocksource* clocksource_get_next(void);
120extern void clocksource_change_rating(struct clocksource *cs, int rating);
121extern void clocksource_suspend(void);
122extern void clocksource_resume(void);
123extern struct clocksource * __init __weak clocksource_default_clock(void);
124extern void clocksource_mark_unstable(struct clocksource *cs);
125
126extern void
127clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
128
129extern int
130__clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
131extern void
132__clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
133
134static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
135{
136 return __clocksource_register_scale(cs, 1, hz);
137}
138
139static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
140{
141 return __clocksource_register_scale(cs, 1000, khz);
142}
143
144static inline void __clocksource_updatefreq_hz(struct clocksource *cs, u32 hz)
145{
146 __clocksource_updatefreq_scale(cs, 1, hz);
147}
148
149static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz)
150{
151 __clocksource_updatefreq_scale(cs, 1000, khz);
152}
153
154#ifdef CONFIG_GENERIC_TIME_VSYSCALL
155extern void
156update_vsyscall(struct timespec *ts, struct timespec *wtm,
157 struct clocksource *c, u32 mult);
158extern void update_vsyscall_tz(void);
159#else
160static inline void
161update_vsyscall(struct timespec *ts, struct timespec *wtm,
162 struct clocksource *c, u32 mult)
163{
164}
165
166static inline void update_vsyscall_tz(void)
167{
168}
169#endif
170
171extern void timekeeping_notify(struct clocksource *clock);
172
173extern cycle_t clocksource_mmio_readl_up(struct clocksource *);
174extern cycle_t clocksource_mmio_readl_down(struct clocksource *);
175extern cycle_t clocksource_mmio_readw_up(struct clocksource *);
176extern cycle_t clocksource_mmio_readw_down(struct clocksource *);
177
178extern int clocksource_mmio_init(void __iomem *, const char *,
179 unsigned long, int, unsigned, cycle_t (*)(struct clocksource *));
180
181extern int clocksource_i8253_init(void);
182
183#endif