home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / clocksource.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  6.8 KB  |  246 lines

  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 */
  21. typedef u64 cycle_t;
  22. struct 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.  */
  57. struct 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.  
  100. extern 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.  */
  122. static 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.  */
  148. static 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.  */
  171. static 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.  */
  185. static 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.  */
  203. static 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 */
  225. extern int clocksource_register(struct clocksource*);
  226. extern void clocksource_unregister(struct clocksource*);
  227. extern void clocksource_touch_watchdog(void);
  228. extern struct clocksource* clocksource_get_next(void);
  229. extern void clocksource_change_rating(struct clocksource *cs, int rating);
  230. extern void clocksource_resume(void);
  231.  
  232. #ifdef CONFIG_GENERIC_TIME_VSYSCALL
  233. extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
  234. extern void update_vsyscall_tz(void);
  235. #else
  236. static inline void update_vsyscall(struct timespec *ts, struct clocksource *c)
  237. {
  238. }
  239.  
  240. static inline void update_vsyscall_tz(void)
  241. {
  242. }
  243. #endif
  244.  
  245. #endif /* _LINUX_CLOCKSOURCE_H */
  246.