linux/include/linux/clocksource.h
<<
>>
Prefs
   1/*  linux/include/linux/clocksource.h
   2 *
   3 *  This file contains the structure definitions for clocksources.
   4 *
   5 *  If you are not a clocksource, or timekeeping code, you should
   6 *  not be including this file!
   7 */
   8#ifndef _LINUX_CLOCKSOURCE_H
   9#define _LINUX_CLOCKSOURCE_H
  10
  11#include <linux/types.h>
  12#include <linux/timex.h>
  13#include <linux/time.h>
  14#include <linux/list.h>
  15#include <linux/cache.h>
  16#include <linux/timer.h>
  17#include <linux/init.h>
  18#include <asm/div64.h>
  19#include <asm/io.h>
  20
  21struct clocksource;
  22struct module;
  23
  24#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
  25#include <asm/clocksource.h>
  26#endif
  27
  28/**
  29 * struct clocksource - hardware abstraction for a free running counter
  30 *      Provides mostly state-free accessors to the underlying hardware.
  31 *      This is the structure used for system time.
  32 *
  33 * @name:               ptr to clocksource name
  34 * @list:               list head for registration
  35 * @rating:             rating value for selection (higher is better)
  36 *                      To avoid rating inflation the following
  37 *                      list should give you a guide as to how
  38 *                      to assign your clocksource a rating
  39 *                      1-99: Unfit for real use
  40 *                              Only available for bootup and testing purposes.
  41 *                      100-199: Base level usability.
  42 *                              Functional for real use, but not desired.
  43 *                      200-299: Good.
  44 *                              A correct and usable clocksource.
  45 *                      300-399: Desired.
  46 *                              A reasonably fast and accurate clocksource.
  47 *                      400-499: Perfect
  48 *                              The ideal clocksource. A must-use where
  49 *                              available.
  50 * @read:               returns a cycle value, passes clocksource as argument
  51 * @enable:             optional function to enable the clocksource
  52 * @disable:            optional function to disable the clocksource
  53 * @mask:               bitmask for two's complement
  54 *                      subtraction of non 64 bit counters
  55 * @mult:               cycle to nanosecond multiplier
  56 * @shift:              cycle to nanosecond divisor (power of two)
  57 * @max_idle_ns:        max idle time permitted by the clocksource (nsecs)
  58 * @maxadj:             maximum adjustment value to mult (~11%)
  59 * @flags:              flags describing special properties
  60 * @archdata:           arch-specific data
  61 * @suspend:            suspend function for the clocksource, if necessary
  62 * @resume:             resume function for the clocksource, if necessary
  63 * @cycle_last:         most recent cycle counter value seen by ::read()
  64 * @owner:              module reference, must be set by clocksource in modules
  65 */
  66struct clocksource {
  67        /*
  68         * Hotpath data, fits in a single cache line when the
  69         * clocksource itself is cacheline aligned.
  70         */
  71        u64 (*read)(struct clocksource *cs);
  72        u64 cycle_last;
  73        u64 mask;
  74        u32 mult;
  75        u32 shift;
  76        u64 max_idle_ns;
  77        u32 maxadj;
  78#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
  79        struct arch_clocksource_data archdata;
  80#endif
  81
  82        const char *name;
  83        struct list_head list;
  84        int rating;
  85        int (*enable)(struct clocksource *cs);
  86        void (*disable)(struct clocksource *cs);
  87        unsigned long flags;
  88        void (*suspend)(struct clocksource *cs);
  89        void (*resume)(struct clocksource *cs);
  90
  91        /* private: */
  92#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
  93        /* Watchdog related data, used by the framework */
  94        struct list_head wd_list;
  95        u64 cs_last;
  96        u64 wd_last;
  97#endif
  98        struct module *owner;
  99} ____cacheline_aligned;
 100
 101/*
 102 * Clock source flags bits::
 103 */
 104#define CLOCK_SOURCE_IS_CONTINUOUS              0x01
 105#define CLOCK_SOURCE_MUST_VERIFY                0x02
 106
 107#define CLOCK_SOURCE_WATCHDOG                   0x10
 108#define CLOCK_SOURCE_VALID_FOR_HRES             0x20
 109#define CLOCK_SOURCE_UNSTABLE                   0x40
 110#define CLOCK_SOURCE_SUSPEND_NONSTOP            0x80
 111#define CLOCK_SOURCE_RESELECT                   0x100
 112
 113/* simplify initialization of mask field */
 114#define CLOCKSOURCE_MASK(bits) (u64)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
 115
 116/**
 117 * clocksource_khz2mult - calculates mult from khz and shift
 118 * @khz:                Clocksource frequency in KHz
 119 * @shift_constant:     Clocksource shift factor
 120 *
 121 * Helper functions that converts a khz counter frequency to a timsource
 122 * multiplier, given the clocksource shift value
 123 */
 124static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
 125{
 126        /*  khz = cyc/(Million ns)
 127         *  mult/2^shift  = ns/cyc
 128         *  mult = ns/cyc * 2^shift
 129         *  mult = 1Million/khz * 2^shift
 130         *  mult = 1000000 * 2^shift / khz
 131         *  mult = (1000000<<shift) / khz
 132         */
 133        u64 tmp = ((u64)1000000) << shift_constant;
 134
 135        tmp += khz/2; /* round for do_div */
 136        do_div(tmp, khz);
 137
 138        return (u32)tmp;
 139}
 140
 141/**
 142 * clocksource_hz2mult - calculates mult from hz and shift
 143 * @hz:                 Clocksource frequency in Hz
 144 * @shift_constant:     Clocksource shift factor
 145 *
 146 * Helper functions that converts a hz counter
 147 * frequency to a timsource multiplier, given the
 148 * clocksource shift value
 149 */
 150static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
 151{
 152        /*  hz = cyc/(Billion ns)
 153         *  mult/2^shift  = ns/cyc
 154         *  mult = ns/cyc * 2^shift
 155         *  mult = 1Billion/hz * 2^shift
 156         *  mult = 1000000000 * 2^shift / hz
 157         *  mult = (1000000000<<shift) / hz
 158         */
 159        u64 tmp = ((u64)1000000000) << shift_constant;
 160
 161        tmp += hz/2; /* round for do_div */
 162        do_div(tmp, hz);
 163
 164        return (u32)tmp;
 165}
 166
 167/**
 168 * clocksource_cyc2ns - converts clocksource cycles to nanoseconds
 169 * @cycles:     cycles
 170 * @mult:       cycle to nanosecond multiplier
 171 * @shift:      cycle to nanosecond divisor (power of two)
 172 *
 173 * Converts cycles to nanoseconds, using the given mult and shift.
 174 *
 175 * XXX - This could use some mult_lxl_ll() asm optimization
 176 */
 177static inline s64 clocksource_cyc2ns(u64 cycles, u32 mult, u32 shift)
 178{
 179        return ((u64) cycles * mult) >> shift;
 180}
 181
 182
 183extern int clocksource_register(struct clocksource*);
 184extern int clocksource_unregister(struct clocksource*);
 185extern void clocksource_touch_watchdog(void);
 186extern struct clocksource* clocksource_get_next(void);
 187extern void clocksource_change_rating(struct clocksource *cs, int rating);
 188extern void clocksource_suspend(void);
 189extern void clocksource_resume(void);
 190extern struct clocksource * __init __weak clocksource_default_clock(void);
 191#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
 192extern void clocksource_mark_unstable(struct clocksource *cs);
 193#else
 194static inline void clocksource_mark_unstable(struct clocksource *cs) { }
 195#endif
 196
 197
 198extern void
 199clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);
 200
 201/*
 202 * Don't call __clocksource_register_scale directly, use
 203 * clocksource_register_hz/khz
 204 */
 205extern int
 206__clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq);
 207extern void
 208__clocksource_updatefreq_scale(struct clocksource *cs, u32 scale, u32 freq);
 209
 210static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
 211{
 212        return __clocksource_register_scale(cs, 1, hz);
 213}
 214
 215static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)
 216{
 217        return __clocksource_register_scale(cs, 1000, khz);
 218}
 219
 220static inline void __clocksource_updatefreq_hz(struct clocksource *cs, u32 hz)
 221{
 222        __clocksource_updatefreq_scale(cs, 1, hz);
 223}
 224
 225static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz)
 226{
 227        __clocksource_updatefreq_scale(cs, 1000, khz);
 228}
 229
 230
 231extern int timekeeping_notify(struct clocksource *clock);
 232
 233extern u64 clocksource_mmio_readl_up(struct clocksource *);
 234extern u64 clocksource_mmio_readl_down(struct clocksource *);
 235extern u64 clocksource_mmio_readw_up(struct clocksource *);
 236extern u64 clocksource_mmio_readw_down(struct clocksource *);
 237
 238extern int clocksource_mmio_init(void __iomem *, const char *,
 239        unsigned long, int, unsigned, u64 (*)(struct clocksource *));
 240
 241extern int clocksource_i8253_init(void);
 242
 243struct device_node;
 244typedef void(*clocksource_of_init_fn)(struct device_node *);
 245#ifdef CONFIG_CLKSRC_OF
 246extern void clocksource_of_init(void);
 247
 248#define CLOCKSOURCE_OF_DECLARE(name, compat, fn)                        \
 249        static const struct of_device_id __clksrc_of_table_##name       \
 250                __used __section(__clksrc_of_table)                     \
 251                 = { .compatible = compat,                              \
 252                     .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn }
 253#else
 254static inline void clocksource_of_init(void) {}
 255#define CLOCKSOURCE_OF_DECLARE(name, compat, fn)                        \
 256        static const struct of_device_id __clksrc_of_table_##name       \
 257                __attribute__((unused))                                 \
 258                 = { .compatible = compat,                              \
 259                     .data = (fn == (clocksource_of_init_fn)NULL) ? fn : fn }
 260#endif
 261
 262#endif /* _LINUX_CLOCKSOURCE_H */
 263