return 1;
}
+static u32 *hpet_boot_cfg;
+
u64 hpet_setup(void)
{
static u64 hpet_rate;
static u32 system_reset_latch;
u32 hpet_id, hpet_period, cfg;
- int i;
+ unsigned int i, last;
if ( system_reset_latch == system_reset_counter )
return hpet_rate;
return 0;
}
+ last = (hpet_id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT;
+ hpet_boot_cfg = xmalloc_array(u32, 2 + last);
+
cfg = hpet_read32(HPET_CFG);
+ if ( hpet_boot_cfg )
+ *hpet_boot_cfg = cfg;
cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
hpet_write32(cfg, HPET_CFG);
- for ( i = 0; i <= ((hpet_id >> 8) & 31); i++ )
+ for ( i = 0; i <= last; ++i )
{
cfg = hpet_read32(HPET_Tn_CFG(i));
+ if ( hpet_boot_cfg )
+ hpet_boot_cfg[i + 1] = cfg;
cfg &= ~HPET_TN_ENABLE;
hpet_write32(cfg, HPET_Tn_CFG(i));
}
return hpet_rate;
}
+
+void hpet_disable(void)
+{
+ unsigned int i;
+ u32 id;
+
+ if ( !hpet_boot_cfg )
+ return;
+
+ hpet_write32(*hpet_boot_cfg & ~HPET_CFG_ENABLE, HPET_CFG);
+
+ id = hpet_read32(HPET_ID);
+ for ( i = 0; i <= ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT); ++i )
+ hpet_write32(hpet_boot_cfg[i + 1], HPET_Tn_CFG(i));
+
+ if ( *hpet_boot_cfg & HPET_CFG_ENABLE )
+ hpet_write32(*hpet_boot_cfg, HPET_CFG);
+}
*/
u64 hpet_setup(void);
+/*
+ * Disable HPET hardware: restore it to boot time state.
+ */
+void hpet_disable(void);
+
/*
* Callback from legacy timer (PIT channel 0) IRQ handler.
* Returns 1 if tick originated from HPET; else 0.