From bf080041ba1975497bce21138d090a72964d5f1f Mon Sep 17 00:00:00 2001 From: john stultz Date: Fri, 8 Dec 2006 02:36:02 -0800 Subject: [PATCH] --- yaml --- r: 43490 b: refs/heads/master c: 562f9c574e0707f9159a729ea41faf53b221cd30 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/clocksource/acpi_pm.c | 36 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index ee1d5eb5ac50..8e49a5f71cb4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a2ee8649ba6d71416712e798276bf7c40b64e6e5 +refs/heads/master: 562f9c574e0707f9159a729ea41faf53b221cd30 diff --git a/trunk/drivers/clocksource/acpi_pm.c b/trunk/drivers/clocksource/acpi_pm.c index 7fcb77a9d011..8ab61ef97b4c 100644 --- a/trunk/drivers/clocksource/acpi_pm.c +++ b/trunk/drivers/clocksource/acpi_pm.c @@ -142,6 +142,39 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, acpi_pm_check_graylist); #endif +#ifndef CONFIG_X86_64 +#include "mach_timer.h" +#define PMTMR_EXPECTED_RATE \ + ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10)) +/* + * Some boards have the PMTMR running way too fast. We check + * the PMTMR rate against PIT channel 2 to catch these cases. + */ +static int verify_pmtmr_rate(void) +{ + u32 value1, value2; + unsigned long count, delta; + + mach_prepare_counter(); + value1 = read_pmtmr(); + mach_countup(&count); + value2 = read_pmtmr(); + delta = (value2 - value1) & ACPI_PM_MASK; + + /* Check that the PMTMR delta is within 5% of what we expect */ + if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 || + delta > (PMTMR_EXPECTED_RATE * 21) / 20) { + printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% " + "of normal - aborting.\n", + 100UL * delta / PMTMR_EXPECTED_RATE); + return -1; + } + + return 0; +} +#else +#define verify_pmtmr_rate() (0) +#endif static int __init init_acpi_pm_clocksource(void) { @@ -173,6 +206,9 @@ static int __init init_acpi_pm_clocksource(void) return -ENODEV; pm_good: + if (verify_pmtmr_rate() != 0) + return -ENODEV; + return clocksource_register(&clocksource_acpi_pm); }