Przeglądaj źródła

clocksource, acpi_pm.c: fix check for monotonicity

Actually check the monotonicity of the ACPI PMTMR ten times, only delay for
0.9 miliseconds at most, and bail out early if some problem is determined.

Reported-by: Jochen Voß <jochen.voss@googlemail.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Dominik Brodowski 17 lat temu
rodzic
commit
f1926ce63b
1 zmienionych plików z 10 dodań i 11 usunięć
  1. 10 11
      drivers/clocksource/acpi_pm.c

+ 10 - 11
drivers/clocksource/acpi_pm.c

@@ -178,11 +178,13 @@ static int verify_pmtmr_rate(void)
 
 
 /* Number of monotonicity checks to perform during initialization */
 /* Number of monotonicity checks to perform during initialization */
 #define ACPI_PM_MONOTONICITY_CHECKS 10
 #define ACPI_PM_MONOTONICITY_CHECKS 10
+/* Number of reads we try to get two different values */
+#define ACPI_PM_READ_CHECKS 10000
 
 
 static int __init init_acpi_pm_clocksource(void)
 static int __init init_acpi_pm_clocksource(void)
 {
 {
 	cycle_t value1, value2;
 	cycle_t value1, value2;
-	unsigned int i, j, good = 0;
+	unsigned int i, j = 0;
 
 
 	if (!pmtmr_ioport)
 	if (!pmtmr_ioport)
 		return -ENODEV;
 		return -ENODEV;
@@ -192,29 +194,26 @@ static int __init init_acpi_pm_clocksource(void)
 
 
 	/* "verify" this timing source: */
 	/* "verify" this timing source: */
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
 	for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
+		udelay(100 * j);
 		value1 = clocksource_acpi_pm.read();
 		value1 = clocksource_acpi_pm.read();
-		for (i = 0; i < 10000; i++) {
+		for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
 			value2 = clocksource_acpi_pm.read();
 			value2 = clocksource_acpi_pm.read();
 			if (value2 == value1)
 			if (value2 == value1)
 				continue;
 				continue;
 			if (value2 > value1)
 			if (value2 > value1)
-				good++;
 				break;
 				break;
 			if ((value2 < value1) && ((value2) < 0xFFF))
 			if ((value2 < value1) && ((value2) < 0xFFF))
-				good++;
 				break;
 				break;
 			printk(KERN_INFO "PM-Timer had inconsistent results:"
 			printk(KERN_INFO "PM-Timer had inconsistent results:"
 			       " 0x%#llx, 0x%#llx - aborting.\n",
 			       " 0x%#llx, 0x%#llx - aborting.\n",
 			       value1, value2);
 			       value1, value2);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
-		udelay(300 * i);
-	}
-
-	if (good != ACPI_PM_MONOTONICITY_CHECKS) {
-		printk(KERN_INFO "PM-Timer failed consistency check "
-		       " (0x%#llx) - aborting.\n", value1);
-		return -ENODEV;
+		if (i == ACPI_PM_READ_CHECKS) {
+			printk(KERN_INFO "PM-Timer failed consistency check "
+			       " (0x%#llx) - aborting.\n", value1);
+			return -ENODEV;
+		}
 	}
 	}
 
 
 	if (verify_pmtmr_rate() != 0)
 	if (verify_pmtmr_rate() != 0)