Hi, Seems this is similar to the overflow problem in the high resolution sched_clock(), If not ensure the 'mult' is in 32bit, we must use the 128bit calculation in the common function clocksource_cyc2ns() defined in include/linux/clocksource.h. Regards, Wu Zhangjin On Tue, 2010-05-18 at 15:11 -0700, David Daney wrote: > The 'mult' element of struct clock_event_device must never be wider > than 32-bits. If it were, it would get truncated when used by > clockevent_delta2ns() when this calls do_div(). > > We meet the requirement by ensuring that the relationship: > > (mips_hpt_frequency >> (32 - shift)) < NSEC_PER_SEC > > Always holds. > > Signed-off-by: David Daney <ddaney@xxxxxxxxxxxxxxxxxx> > CC: Thomas Gleixner <tglx@xxxxxxxxxxxxx> > --- > arch/mips/kernel/cevt-r4k.c | 16 +++++++++++++--- > 1 files changed, 13 insertions(+), 3 deletions(-) > > diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c > index 0b2450c..4495158 100644 > --- a/arch/mips/kernel/cevt-r4k.c > +++ b/arch/mips/kernel/cevt-r4k.c > @@ -163,10 +163,11 @@ int c0_compare_int_usable(void) > > int __cpuinit r4k_clockevent_init(void) > { > - uint64_t mips_freq = mips_hpt_frequency; > + uint64_t scaled_freq = mips_hpt_frequency; > unsigned int cpu = smp_processor_id(); > struct clock_event_device *cd; > unsigned int irq; > + int shift; > > if (!cpu_has_counter || !mips_hpt_frequency) > return -ENXIO; > @@ -189,8 +190,17 @@ int __cpuinit r4k_clockevent_init(void) > cd->features = CLOCK_EVT_FEAT_ONESHOT; > > /* Calculate the min / max delta */ > - cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); > - cd->shift = 32; > + shift = 32; > + while (scaled_freq >= NSEC_PER_SEC && shift) { > + scaled_freq = scaled_freq >> 1; > + shift--; > + } > + BUG_ON(shift == 0); > + > + cd->mult = div_sc((unsigned long) mips_hpt_frequency, > + NSEC_PER_SEC, shift); > + cd->shift = shift; > + > cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); > cd->min_delta_ns = clockevent_delta2ns(0x300, cd); >