aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h2
-rw-r--r--drivers/net/ethernet/freescale/fec.h1
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h2
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h2
-rw-r--r--drivers/net/ethernet/ti/cpts.h1
-rw-r--r--include/clocksource/arm_arch_timer.h2
-rw-r--r--include/linux/clocksource.h102
-rw-r--r--include/linux/mlx4/device.h2
-rw-r--r--include/linux/timecounter.h122
-rw-r--r--include/linux/types.h3
-rw-r--r--kernel/time/Makefile2
-rw-r--r--kernel/time/clocksource.c76
-rw-r--r--kernel/time/timecounter.c95
-rw-r--r--sound/pci/hda/hda_priv.h2
16 files changed, 231 insertions, 187 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index f9ec762ac3f0..2af6affc35a7 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -124,7 +124,7 @@
124#include <linux/if_vlan.h> 124#include <linux/if_vlan.h>
125#include <linux/bitops.h> 125#include <linux/bitops.h>
126#include <linux/ptp_clock_kernel.h> 126#include <linux/ptp_clock_kernel.h>
127#include <linux/clocksource.h> 127#include <linux/timecounter.h>
128#include <linux/net_tstamp.h> 128#include <linux/net_tstamp.h>
129#include <net/dcbnl.h> 129#include <net/dcbnl.h>
130 130
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index c3a6072134f5..792ba72fb5c8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -22,7 +22,7 @@
22 22
23#include <linux/ptp_clock_kernel.h> 23#include <linux/ptp_clock_kernel.h>
24#include <linux/net_tstamp.h> 24#include <linux/net_tstamp.h>
25#include <linux/clocksource.h> 25#include <linux/timecounter.h>
26 26
27/* compilation time flags */ 27/* compilation time flags */
28 28
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 469691ad4a1e..df8bbddaeb37 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -16,6 +16,7 @@
16#include <linux/clocksource.h> 16#include <linux/clocksource.h>
17#include <linux/net_tstamp.h> 17#include <linux/net_tstamp.h>
18#include <linux/ptp_clock_kernel.h> 18#include <linux/ptp_clock_kernel.h>
19#include <linux/timecounter.h>
19 20
20#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ 21#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
21 defined(CONFIG_M520x) || defined(CONFIG_M532x) || \ 22 defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 7785240a0da1..9416e5a7e0c8 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -34,7 +34,7 @@
34#include <linux/pci-aspm.h> 34#include <linux/pci-aspm.h>
35#include <linux/crc32.h> 35#include <linux/crc32.h>
36#include <linux/if_vlan.h> 36#include <linux/if_vlan.h>
37#include <linux/clocksource.h> 37#include <linux/timecounter.h>
38#include <linux/net_tstamp.h> 38#include <linux/net_tstamp.h>
39#include <linux/ptp_clock_kernel.h> 39#include <linux/ptp_clock_kernel.h>
40#include <linux/ptp_classify.h> 40#include <linux/ptp_classify.h>
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 82d891e183b1..ee22da391474 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -29,7 +29,7 @@
29#include "e1000_mac.h" 29#include "e1000_mac.h"
30#include "e1000_82575.h" 30#include "e1000_82575.h"
31 31
32#include <linux/clocksource.h> 32#include <linux/timecounter.h>
33#include <linux/net_tstamp.h> 33#include <linux/net_tstamp.h>
34#include <linux/ptp_clock_kernel.h> 34#include <linux/ptp_clock_kernel.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index b6137be43920..38fc64cf5dca 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -38,7 +38,7 @@
38#include <linux/if_vlan.h> 38#include <linux/if_vlan.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40 40
41#include <linux/clocksource.h> 41#include <linux/timecounter.h>
42#include <linux/net_tstamp.h> 42#include <linux/net_tstamp.h>
43#include <linux/ptp_clock_kernel.h> 43#include <linux/ptp_clock_kernel.h>
44 44
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
index 1a581ef7eee8..69a46b92c7d6 100644
--- a/drivers/net/ethernet/ti/cpts.h
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -27,6 +27,7 @@
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/ptp_clock_kernel.h> 28#include <linux/ptp_clock_kernel.h>
29#include <linux/skbuff.h> 29#include <linux/skbuff.h>
30#include <linux/timecounter.h>
30 31
31struct cpsw_cpts { 32struct cpsw_cpts {
32 u32 idver; /* Identification and version */ 33 u32 idver; /* Identification and version */
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 6d26b40cbf5d..9916d0e4eff5 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -16,7 +16,7 @@
16#ifndef __CLKSOURCE_ARM_ARCH_TIMER_H 16#ifndef __CLKSOURCE_ARM_ARCH_TIMER_H
17#define __CLKSOURCE_ARM_ARCH_TIMER_H 17#define __CLKSOURCE_ARM_ARCH_TIMER_H
18 18
19#include <linux/clocksource.h> 19#include <linux/timecounter.h>
20#include <linux/types.h> 20#include <linux/types.h>
21 21
22#define ARCH_TIMER_CTRL_ENABLE (1 << 0) 22#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index abcafaa20b86..9c78d15d33e4 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -18,8 +18,6 @@
18#include <asm/div64.h> 18#include <asm/div64.h>
19#include <asm/io.h> 19#include <asm/io.h>
20 20
21/* clocksource cycle base type */
22typedef u64 cycle_t;
23struct clocksource; 21struct clocksource;
24struct module; 22struct module;
25 23
@@ -28,106 +26,6 @@ struct module;
28#endif 26#endif
29 27
30/** 28/**
31 * struct cyclecounter - hardware abstraction for a free running counter
32 * Provides completely state-free accessors to the underlying hardware.
33 * Depending on which hardware it reads, the cycle counter may wrap
34 * around quickly. Locking rules (if necessary) have to be defined
35 * by the implementor and user of specific instances of this API.
36 *
37 * @read: returns the current cycle value
38 * @mask: bitmask for two's complement
39 * subtraction of non 64 bit counters,
40 * see CLOCKSOURCE_MASK() helper macro
41 * @mult: cycle to nanosecond multiplier
42 * @shift: cycle to nanosecond divisor (power of two)
43 */
44struct cyclecounter {
45 cycle_t (*read)(const struct cyclecounter *cc);
46 cycle_t mask;
47 u32 mult;
48 u32 shift;
49};
50
51/**
52 * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds
53 * Contains the state needed by timecounter_read() to detect
54 * cycle counter wrap around. Initialize with
55 * timecounter_init(). Also used to convert cycle counts into the
56 * corresponding nanosecond counts with timecounter_cyc2time(). Users
57 * of this code are responsible for initializing the underlying
58 * cycle counter hardware, locking issues and reading the time
59 * more often than the cycle counter wraps around. The nanosecond
60 * counter will only wrap around after ~585 years.
61 *
62 * @cc: the cycle counter used by this instance
63 * @cycle_last: most recent cycle counter value seen by
64 * timecounter_read()
65 * @nsec: continuously increasing count
66 */
67struct timecounter {
68 const struct cyclecounter *cc;
69 cycle_t cycle_last;
70 u64 nsec;
71};
72
73/**
74 * cyclecounter_cyc2ns - converts cycle counter cycles to nanoseconds
75 * @cc: Pointer to cycle counter.
76 * @cycles: Cycles
77 *
78 * XXX - This could use some mult_lxl_ll() asm optimization. Same code
79 * as in cyc2ns, but with unsigned result.
80 */
81static inline u64 cyclecounter_cyc2ns(const struct cyclecounter *cc,
82 cycle_t cycles)
83{
84 u64 ret = (u64)cycles;
85 ret = (ret * cc->mult) >> cc->shift;
86 return ret;
87}
88
89/**
90 * timecounter_init - initialize a time counter
91 * @tc: Pointer to time counter which is to be initialized/reset
92 * @cc: A cycle counter, ready to be used.
93 * @start_tstamp: Arbitrary initial time stamp.
94 *
95 * After this call the current cycle register (roughly) corresponds to
96 * the initial time stamp. Every call to timecounter_read() increments
97 * the time stamp counter by the number of elapsed nanoseconds.
98 */
99extern void timecounter_init(struct timecounter *tc,
100 const struct cyclecounter *cc,
101 u64 start_tstamp);
102
103/**
104 * timecounter_read - return nanoseconds elapsed since timecounter_init()
105 * plus the initial time stamp
106 * @tc: Pointer to time counter.
107 *
108 * In other words, keeps track of time since the same epoch as
109 * the function which generated the initial time stamp.
110 */
111extern u64 timecounter_read(struct timecounter *tc);
112
113/**
114 * timecounter_cyc2time - convert a cycle counter to same
115 * time base as values returned by
116 * timecounter_read()
117 * @tc: Pointer to time counter.
118 * @cycle_tstamp: a value returned by tc->cc->read()
119 *
120 * Cycle counts that are converted correctly as long as they
121 * fall into the interval [-1/2 max cycle count, +1/2 max cycle count],
122 * with "max cycle count" == cs->mask+1.
123 *
124 * This allows conversion of cycle counter values which were generated
125 * in the past.
126 */
127extern u64 timecounter_cyc2time(struct timecounter *tc,
128 cycle_t cycle_tstamp);
129
130/**
131 * struct clocksource - hardware abstraction for a free running counter 29 * struct clocksource - hardware abstraction for a free running counter
132 * Provides mostly state-free accessors to the underlying hardware. 30 * Provides mostly state-free accessors to the underlying hardware.
133 * This is the structure used for system time. 31 * This is the structure used for system time.
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 25c791e295fd..f1e41b33462f 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -42,7 +42,7 @@
42 42
43#include <linux/atomic.h> 43#include <linux/atomic.h>
44 44
45#include <linux/clocksource.h> 45#include <linux/timecounter.h>
46 46
47#define MAX_MSIX_P_PORT 17 47#define MAX_MSIX_P_PORT 17
48#define MAX_MSIX 64 48#define MAX_MSIX 64
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
diff --git a/include/linux/types.h b/include/linux/types.h
index a0bb7048687f..62323825cff9 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -213,5 +213,8 @@ struct callback_head {
213}; 213};
214#define rcu_head callback_head 214#define rcu_head callback_head
215 215
216/* clocksource cycle base type */
217typedef u64 cycle_t;
218
216#endif /* __ASSEMBLY__ */ 219#endif /* __ASSEMBLY__ */
217#endif /* _LINUX_TYPES_H */ 220#endif /* _LINUX_TYPES_H */
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);
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h
index 166e3e84b963..daf458299753 100644
--- a/sound/pci/hda/hda_priv.h
+++ b/sound/pci/hda/hda_priv.h
@@ -15,7 +15,7 @@
15#ifndef __SOUND_HDA_PRIV_H 15#ifndef __SOUND_HDA_PRIV_H
16#define __SOUND_HDA_PRIV_H 16#define __SOUND_HDA_PRIV_H
17 17
18#include <linux/clocksource.h> 18#include <linux/timecounter.h>
19#include <sound/core.h> 19#include <sound/core.h>
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21 21