aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/timecounter.h
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2014-12-21 13:46:56 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-30 18:29:25 -0500
commit74d23cc704d19732e70ef1579a669f7d5f09dd9a (patch)
treeebe90655a1cdd0414df3e289b1ead86599adc557 /include/linux/timecounter.h
parent2c90331cf5ed1d648a711b9483e173aaaf2c4a9b (diff)
time: move the timecounter/cyclecounter code into its own file.
The timecounter code has almost nothing to do with the clocksource code. Let it live in its own file. This will help isolate the timecounter users from the clocksource users in the source tree. Signed-off-by: Richard Cochran <richardcochran@gmail.com> Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/timecounter.h')
-rw-r--r--include/linux/timecounter.h122
1 files changed, 122 insertions, 0 deletions
diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
new file mode 100644
index 000000000000..146f07a6651b
--- /dev/null
+++ b/include/linux/timecounter.h
@@ -0,0 +1,122 @@
1/*
2 * linux/include/linux/timecounter.h
3 *
4 * based on code that migrated away from
5 * linux/include/linux/clocksource.h
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifndef _LINUX_TIMECOUNTER_H
18#define _LINUX_TIMECOUNTER_H
19
20#include <linux/types.h>
21
22/**
23 * struct cyclecounter - hardware abstraction for a free running counter
24 * Provides completely state-free accessors to the underlying hardware.
25 * Depending on which hardware it reads, the cycle counter may wrap
26 * around quickly. Locking rules (if necessary) have to be defined
27 * by the implementor and user of specific instances of this API.
28 *
29 * @read: returns the current cycle value
30 * @mask: bitmask for two's complement
31 * subtraction of non 64 bit counters,
32 * see CLOCKSOURCE_MASK() helper macro
33 * @mult: cycle to nanosecond multiplier
34 * @shift: cycle to nanosecond divisor (power of two)
35 */
36struct cyclecounter {
37 cycle_t (*read)(const struct cyclecounter *cc);
38 cycle_t mask;
39 u32 mult;
40 u32 shift;
41};
42
43/**
44 * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds
45 * Contains the state needed by timecounter_read() to detect
46 * cycle counter wrap around. Initialize with
47 * timecounter_init(). Also used to convert cycle counts into the
48 * corresponding nanosecond counts with timecounter_cyc2time(). Users
49 * of this code are responsible for initializing the underlying
50 * cycle counter hardware, locking issues and reading the time
51 * more often than the cycle counter wraps around. The nanosecond
52 * counter will only wrap around after ~585 years.
53 *
54 * @cc: the cycle counter used by this instance
55 * @cycle_last: most recent cycle counter value seen by
56 * timecounter_read()
57 * @nsec: continuously increasing count
58 */
59struct timecounter {
60 const struct cyclecounter *cc;
61 cycle_t cycle_last;
62 u64 nsec;
63};
64
65/**
66 * cyclecounter_cyc2ns - converts cycle counter cycles to nanoseconds
67 * @cc: Pointer to cycle counter.
68 * @cycles: Cycles
69 *
70 * XXX - This could use some mult_lxl_ll() asm optimization. Same code
71 * as in cyc2ns, but with unsigned result.
72 */
73static inline u64 cyclecounter_cyc2ns(const struct cyclecounter *cc,
74 cycle_t cycles)
75{
76 u64 ret = (u64)cycles;
77 ret = (ret * cc->mult) >> cc->shift;
78 return ret;
79}
80
81/**
82 * timecounter_init - initialize a time counter
83 * @tc: Pointer to time counter which is to be initialized/reset
84 * @cc: A cycle counter, ready to be used.
85 * @start_tstamp: Arbitrary initial time stamp.
86 *
87 * After this call the current cycle register (roughly) corresponds to
88 * the initial time stamp. Every call to timecounter_read() increments
89 * the time stamp counter by the number of elapsed nanoseconds.
90 */
91extern void timecounter_init(struct timecounter *tc,
92 const struct cyclecounter *cc,
93 u64 start_tstamp);
94
95/**
96 * timecounter_read - return nanoseconds elapsed since timecounter_init()
97 * plus the initial time stamp
98 * @tc: Pointer to time counter.
99 *
100 * In other words, keeps track of time since the same epoch as
101 * the function which generated the initial time stamp.
102 */
103extern u64 timecounter_read(struct timecounter *tc);
104
105/**
106 * timecounter_cyc2time - convert a cycle counter to same
107 * time base as values returned by
108 * timecounter_read()
109 * @tc: Pointer to time counter.
110 * @cycle_tstamp: a value returned by tc->cc->read()
111 *
112 * Cycle counts that are converted correctly as long as they
113 * fall into the interval [-1/2 max cycle count, +1/2 max cycle count],
114 * with "max cycle count" == cs->mask+1.
115 *
116 * This allows conversion of cycle counter values which were generated
117 * in the past.
118 */
119extern u64 timecounter_cyc2time(struct timecounter *tc,
120 cycle_t cycle_tstamp);
121
122#endif