i386 HPET code

john stultz
2005-02-03T02:05:57Z

Hey Venkatesh,
I've been looking into a bug where i386 2.6 kernels do not boot on IBM
e325s if HPET_TIMER is enabled (hpet=disable works around the issue).
When running x86-64 kernels, the issue isn't seen. It appears that after
the hpet is enabled, we stop receiving timer ticks. I've not played on
any other HPET enabled systems, nor have I looked at the HPET spec, so
I'm not sure if this is a hardware issue or not.

The following patch, which uses the x86-64 code for
hpet_timer_stop_set_go() seems to fix the issue.

Your thoughts?

thanks
-john

===== arch/i386/kernel/time_hpet.c 1.10 vs edited =====
--- 1.10/arch/i386/kernel/time_hpet.c 2004-11-02 06:40:42 -08:00
+++ edited/arch/i386/kernel/time_hpet.c 2005-02-02 17:59:27 -08:00
@@ -64,29 +64,30 @@
{
unsigned int cfg;

- /*
- * Stop the timers and reset the main counter.
- */
+/*
+ * Stop the timers and reset the main counter.
+ */
+
cfg = hpet_readl(HPET_CFG);
- cfg &= ~HPET_CFG_ENABLE;
+ cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
hpet_writel(cfg, HPET_CFG);
hpet_writel(0, HPET_COUNTER);
hpet_writel(0, HPET_COUNTER + 4);

- /*
- * Set up timer 0, as periodic with first interrupt to happen at
- * hpet_tick, and period also hpet_tick.
- */
- cfg = hpet_readl(HPET_T0_CFG);
- cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
- HPET_TN_SETVAL | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T0_CFG);
- hpet_writel(tick, HPET_T0_CMP);
+/*
+ * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
+ * and period also hpet_tick.
+ */
+
+ hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
+ HPET_TN_32BIT, HPET_T0_CFG);
+ hpet_writel(hpet_tick, HPET_T0_CMP);
+ hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */
+
+/*
+ * Go!
+ */

- /*
- * Go!
- */
- cfg = hpet_readl(HPET_CFG);
cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY;
hpet_writel(cfg, HPET_CFG);