Hi Andreas,
On Sun, Aug 10, 2008 at 12:17:30PM +0200, Andreas Mohr wrote:
this isn't the bug which is handled by the read-three-times-workaround.
Instead, that handels the following PIIX4 errata:
* PIIX4 Errata:
*
* The power management timer may return improper results when read.
* Although the timer value settles properly after incrementing,
* while incrementing there is a 3 ns window every 69.8 ns where the
* timer value is indeterminate (a 4.2% chance that the data will be
* incorrect when read). As a result, the ACPI free running count up
* timer specification is violated due to erroneous reads.
No surprise there -- it is the first time I see such an error; and it might
actually be a bug specific to your computer's motherboard.
See patch below. Is there a proper format modifier for cycle_t ?
Well, we could do something like this for sure, but I haven't seen any other
such bug report before...
=> see patch below.
=> might do this, but currently I'm not yet convinced whether we really need
it.
Best,
Dominik
acpi_pm.c: use proper read function also in errata mode.
When acpi_pm is used in errata mode (three reads instead of one), also the
acpi_pm init functions need to use three reads instead of just one.
Thanks to Andreas Mohr for spotting this issue.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.de>
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 5ca1d80..2c00edd 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -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:
--