aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clocksource
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/acpi_pm.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 3df338481004..c20171078d1d 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -21,6 +21,7 @@
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/delay.h>
24#include <asm/io.h> 25#include <asm/io.h>
25 26
26/* 27/*
@@ -151,13 +152,13 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE,
151 */ 152 */
152static int verify_pmtmr_rate(void) 153static int verify_pmtmr_rate(void)
153{ 154{
154 u32 value1, value2; 155 cycle_t value1, value2;
155 unsigned long count, delta; 156 unsigned long count, delta;
156 157
157 mach_prepare_counter(); 158 mach_prepare_counter();
158 value1 = read_pmtmr(); 159 value1 = clocksource_acpi_pm.read();
159 mach_countup(&count); 160 mach_countup(&count);
160 value2 = read_pmtmr(); 161 value2 = clocksource_acpi_pm.read();
161 delta = (value2 - value1) & ACPI_PM_MASK; 162 delta = (value2 - value1) & ACPI_PM_MASK;
162 163
163 /* Check that the PMTMR delta is within 5% of what we expect */ 164 /* Check that the PMTMR delta is within 5% of what we expect */
@@ -175,10 +176,15 @@ static int verify_pmtmr_rate(void)
175#define verify_pmtmr_rate() (0) 176#define verify_pmtmr_rate() (0)
176#endif 177#endif
177 178
179/* Number of monotonicity checks to perform during initialization */
180#define ACPI_PM_MONOTONICITY_CHECKS 10
181/* Number of reads we try to get two different values */
182#define ACPI_PM_READ_CHECKS 10000
183
178static int __init init_acpi_pm_clocksource(void) 184static int __init init_acpi_pm_clocksource(void)
179{ 185{
180 u32 value1, value2; 186 cycle_t value1, value2;
181 unsigned int i; 187 unsigned int i, j = 0;
182 188
183 if (!pmtmr_ioport) 189 if (!pmtmr_ioport)
184 return -ENODEV; 190 return -ENODEV;
@@ -187,24 +193,29 @@ static int __init init_acpi_pm_clocksource(void)
187 clocksource_acpi_pm.shift); 193 clocksource_acpi_pm.shift);
188 194
189 /* "verify" this timing source: */ 195 /* "verify" this timing source: */
190 value1 = read_pmtmr(); 196 for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
191 for (i = 0; i < 10000; i++) { 197 udelay(100 * j);
192 value2 = read_pmtmr(); 198 value1 = clocksource_acpi_pm.read();
193 if (value2 == value1) 199 for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
194 continue; 200 value2 = clocksource_acpi_pm.read();
195 if (value2 > value1) 201 if (value2 == value1)
196 goto pm_good; 202 continue;
197 if ((value2 < value1) && ((value2) < 0xFFF)) 203 if (value2 > value1)
198 goto pm_good; 204 break;
199 printk(KERN_INFO "PM-Timer had inconsistent results:" 205 if ((value2 < value1) && ((value2) < 0xFFF))
200 " 0x%#x, 0x%#x - aborting.\n", value1, value2); 206 break;
201 return -EINVAL; 207 printk(KERN_INFO "PM-Timer had inconsistent results:"
208 " 0x%#llx, 0x%#llx - aborting.\n",
209 value1, value2);
210 return -EINVAL;
211 }
212 if (i == ACPI_PM_READ_CHECKS) {
213 printk(KERN_INFO "PM-Timer failed consistency check "
214 " (0x%#llx) - aborting.\n", value1);
215 return -ENODEV;
216 }
202 } 217 }
203 printk(KERN_INFO "PM-Timer had no reasonable result:"
204 " 0x%#x - aborting.\n", value1);
205 return -ENODEV;
206 218
207pm_good:
208 if (verify_pmtmr_rate() != 0) 219 if (verify_pmtmr_rate() != 0)
209 return -ENODEV; 220 return -ENODEV;
210 221