From 4aae35435ca527eb8b82c369c4b171e780236d39 Mon Sep 17 00:00:00 2001 From: "David P. Reed" Date: Wed, 14 Nov 2007 20:14:50 -0500 Subject: [PATCH] --- yaml --- r: 73900 b: refs/heads/master c: bbbd99955bfe84c9ae63f51db946a7bcd21f48be h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/x86/kernel/time_64.c | 30 ++++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/[refs] b/[refs] index 43a7e0011b49..47784ed9828c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c399da0d97e06803e51085ec076b63a3168aad1b +refs/heads/master: bbbd99955bfe84c9ae63f51db946a7bcd21f48be diff --git a/trunk/arch/x86/kernel/time_64.c b/trunk/arch/x86/kernel/time_64.c index 4ad1f7a6a839..368b1942b39a 100644 --- a/trunk/arch/x86/kernel/time_64.c +++ b/trunk/arch/x86/kernel/time_64.c @@ -161,21 +161,27 @@ unsigned long read_persistent_clock(void) unsigned century = 0; spin_lock_irqsave(&rtc_lock, flags); + /* + * if UIP is clear, then we have >= 244 microseconds before RTC + * registers will be updated. Spec sheet says that this is the + * reliable way to read RTC - registers invalid (off bus) during update + */ + while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + cpu_relax(); - do { - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); + + /* now read all RTC registers while stable with interrupts disabled */ + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); #ifdef CONFIG_ACPI - if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && - acpi_gbl_FADT.century) - century = CMOS_READ(acpi_gbl_FADT.century); + if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && + acpi_gbl_FADT.century) + century = CMOS_READ(acpi_gbl_FADT.century); #endif - } while (sec != CMOS_READ(RTC_SECONDS)); - spin_unlock_irqrestore(&rtc_lock, flags); /*