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