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