clocksource, acpi_pm.c: use proper read function also in errata mode
authorDominik Brodowski <linux@dominikbrodowski.net>
Fri, 5 Sep 2008 21:05:33 +0000 (14:05 -0700)
committerIngo Molnar <mingo@elte.hu>
Sat, 6 Sep 2008 13:33:31 +0000 (15:33 +0200)
On all hardware (some Intel ICH4, PIIX4 and PIIX4E chipsets) affected by a
hardware errata there's about a 4.2% chance that initialization of the
ACPI PMTMR fails.  On those chipsets, we need to read out the timer value
at least three times to get a correct result, for every once in a while
(i.e.  within a 3 ns window every 69.8 ns) the read returns a bogus
result.  During normal operation we work around this issue, but during
initialization reading a bogus value may lead to -EINVAL even though the
hardware is usable.

Thanks to Andreas Mohr for spotting this issue.

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
drivers/clocksource/acpi_pm.c

index 5ca1d80de182bfa3bb333f0aeca907f7929ed26c..860d033bc74f81bd99301b8db244147deeb0fc02 100644 (file)
@@ -151,13 +151,13 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
  */
 static int verify_pmtmr_rate(void)
 {
-       u32 value1, value2;
+       cycle_t value1, value2;
        unsigned long count, delta;
 
        mach_prepare_counter();
-       value1 = read_pmtmr();
+       value1 = clocksource_acpi_pm.read();
        mach_countup(&count);
-       value2 = read_pmtmr();
+       value2 = clocksource_acpi_pm.read();
        delta = (value2 - value1) & ACPI_PM_MASK;
 
        /* Check that the PMTMR delta is within 5% of what we expect */
@@ -177,7 +177,7 @@ static int verify_pmtmr_rate(void)
 
 static int __init init_acpi_pm_clocksource(void)
 {
-       u32 value1, value2;
+       cycle_t value1, value2;
        unsigned int i;
 
        if (!pmtmr_ioport)
@@ -187,9 +187,9 @@ static int __init init_acpi_pm_clocksource(void)
                                                clocksource_acpi_pm.shift);
 
        /* "verify" this timing source: */
-       value1 = read_pmtmr();
+       value1 = clocksource_acpi_pm.read();
        for (i = 0; i < 10000; i++) {
-               value2 = read_pmtmr();
+               value2 = clocksource_acpi_pm.read();
                if (value2 == value1)
                        continue;
                if (value2 > value1)
@@ -197,11 +197,11 @@ static int __init init_acpi_pm_clocksource(void)
                if ((value2 < value1) && ((value2) < 0xFFF))
                        goto pm_good;
                printk(KERN_INFO "PM-Timer had inconsistent results:"
-                       " 0x%#x, 0x%#x - aborting.\n", value1, value2);
+                       " 0x%#llx, 0x%#llx - aborting.\n", value1, value2);
                return -EINVAL;
        }
        printk(KERN_INFO "PM-Timer had no reasonable result:"
-                       " 0x%#x - aborting.\n", value1);
+                       " 0x%#llx - aborting.\n", value1);
        return -ENODEV;
 
 pm_good: