[RFC PATCH v2 06/14] x86/hpet: Configure the timer used by the hardlockup detector

From: Ricardo Neri
Date: Wed Feb 27 2019 - 11:06:29 EST


Implement the initial configuration of the timer to be used by the
hardlockup detector. Return a data structure with a description of the
timer; this information is subsequently used by the hardlockup detector.

Only provide the timer if it supports Front Side Bus interrupt delivery.
This condition greatly simplifies the implementation of the detector.

Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
Cc: Ashok Raj <ashok.raj@xxxxxxxxx>
Cc: Andi Kleen <andi.kleen@xxxxxxxxx>
Cc: Tony Luck <tony.luck@xxxxxxxxx>
Cc: Clemens Ladisch <clemens@xxxxxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
Cc: Philippe Ombredanne <pombredanne@xxxxxxxx>
Cc: Kate Stewart <kstewart@xxxxxxxxxxxxxxxxxxx>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@xxxxxxxxx>
Cc: "Ravi V. Shankar" <ravi.v.shankar@xxxxxxxxx>
Cc: x86@xxxxxxxxxx
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@xxxxxxxxxxxxxxx>
---
arch/x86/include/asm/hpet.h | 13 +++++++++++++
arch/x86/kernel/hpet.c | 27 +++++++++++++++++++++++++++
2 files changed, 40 insertions(+)

diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h
index 9fd112a0ffdd..4d559e0c746f 100644
--- a/arch/x86/include/asm/hpet.h
+++ b/arch/x86/include/asm/hpet.h
@@ -118,6 +118,19 @@ extern void hpet_unregister_irq_handler(rtc_irq_handler handler);

#endif /* CONFIG_HPET_EMULATE_RTC */

+#ifdef CONFIG_X86_HARDLOCKUP_DETECTOR_HPET
+struct hpet_hld_data {
+ u32 num;
+ u32 flags;
+ u64 ticks_per_second;
+};
+
+extern struct hpet_hld_data *hpet_hardlockup_detector_assign_timer(void);
+#else
+static inline struct hpet_hld_data *hpet_hardlockup_detector_assign_timer(void)
+{ return NULL; }
+#endif /* CONFIG_X86_HARDLOCKUP_DETECTOR_HPET */
+
#else /* CONFIG_HPET_TIMER */

static inline int hpet_enable(void) { return 0; }
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index 1c5c63366109..923b8061e815 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -174,6 +174,33 @@ do { \
_hpet_print_config(__func__, __LINE__); \
} while (0)

+#ifdef CONFIG_X86_HARDLOCKUP_DETECTOR_HPET
+struct hpet_hld_data *hpet_hardlockup_detector_assign_timer(void)
+{
+ struct hpet_hld_data *hdata;
+ unsigned int cfg;
+
+ cfg = hpet_readl(HPET_Tn_CFG(HPET_WD_TIMER_NR));
+
+ if (!(cfg & HPET_TN_FSB_CAP))
+ return NULL;
+
+ hdata = kzalloc(sizeof(*hdata), GFP_KERNEL);
+ if (!hdata)
+ return NULL;
+
+ hdata->flags = HPET_DEV_FSB_CAP;
+
+ if (cfg & HPET_TN_PERIODIC_CAP)
+ hdata->flags |= HPET_DEV_PERI_CAP;
+
+ hdata->num = HPET_WD_TIMER_NR;
+ hdata->ticks_per_second = hpet_get_ticks_per_sec(hpet_readq(HPET_ID));
+
+ return hdata;
+}
+#endif /* CONFIG_X86_HARDLOCKUP_DETECTOR_HPET */
+
/*
* When the hpet driver (/dev/hpet) is enabled, we need to reserve
* timer 0 and timer 1 in case of RTC emulation. Timer 2 is reserved in case
--
2.17.1