aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-01-22 04:55:31 -0500
committerPaul Mundt <lethal@linux-sh.org>2009-01-29 02:44:17 -0500
commit955c0778723501cc16fec40501cd54b7e72d3e74 (patch)
tree5e97004d7d5e3cb990e385beb045664e26f20a48
parentdc66ff6220f0a6c938df41add526d645852d9a75 (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.h4
-rw-r--r--arch/sh/kernel/time_32.c59
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c10
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 */
41void handle_timer_tick(void); 40void handle_timer_tick(void);
42extern unsigned long sh_hpt_frequency; 41
42extern 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 */
47static cycle_t null_hpt_read(void)
48{
49 return 0;
50}
51
52void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; 44void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
53int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; 45int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
54 46
@@ -200,42 +192,21 @@ device_initcall(timer_init_sysfs);
200 192
201void (*board_time_init)(void); 193void (*board_time_init)(void);
202 194
203/* 195struct clocksource clocksource_sh = {
204 * Shamelessly based on the MIPS and Sparc64 work.
205 */
206static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
207unsigned long sh_hpt_frequency = 0;
208
209#define NSEC_PER_CYC_SHIFT 10
210
211static 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
220static 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
235unsigned long long sched_clock(void) 200unsigned 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
280struct sys_timer tmu_timer = { 286struct sys_timer tmu_timer = {