1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2734efb46Sjohn stultz /* linux/include/linux/clocksource.h
3734efb46Sjohn stultz *
4734efb46Sjohn stultz * This file contains the structure definitions for clocksources.
5734efb46Sjohn stultz *
6734efb46Sjohn stultz * If you are not a clocksource, or timekeeping code, you should
7734efb46Sjohn stultz * not be including this file!
8734efb46Sjohn stultz */
9734efb46Sjohn stultz #ifndef _LINUX_CLOCKSOURCE_H
10734efb46Sjohn stultz #define _LINUX_CLOCKSOURCE_H
11734efb46Sjohn stultz
12734efb46Sjohn stultz #include <linux/types.h>
13734efb46Sjohn stultz #include <linux/timex.h>
14734efb46Sjohn stultz #include <linux/time.h>
15734efb46Sjohn stultz #include <linux/list.h>
16329c8d84SEric Dumazet #include <linux/cache.h>
175d8b34fdSThomas Gleixner #include <linux/timer.h>
18f1b82746SMartin Schwidefsky #include <linux/init.h>
1902fad5e9SDavid Lechner #include <linux/of.h>
20b2c67cbeSThomas Gleixner #include <linux/clocksource_ids.h>
21734efb46Sjohn stultz #include <asm/div64.h>
22734efb46Sjohn stultz #include <asm/io.h>
23734efb46Sjohn stultz
246b2e2997SLakshmi Sowjanya D struct clocksource_base;
255d8b34fdSThomas Gleixner struct clocksource;
2609ac369cSThomas Gleixner struct module;
27734efb46Sjohn stultz
285d51bee7SThomas Gleixner #if defined(CONFIG_ARCH_CLOCKSOURCE_DATA) || \
29f86fd32dSThomas Gleixner defined(CONFIG_GENERIC_GETTIMEOFDAY)
30433bd805SAndy Lutomirski #include <asm/clocksource.h>
31ae7bd11bSH. Peter Anvin #endif
32433bd805SAndy Lutomirski
3314ee2ac6SVincenzo Frascino #include <vdso/clocksource.h>
345d51bee7SThomas Gleixner
35734efb46Sjohn stultz /**
36734efb46Sjohn stultz * struct clocksource - hardware abstraction for a free running counter
37734efb46Sjohn stultz * Provides mostly state-free accessors to the underlying hardware.
38a038a353SPatrick Ohly * This is the structure used for system time.
39734efb46Sjohn stultz *
403bd142a4SThomas Gleixner * @read: Returns a cycle value, passes clocksource as argument
413bd142a4SThomas Gleixner * @mask: Bitmask for two's complement
423bd142a4SThomas Gleixner * subtraction of non 64 bit counters
433bd142a4SThomas Gleixner * @mult: Cycle to nanosecond multiplier
443bd142a4SThomas Gleixner * @shift: Cycle to nanosecond divisor (power of two)
453bd142a4SThomas Gleixner * @max_idle_ns: Maximum idle time permitted by the clocksource (nsecs)
463bd142a4SThomas Gleixner * @maxadj: Maximum adjustment value to mult (~11%)
472e27e793SPaul E. McKenney * @uncertainty_margin: Maximum uncertainty in nanoseconds per half second.
482e27e793SPaul E. McKenney * Zero says to use default WATCHDOG_THRESHOLD.
493bd142a4SThomas Gleixner * @archdata: Optional arch-specific data
503bd142a4SThomas Gleixner * @max_cycles: Maximum safe cycle value which won't overflow on
513bd142a4SThomas Gleixner * multiplication
52*76031d95SThomas Gleixner * @max_raw_delta: Maximum safe delta value for negative motion detection
533bd142a4SThomas Gleixner * @name: Pointer to clocksource name
543bd142a4SThomas Gleixner * @list: List head for registration (internal)
556b2e2997SLakshmi Sowjanya D * @freq_khz: Clocksource frequency in khz.
563bd142a4SThomas Gleixner * @rating: Rating value for selection (higher is better)
57734efb46Sjohn stultz * To avoid rating inflation the following
58734efb46Sjohn stultz * list should give you a guide as to how
59734efb46Sjohn stultz * to assign your clocksource a rating
60734efb46Sjohn stultz * 1-99: Unfit for real use
61734efb46Sjohn stultz * Only available for bootup and testing purposes.
62734efb46Sjohn stultz * 100-199: Base level usability.
63734efb46Sjohn stultz * Functional for real use, but not desired.
64734efb46Sjohn stultz * 200-299: Good.
65734efb46Sjohn stultz * A correct and usable clocksource.
66734efb46Sjohn stultz * 300-399: Desired.
67734efb46Sjohn stultz * A reasonably fast and accurate clocksource.
68734efb46Sjohn stultz * 400-499: Perfect
69734efb46Sjohn stultz * The ideal clocksource. A must-use where
70734efb46Sjohn stultz * available.
71b2c67cbeSThomas Gleixner * @id: Defaults to CSID_GENERIC. The id value is captured
72b2c67cbeSThomas Gleixner * in certain snapshot functions to allow callers to
73b2c67cbeSThomas Gleixner * validate the clocksource from which the snapshot was
74b2c67cbeSThomas Gleixner * taken.
753bd142a4SThomas Gleixner * @flags: Flags describing special properties
766b2e2997SLakshmi Sowjanya D * @base: Hardware abstraction for clock on which a clocksource
776b2e2997SLakshmi Sowjanya D * is based
783bd142a4SThomas Gleixner * @enable: Optional function to enable the clocksource
793bd142a4SThomas Gleixner * @disable: Optional function to disable the clocksource
803bd142a4SThomas Gleixner * @suspend: Optional suspend function for the clocksource
813bd142a4SThomas Gleixner * @resume: Optional resume function for the clocksource
8212907fbbSThomas Gleixner * @mark_unstable: Optional function to inform the clocksource driver that
8312907fbbSThomas Gleixner * the watchdog marked the clocksource unstable
843bd142a4SThomas Gleixner * @tick_stable: Optional function called periodically from the watchdog
854bf07f65SIngo Molnar * code to provide stable synchronization points
863bd142a4SThomas Gleixner * @wd_list: List head to enqueue into the watchdog list (internal)
873bd142a4SThomas Gleixner * @cs_last: Last clocksource value for clocksource watchdog
883bd142a4SThomas Gleixner * @wd_last: Last watchdog value corresponding to @cs_last
893bd142a4SThomas Gleixner * @owner: Module reference, must be set by clocksource in modules
9009a99820SThomas Gleixner *
9109a99820SThomas Gleixner * Note: This struct is not used in hotpathes of the timekeeping code
9209a99820SThomas Gleixner * because the timekeeper caches the hot path fields in its own data
933bd142a4SThomas Gleixner * structure, so no cache line alignment is required,
9409a99820SThomas Gleixner *
9509a99820SThomas Gleixner * The pointer to the clocksource itself is handed to the read
9609a99820SThomas Gleixner * callback. If you need extra information there you can wrap struct
9709a99820SThomas Gleixner * clocksource into your own struct. Depending on the amount of
9809a99820SThomas Gleixner * information you need you should consider to cache line align that
9909a99820SThomas Gleixner * structure.
100734efb46Sjohn stultz */
101734efb46Sjohn stultz struct clocksource {
102a5a1d1c2SThomas Gleixner u64 (*read)(struct clocksource *cs);
103a5a1d1c2SThomas Gleixner u64 mask;
104734efb46Sjohn stultz u32 mult;
105734efb46Sjohn stultz u32 shift;
10698962465SJon Hunter u64 max_idle_ns;
107d65670a7SJohn Stultz u32 maxadj;
1082e27e793SPaul E. McKenney u32 uncertainty_margin;
109ae7bd11bSH. Peter Anvin #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
110433bd805SAndy Lutomirski struct arch_clocksource_data archdata;
1110aa366f3STony Luck #endif
112fb82fe2fSJohn Stultz u64 max_cycles;
113*76031d95SThomas Gleixner u64 max_raw_delta;
114369db4c9SThomas Gleixner const char *name;
115369db4c9SThomas Gleixner struct list_head list;
1166b2e2997SLakshmi Sowjanya D u32 freq_khz;
117369db4c9SThomas Gleixner int rating;
118b2c67cbeSThomas Gleixner enum clocksource_ids id;
1195d51bee7SThomas Gleixner enum vdso_clock_mode vdso_clock_mode;
1203bd142a4SThomas Gleixner unsigned long flags;
1216b2e2997SLakshmi Sowjanya D struct clocksource_base *base;
1223bd142a4SThomas Gleixner
123369db4c9SThomas Gleixner int (*enable)(struct clocksource *cs);
124369db4c9SThomas Gleixner void (*disable)(struct clocksource *cs);
125369db4c9SThomas Gleixner void (*suspend)(struct clocksource *cs);
126369db4c9SThomas Gleixner void (*resume)(struct clocksource *cs);
12712907fbbSThomas Gleixner void (*mark_unstable)(struct clocksource *cs);
128b421b22bSPeter Zijlstra void (*tick_stable)(struct clocksource *cs);
1295d8b34fdSThomas Gleixner
130b1b73d09SKusanagi Kouichi /* private: */
1315d8b34fdSThomas Gleixner #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
1325d8b34fdSThomas Gleixner /* Watchdog related data, used by the framework */
1335d8b34fdSThomas Gleixner struct list_head wd_list;
134a5a1d1c2SThomas Gleixner u64 cs_last;
135a5a1d1c2SThomas Gleixner u64 wd_last;
1365d8b34fdSThomas Gleixner #endif
13709ac369cSThomas Gleixner struct module *owner;
13809a99820SThomas Gleixner };
139734efb46Sjohn stultz
14073b08d2aSThomas Gleixner /*
14173b08d2aSThomas Gleixner * Clock source flags bits::
14273b08d2aSThomas Gleixner */
14373b08d2aSThomas Gleixner #define CLOCK_SOURCE_IS_CONTINUOUS 0x01
14473b08d2aSThomas Gleixner #define CLOCK_SOURCE_MUST_VERIFY 0x02
14573b08d2aSThomas Gleixner
1465d8b34fdSThomas Gleixner #define CLOCK_SOURCE_WATCHDOG 0x10
1475d8b34fdSThomas Gleixner #define CLOCK_SOURCE_VALID_FOR_HRES 0x20
148c55c87c8SMartin Schwidefsky #define CLOCK_SOURCE_UNSTABLE 0x40
1495caf4636SFeng Tang #define CLOCK_SOURCE_SUSPEND_NONSTOP 0x80
150332962f2SThomas Gleixner #define CLOCK_SOURCE_RESELECT 0x100
1517560c02bSPaul E. McKenney #define CLOCK_SOURCE_VERIFY_PERCPU 0x200
1527f9f303aSJim Cromie /* simplify initialization of mask field */
1530773cea3SMatthias Kaehlcke #define CLOCKSOURCE_MASK(bits) GENMASK_ULL((bits) - 1, 0)
154734efb46Sjohn stultz
clocksource_freq2mult(u32 freq,u32 shift_constant,u64 from)1557aca0c07SAlexander Kuleshov static inline u32 clocksource_freq2mult(u32 freq, u32 shift_constant, u64 from)
1567aca0c07SAlexander Kuleshov {
1577aca0c07SAlexander Kuleshov /* freq = cyc/from
1587aca0c07SAlexander Kuleshov * mult/2^shift = ns/cyc
1597aca0c07SAlexander Kuleshov * mult = ns/cyc * 2^shift
1607aca0c07SAlexander Kuleshov * mult = from/freq * 2^shift
1617aca0c07SAlexander Kuleshov * mult = from * 2^shift / freq
1627aca0c07SAlexander Kuleshov * mult = (from<<shift) / freq
1637aca0c07SAlexander Kuleshov */
1647aca0c07SAlexander Kuleshov u64 tmp = ((u64)from) << shift_constant;
1657aca0c07SAlexander Kuleshov
1667aca0c07SAlexander Kuleshov tmp += freq/2; /* round for do_div */
1677aca0c07SAlexander Kuleshov do_div(tmp, freq);
1687aca0c07SAlexander Kuleshov
1697aca0c07SAlexander Kuleshov return (u32)tmp;
1707aca0c07SAlexander Kuleshov }
1717aca0c07SAlexander Kuleshov
172734efb46Sjohn stultz /**
173734efb46Sjohn stultz * clocksource_khz2mult - calculates mult from khz and shift
174734efb46Sjohn stultz * @khz: Clocksource frequency in KHz
175734efb46Sjohn stultz * @shift_constant: Clocksource shift factor
176734efb46Sjohn stultz *
177734efb46Sjohn stultz * Helper functions that converts a khz counter frequency to a timsource
178734efb46Sjohn stultz * multiplier, given the clocksource shift value
179734efb46Sjohn stultz */
clocksource_khz2mult(u32 khz,u32 shift_constant)180734efb46Sjohn stultz static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
181734efb46Sjohn stultz {
1827aca0c07SAlexander Kuleshov return clocksource_freq2mult(khz, shift_constant, NSEC_PER_MSEC);
183734efb46Sjohn stultz }
184734efb46Sjohn stultz
185734efb46Sjohn stultz /**
186734efb46Sjohn stultz * clocksource_hz2mult - calculates mult from hz and shift
187734efb46Sjohn stultz * @hz: Clocksource frequency in Hz
188734efb46Sjohn stultz * @shift_constant: Clocksource shift factor
189734efb46Sjohn stultz *
190734efb46Sjohn stultz * Helper functions that converts a hz counter
191734efb46Sjohn stultz * frequency to a timsource multiplier, given the
192734efb46Sjohn stultz * clocksource shift value
193734efb46Sjohn stultz */
clocksource_hz2mult(u32 hz,u32 shift_constant)194734efb46Sjohn stultz static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
195734efb46Sjohn stultz {
1967aca0c07SAlexander Kuleshov return clocksource_freq2mult(hz, shift_constant, NSEC_PER_SEC);
197734efb46Sjohn stultz }
198734efb46Sjohn stultz
199734efb46Sjohn stultz /**
200155ec602SMartin Schwidefsky * clocksource_cyc2ns - converts clocksource cycles to nanoseconds
201b1b73d09SKusanagi Kouichi * @cycles: cycles
202b1b73d09SKusanagi Kouichi * @mult: cycle to nanosecond multiplier
203b1b73d09SKusanagi Kouichi * @shift: cycle to nanosecond divisor (power of two)
204734efb46Sjohn stultz *
205ec4101e8SChris Metcalf * Converts clocksource cycles to nanoseconds, using the given @mult and @shift.
206ec4101e8SChris Metcalf * The code is optimized for performance and is not intended to work
207ec4101e8SChris Metcalf * with absolute clocksource cycles (as those will easily overflow),
208ec4101e8SChris Metcalf * but is only intended to be used with relative (delta) clocksource cycles.
209734efb46Sjohn stultz *
210734efb46Sjohn stultz * XXX - This could use some mult_lxl_ll() asm optimization
211734efb46Sjohn stultz */
clocksource_cyc2ns(u64 cycles,u32 mult,u32 shift)212a5a1d1c2SThomas Gleixner static inline s64 clocksource_cyc2ns(u64 cycles, u32 mult, u32 shift)
213734efb46Sjohn stultz {
214155ec602SMartin Schwidefsky return ((u64) cycles * mult) >> shift;
2155eb6d205Sjohn stultz }
2165eb6d205Sjohn stultz
2175eb6d205Sjohn stultz
218a89c7edbSThomas Gleixner extern int clocksource_unregister(struct clocksource*);
2197c3078b6SJason Wessel extern void clocksource_touch_watchdog(void);
220c54a42b1SMagnus Damm extern void clocksource_suspend(void);
221b52f52a0SThomas Gleixner extern void clocksource_resume(void);
22296a2adbcSBjorn Helgaas extern struct clocksource * __init clocksource_default_clock(void);
2237285dd7fSThomas Gleixner extern void clocksource_mark_unstable(struct clocksource *cs);
22439232ed5SBaolin Wang extern void
22539232ed5SBaolin Wang clocksource_start_suspend_timing(struct clocksource *cs, u64 start_cycles);
22639232ed5SBaolin Wang extern u64 clocksource_stop_suspend_timing(struct clocksource *cs, u64 now);
227734efb46Sjohn stultz
22887d8b9ebSStephen Boyd extern u64
229fb82fe2fSJohn Stultz clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cycles);
2307d2f944aSThomas Gleixner extern void
2317d2f944aSThomas Gleixner clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
2327d2f944aSThomas Gleixner
233d7e81c26SJohn Stultz /*
234d7e81c26SJohn Stultz * Don't call __clocksource_register_scale directly, use
235d7e81c26SJohn Stultz * clocksource_register_hz/khz
236d7e81c26SJohn Stultz */
237d7e81c26SJohn Stultz extern int
238d7e81c26SJohn Stultz __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
239852db46dSJohn Stultz extern void
240fba9e072SJohn Stultz __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq);
241d7e81c26SJohn Stultz
242f8935983SJohn Stultz /*
243f8935983SJohn Stultz * Don't call this unless you are a default clocksource
244f8935983SJohn Stultz * (AKA: jiffies) and absolutely have to.
245f8935983SJohn Stultz */
__clocksource_register(struct clocksource * cs)246f8935983SJohn Stultz static inline int __clocksource_register(struct clocksource *cs)
247f8935983SJohn Stultz {
248f8935983SJohn Stultz return __clocksource_register_scale(cs, 1, 0);
249f8935983SJohn Stultz }
250f8935983SJohn Stultz
clocksource_register_hz(struct clocksource * cs,u32 hz)251d7e81c26SJohn Stultz static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
252d7e81c26SJohn Stultz {
253d7e81c26SJohn Stultz return __clocksource_register_scale(cs, 1, hz);
254d7e81c26SJohn Stultz }
255d7e81c26SJohn Stultz
clocksource_register_khz(struct clocksource * cs,u32 khz)256d7e81c26SJohn Stultz static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
257d7e81c26SJohn Stultz {
258d7e81c26SJohn Stultz return __clocksource_register_scale(cs, 1000, khz);
259d7e81c26SJohn Stultz }
260d7e81c26SJohn Stultz
__clocksource_update_freq_hz(struct clocksource * cs,u32 hz)261fba9e072SJohn Stultz static inline void __clocksource_update_freq_hz(struct clocksource *cs, u32 hz)
262852db46dSJohn Stultz {
263fba9e072SJohn Stultz __clocksource_update_freq_scale(cs, 1, hz);
264852db46dSJohn Stultz }
265852db46dSJohn Stultz
__clocksource_update_freq_khz(struct clocksource * cs,u32 khz)266fba9e072SJohn Stultz static inline void __clocksource_update_freq_khz(struct clocksource *cs, u32 khz)
267852db46dSJohn Stultz {
268fba9e072SJohn Stultz __clocksource_update_freq_scale(cs, 1000, khz);
269852db46dSJohn Stultz }
270d7e81c26SJohn Stultz
271d67f34c1SThomas Gleixner #ifdef CONFIG_ARCH_CLOCKSOURCE_INIT
272d67f34c1SThomas Gleixner extern void clocksource_arch_init(struct clocksource *cs);
273d67f34c1SThomas Gleixner #else
clocksource_arch_init(struct clocksource * cs)274d67f34c1SThomas Gleixner static inline void clocksource_arch_init(struct clocksource *cs) { }
275d67f34c1SThomas Gleixner #endif
276acc9a9dcSjohn stultz
277ba919d1cSThomas Gleixner extern int timekeeping_notify(struct clocksource *clock);
27875c5158fSMartin Schwidefsky
279a5a1d1c2SThomas Gleixner extern u64 clocksource_mmio_readl_up(struct clocksource *);
280a5a1d1c2SThomas Gleixner extern u64 clocksource_mmio_readl_down(struct clocksource *);
281a5a1d1c2SThomas Gleixner extern u64 clocksource_mmio_readw_up(struct clocksource *);
282a5a1d1c2SThomas Gleixner extern u64 clocksource_mmio_readw_down(struct clocksource *);
283442c8176SRussell King
284442c8176SRussell King extern int clocksource_mmio_init(void __iomem *, const char *,
285a5a1d1c2SThomas Gleixner unsigned long, int, unsigned, u64 (*)(struct clocksource *));
286442c8176SRussell King
2878c414ff3SRussell King extern int clocksource_i8253_init(void);
2888c414ff3SRussell King
28917273395SDaniel Lezcano #define TIMER_OF_DECLARE(name, compat, fn) \
2902fcc112aSDaniel Lezcano OF_DECLARE_1_RET(timer, name, compat, fn)
291b7c4db86SDaniel Lezcano
292bb0eb050SDaniel Lezcano #ifdef CONFIG_TIMER_PROBE
293ba5d08c0SDaniel Lezcano extern void timer_probe(void);
294e1d7ef1cSStephen Warren #else
timer_probe(void)295ba5d08c0SDaniel Lezcano static inline void timer_probe(void) {}
296ae278a93SStephen Warren #endif
297ae278a93SStephen Warren
29877d62f53SDaniel Lezcano #define TIMER_ACPI_DECLARE(name, table_id, fn) \
2992fcc112aSDaniel Lezcano ACPI_DECLARE_PROBE_ENTRY(timer, name, table_id, 0, NULL, 0, fn)
300c625f76aSMarc Zyngier
clocksource_get_max_watchdog_retry(void)3012ed08e4bSFeng Tang static inline unsigned int clocksource_get_max_watchdog_retry(void)
3022ed08e4bSFeng Tang {
3032ed08e4bSFeng Tang /*
3042ed08e4bSFeng Tang * When system is in the boot phase or under heavy workload, there
3052ed08e4bSFeng Tang * can be random big latencies during the clocksource/watchdog
3062ed08e4bSFeng Tang * read, so allow retries to filter the noise latency. As the
3072ed08e4bSFeng Tang * latency's frequency and maximum value goes up with the number of
3082ed08e4bSFeng Tang * CPUs, scale the number of retries with the number of online
3092ed08e4bSFeng Tang * CPUs.
3102ed08e4bSFeng Tang */
3112ed08e4bSFeng Tang return (ilog2(num_online_cpus()) / 2) + 1;
3122ed08e4bSFeng Tang }
3132ed08e4bSFeng Tang
3141253b9b8SPaul E. McKenney void clocksource_verify_percpu(struct clocksource *cs);
3151253b9b8SPaul E. McKenney
3166b2e2997SLakshmi Sowjanya D /**
3176b2e2997SLakshmi Sowjanya D * struct clocksource_base - hardware abstraction for clock on which a clocksource
3186b2e2997SLakshmi Sowjanya D * is based
3196b2e2997SLakshmi Sowjanya D * @id: Defaults to CSID_GENERIC. The id value is used for conversion
3206b2e2997SLakshmi Sowjanya D * functions which require that the current clocksource is based
3216b2e2997SLakshmi Sowjanya D * on a clocksource_base with a particular ID in certain snapshot
3226b2e2997SLakshmi Sowjanya D * functions to allow callers to validate the clocksource from
3236b2e2997SLakshmi Sowjanya D * which the snapshot was taken.
3246b2e2997SLakshmi Sowjanya D * @freq_khz: Nominal frequency of the base clock in kHz
3256b2e2997SLakshmi Sowjanya D * @offset: Offset between the base clock and the clocksource
3266b2e2997SLakshmi Sowjanya D * @numerator: Numerator of the clock ratio between base clock and the clocksource
3276b2e2997SLakshmi Sowjanya D * @denominator: Denominator of the clock ratio between base clock and the clocksource
3286b2e2997SLakshmi Sowjanya D */
3296b2e2997SLakshmi Sowjanya D struct clocksource_base {
3306b2e2997SLakshmi Sowjanya D enum clocksource_ids id;
3316b2e2997SLakshmi Sowjanya D u32 freq_khz;
3326b2e2997SLakshmi Sowjanya D u64 offset;
3336b2e2997SLakshmi Sowjanya D u32 numerator;
3346b2e2997SLakshmi Sowjanya D u32 denominator;
3356b2e2997SLakshmi Sowjanya D };
3366b2e2997SLakshmi Sowjanya D
337734efb46Sjohn stultz #endif /* _LINUX_CLOCKSOURCE_H */
338