|
@@ -359,6 +359,7 @@ static int hpet_clocksource_register(void)
|
|
int __init hpet_enable(void)
|
|
int __init hpet_enable(void)
|
|
{
|
|
{
|
|
unsigned long id;
|
|
unsigned long id;
|
|
|
|
+ int i;
|
|
|
|
|
|
if (!is_hpet_capable())
|
|
if (!is_hpet_capable())
|
|
return 0;
|
|
return 0;
|
|
@@ -369,6 +370,29 @@ int __init hpet_enable(void)
|
|
* Read the period and check for a sane value:
|
|
* Read the period and check for a sane value:
|
|
*/
|
|
*/
|
|
hpet_period = hpet_readl(HPET_PERIOD);
|
|
hpet_period = hpet_readl(HPET_PERIOD);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * AMD SB700 based systems with spread spectrum enabled use a
|
|
|
|
+ * SMM based HPET emulation to provide proper frequency
|
|
|
|
+ * setting. The SMM code is initialized with the first HPET
|
|
|
|
+ * register access and takes some time to complete. During
|
|
|
|
+ * this time the config register reads 0xffffffff. We check
|
|
|
|
+ * for max. 1000 loops whether the config register reads a non
|
|
|
|
+ * 0xffffffff value to make sure that HPET is up and running
|
|
|
|
+ * before we go further. A counting loop is safe, as the HPET
|
|
|
|
+ * access takes thousands of CPU cycles. On non SB700 based
|
|
|
|
+ * machines this check is only done once and has no side
|
|
|
|
+ * effects.
|
|
|
|
+ */
|
|
|
|
+ for (i = 0; hpet_readl(HPET_CFG) == 0xFFFFFFFF; i++) {
|
|
|
|
+ if (i == 1000) {
|
|
|
|
+ printk(KERN_WARNING
|
|
|
|
+ "HPET config register value = 0xFFFFFFFF. "
|
|
|
|
+ "Disabling HPET\n");
|
|
|
|
+ goto out_nohpet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
|
|
if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
|
|
goto out_nohpet;
|
|
goto out_nohpet;
|
|
|
|
|