[RFC PATCH 08/23] x86/hpet: Calculate ticks-per-second in a separate function
Ricardo Neri
ricardo.neri-calderon at linux.intel.com
Wed Jun 13 10:57:28 AEST 2018
It is easier to compute the expiration times of an HPET timer by using
its frequency (i.e., the number of times it ticks in a second) than its
period, as given in the capabilities register.
In addition to the HPET char driver, the HPET-based hardlockup detector
will also need to know the timer's frequency. Thus, create a common
function that both can use.
Cc: Ashok Raj <ashok.raj at intel.com>
Cc: Andi Kleen <andi.kleen at intel.com>
Cc: Tony Luck <tony.luck at intel.com>
Cc: Borislav Petkov <bp at suse.de>
Cc: Jacob Pan <jacob.jun.pan at intel.com>
Cc: Clemens Ladisch <clemens at ladisch.de>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Philippe Ombredanne <pombredanne at nexb.com>
Cc: Kate Stewart <kstewart at linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki at intel.com>
Cc: "Ravi V. Shankar" <ravi.v.shankar at intel.com>
Cc: x86 at kernel.org
Cc: iommu at lists.linux-foundation.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon at linux.intel.com>
---
drivers/char/hpet.c | 31 +++++++++++++++++++++++++------
include/linux/hpet.h | 1 +
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index be426eb..1c9584a 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -838,6 +838,29 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
return ret;
}
+u64 hpet_get_ticks_per_sec(u64 hpet_caps)
+{
+ u64 ticks_per_sec, period;
+
+ period = (hpet_caps & HPET_COUNTER_CLK_PERIOD_MASK) >>
+ HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
+
+ /*
+ * The frequency is the reciprocal of the period. The period is given
+ * femtoseconds per second. Thus, prepare a dividend to obtain the
+ * frequency in ticks per second.
+ */
+
+ /* 10^15 femtoseconds per second */
+ ticks_per_sec = 1000000000000000uLL;
+ ticks_per_sec += period >> 1; /* round */
+
+ /* The quotient is put in the dividend. We drop the remainder. */
+ do_div(ticks_per_sec, period);
+
+ return ticks_per_sec;
+}
+
int hpet_alloc(struct hpet_data *hdp)
{
u64 cap, mcfg;
@@ -847,7 +870,6 @@ int hpet_alloc(struct hpet_data *hdp)
size_t siz;
struct hpet __iomem *hpet;
static struct hpets *last;
- unsigned long period;
unsigned long long temp;
u32 remainder;
@@ -883,6 +905,8 @@ int hpet_alloc(struct hpet_data *hdp)
cap = readq(&hpet->hpet_cap);
+ temp = hpet_get_ticks_per_sec(cap);
+
ntimer = ((cap & HPET_NUM_TIM_CAP_MASK) >> HPET_NUM_TIM_CAP_SHIFT) + 1;
if (hpetp->hp_ntimer != ntimer) {
@@ -899,11 +923,6 @@ int hpet_alloc(struct hpet_data *hdp)
last = hpetp;
- period = (cap & HPET_COUNTER_CLK_PERIOD_MASK) >>
- HPET_COUNTER_CLK_PERIOD_SHIFT; /* fs, 10^-15 */
- temp = 1000000000000000uLL; /* 10^15 femtoseconds per second */
- temp += period >> 1; /* round */
- do_div(temp, period);
hpetp->hp_tick_freq = temp; /* ticks per second */
printk(KERN_INFO "hpet%d: at MMIO 0x%lx, IRQ%s",
diff --git a/include/linux/hpet.h b/include/linux/hpet.h
index 8604564..e7b36bcf4 100644
--- a/include/linux/hpet.h
+++ b/include/linux/hpet.h
@@ -107,5 +107,6 @@ static inline void hpet_reserve_timer(struct hpet_data *hd, int timer)
}
int hpet_alloc(struct hpet_data *);
+u64 hpet_get_ticks_per_sec(u64 hpet_caps);
#endif /* !__HPET__ */
--
2.7.4
More information about the Linuxppc-dev
mailing list