[RFC PATCH 08/23] x86/hpet: Calculate ticks-per-second in a separate function
From: Ricardo Neri <hidden>
Date: 2018-06-13 01:05:39
Also in:
linux-iommu, lkml, sparclinux
Subsystem:
char and misc drivers, hpet: high precision event timers driver, the rest · Maintainers:
Arnd Bergmann, Greg Kroah-Hartman, Clemens Ladisch, Linus Torvalds
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 <redacted> Cc: Andi Kleen <redacted> Cc: Tony Luck <tony.luck@intel.com> Cc: Borislav Petkov <redacted> Cc: Jacob Pan <redacted> Cc: Clemens Ladisch <clemens@ladisch.de> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Philippe Ombredanne <redacted> Cc: Kate Stewart <redacted> Cc: "Rafael J. Wysocki" <redacted> Cc: "Ravi V. Shankar" <redacted> Cc: x86@kernel.org Cc: iommu@lists.linux-foundation.org Signed-off-by: Ricardo Neri <redacted> --- 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