aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
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 /kernel
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 'kernel')
-rw-r--r--kernel/time/Makefile2
-rw-r--r--kernel/time/clocksource.c76
-rw-r--r--kernel/time/timecounter.c95
3 files changed, 96 insertions, 77 deletions
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index f622cf28628a..c09c07817d7a 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -1,6 +1,6 @@
1obj-y += time.o timer.o hrtimer.o itimer.o posix-timers.o posix-cpu-timers.o 1obj-y += time.o timer.o hrtimer.o itimer.o posix-timers.o posix-cpu-timers.o
2obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o 2obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
3obj-y += timeconv.o posix-clock.o alarmtimer.o 3obj-y += timeconv.o timecounter.o posix-clock.o alarmtimer.o
4 4
5obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o 5obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o
6obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o 6obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index b79f39bda7e1..4892352f0e49 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -34,82 +34,6 @@
34#include "tick-internal.h" 34#include "tick-internal.h"
35#include "timekeeping_internal.h" 35#include "timekeeping_internal.h"
36 36
37void timecounter_init(struct timecounter *tc,
38 const struct cyclecounter *cc,
39 u64 start_tstamp)
40{
41 tc->cc = cc;
42 tc->cycle_last = cc->read(cc);
43 tc->nsec = start_tstamp;
44}
45EXPORT_SYMBOL_GPL(timecounter_init);
46
47/**
48 * timecounter_read_delta - get nanoseconds since last call of this function
49 * @tc: Pointer to time counter
50 *
51 * When the underlying cycle counter runs over, this will be handled
52 * correctly as long as it does not run over more than once between
53 * calls.
54 *
55 * The first call to this function for a new time counter initializes
56 * the time tracking and returns an undefined result.
57 */
58static u64 timecounter_read_delta(struct timecounter *tc)
59{
60 cycle_t cycle_now, cycle_delta;
61 u64 ns_offset;
62
63 /* read cycle counter: */
64 cycle_now = tc->cc->read(tc->cc);
65
66 /* calculate the delta since the last timecounter_read_delta(): */
67 cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
68
69 /* convert to nanoseconds: */
70 ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta);
71
72 /* update time stamp of timecounter_read_delta() call: */
73 tc->cycle_last = cycle_now;
74
75 return ns_offset;
76}
77
78u64 timecounter_read(struct timecounter *tc)
79{
80 u64 nsec;
81
82 /* increment time by nanoseconds since last call */
83 nsec = timecounter_read_delta(tc);
84 nsec += tc->nsec;
85 tc->nsec = nsec;
86
87 return nsec;
88}
89EXPORT_SYMBOL_GPL(timecounter_read);
90
91u64 timecounter_cyc2time(struct timecounter *tc,
92 cycle_t cycle_tstamp)
93{
94 u64 cycle_delta = (cycle_tstamp - tc->cycle_last) & tc->cc->mask;
95 u64 nsec;
96
97 /*
98 * Instead of always treating cycle_tstamp as more recent
99 * than tc->cycle_last, detect when it is too far in the
100 * future and treat it as old time stamp instead.
101 */
102 if (cycle_delta > tc->cc->mask / 2) {
103 cycle_delta = (tc->cycle_last - cycle_tstamp) & tc->cc->mask;
104 nsec = tc->nsec - cyclecounter_cyc2ns(tc->cc, cycle_delta);
105 } else {
106 nsec = cyclecounter_cyc2ns(tc->cc, cycle_delta) + tc->nsec;
107 }
108
109 return nsec;
110}
111EXPORT_SYMBOL_GPL(timecounter_cyc2time);
112
113/** 37/**
114 * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks 38 * clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
115 * @mult: pointer to mult variable 39 * @mult: pointer to mult variable
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
new file mode 100644
index 000000000000..59a1ec3a57cb
--- /dev/null
+++ b/kernel/time/timecounter.c
@@ -0,0 +1,95 @@
1/*
2 * linux/kernel/time/timecounter.c
3 *
4 * based on code that migrated away from
5 * linux/kernel/time/clocksource.c
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
18#include <linux/export.h>
19#include <linux/timecounter.h>
20
21void timecounter_init(struct timecounter *tc,
22 const struct cyclecounter *cc,
23 u64 start_tstamp)
24{
25 tc->cc = cc;
26 tc->cycle_last = cc->read(cc);
27 tc->nsec = start_tstamp;
28}
29EXPORT_SYMBOL_GPL(timecounter_init);
30
31/**
32 * timecounter_read_delta - get nanoseconds since last call of this function
33 * @tc: Pointer to time counter
34 *
35 * When the underlying cycle counter runs over, this will be handled
36 * correctly as long as it does not run over more than once between
37 * calls.
38 *
39 * The first call to this function for a new time counter initializes
40 * the time tracking and returns an undefined result.
41 */
42static u64 timecounter_read_delta(struct timecounter *tc)
43{
44 cycle_t cycle_now, cycle_delta;
45 u64 ns_offset;
46
47 /* read cycle counter: */
48 cycle_now = tc->cc->read(tc->cc);
49
50 /* calculate the delta since the last timecounter_read_delta(): */
51 cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
52
53 /* convert to nanoseconds: */
54 ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta);
55
56 /* update time stamp of timecounter_read_delta() call: */
57 tc->cycle_last = cycle_now;
58
59 return ns_offset;
60}
61
62u64 timecounter_read(struct timecounter *tc)
63{
64 u64 nsec;
65
66 /* increment time by nanoseconds since last call */
67 nsec = timecounter_read_delta(tc);
68 nsec += tc->nsec;
69 tc->nsec = nsec;
70
71 return nsec;
72}
73EXPORT_SYMBOL_GPL(timecounter_read);
74
75u64 timecounter_cyc2time(struct timecounter *tc,
76 cycle_t cycle_tstamp)
77{
78 u64 cycle_delta = (cycle_tstamp - tc->cycle_last) & tc->cc->mask;
79 u64 nsec;
80
81 /*
82 * Instead of always treating cycle_tstamp as more recent
83 * than tc->cycle_last, detect when it is too far in the
84 * future and treat it as old time stamp instead.
85 */
86 if (cycle_delta > tc->cc->mask / 2) {
87 cycle_delta = (tc->cycle_last - cycle_tstamp) & tc->cc->mask;
88 nsec = tc->nsec - cyclecounter_cyc2ns(tc->cc, cycle_delta);
89 } else {
90 nsec = cyclecounter_cyc2ns(tc->cc, cycle_delta) + tc->nsec;
91 }
92
93 return nsec;
94}
95EXPORT_SYMBOL_GPL(timecounter_cyc2time);