aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource/acpi_pm.c
diff options
context:
space:
mode:
authorjohn stultz <johnstul@us.ibm.com>2006-12-08 05:36:02 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:37 -0500
commit562f9c574e0707f9159a729ea41faf53b221cd30 (patch)
tree54fb7d5195d09cd7ce9ceb312a98d7538e8a34f0 /drivers/clocksource/acpi_pm.c
parenta2ee8649ba6d71416712e798276bf7c40b64e6e5 (diff)
[PATCH] time: re-add verify_pmtmr_rate
This patch re-adds the verify_pmtmr_rate functionality from 2.6.17 that I dropped 2.6.18. This resolves problems seen on older K6 ASUS boards where the ACPI PM timer runs too fast. See: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=211902 http://bugme.osdl.org/show_bug.cgi?id=2375 Thanks to Ian Campbell for re-reporting this and testing the fix! Signed-off-by: John Stultz <johnstul@us.ibm.com> Cc: Andi Kleen <ak@suse.de> Cc: Ian Campbell <ijc@hellion.org.uk> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/clocksource/acpi_pm.c')
-rw-r--r--drivers/clocksource/acpi_pm.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 7fcb77a9d011..8ab61ef97b4c 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -142,6 +142,39 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
142 acpi_pm_check_graylist); 142 acpi_pm_check_graylist);
143#endif 143#endif
144 144
145#ifndef CONFIG_X86_64
146#include "mach_timer.h"
147#define PMTMR_EXPECTED_RATE \
148 ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10))
149/*
150 * Some boards have the PMTMR running way too fast. We check
151 * the PMTMR rate against PIT channel 2 to catch these cases.
152 */
153static int verify_pmtmr_rate(void)
154{
155 u32 value1, value2;
156 unsigned long count, delta;
157
158 mach_prepare_counter();
159 value1 = read_pmtmr();
160 mach_countup(&count);
161 value2 = read_pmtmr();
162 delta = (value2 - value1) & ACPI_PM_MASK;
163
164 /* Check that the PMTMR delta is within 5% of what we expect */
165 if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
166 delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
167 printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% "
168 "of normal - aborting.\n",
169 100UL * delta / PMTMR_EXPECTED_RATE);
170 return -1;
171 }
172
173 return 0;
174}
175#else
176#define verify_pmtmr_rate() (0)
177#endif
145 178
146static int __init init_acpi_pm_clocksource(void) 179static int __init init_acpi_pm_clocksource(void)
147{ 180{
@@ -173,6 +206,9 @@ static int __init init_acpi_pm_clocksource(void)
173 return -ENODEV; 206 return -ENODEV;
174 207
175pm_good: 208pm_good:
209 if (verify_pmtmr_rate() != 0)
210 return -ENODEV;
211
176 return clocksource_register(&clocksource_acpi_pm); 212 return clocksource_register(&clocksource_acpi_pm);
177} 213}
178 214