at v2.6.30 11 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/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 cyclecounter - hardware abstraction for a free running counter 26 * Provides completely state-free accessors to the underlying hardware. 27 * Depending on which hardware it reads, the cycle counter may wrap 28 * around quickly. Locking rules (if necessary) have to be defined 29 * by the implementor and user of specific instances of this API. 30 * 31 * @read: returns the current cycle value 32 * @mask: bitmask for two's complement 33 * subtraction of non 64 bit counters, 34 * see CLOCKSOURCE_MASK() helper macro 35 * @mult: cycle to nanosecond multiplier 36 * @shift: cycle to nanosecond divisor (power of two) 37 */ 38struct cyclecounter { 39 cycle_t (*read)(const struct cyclecounter *cc); 40 cycle_t mask; 41 u32 mult; 42 u32 shift; 43}; 44 45/** 46 * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds 47 * Contains the state needed by timecounter_read() to detect 48 * cycle counter wrap around. Initialize with 49 * timecounter_init(). Also used to convert cycle counts into the 50 * corresponding nanosecond counts with timecounter_cyc2time(). Users 51 * of this code are responsible for initializing the underlying 52 * cycle counter hardware, locking issues and reading the time 53 * more often than the cycle counter wraps around. The nanosecond 54 * counter will only wrap around after ~585 years. 55 * 56 * @cc: the cycle counter used by this instance 57 * @cycle_last: most recent cycle counter value seen by 58 * timecounter_read() 59 * @nsec: continuously increasing count 60 */ 61struct timecounter { 62 const struct cyclecounter *cc; 63 cycle_t cycle_last; 64 u64 nsec; 65}; 66 67/** 68 * cyclecounter_cyc2ns - converts cycle counter cycles to nanoseconds 69 * @tc: Pointer to cycle counter. 70 * @cycles: Cycles 71 * 72 * XXX - This could use some mult_lxl_ll() asm optimization. Same code 73 * as in cyc2ns, but with unsigned result. 74 */ 75static inline u64 cyclecounter_cyc2ns(const struct cyclecounter *cc, 76 cycle_t cycles) 77{ 78 u64 ret = (u64)cycles; 79 ret = (ret * cc->mult) >> cc->shift; 80 return ret; 81} 82 83/** 84 * timecounter_init - initialize a time counter 85 * @tc: Pointer to time counter which is to be initialized/reset 86 * @cc: A cycle counter, ready to be used. 87 * @start_tstamp: Arbitrary initial time stamp. 88 * 89 * After this call the current cycle register (roughly) corresponds to 90 * the initial time stamp. Every call to timecounter_read() increments 91 * the time stamp counter by the number of elapsed nanoseconds. 92 */ 93extern void timecounter_init(struct timecounter *tc, 94 const struct cyclecounter *cc, 95 u64 start_tstamp); 96 97/** 98 * timecounter_read - return nanoseconds elapsed since timecounter_init() 99 * plus the initial time stamp 100 * @tc: Pointer to time counter. 101 * 102 * In other words, keeps track of time since the same epoch as 103 * the function which generated the initial time stamp. 104 */ 105extern u64 timecounter_read(struct timecounter *tc); 106 107/** 108 * timecounter_cyc2time - convert a cycle counter to same 109 * time base as values returned by 110 * timecounter_read() 111 * @tc: Pointer to time counter. 112 * @cycle: a value returned by tc->cc->read() 113 * 114 * Cycle counts that are converted correctly as long as they 115 * fall into the interval [-1/2 max cycle count, +1/2 max cycle count], 116 * with "max cycle count" == cs->mask+1. 117 * 118 * This allows conversion of cycle counter values which were generated 119 * in the past. 120 */ 121extern u64 timecounter_cyc2time(struct timecounter *tc, 122 cycle_t cycle_tstamp); 123 124/** 125 * struct clocksource - hardware abstraction for a free running counter 126 * Provides mostly state-free accessors to the underlying hardware. 127 * This is the structure used for system time. 128 * 129 * @name: ptr to clocksource name 130 * @list: list head for registration 131 * @rating: rating value for selection (higher is better) 132 * To avoid rating inflation the following 133 * list should give you a guide as to how 134 * to assign your clocksource a rating 135 * 1-99: Unfit for real use 136 * Only available for bootup and testing purposes. 137 * 100-199: Base level usability. 138 * Functional for real use, but not desired. 139 * 200-299: Good. 140 * A correct and usable clocksource. 141 * 300-399: Desired. 142 * A reasonably fast and accurate clocksource. 143 * 400-499: Perfect 144 * The ideal clocksource. A must-use where 145 * available. 146 * @read: returns a cycle value, passes clocksource as argument 147 * @enable: optional function to enable the clocksource 148 * @disable: optional function to disable the clocksource 149 * @mask: bitmask for two's complement 150 * subtraction of non 64 bit counters 151 * @mult: cycle to nanosecond multiplier (adjusted by NTP) 152 * @mult_orig: cycle to nanosecond multiplier (unadjusted by NTP) 153 * @shift: cycle to nanosecond divisor (power of two) 154 * @flags: flags describing special properties 155 * @vread: vsyscall based read 156 * @resume: resume function for the clocksource, if necessary 157 * @cycle_interval: Used internally by timekeeping core, please ignore. 158 * @xtime_interval: Used internally by timekeeping core, please ignore. 159 */ 160struct clocksource { 161 /* 162 * First part of structure is read mostly 163 */ 164 char *name; 165 struct list_head list; 166 int rating; 167 cycle_t (*read)(struct clocksource *cs); 168 int (*enable)(struct clocksource *cs); 169 void (*disable)(struct clocksource *cs); 170 cycle_t mask; 171 u32 mult; 172 u32 mult_orig; 173 u32 shift; 174 unsigned long flags; 175 cycle_t (*vread)(void); 176 void (*resume)(void); 177#ifdef CONFIG_IA64 178 void *fsys_mmio; /* used by fsyscall asm code */ 179#define CLKSRC_FSYS_MMIO_SET(mmio, addr) ((mmio) = (addr)) 180#else 181#define CLKSRC_FSYS_MMIO_SET(mmio, addr) do { } while (0) 182#endif 183 184 /* timekeeping specific data, ignore */ 185 cycle_t cycle_interval; 186 u64 xtime_interval; 187 u32 raw_interval; 188 /* 189 * Second part is written at each timer interrupt 190 * Keep it in a different cache line to dirty no 191 * more than one cache line. 192 */ 193 cycle_t cycle_last ____cacheline_aligned_in_smp; 194 u64 xtime_nsec; 195 s64 error; 196 struct timespec raw_time; 197 198#ifdef CONFIG_CLOCKSOURCE_WATCHDOG 199 /* Watchdog related data, used by the framework */ 200 struct list_head wd_list; 201 cycle_t wd_last; 202#endif 203}; 204 205extern struct clocksource *clock; /* current clocksource */ 206 207/* 208 * Clock source flags bits:: 209 */ 210#define CLOCK_SOURCE_IS_CONTINUOUS 0x01 211#define CLOCK_SOURCE_MUST_VERIFY 0x02 212 213#define CLOCK_SOURCE_WATCHDOG 0x10 214#define CLOCK_SOURCE_VALID_FOR_HRES 0x20 215 216/* simplify initialization of mask field */ 217#define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1) 218 219/** 220 * clocksource_khz2mult - calculates mult from khz and shift 221 * @khz: Clocksource frequency in KHz 222 * @shift_constant: Clocksource shift factor 223 * 224 * Helper functions that converts a khz counter frequency to a timsource 225 * multiplier, given the clocksource shift value 226 */ 227static inline u32 clocksource_khz2mult(u32 khz, u32 shift_constant) 228{ 229 /* khz = cyc/(Million ns) 230 * mult/2^shift = ns/cyc 231 * mult = ns/cyc * 2^shift 232 * mult = 1Million/khz * 2^shift 233 * mult = 1000000 * 2^shift / khz 234 * mult = (1000000<<shift) / khz 235 */ 236 u64 tmp = ((u64)1000000) << shift_constant; 237 238 tmp += khz/2; /* round for do_div */ 239 do_div(tmp, khz); 240 241 return (u32)tmp; 242} 243 244/** 245 * clocksource_hz2mult - calculates mult from hz and shift 246 * @hz: Clocksource frequency in Hz 247 * @shift_constant: Clocksource shift factor 248 * 249 * Helper functions that converts a hz counter 250 * frequency to a timsource multiplier, given the 251 * clocksource shift value 252 */ 253static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant) 254{ 255 /* hz = cyc/(Billion ns) 256 * mult/2^shift = ns/cyc 257 * mult = ns/cyc * 2^shift 258 * mult = 1Billion/hz * 2^shift 259 * mult = 1000000000 * 2^shift / hz 260 * mult = (1000000000<<shift) / hz 261 */ 262 u64 tmp = ((u64)1000000000) << shift_constant; 263 264 tmp += hz/2; /* round for do_div */ 265 do_div(tmp, hz); 266 267 return (u32)tmp; 268} 269 270/** 271 * clocksource_read: - Access the clocksource's current cycle value 272 * @cs: pointer to clocksource being read 273 * 274 * Uses the clocksource to return the current cycle_t value 275 */ 276static inline cycle_t clocksource_read(struct clocksource *cs) 277{ 278 return cs->read(cs); 279} 280 281/** 282 * clocksource_enable: - enable clocksource 283 * @cs: pointer to clocksource 284 * 285 * Enables the specified clocksource. The clocksource callback 286 * function should start up the hardware and setup mult and field 287 * members of struct clocksource to reflect hardware capabilities. 288 */ 289static inline int clocksource_enable(struct clocksource *cs) 290{ 291 return cs->enable ? cs->enable(cs) : 0; 292} 293 294/** 295 * clocksource_disable: - disable clocksource 296 * @cs: pointer to clocksource 297 * 298 * Disables the specified clocksource. The clocksource callback 299 * function should power down the now unused hardware block to 300 * save power. 301 */ 302static inline void clocksource_disable(struct clocksource *cs) 303{ 304 if (cs->disable) 305 cs->disable(cs); 306} 307 308/** 309 * cyc2ns - converts clocksource cycles to nanoseconds 310 * @cs: Pointer to clocksource 311 * @cycles: Cycles 312 * 313 * Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds. 314 * 315 * XXX - This could use some mult_lxl_ll() asm optimization 316 */ 317static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles) 318{ 319 u64 ret = (u64)cycles; 320 ret = (ret * cs->mult) >> cs->shift; 321 return ret; 322} 323 324/** 325 * clocksource_calculate_interval - Calculates a clocksource interval struct 326 * 327 * @c: Pointer to clocksource. 328 * @length_nsec: Desired interval length in nanoseconds. 329 * 330 * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment 331 * pair and interval request. 332 * 333 * Unless you're the timekeeping code, you should not be using this! 334 */ 335static inline void clocksource_calculate_interval(struct clocksource *c, 336 unsigned long length_nsec) 337{ 338 u64 tmp; 339 340 /* Do the ns -> cycle conversion first, using original mult */ 341 tmp = length_nsec; 342 tmp <<= c->shift; 343 tmp += c->mult_orig/2; 344 do_div(tmp, c->mult_orig); 345 346 c->cycle_interval = (cycle_t)tmp; 347 if (c->cycle_interval == 0) 348 c->cycle_interval = 1; 349 350 /* Go back from cycles -> shifted ns, this time use ntp adjused mult */ 351 c->xtime_interval = (u64)c->cycle_interval * c->mult; 352 c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift; 353} 354 355 356/* used to install a new clocksource */ 357extern int clocksource_register(struct clocksource*); 358extern void clocksource_unregister(struct clocksource*); 359extern void clocksource_touch_watchdog(void); 360extern struct clocksource* clocksource_get_next(void); 361extern void clocksource_change_rating(struct clocksource *cs, int rating); 362extern void clocksource_resume(void); 363 364#ifdef CONFIG_GENERIC_TIME_VSYSCALL 365extern void update_vsyscall(struct timespec *ts, struct clocksource *c); 366extern void update_vsyscall_tz(void); 367#else 368static inline void update_vsyscall(struct timespec *ts, struct clocksource *c) 369{ 370} 371 372static inline void update_vsyscall_tz(void) 373{ 374} 375#endif 376 377#endif /* _LINUX_CLOCKSOURCE_H */