[PATCH 02/27] timecounter: Introduce timecounter_initialize to update timecounter and cyclecounter

From: Sagar Arun Kamble
Date: Fri Dec 15 2017 - 02:35:31 EST


With cyclecounter coupled with timecounter, we should move to use
interface that initializes entire timecounter structure. This patch
creates function timecounter_initialize that takes cyclecounter
parameters and start time and initializes the timecounter and underlying
cyclecounter.
Function timecounter_init which requires initialized cyclecounter can be
removed once all drivers are migrated to this new interface.

Suggested-by: Richard Cochran <richardcochran@xxxxxxxxx>
Signed-off-by: Sagar Arun Kamble <sagar.a.kamble@xxxxxxxxx>
Cc: Richard Cochran <richardcochran@xxxxxxxxx>
Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx>
Cc: John Stultz <john.stultz@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Stephen Boyd <sboyd@xxxxxxxxxxxxxx>
Cc: linux-kernel@xxxxxxxxxxxxxxx
---
include/linux/timecounter.h | 41 ++++++++++++++++++++++++++++++++---------
kernel/time/timecounter.c | 18 ++++++++++++++++++
2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h
index 6daca06..59d3fd7 100644
--- a/include/linux/timecounter.h
+++ b/include/linux/timecounter.h
@@ -46,13 +46,14 @@ struct cyclecounter {
/**
* struct timecounter - layer above a %struct cyclecounter which counts nanoseconds
* Contains the state needed by timecounter_read() to detect
- * cycle counter wrap around. Initialize with
- * timecounter_init(). Also used to convert cycle counts into the
- * corresponding nanosecond counts with timecounter_cyc2time(). Users
- * of this code are responsible for initializing the underlying
- * cycle counter hardware, locking issues and reading the time
- * more often than the cycle counter wraps around. The nanosecond
- * counter will only wrap around after ~585 years.
+ * cycle counter wrap around. Initialize with timecounter_init() when
+ * underlying cyclecounter is initialized, with timecounter_initialize() to
+ * initialize cyclecounter and timecounter fields. Also used to convert
+ * cycle counts into the corresponding nanosecond counts with
+ * timecounter_cyc2time(). Users of this code are responsible for
+ * locking issues and reading the time more often than the cycle counter
+ * wraps around. The nanosecond counter will only wrap around after ~585
+ * years.
*
* @cc: the cycle counter used by this instance
* @cycle_last: most recent cycle counter value seen by
@@ -108,8 +109,30 @@ extern void timecounter_init(struct timecounter *tc,
u64 start_tstamp);

/**
- * timecounter_read - return nanoseconds elapsed since timecounter_init()
- * plus the initial time stamp
+ * timecounter_initialize - initialize a time counter and underlying
+ cyclecounter
+ * @tc: Pointer to time counter which is to be initialized
+ * @read: Pointer to function that returns the current cycle value
+ * @mask: bitmask for two's complement
+ * subtraction of non 64 bit counters,
+ * @mult: cycle to nanosecond multiplier
+ * @shift: cycle to nanosecond divisor (power of two)
+ * @start_tstamp: Arbitrary initial time stamp.
+ *
+ * After this call the current cycle register (roughly) corresponds to
+ * the initial time stamp. Every call to timecounter_read() increments
+ * the time stamp counter by the number of elapsed nanoseconds.
+ */
+extern void timecounter_initialize(struct timecounter *tc,
+ u64 (*read)(const struct cyclecounter *cc),
+ u64 mask,
+ u32 mult,
+ u32 shift,
+ u64 start_tstamp);
+
+/**
+ * timecounter_read - return nanoseconds elapsed since timecounter_init() or
+ * timecounter_initialize() plus the initial time stamp
* @tc: Pointer to time counter.
*
* In other words, keeps track of time since the same epoch as
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index 7919acb..6d915752 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -29,6 +29,24 @@ void timecounter_init(struct timecounter *tc, u64 start_tstamp)
}
EXPORT_SYMBOL_GPL(timecounter_init);

+void timecounter_initialize(struct timecounter *tc,
+ u64 (*read)(const struct cyclecounter *cc),
+ u64 mask,
+ u32 mult,
+ u32 shift,
+ u64 start_tstamp)
+{
+ struct cyclecounter *cc = &tc->cc;
+
+ cc->read = read;
+ cc->mask = mask;
+ cc->mult = mult;
+ cc->shift = shift;
+
+ timecounter_init(tc, start_tstamp);
+}
+EXPORT_SYMBOL_GPL(timecounter_initialize);
+
/**
* timecounter_read_delta - get nanoseconds since last call of this function
* @tc: Pointer to time counter
--
1.9.1