Plain (unsigned) integer division simply truncates the results. The
overall errors are smaller though if we use proper rounding. (Extend
this to the purely cosmetic aspect of time.c's freq_string(), which
before this change I've frequently observed to report e.g. NN.999MHz
HPET clock speeds.)
While adding the rounding logic, also switch to using an unsigned
constant for the other, original half of bus_cycle's calculation.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
/* set up multipliers for accurate timer code */
bus_freq = result*HZ;
- bus_cycle = (u32) (1000000000000LL/bus_freq); /* in pico seconds */
+ bus_cycle = 1000000000000UL / bus_freq; /* in pico seconds */
+ bus_cycle += (1000000000000UL % bus_freq) * 2 > bus_freq;
bus_scale = (1000*262144)/bus_cycle;
+ bus_scale += ((1000 * 262144) % bus_cycle) * 2 > bus_cycle;
apic_printk(APIC_VERBOSE, "..... bus_scale = %#x\n", bus_scale);
/* reset APIC to zero timeout value */
hpet_resume(hpet_boot_cfg);
hpet_rate = 1000000000000000ULL; /* 10^15 */
- (void)do_div(hpet_rate, hpet_period);
+ last = do_div(hpet_rate, hpet_period);
- return hpet_rate;
+ return hpet_rate + (last * 2 > hpet_period);
}
void hpet_resume(u32 *boot_cfg)
{
static char s[20];
unsigned int x, y;
- y = (unsigned int)do_div(freq, 1000000) / 1000;
+
+ if ( do_div(freq, 1000) > 500 )
+ ++freq;
+ y = (unsigned int)do_div(freq, 1000);
x = (unsigned int)freq;
snprintf(s, sizeof(s), "%u.%03uMHz", x, y);
return s;