- time-i386-clocksource-drivers-pm-timer-doesnt-use-workaround-if-chipset-is-not-buggy.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     PM-Timer: doesn't use workaround if chipset is not buggy

has been removed from the -mm tree.  Its filename is

     time-i386-clocksource-drivers-pm-timer-doesnt-use-workaround-if-chipset-is-not-buggy.patch

This patch was dropped because it was folded into time-i386-clocksource-drivers.patch

------------------------------------------------------
Subject: PM-Timer: doesn't use workaround if chipset is not buggy
From: john stultz <johnstul@xxxxxxxxxx>


My reimplementation of pmtimer workaround from OGAWA Hirofumi.

Signed-off-by: OGAWA Hirofumi <hirofumi@xxxxxxxxxxxxxxxxxx>
Signed-off-by: John Stultz <johnstul@xxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 drivers/clocksource/acpi_pm.c |  102 +++++++++++++++++++++++++++++++-
 1 file changed, 99 insertions(+), 3 deletions(-)

diff -puN drivers/clocksource/acpi_pm.c~time-i386-clocksource-drivers-pm-timer-doesnt-use-workaround-if-chipset-is-not-buggy drivers/clocksource/acpi_pm.c
--- a/drivers/clocksource/acpi_pm.c~time-i386-clocksource-drivers-pm-timer-doesnt-use-workaround-if-chipset-is-not-buggy
+++ a/drivers/clocksource/acpi_pm.c
@@ -19,6 +19,7 @@
 #include <linux/clocksource.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/pci.h>
 #include <asm/io.h>
 
 /* Number of PMTMR ticks expected during calibration run */
@@ -30,6 +31,7 @@
  * in arch/i386/acpi/boot.c
  */
 u32 pmtmr_ioport;
+static int pmtmr_need_workaround = 1;
 
 #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
 
@@ -39,6 +41,26 @@ static inline u32 read_pmtmr(void)
 	return inl(pmtmr_ioport) & ACPI_PM_MASK;
 }
 
+static cycle_t acpi_pm_read_verified(void)
+{
+	u32 v1 = 0, v2 = 0, v3 = 0;
+
+	/*
+	 * It has been reported that because of various broken
+	 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM clock
+	 * source is not latched, so you must read it multiple
+	 * times to ensure a safe value is read:
+	 */
+	do {
+		v1 = read_pmtmr();
+		v2 = read_pmtmr();
+		v3 = read_pmtmr();
+	} while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
+			|| (v3 > v1 && v3 < v2));
+
+	return (cycle_t)v2;
+}
+
 static cycle_t acpi_pm_read(void)
 {
 	return (cycle_t)read_pmtmr();
@@ -54,6 +76,73 @@ static struct clocksource clocksource_ac
 	.is_continuous	= 1,
 };
 
+
+#ifdef CONFIG_PCI
+/*
+ * 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.
+ */
+static void __init pmtmr_bug_check(void)
+{
+	static struct pci_device_id gray_list[] __initdata = {
+		/* these chipsets may have bug. */
+		{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82801DB_0) },
+		{ },
+	};
+	struct pci_dev *dev;
+	int pmtmr_has_bug = 0;
+	u8 rev;
+
+	if (!pmtmr_need_workaround)
+		return;
+
+	dev = pci_get_device(PCI_VENDOR_ID_INTEL,
+				PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+	if (dev) {
+		pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+		/* the bug has been fixed in PIIX4M */
+		if (rev < 3) {
+			printk(KERN_WARNING "* Found PM-Timer Bug on this"
+				" chipset. Due to workarounds for a bug,\n"
+				"* this time source is slow. Consider trying"
+				" other time sources (clock=)\n");
+			pmtmr_has_bug = 1;
+		}
+		pci_dev_put(dev);
+	}
+
+	if (pci_dev_present(gray_list)) {
+		printk(KERN_WARNING "* This chipset may have PM-Timer Bug."
+			" Due to workarounds for a bug,\n"
+			"* this time source is slow. If you are sure your"
+			" timer does not have\n"
+			"* this bug, please use \"pmtmr_good\" to disable?"
+			" the workaround\n");
+		pmtmr_has_bug = 1;
+	}
+
+	if (!pmtmr_has_bug)
+		pmtmr_need_workaround = 0;
+}
+#else
+#define pmtmr_bug_check()
+#endif
+
+static int __init pmtr_good_setup(char *__str)
+{
+       pmtmr_need_workaround = 0;
+       return 1;
+}
+__setup("pmtmr_good", pmtr_good_setup);
+
+
 static int __init init_acpi_pm_clocksource(void)
 {
 	u32 value1, value2;
@@ -75,14 +164,21 @@ static int __init init_acpi_pm_clocksour
 			goto pm_good;
 		if ((value2 < value1) && ((value2) < 0xFFF))
 			goto pm_good;
-		printk(KERN_INFO "PM-Timer had inconsistent results: 0x%#x, 0x%#x - aborting.\n", value1, value2);
+		printk(KERN_INFO "PM-Timer had inconsistent results:"
+			" 0x%#x, 0x%#x - aborting.\n", value1, value2);
 		return -EINVAL;
 	}
-	printk(KERN_INFO "PM-Timer had no reasonable result: 0x%#x - aborting.\n", value1);
+	printk(KERN_INFO "PM-Timer had no reasonable result:"
+			" 0x%#x - aborting.\n", value1);
 	return -ENODEV;
 
 pm_good:
-
+	pmtmr_bug_check();
+	/* check to see if pmtmr is known buggy: */
+	if (pmtmr_need_workaround) {
+		clocksource_acpi_pm.read = acpi_pm_read_verified;
+		clocksource_acpi_pm.rating = 110;
+	}
 	return register_clocksource(&clocksource_acpi_pm);
 }
 
_

Patches currently in -mm which might be from johnstul@xxxxxxxxxx are

time-clocksource-infrastructure.patch
time-use-clocksource-infrastructure-for-update_wall_time.patch
time-let-user-request-precision-from-current_tick_length.patch
time-use-clocksource-abstraction-for-ntp-adjustments.patch
time-introduce-arch-generic-time-accessors.patch
hangcheck-remove-monotomic_clock-on-x86.patch
time-i386-conversion-part-1-move-timer_pitc-to-i8253c.patch
time-i386-conversion-part-2-rework-tsc-support.patch
time-i386-conversion-part-3-enable-generic-timekeeping.patch
time-i386-conversion-part-4-remove-old-timer_opts-code.patch
time-i386-clocksource-drivers.patch
time-i386-clocksource-drivers-pm-timer-doesnt-use-workaround-if-chipset-is-not-buggy.patch
time-i386-clocksource-drivers-pm-timer-doesnt-use-workaround-if-chipset-is-not-buggy-acpi_pm-cleanup.patch
time-i386-clocksource-drivers-pm-timer-doesnt-use-workaround-if-chipset-is-not-buggy-acpi_pm-cleanup-fix-missing-to-rename-pmtmr_good-to-acpi_pm_good.patch
time-i386-clocksource-drivers-fix-spelling-typos.patch
time-rename-clocksource-functions.patch
make-pmtmr_ioport-__read_mostly.patch
generic-time-add-macro-to-simplify-hide-mask.patch
time-fix-time-going-backward-w-clock=pit.patch
fix-and-optimize-clock-source-update.patch
gtod-add-scx200-hrt-clocksourcediff.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux