9
0
Fork 0

shift and clocksource

Added clocks_calc_mult_shift()

Signed-off-by: Carlo Caione <carlo.caione@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
Carlo Caione 2011-06-21 20:56:53 +02:00 committed by Sascha Hauer
parent f568880f8f
commit 701edd4d98
2 changed files with 57 additions and 0 deletions

View File

@ -56,6 +56,61 @@ uint64_t get_time_ns(void)
}
EXPORT_SYMBOL(get_time_ns);
/**
* clocks_calc_mult_shift - calculate mult/shift factors for scaled math of clocks
* @mult: pointer to mult variable
* @shift: pointer to shift variable
* @from: frequency to convert from
* @to: frequency to convert to
* @maxsec: guaranteed runtime conversion range in seconds
*
* The function evaluates the shift/mult pair for the scaled math
* operations of clocksources and clockevents.
*
* @to and @from are frequency values in HZ. For clock sources @to is
* NSEC_PER_SEC == 1GHz and @from is the counter frequency. For clock
* event @to is the counter frequency and @from is NSEC_PER_SEC.
*
* The @maxsec conversion range argument controls the time frame in
* seconds which must be covered by the runtime conversion with the
* calculated mult and shift factors. This guarantees that no 64bit
* overflow happens when the input value of the conversion is
* multiplied with the calculated mult factor. Larger ranges may
* reduce the conversion accuracy by chosing smaller mult and shift
* factors.
*/
void clocks_calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint32_t to, uint32_t maxsec)
{
uint64_t tmp;
uint32_t sft, sftacc = 32;
/*
* Calculate the shift factor which is limiting the conversion
* range:
*/
tmp = ((uint64_t)maxsec * from) >> 32;
while (tmp) {
tmp >>=1;
sftacc--;
}
/*
* Find the conversion shift/mult pair which has the best
* accuracy and fits the maxsec conversion range:
*/
for (sft = 32; sft > 0; sft--) {
tmp = (uint64_t) to << sft;
tmp += from / 2;
do_div(tmp, from);
if ((tmp >> sftacc) == 0)
break;
}
*mult = tmp;
*shift = sft;
}
/**
* clocksource_hz2mult - calculates mult from hz and shift
* @hz: Clocksource frequency in Hz

View File

@ -25,6 +25,8 @@ int init_clock(struct clocksource *);
uint64_t get_time_ns(void);
void clocks_calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint32_t to, uint32_t maxsec);
uint32_t clocksource_hz2mult(uint32_t hz, uint32_t shift_constant);
int is_timeout(uint64_t start_ns, uint64_t time_offset_ns);