X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Fmips%2Fkernel%2Fcevt-r4k.c;h=24a2d907aa0de4c022c0d5e89227dceae2a8a572;hb=7f268a2ba7c884a239713696238dd4207a57dd9a;hp=7274fd2513f951aed26a7d3cffe2c83eb5e93316;hpb=c637fecb4fe67e2baccef24b9b7e9cb79ee23cf8;p=linux-2.6-omap-h63xx.git diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 7274fd2513f..24a2d907aa0 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -179,7 +179,7 @@ static int c0_compare_int_pending(void) static int c0_compare_int_usable(void) { - const unsigned int delta = 0x300000; + unsigned int delta; unsigned int cnt; /* @@ -192,9 +192,15 @@ static int c0_compare_int_usable(void) return 0; } - cnt = read_c0_count(); - cnt += delta; - write_c0_compare(cnt); + for (delta = 0x10; delta <= 0x400000; delta <<= 1) { + cnt = read_c0_count(); + cnt += delta; + write_c0_compare(cnt); + irq_disable_hazard(); + if ((int)(read_c0_count() - cnt) < 0) + break; + /* increase delta if the timer was already expired */ + } while ((int)(read_c0_count() - cnt) <= 0) ; /* Wait for expiry */ @@ -213,15 +219,15 @@ static int c0_compare_int_usable(void) return 1; } -void __cpuinit mips_clockevent_init(void) +int __cpuinit mips_clockevent_init(void) { uint64_t mips_freq = mips_hpt_frequency; unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; - unsigned int irq = MIPS_CPU_IRQ_BASE + 7; + unsigned int irq; if (!cpu_has_counter || !mips_hpt_frequency) - return; + return -ENXIO; #ifdef CONFIG_MIPS_MT_SMTC setup_smtc_dummy_clockevent_device(); @@ -231,11 +237,20 @@ void __cpuinit mips_clockevent_init(void) * device. */ if (cpu) - return; + return 0; #endif if (!c0_compare_int_usable()) - return; + return -ENXIO; + + /* + * With vectored interrupts things are getting platform specific. + * get_c0_compare_int is a hook to allow a platform to return the + * interrupt number of it's liking. + */ + irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; + if (get_c0_compare_int) + irq = get_c0_compare_int(); cd = &per_cpu(mips_clockevent_device, cpu); @@ -261,13 +276,17 @@ void __cpuinit mips_clockevent_init(void) clockevents_register_device(cd); - if (!cp0_timer_irq_installed) { + if (cp0_timer_irq_installed) + return 0; + + cp0_timer_irq_installed = 1; + #ifdef CONFIG_MIPS_MT_SMTC #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) - setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); + setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); #else - setup_irq(irq, &c0_compare_irqaction); -#endif /* CONFIG_MIPS_MT_SMTC */ - cp0_timer_irq_installed = 1; - } + setup_irq(irq, &c0_compare_irqaction); +#endif + + return 0; }