static unsigned long div64_32(unsigned long v1, unsigned long v2, unsigned long v3) { unsigned long r0; do_div64_32(r0, v1, v2, v3); return r0; }
/* * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij. */ unsigned long calibrate_div32_gettimeoffset(void) { u32 count; unsigned long res, tmp; unsigned long quotient; tmp = jiffies; quotient = cached_quotient; if (last_jiffies != tmp) { last_jiffies = tmp; if (last_jiffies != 0) { unsigned long r0; do_div64_32(r0, timerhi, timerlo, tmp); do_div64_32(quotient, USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); cached_quotient = quotient; } } /* Get last timer tick in absolute kernel time */ count = read_32bit_cp0_register(CP0_COUNT); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; __asm__("multu %2,%3" : "=l" (tmp), "=h" (res) : "r" (count), "r" (quotient)); /* * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) res = USECS_PER_JIFFY - 1; return res; }