diff options
Diffstat (limited to 'include/linux/clocksource.h')
| -rw-r--r-- | include/linux/clocksource.h | 149 |
1 files changed, 106 insertions, 43 deletions
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index b21db536fd52..65b7c41471c3 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -17,24 +17,43 @@ #include <linux/timer.h> #include <linux/init.h> #include <linux/of.h> +#include <linux/clocksource_ids.h> #include <asm/div64.h> #include <asm/io.h> +struct clocksource_base; struct clocksource; struct module; -#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA +#if defined(CONFIG_ARCH_CLOCKSOURCE_DATA) || \ + defined(CONFIG_GENERIC_GETTIMEOFDAY) #include <asm/clocksource.h> #endif +#include <vdso/clocksource.h> + /** * struct clocksource - hardware abstraction for a free running counter * Provides mostly state-free accessors to the underlying hardware. * This is the structure used for system time. * - * @name: ptr to clocksource name - * @list: list head for registration - * @rating: rating value for selection (higher is better) + * @read: Returns a cycle value, passes clocksource as argument + * @mask: Bitmask for two's complement + * subtraction of non 64 bit counters + * @mult: Cycle to nanosecond multiplier + * @shift: Cycle to nanosecond divisor (power of two) + * @max_idle_ns: Maximum idle time permitted by the clocksource (nsecs) + * @maxadj: Maximum adjustment value to mult (~11%) + * @uncertainty_margin: Maximum uncertainty in nanoseconds per half second. + * Zero says to use default WATCHDOG_THRESHOLD. + * @archdata: Optional arch-specific data + * @max_cycles: Maximum safe cycle value which won't overflow on + * multiplication + * @max_raw_delta: Maximum safe delta value for negative motion detection + * @name: Pointer to clocksource name + * @list: List head for registration (internal) + * @freq_khz: Clocksource frequency in khz. + * @rating: Rating value for selection (higher is better) * To avoid rating inflation the following * list should give you a guide as to how * to assign your clocksource a rating @@ -49,27 +68,29 @@ struct module; * 400-499: Perfect * The ideal clocksource. A must-use where * available. - * @read: returns a cycle value, passes clocksource as argument - * @enable: optional function to enable the clocksource - * @disable: optional function to disable the clocksource - * @mask: bitmask for two's complement - * subtraction of non 64 bit counters - * @mult: cycle to nanosecond multiplier - * @shift: cycle to nanosecond divisor (power of two) - * @max_idle_ns: max idle time permitted by the clocksource (nsecs) - * @maxadj: maximum adjustment value to mult (~11%) - * @max_cycles: maximum safe cycle value which won't overflow on multiplication - * @flags: flags describing special properties - * @archdata: arch-specific data - * @suspend: suspend function for the clocksource, if necessary - * @resume: resume function for the clocksource, if necessary + * @id: Defaults to CSID_GENERIC. The id value is captured + * in certain snapshot functions to allow callers to + * validate the clocksource from which the snapshot was + * taken. + * @flags: Flags describing special properties + * @base: Hardware abstraction for clock on which a clocksource + * is based + * @enable: Optional function to enable the clocksource + * @disable: Optional function to disable the clocksource + * @suspend: Optional suspend function for the clocksource + * @resume: Optional resume function for the clocksource * @mark_unstable: Optional function to inform the clocksource driver that * the watchdog marked the clocksource unstable - * @owner: module reference, must be set by clocksource in modules + * @tick_stable: Optional function called periodically from the watchdog + * code to provide stable synchronization points + * @wd_list: List head to enqueue into the watchdog list (internal) + * @cs_last: Last clocksource value for clocksource watchdog + * @wd_last: Last watchdog value corresponding to @cs_last + * @owner: Module reference, must be set by clocksource in modules * * Note: This struct is not used in hotpathes of the timekeeping code * because the timekeeper caches the hot path fields in its own data - * structure, so no line cache alignment is required, + * structure, so no cache line alignment is required, * * The pointer to the clocksource itself is handed to the read * callback. If you need extra information there you can wrap struct @@ -78,35 +99,42 @@ struct module; * structure. */ struct clocksource { - u64 (*read)(struct clocksource *cs); - u64 mask; - u32 mult; - u32 shift; - u64 max_idle_ns; - u32 maxadj; + u64 (*read)(struct clocksource *cs); + u64 mask; + u32 mult; + u32 shift; + u64 max_idle_ns; + u32 maxadj; + u32 uncertainty_margin; #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA struct arch_clocksource_data archdata; #endif - u64 max_cycles; - const char *name; - struct list_head list; - int rating; - int (*enable)(struct clocksource *cs); - void (*disable)(struct clocksource *cs); - unsigned long flags; - void (*suspend)(struct clocksource *cs); - void (*resume)(struct clocksource *cs); - void (*mark_unstable)(struct clocksource *cs); - void (*tick_stable)(struct clocksource *cs); + u64 max_cycles; + u64 max_raw_delta; + const char *name; + struct list_head list; + u32 freq_khz; + int rating; + enum clocksource_ids id; + enum vdso_clock_mode vdso_clock_mode; + unsigned long flags; + struct clocksource_base *base; + + int (*enable)(struct clocksource *cs); + void (*disable)(struct clocksource *cs); + void (*suspend)(struct clocksource *cs); + void (*resume)(struct clocksource *cs); + void (*mark_unstable)(struct clocksource *cs); + void (*tick_stable)(struct clocksource *cs); /* private: */ #ifdef CONFIG_CLOCKSOURCE_WATCHDOG /* Watchdog related data, used by the framework */ - struct list_head wd_list; - u64 cs_last; - u64 wd_last; + struct list_head wd_list; + u64 cs_last; + u64 wd_last; #endif - struct module *owner; + struct module *owner; }; /* @@ -120,7 +148,7 @@ struct clocksource { #define CLOCK_SOURCE_UNSTABLE 0x40 #define CLOCK_SOURCE_SUSPEND_NONSTOP 0x80 #define CLOCK_SOURCE_RESELECT 0x100 - +#define CLOCK_SOURCE_VERIFY_PERCPU 0x200 /* simplify initialization of mask field */ #define CLOCKSOURCE_MASK(bits) GENMASK_ULL((bits) - 1, 0) @@ -189,7 +217,6 @@ static inline s64 clocksource_cyc2ns(u64 cycles, u32 mult, u32 shift) extern int clocksource_unregister(struct clocksource*); extern void clocksource_touch_watchdog(void); -extern void clocksource_change_rating(struct clocksource *cs, int rating); extern void clocksource_suspend(void); extern void clocksource_resume(void); extern struct clocksource * __init clocksource_default_clock(void); @@ -271,4 +298,40 @@ static inline void timer_probe(void) {} #define TIMER_ACPI_DECLARE(name, table_id, fn) \ ACPI_DECLARE_PROBE_ENTRY(timer, name, table_id, 0, NULL, 0, fn) +static inline unsigned int clocksource_get_max_watchdog_retry(void) +{ + /* + * When system is in the boot phase or under heavy workload, there + * can be random big latencies during the clocksource/watchdog + * read, so allow retries to filter the noise latency. As the + * latency's frequency and maximum value goes up with the number of + * CPUs, scale the number of retries with the number of online + * CPUs. + */ + return (ilog2(num_online_cpus()) / 2) + 1; +} + +void clocksource_verify_percpu(struct clocksource *cs); + +/** + * struct clocksource_base - hardware abstraction for clock on which a clocksource + * is based + * @id: Defaults to CSID_GENERIC. The id value is used for conversion + * functions which require that the current clocksource is based + * on a clocksource_base with a particular ID in certain snapshot + * functions to allow callers to validate the clocksource from + * which the snapshot was taken. + * @freq_khz: Nominal frequency of the base clock in kHz + * @offset: Offset between the base clock and the clocksource + * @numerator: Numerator of the clock ratio between base clock and the clocksource + * @denominator: Denominator of the clock ratio between base clock and the clocksource + */ +struct clocksource_base { + enum clocksource_ids id; + u32 freq_khz; + u64 offset; + u32 numerator; + u32 denominator; +}; + #endif /* _LINUX_CLOCKSOURCE_H */ |
