diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2006-10-23 11:21:27 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-10-31 15:13:23 -0500 |
commit | 16b7b2ac0148e839da86af8747b6fa4aad43a9b7 (patch) | |
tree | 93912ae2e9c64f71a8cca028677fd918b9edf0fa /arch/mips/au1000/common | |
parent | 70e46f48cb5933119712ee27945309a4bfc98282 (diff) |
[MIPS] Fixup migration to GENERIC_TIME
Since we already moved to GENERIC_TIME, we should implement alternatives
of old do_gettimeoffset routines to get sub-jiffies resolution from
gettimeofday(). This patch includes:
* MIPS clocksource support (based on works by Manish Lachwani).
* remove unused gettimeoffset routines and related codes.
* remove unised 64bit do_div64_32().
* simplify mips_hpt_init. (no argument needed, __init tag)
* simplify c0_hpt_timer_init. (no need to write to c0_count)
* remove some hpt_init routines.
* mips_hpt_mask variable to specify bitmask of hpt value.
* convert jmr3927_do_gettimeoffset to jmr3927_hpt_read.
* convert ip27_do_gettimeoffset to ip27_hpt_read.
* convert bcm1480_do_gettimeoffset to bcm1480_hpt_read.
* simplify sb1250 hpt functions. (no need to subtract and shift)
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/au1000/common')
-rw-r--r-- | arch/mips/au1000/common/time.c | 98 |
1 files changed, 0 insertions, 98 deletions
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 6768638883ea..fa1c62f05515 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c | |||
@@ -53,9 +53,6 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */ | |||
53 | int no_au1xxx_32khz; | 53 | int no_au1xxx_32khz; |
54 | extern int allow_au1k_wait; /* default off for CP0 Counter */ | 54 | extern int allow_au1k_wait; /* default off for CP0 Counter */ |
55 | 55 | ||
56 | /* Cycle counter value at the previous timer interrupt.. */ | ||
57 | static unsigned int timerhi = 0, timerlo = 0; | ||
58 | |||
59 | #ifdef CONFIG_PM | 56 | #ifdef CONFIG_PM |
60 | #if HZ < 100 || HZ > 1000 | 57 | #if HZ < 100 || HZ > 1000 |
61 | #error "unsupported HZ value! Must be in [100,1000]" | 58 | #error "unsupported HZ value! Must be in [100,1000]" |
@@ -90,10 +87,6 @@ void mips_timer_interrupt(void) | |||
90 | goto null; | 87 | goto null; |
91 | 88 | ||
92 | do { | 89 | do { |
93 | count = read_c0_count(); | ||
94 | timerhi += (count < timerlo); /* Wrap around */ | ||
95 | timerlo = count; | ||
96 | |||
97 | kstat_this_cpu.irqs[irq]++; | 90 | kstat_this_cpu.irqs[irq]++; |
98 | do_timer(1); | 91 | do_timer(1); |
99 | #ifndef CONFIG_SMP | 92 | #ifndef CONFIG_SMP |
@@ -297,88 +290,6 @@ unsigned long cal_r4koff(void) | |||
297 | return (cpu_speed / HZ); | 290 | return (cpu_speed / HZ); |
298 | } | 291 | } |
299 | 292 | ||
300 | /* This is for machines which generate the exact clock. */ | ||
301 | #define USECS_PER_JIFFY (1000000/HZ) | ||
302 | #define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff) | ||
303 | |||
304 | static unsigned long | ||
305 | div64_32(unsigned long v1, unsigned long v2, unsigned long v3) | ||
306 | { | ||
307 | unsigned long r0; | ||
308 | do_div64_32(r0, v1, v2, v3); | ||
309 | return r0; | ||
310 | } | ||
311 | |||
312 | static unsigned long do_fast_cp0_gettimeoffset(void) | ||
313 | { | ||
314 | u32 count; | ||
315 | unsigned long res, tmp; | ||
316 | unsigned long r0; | ||
317 | |||
318 | /* Last jiffy when do_fast_gettimeoffset() was called. */ | ||
319 | static unsigned long last_jiffies=0; | ||
320 | unsigned long quotient; | ||
321 | |||
322 | /* | ||
323 | * Cached "1/(clocks per usec)*2^32" value. | ||
324 | * It has to be recalculated once each jiffy. | ||
325 | */ | ||
326 | static unsigned long cached_quotient=0; | ||
327 | |||
328 | tmp = jiffies; | ||
329 | |||
330 | quotient = cached_quotient; | ||
331 | |||
332 | if (tmp && last_jiffies != tmp) { | ||
333 | last_jiffies = tmp; | ||
334 | if (last_jiffies != 0) { | ||
335 | r0 = div64_32(timerhi, timerlo, tmp); | ||
336 | quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); | ||
337 | cached_quotient = quotient; | ||
338 | } | ||
339 | } | ||
340 | |||
341 | /* Get last timer tick in absolute kernel time */ | ||
342 | count = read_c0_count(); | ||
343 | |||
344 | /* .. relative to previous jiffy (32 bits is enough) */ | ||
345 | count -= timerlo; | ||
346 | |||
347 | __asm__("multu\t%1,%2\n\t" | ||
348 | "mfhi\t%0" | ||
349 | : "=r" (res) | ||
350 | : "r" (count), "r" (quotient) | ||
351 | : "hi", "lo", GCC_REG_ACCUM); | ||
352 | |||
353 | /* | ||
354 | * Due to possible jiffies inconsistencies, we need to check | ||
355 | * the result so that we'll get a timer that is monotonic. | ||
356 | */ | ||
357 | if (res >= USECS_PER_JIFFY) | ||
358 | res = USECS_PER_JIFFY-1; | ||
359 | |||
360 | return res; | ||
361 | } | ||
362 | |||
363 | #ifdef CONFIG_PM | ||
364 | static unsigned long do_fast_pm_gettimeoffset(void) | ||
365 | { | ||
366 | unsigned long pc0; | ||
367 | unsigned long offset; | ||
368 | |||
369 | pc0 = au_readl(SYS_TOYREAD); | ||
370 | au_sync(); | ||
371 | offset = pc0 - last_pc0; | ||
372 | if (offset > 2*MATCH20_INC) { | ||
373 | printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", | ||
374 | (unsigned)offset, (unsigned)last_pc0, | ||
375 | (unsigned)last_match20, (unsigned)pc0); | ||
376 | } | ||
377 | offset = (unsigned long)((offset * 305) / 10); | ||
378 | return offset; | ||
379 | } | ||
380 | #endif | ||
381 | |||
382 | void __init plat_timer_setup(struct irqaction *irq) | 293 | void __init plat_timer_setup(struct irqaction *irq) |
383 | { | 294 | { |
384 | unsigned int est_freq; | 295 | unsigned int est_freq; |
@@ -416,7 +327,6 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
416 | unsigned int c0_status; | 327 | unsigned int c0_status; |
417 | 328 | ||
418 | printk("WARNING: no 32KHz clock found.\n"); | 329 | printk("WARNING: no 32KHz clock found.\n"); |
419 | do_gettimeoffset = do_fast_cp0_gettimeoffset; | ||
420 | 330 | ||
421 | /* Ensure we get CPO_COUNTER interrupts. | 331 | /* Ensure we get CPO_COUNTER interrupts. |
422 | */ | 332 | */ |
@@ -441,19 +351,11 @@ void __init plat_timer_setup(struct irqaction *irq) | |||
441 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); | 351 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); |
442 | startup_match20_interrupt(counter0_irq); | 352 | startup_match20_interrupt(counter0_irq); |
443 | 353 | ||
444 | do_gettimeoffset = do_fast_pm_gettimeoffset; | ||
445 | |||
446 | /* We can use the real 'wait' instruction. | 354 | /* We can use the real 'wait' instruction. |
447 | */ | 355 | */ |
448 | allow_au1k_wait = 1; | 356 | allow_au1k_wait = 1; |
449 | } | 357 | } |
450 | 358 | ||
451 | #else | ||
452 | /* We have to do this here instead of in timer_init because | ||
453 | * the generic code in arch/mips/kernel/time.c will write | ||
454 | * over our function pointer. | ||
455 | */ | ||
456 | do_gettimeoffset = do_fast_cp0_gettimeoffset; | ||
457 | #endif | 359 | #endif |
458 | } | 360 | } |
459 | 361 | ||