linux/include/linux/clocksource.h History
<<
>>
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 <asm/div64.h>
  18#include <asm/io.h>
  19
  20/* clocksource cycle base type */
  21typedef u64 cycle_t;
  22struct clocksource;
  23
  24/**
  25 * struct clocksource - hardware abstraction for a free running counter
  26 *      Provides mostly state-free accessors to the underlying hardware.
  27 *
  28 * @name:               ptr to clocksource name
  29 * @list:               list head for registration
  30 * @rating:             rating value for selection (higher is better)
  31 *                      To avoid rating inflation the following
  32 *                      list should give you a guide as to how
  33 *                      to assign your clocksource a rating
  34 *                      1-99: Unfit for real use
  35 *                              Only available for bootup and testing purposes.
  36 *                      100-199: Base level usability.
  37 *                              Functional for real use, but not desired.
  38 *                      200-299: Good.
  39 *                              A correct and usable clocksource.
  40 *                      300-399: Desired.
  41 *                              A reasonably fast and accurate clocksource.
  42 *                      400-499: Perfect
  43 *                              The ideal clocksource. A must-use where
  44 *                              available.
  45 * @read:               returns a cycle value
  46 * @mask:               bitmask for two's complement
  47 *                      subtraction of non 64 bit counters
  48 * @mult:               cycle to nanosecond multiplier (adjusted by NTP)
  49 * @mult_orig:          cycle to nanosecond multiplier (unadjusted by NTP)
  50 * @shift:              cycle to nanosecond divisor (power of two)
  51 * @flags:              flags describing special properties
  52 * @vread:              vsyscall based read
  53 * @resume:             resume function for the clocksource, if necessary
  54 * @cycle_interval:     Used internally by timekeeping core, please ignore.
  55 * @xtime_interval:     Used internally by timekeeping core, please ignore.
  56 */
  57struct clocksource {
  58        /*
  59         * First part of structure is read mostly
  60         */
  61        char *name;
  62        struct list_head list;
  63        int rating;
  64        cycle_t (*read)(void);
  65        cycle_t mask;
  66        u32 mult;
  67        u32 mult_orig;
  68        u32 shift;
  69        unsigned long flags;
  70        cycle_t (*vread)(void);
  71        void (*resume)(void);
  72#ifdef CONFIG_IA64
  73        void *fsys_mmio;        /* used by fsyscall asm code */
  74#define CLKSRC_FSYS_MMIO_SET(mmio, addr)      ((mmio) = (addr))
  75#else
  76#define CLKSRC_FSYS_MMIO_SET(mmio, addr)      do { } while (0)
  77#endif
  78
  79        /* timekeeping specific data, ignore */
  80        cycle_t cycle_interval;
  81        u64     xtime_interval;
  82        u32     raw_interval;
  83        /*
  84         * Second part is written at each timer interrupt
  85         * Keep it in a different cache line to dirty no
  86         * more than one cache line.
  87         */
  88        cycle_t cycle_last ____cacheline_aligned_in_smp;
  89        u64 xtime_nsec;
  90        s64 error;
  91        struct timespec raw_time;
  92
  93#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
  94        /* Watchdog related data, used by the framework */
  95        struct list_head wd_list;
  96        cycle_t wd_last;
  97#endif
  98};
  99
 100extern struct clocksource *clock;       /* current clocksource */
 101
 102/*
 103 * Clock source flags bits::
 104 */
 105#define CLOCK_SOURCE_IS_CONTINUOUS              0x01
 106#define CLOCK_SOURCE_MUST_VERIFY                0x02
 107
 108#define CLOCK_SOURCE_WATCHDOG                   0x10
 109#define CLOCK_SOURCE_VALID_FOR_HRES             0x20
 110
 111/* simplify initialization of mask field */
 112#define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
 113
 114/**
 115 * clocksource_khz2mult - calculates mult from khz and shift
 116 * @khz:                Clocksource frequency in KHz
 117 * @shift_constant:     Clocksource shift factor
 118 *
 119 * Helper functions that converts a khz counter frequency to a timsource
 120 * multiplier, given the clocksource shift value
 121 */
 122static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant)
 123{
 124        /*  khz = cyc/(Million ns)
 125         *  mult/2^shift  = ns/cyc
 126         *  mult = ns/cyc * 2^shift
 127         *  mult = 1Million/khz * 2^shift
 128         *  mult = 1000000 * 2^shift / khz
 129         *  mult = (1000000<<shift) / khz
 130         */
 131        u64 tmp = ((u64)1000000) << shift_constant;
 132
 133        tmp += khz/2; /* round for do_div */
 134        do_div(tmp, khz);
 135
 136        return (u32)tmp;
 137}
 138
 139/**
 140 * clocksource_hz2mult - calculates mult from hz and shift
 141 * @hz:                 Clocksource frequency in Hz
 142 * @shift_constant:     Clocksource shift factor
 143 *
 144 * Helper functions that converts a hz counter
 145 * frequency to a timsource multiplier, given the
 146 * clocksource shift value
 147 */
 148static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
 149{
 150        /*  hz = cyc/(Billion ns)
 151         *  mult/2^shift  = ns/cyc
 152         *  mult = ns/cyc * 2^shift
 153         *  mult = 1Billion/hz * 2^shift
 154         *  mult = 1000000000 * 2^shift / hz
 155         *  mult = (1000000000<<shift) / hz
 156         */
 157        u64 tmp = ((u64)1000000000) << shift_constant;
 158
 159        tmp += hz/2; /* round for do_div */
 160        do_div(tmp, hz);
 161
 162        return (u32)tmp;
 163}
 164
 165/**
 166 * clocksource_read: - Access the clocksource's current cycle value
 167 * @cs:         pointer to clocksource being read
 168 *
 169 * Uses the clocksource to return the current cycle_t value
 170 */
 171static inline cycle_t clocksource_read(struct clocksource *cs)
 172{
 173        return cs->read();
 174}
 175
 176/**
 177 * cyc2ns - converts clocksource cycles to nanoseconds
 178 * @cs:         Pointer to clocksource
 179 * @cycles:     Cycles
 180 *
 181 * Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds.
 182 *
 183 * XXX - This could use some mult_lxl_ll() asm optimization
 184 */
 185static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles)
 186{
 187        u64 ret = (u64)cycles;
 188        ret = (ret * cs->mult) >> cs->shift;
 189        return ret;
 190}
 191
 192/**
 193 * clocksource_calculate_interval - Calculates a clocksource interval struct
 194 *
 195 * @c:          Pointer to clocksource.
 196 * @length_nsec: Desired interval length in nanoseconds.
 197 *
 198 * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment
 199 * pair and interval request.
 200 *
 201 * Unless you're the timekeeping code, you should not be using this!
 202 */
 203static inline void clocksource_calculate_interval(struct clocksource *c,
 204                                                  unsigned long length_nsec)
 205{
 206        u64 tmp;
 207
 208        /* Do the ns -> cycle conversion first, using original mult */
 209        tmp = length_nsec;
 210        tmp <<= c->shift;
 211        tmp += c->mult_orig/2;
 212        do_div(tmp, c->mult_orig);
 213
 214        c->cycle_interval = (cycle_t)tmp;
 215        if (c->cycle_interval == 0)
 216                c->cycle_interval = 1;
 217
 218        /* Go back from cycles -> shifted ns, this time use ntp adjused mult */
 219        c->xtime_interval = (u64)c->cycle_interval * c->mult;
 220        c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
 221}
 222
 223
 224/* used to install a new clocksource */
 225extern int clocksource_register(struct clocksource*);
 226extern void clocksource_unregister(struct clocksource*);
 227extern void clocksource_touch_watchdog(void);
 228extern struct clocksource* clocksource_get_next(void);
 229extern void clocksource_change_rating(struct clocksource *cs, int rating);
 230extern void clocksource_resume(void);
 231
 232#ifdef CONFIG_GENERIC_TIME_VSYSCALL
 233extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
 234extern void update_vsyscall_tz(void);
 235#else
 236static inline void update_vsyscall(struct timespec *ts, struct clocksource *c)
 237{
 238}
 239
 240static inline void update_vsyscall_tz(void)
 241{
 242}
 243#endif
 244
 245#endif /* _LINUX_CLOCKSOURCE_H */
 246
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.