diff options
Diffstat (limited to 'arch/mips/kernel/time.c')
-rw-r--r-- | arch/mips/kernel/time.c | 66 |
1 files changed, 24 insertions, 42 deletions
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index e535f86efa2f..8aa544f73a5e 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
@@ -11,7 +11,6 @@ | |||
11 | * Free Software Foundation; either version 2 of the License, or (at your | 11 | * Free Software Foundation; either version 2 of the License, or (at your |
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | #include <linux/clocksource.h> | ||
15 | #include <linux/types.h> | 14 | #include <linux/types.h> |
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 16 | #include <linux/init.h> |
@@ -83,17 +82,11 @@ static void null_timer_ack(void) { /* nothing */ } | |||
83 | /* | 82 | /* |
84 | * Null high precision timer functions for systems lacking one. | 83 | * Null high precision timer functions for systems lacking one. |
85 | */ | 84 | */ |
86 | static unsigned int null_hpt_read(void) | 85 | static cycle_t null_hpt_read(void) |
87 | { | 86 | { |
88 | return 0; | 87 | return 0; |
89 | } | 88 | } |
90 | 89 | ||
91 | static void __init null_hpt_init(void) | ||
92 | { | ||
93 | /* nothing */ | ||
94 | } | ||
95 | |||
96 | |||
97 | /* | 90 | /* |
98 | * Timer ack for an R4k-compatible timer of a known frequency. | 91 | * Timer ack for an R4k-compatible timer of a known frequency. |
99 | */ | 92 | */ |
@@ -101,10 +94,8 @@ static void c0_timer_ack(void) | |||
101 | { | 94 | { |
102 | unsigned int count; | 95 | unsigned int count; |
103 | 96 | ||
104 | #ifndef CONFIG_SOC_PNX8550 /* pnx8550 resets to zero */ | ||
105 | /* Ack this timer interrupt and set the next one. */ | 97 | /* Ack this timer interrupt and set the next one. */ |
106 | expirelo += cycles_per_jiffy; | 98 | expirelo += cycles_per_jiffy; |
107 | #endif | ||
108 | write_c0_compare(expirelo); | 99 | write_c0_compare(expirelo); |
109 | 100 | ||
110 | /* Check to see if we have missed any timer interrupts. */ | 101 | /* Check to see if we have missed any timer interrupts. */ |
@@ -118,7 +109,7 @@ static void c0_timer_ack(void) | |||
118 | /* | 109 | /* |
119 | * High precision timer functions for a R4k-compatible timer. | 110 | * High precision timer functions for a R4k-compatible timer. |
120 | */ | 111 | */ |
121 | static unsigned int c0_hpt_read(void) | 112 | static cycle_t c0_hpt_read(void) |
122 | { | 113 | { |
123 | return read_c0_count(); | 114 | return read_c0_count(); |
124 | } | 115 | } |
@@ -132,9 +123,6 @@ static void __init c0_hpt_timer_init(void) | |||
132 | 123 | ||
133 | int (*mips_timer_state)(void); | 124 | int (*mips_timer_state)(void); |
134 | void (*mips_timer_ack)(void); | 125 | void (*mips_timer_ack)(void); |
135 | unsigned int (*mips_hpt_read)(void); | ||
136 | void (*mips_hpt_init)(void) __initdata = null_hpt_init; | ||
137 | unsigned int mips_hpt_mask = 0xffffffff; | ||
138 | 126 | ||
139 | /* last time when xtime and rtc are sync'ed up */ | 127 | /* last time when xtime and rtc are sync'ed up */ |
140 | static long last_rtc_update; | 128 | static long last_rtc_update; |
@@ -276,8 +264,7 @@ static struct irqaction timer_irqaction = { | |||
276 | 264 | ||
277 | static unsigned int __init calibrate_hpt(void) | 265 | static unsigned int __init calibrate_hpt(void) |
278 | { | 266 | { |
279 | u64 frequency; | 267 | cycle_t frequency, hpt_start, hpt_end, hpt_count, hz; |
280 | u32 hpt_start, hpt_end, hpt_count, hz; | ||
281 | 268 | ||
282 | const int loops = HZ / 10; | 269 | const int loops = HZ / 10; |
283 | int log_2_loops = 0; | 270 | int log_2_loops = 0; |
@@ -303,28 +290,23 @@ static unsigned int __init calibrate_hpt(void) | |||
303 | * during the calculated number of periods between timer | 290 | * during the calculated number of periods between timer |
304 | * interrupts. | 291 | * interrupts. |
305 | */ | 292 | */ |
306 | hpt_start = mips_hpt_read(); | 293 | hpt_start = clocksource_mips.read(); |
307 | do { | 294 | do { |
308 | while (mips_timer_state()); | 295 | while (mips_timer_state()); |
309 | while (!mips_timer_state()); | 296 | while (!mips_timer_state()); |
310 | } while (--i); | 297 | } while (--i); |
311 | hpt_end = mips_hpt_read(); | 298 | hpt_end = clocksource_mips.read(); |
312 | 299 | ||
313 | hpt_count = (hpt_end - hpt_start) & mips_hpt_mask; | 300 | hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask; |
314 | hz = HZ; | 301 | hz = HZ; |
315 | frequency = (u64)hpt_count * (u64)hz; | 302 | frequency = hpt_count * hz; |
316 | 303 | ||
317 | return frequency >> log_2_loops; | 304 | return frequency >> log_2_loops; |
318 | } | 305 | } |
319 | 306 | ||
320 | static cycle_t read_mips_hpt(void) | 307 | struct clocksource clocksource_mips = { |
321 | { | ||
322 | return (cycle_t)mips_hpt_read(); | ||
323 | } | ||
324 | |||
325 | static struct clocksource clocksource_mips = { | ||
326 | .name = "MIPS", | 308 | .name = "MIPS", |
327 | .read = read_mips_hpt, | 309 | .mask = 0xffffffff, |
328 | .is_continuous = 1, | 310 | .is_continuous = 1, |
329 | }; | 311 | }; |
330 | 312 | ||
@@ -333,7 +315,7 @@ static void __init init_mips_clocksource(void) | |||
333 | u64 temp; | 315 | u64 temp; |
334 | u32 shift; | 316 | u32 shift; |
335 | 317 | ||
336 | if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read) | 318 | if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read) |
337 | return; | 319 | return; |
338 | 320 | ||
339 | /* Calclate a somewhat reasonable rating value */ | 321 | /* Calclate a somewhat reasonable rating value */ |
@@ -347,7 +329,6 @@ static void __init init_mips_clocksource(void) | |||
347 | } | 329 | } |
348 | clocksource_mips.shift = shift; | 330 | clocksource_mips.shift = shift; |
349 | clocksource_mips.mult = (u32)temp; | 331 | clocksource_mips.mult = (u32)temp; |
350 | clocksource_mips.mask = mips_hpt_mask; | ||
351 | 332 | ||
352 | clocksource_register(&clocksource_mips); | 333 | clocksource_register(&clocksource_mips); |
353 | } | 334 | } |
@@ -367,32 +348,36 @@ void __init time_init(void) | |||
367 | -xtime.tv_sec, -xtime.tv_nsec); | 348 | -xtime.tv_sec, -xtime.tv_nsec); |
368 | 349 | ||
369 | /* Choose appropriate high precision timer routines. */ | 350 | /* Choose appropriate high precision timer routines. */ |
370 | if (!cpu_has_counter && !mips_hpt_read) | 351 | if (!cpu_has_counter && !clocksource_mips.read) |
371 | /* No high precision timer -- sorry. */ | 352 | /* No high precision timer -- sorry. */ |
372 | mips_hpt_read = null_hpt_read; | 353 | clocksource_mips.read = null_hpt_read; |
373 | else if (!mips_hpt_frequency && !mips_timer_state) { | 354 | else if (!mips_hpt_frequency && !mips_timer_state) { |
374 | /* A high precision timer of unknown frequency. */ | 355 | /* A high precision timer of unknown frequency. */ |
375 | if (!mips_hpt_read) | 356 | if (!clocksource_mips.read) |
376 | /* No external high precision timer -- use R4k. */ | 357 | /* No external high precision timer -- use R4k. */ |
377 | mips_hpt_read = c0_hpt_read; | 358 | clocksource_mips.read = c0_hpt_read; |
378 | } else { | 359 | } else { |
379 | /* We know counter frequency. Or we can get it. */ | 360 | /* We know counter frequency. Or we can get it. */ |
380 | if (!mips_hpt_read) { | 361 | if (!clocksource_mips.read) { |
381 | /* No external high precision timer -- use R4k. */ | 362 | /* No external high precision timer -- use R4k. */ |
382 | mips_hpt_read = c0_hpt_read; | 363 | clocksource_mips.read = c0_hpt_read; |
383 | 364 | ||
384 | if (!mips_timer_state) { | 365 | if (!mips_timer_state) { |
385 | /* No external timer interrupt -- use R4k. */ | 366 | /* No external timer interrupt -- use R4k. */ |
386 | mips_hpt_init = c0_hpt_timer_init; | ||
387 | mips_timer_ack = c0_timer_ack; | 367 | mips_timer_ack = c0_timer_ack; |
368 | /* Calculate cache parameters. */ | ||
369 | cycles_per_jiffy = | ||
370 | (mips_hpt_frequency + HZ / 2) / HZ; | ||
371 | /* | ||
372 | * This sets up the high precision | ||
373 | * timer for the first interrupt. | ||
374 | */ | ||
375 | c0_hpt_timer_init(); | ||
388 | } | 376 | } |
389 | } | 377 | } |
390 | if (!mips_hpt_frequency) | 378 | if (!mips_hpt_frequency) |
391 | mips_hpt_frequency = calibrate_hpt(); | 379 | mips_hpt_frequency = calibrate_hpt(); |
392 | 380 | ||
393 | /* Calculate cache parameters. */ | ||
394 | cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; | ||
395 | |||
396 | /* Report the high precision timer rate for a reference. */ | 381 | /* Report the high precision timer rate for a reference. */ |
397 | printk("Using %u.%03u MHz high precision timer.\n", | 382 | printk("Using %u.%03u MHz high precision timer.\n", |
398 | ((mips_hpt_frequency + 500) / 1000) / 1000, | 383 | ((mips_hpt_frequency + 500) / 1000) / 1000, |
@@ -403,9 +388,6 @@ void __init time_init(void) | |||
403 | /* No timer interrupt ack (e.g. i8254). */ | 388 | /* No timer interrupt ack (e.g. i8254). */ |
404 | mips_timer_ack = null_timer_ack; | 389 | mips_timer_ack = null_timer_ack; |
405 | 390 | ||
406 | /* This sets up the high precision timer for the first interrupt. */ | ||
407 | mips_hpt_init(); | ||
408 | |||
409 | /* | 391 | /* |
410 | * Call board specific timer interrupt setup. | 392 | * Call board specific timer interrupt setup. |
411 | * | 393 | * |