aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/time-ts.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/blackfin/kernel/time-ts.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/blackfin/kernel/time-ts.c')
-rw-r--r--arch/blackfin/kernel/time-ts.c43
1 files changed, 9 insertions, 34 deletions
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 8c9a43daf80f..9e9b60d969dc 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -23,29 +23,6 @@
23#include <asm/gptimers.h> 23#include <asm/gptimers.h>
24#include <asm/nmi.h> 24#include <asm/nmi.h>
25 25
26/* Accelerators for sched_clock()
27 * convert from cycles(64bits) => nanoseconds (64bits)
28 * basic equation:
29 * ns = cycles / (freq / ns_per_sec)
30 * ns = cycles * (ns_per_sec / freq)
31 * ns = cycles * (10^9 / (cpu_khz * 10^3))
32 * ns = cycles * (10^6 / cpu_khz)
33 *
34 * Then we use scaling math (suggested by george@mvista.com) to get:
35 * ns = cycles * (10^6 * SC / cpu_khz) / SC
36 * ns = cycles * cyc2ns_scale / SC
37 *
38 * And since SC is a constant power of two, we can convert the div
39 * into a shift.
40 *
41 * We can use khz divisor instead of mhz to keep a better precision, since
42 * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
43 * (mathieu.desnoyers@polymtl.ca)
44 *
45 * -johnstul@us.ibm.com "math is hard, lets go shopping!"
46 */
47
48#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
49 26
50#if defined(CONFIG_CYCLES_CLOCKSOURCE) 27#if defined(CONFIG_CYCLES_CLOCKSOURCE)
51 28
@@ -63,7 +40,6 @@ static struct clocksource bfin_cs_cycles = {
63 .rating = 400, 40 .rating = 400,
64 .read = bfin_read_cycles, 41 .read = bfin_read_cycles,
65 .mask = CLOCKSOURCE_MASK(64), 42 .mask = CLOCKSOURCE_MASK(64),
66 .shift = CYC2NS_SCALE_FACTOR,
67 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 43 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
68}; 44};
69 45
@@ -75,10 +51,7 @@ static inline unsigned long long bfin_cs_cycles_sched_clock(void)
75 51
76static int __init bfin_cs_cycles_init(void) 52static int __init bfin_cs_cycles_init(void)
77{ 53{
78 bfin_cs_cycles.mult = \ 54 if (clocksource_register_hz(&bfin_cs_cycles, get_cclk()))
79 clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift);
80
81 if (clocksource_register(&bfin_cs_cycles))
82 panic("failed to register clocksource"); 55 panic("failed to register clocksource");
83 56
84 return 0; 57 return 0;
@@ -111,7 +84,6 @@ static struct clocksource bfin_cs_gptimer0 = {
111 .rating = 350, 84 .rating = 350,
112 .read = bfin_read_gptimer0, 85 .read = bfin_read_gptimer0,
113 .mask = CLOCKSOURCE_MASK(32), 86 .mask = CLOCKSOURCE_MASK(32),
114 .shift = CYC2NS_SCALE_FACTOR,
115 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 87 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
116}; 88};
117 89
@@ -125,10 +97,7 @@ static int __init bfin_cs_gptimer0_init(void)
125{ 97{
126 setup_gptimer0(); 98 setup_gptimer0();
127 99
128 bfin_cs_gptimer0.mult = \ 100 if (clocksource_register_hz(&bfin_cs_gptimer0, get_sclk()))
129 clocksource_hz2mult(get_sclk(), bfin_cs_gptimer0.shift);
130
131 if (clocksource_register(&bfin_cs_gptimer0))
132 panic("failed to register clocksource"); 101 panic("failed to register clocksource");
133 102
134 return 0; 103 return 0;
@@ -206,8 +175,14 @@ irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id)
206{ 175{
207 struct clock_event_device *evt = dev_id; 176 struct clock_event_device *evt = dev_id;
208 smp_mb(); 177 smp_mb();
209 evt->event_handler(evt); 178 /*
179 * We want to ACK before we handle so that we can handle smaller timer
180 * intervals. This way if the timer expires again while we're handling
181 * things, we're more likely to see that 2nd int rather than swallowing
182 * it by ACKing the int at the end of this handler.
183 */
210 bfin_gptmr0_ack(); 184 bfin_gptmr0_ack();
185 evt->event_handler(evt);
211 return IRQ_HANDLED; 186 return IRQ_HANDLED;
212} 187}
213 188