diff options
author | Magnus Damm <damm@igel.co.jp> | 2009-01-22 04:55:31 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-01-29 02:44:17 -0500 |
commit | 955c0778723501cc16fec40501cd54b7e72d3e74 (patch) | |
tree | 5e97004d7d5e3cb990e385beb045664e26f20a48 | |
parent | dc66ff6220f0a6c938df41add526d645852d9a75 (diff) |
sh: rework clocksource and sched_clock
Rework and simplify the sched_clock and clocksource code. Instead
of registering the clocksource in a shared file we move it into the
tmu driver. Also, add code to handle sched_clock in the case of no
clocksource.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/include/asm/timer.h | 4 | ||||
-rw-r--r-- | arch/sh/kernel/time_32.c | 59 | ||||
-rw-r--r-- | arch/sh/kernel/timers/timer-tmu.c | 10 |
3 files changed, 19 insertions, 54 deletions
diff --git a/arch/sh/include/asm/timer.h b/arch/sh/include/asm/timer.h index a7ca3a195bb5..4c3b66e30af2 100644 --- a/arch/sh/include/asm/timer.h +++ b/arch/sh/include/asm/timer.h | |||
@@ -9,7 +9,6 @@ struct sys_timer_ops { | |||
9 | int (*init)(void); | 9 | int (*init)(void); |
10 | int (*start)(void); | 10 | int (*start)(void); |
11 | int (*stop)(void); | 11 | int (*stop)(void); |
12 | cycle_t (*read)(void); | ||
13 | #ifndef CONFIG_GENERIC_TIME | 12 | #ifndef CONFIG_GENERIC_TIME |
14 | unsigned long (*get_offset)(void); | 13 | unsigned long (*get_offset)(void); |
15 | #endif | 14 | #endif |
@@ -39,6 +38,7 @@ struct sys_timer *get_sys_timer(void); | |||
39 | 38 | ||
40 | /* arch/sh/kernel/time.c */ | 39 | /* arch/sh/kernel/time.c */ |
41 | void handle_timer_tick(void); | 40 | void handle_timer_tick(void); |
42 | extern unsigned long sh_hpt_frequency; | 41 | |
42 | extern struct clocksource clocksource_sh; | ||
43 | 43 | ||
44 | #endif /* __ASM_SH_TIMER_H */ | 44 | #endif /* __ASM_SH_TIMER_H */ |
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c index 8457f83242c5..ca22eef669ae 100644 --- a/arch/sh/kernel/time_32.c +++ b/arch/sh/kernel/time_32.c | |||
@@ -41,14 +41,6 @@ static int null_rtc_set_time(const time_t secs) | |||
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | /* | ||
45 | * Null high precision timer functions for systems lacking one. | ||
46 | */ | ||
47 | static cycle_t null_hpt_read(void) | ||
48 | { | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; | 44 | void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; |
53 | int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; | 45 | int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; |
54 | 46 | ||
@@ -200,42 +192,21 @@ device_initcall(timer_init_sysfs); | |||
200 | 192 | ||
201 | void (*board_time_init)(void); | 193 | void (*board_time_init)(void); |
202 | 194 | ||
203 | /* | 195 | struct clocksource clocksource_sh = { |
204 | * Shamelessly based on the MIPS and Sparc64 work. | ||
205 | */ | ||
206 | static unsigned long timer_ticks_per_nsec_quotient __read_mostly; | ||
207 | unsigned long sh_hpt_frequency = 0; | ||
208 | |||
209 | #define NSEC_PER_CYC_SHIFT 10 | ||
210 | |||
211 | static struct clocksource clocksource_sh = { | ||
212 | .name = "SuperH", | 196 | .name = "SuperH", |
213 | .rating = 200, | ||
214 | .mask = CLOCKSOURCE_MASK(32), | ||
215 | .read = null_hpt_read, | ||
216 | .shift = 16, | ||
217 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
218 | }; | 197 | }; |
219 | 198 | ||
220 | static void __init init_sh_clocksource(void) | ||
221 | { | ||
222 | if (!sh_hpt_frequency || clocksource_sh.read == null_hpt_read) | ||
223 | return; | ||
224 | |||
225 | clocksource_sh.mult = clocksource_hz2mult(sh_hpt_frequency, | ||
226 | clocksource_sh.shift); | ||
227 | |||
228 | timer_ticks_per_nsec_quotient = | ||
229 | clocksource_hz2mult(sh_hpt_frequency, NSEC_PER_CYC_SHIFT); | ||
230 | |||
231 | clocksource_register(&clocksource_sh); | ||
232 | } | ||
233 | |||
234 | #ifdef CONFIG_GENERIC_TIME | 199 | #ifdef CONFIG_GENERIC_TIME |
235 | unsigned long long sched_clock(void) | 200 | unsigned long long sched_clock(void) |
236 | { | 201 | { |
237 | unsigned long long ticks = clocksource_sh.read(); | 202 | unsigned long long cycles; |
238 | return (ticks * timer_ticks_per_nsec_quotient) >> NSEC_PER_CYC_SHIFT; | 203 | |
204 | /* jiffies based sched_clock if no clocksource is installed */ | ||
205 | if (!clocksource_sh.rating) | ||
206 | return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ); | ||
207 | |||
208 | cycles = clocksource_sh.read(); | ||
209 | return cyc2ns(&clocksource_sh, cycles); | ||
239 | } | 210 | } |
240 | #endif | 211 | #endif |
241 | 212 | ||
@@ -260,16 +231,4 @@ void __init time_init(void) | |||
260 | */ | 231 | */ |
261 | sys_timer = get_sys_timer(); | 232 | sys_timer = get_sys_timer(); |
262 | printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); | 233 | printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); |
263 | |||
264 | |||
265 | if (sys_timer->ops->read) | ||
266 | clocksource_sh.read = sys_timer->ops->read; | ||
267 | |||
268 | init_sh_clocksource(); | ||
269 | |||
270 | if (sh_hpt_frequency) | ||
271 | printk("Using %lu.%03lu MHz high precision timer.\n", | ||
272 | ((sh_hpt_frequency + 500) / 1000) / 1000, | ||
273 | ((sh_hpt_frequency + 500) / 1000) % 1000); | ||
274 | |||
275 | } | 234 | } |
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 0db3f9510336..33a24fcf0a1d 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c | |||
@@ -254,7 +254,14 @@ static int tmu_timer_init(void) | |||
254 | 254 | ||
255 | _tmu_start(TMU1); | 255 | _tmu_start(TMU1); |
256 | 256 | ||
257 | sh_hpt_frequency = clk_get_rate(&tmu1_clk); | 257 | clocksource_sh.rating = 200; |
258 | clocksource_sh.mask = CLOCKSOURCE_MASK(32); | ||
259 | clocksource_sh.read = tmu_timer_read; | ||
260 | clocksource_sh.shift = 10; | ||
261 | clocksource_sh.mult = clocksource_hz2mult(clk_get_rate(&tmu1_clk), | ||
262 | clocksource_sh.shift); | ||
263 | clocksource_sh.flags = CLOCK_SOURCE_IS_CONTINUOUS; | ||
264 | clocksource_register(&clocksource_sh); | ||
258 | 265 | ||
259 | tmu0_clockevent.mult = div_sc(frequency, NSEC_PER_SEC, | 266 | tmu0_clockevent.mult = div_sc(frequency, NSEC_PER_SEC, |
260 | tmu0_clockevent.shift); | 267 | tmu0_clockevent.shift); |
@@ -274,7 +281,6 @@ static struct sys_timer_ops tmu_timer_ops = { | |||
274 | .init = tmu_timer_init, | 281 | .init = tmu_timer_init, |
275 | .start = tmu_timer_start, | 282 | .start = tmu_timer_start, |
276 | .stop = tmu_timer_stop, | 283 | .stop = tmu_timer_stop, |
277 | .read = tmu_timer_read, | ||
278 | }; | 284 | }; |
279 | 285 | ||
280 | struct sys_timer tmu_timer = { | 286 | struct sys_timer tmu_timer = { |