|
@@ -107,6 +107,59 @@ u64 timecounter_cyc2time(struct timecounter *tc,
|
|
|
}
|
|
|
EXPORT_SYMBOL(timecounter_cyc2time);
|
|
|
|
|
|
+/**
|
|
|
+ * 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
|
|
|
+ * @minsec: 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 @minsec 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(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec)
|
|
|
+{
|
|
|
+ u64 tmp;
|
|
|
+ u32 sft, sftacc= 32;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Calculate the shift factor which is limiting the conversion
|
|
|
+ * range:
|
|
|
+ */
|
|
|
+ tmp = ((u64)minsec * 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 = (u64) to << sft;
|
|
|
+ do_div(tmp, from);
|
|
|
+ if ((tmp >> sftacc) == 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ *mult = tmp;
|
|
|
+ *shift = sft;
|
|
|
+}
|
|
|
+
|
|
|
/*[Clocksource internal variables]---------
|
|
|
* curr_clocksource:
|
|
|
* currently selected clocksource.
|