Minor logic fix. The century change was previously always BCD,
even when the CMOS data would report itself not being BCD.
Signed-off-by: Andi Kleen <ak@suse.de>
---
arch/x86/kernel/rtc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux/arch/x86/kernel/rtc.c
===================================================================
--- linux.orig/arch/x86/kernel/rtc.c
+++ linux/arch/x86/kernel/rtc.c
@@ -130,10 +130,10 @@ unsigned long mach_get_cmos_time(void)
BCD_TO_BIN(day);
BCD_TO_BIN(mon);
BCD_TO_BIN(year);
+ BCD_TO_BIN(century);
}
if (century) {
- BCD_TO_BIN(century);
year += century * 100;
printk(KERN_INFO "Extended CMOS year: %d\n", century * 100);
} else {
--
We know it is already after 2000. This extends the effective lifetime of 32bit systems by 8 years: from 2030 to 2038. The only drawback is that users cannot set the cmos date to before 2000 now on 32bit with systems that don't support extended century in the RTC clock. 64bit systems had this limitation for some time and nobody complained. And they can always set it to such a date in Linux only using date -s if they really want. Signed-off-by: Andi Kleen <ak@suse.de> --- arch/x86/kernel/rtc.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) Index: linux/arch/x86/kernel/rtc.c =================================================================== --- linux.orig/arch/x86/kernel/rtc.c +++ linux/arch/x86/kernel/rtc.c @@ -9,7 +9,6 @@ #include <asm/vsyscall.h> #ifdef CONFIG_X86_32 -# define CMOS_YEARS_OFFS 1900 /* * This is a special lock that is owned by the CPU and holds the index * register we are working with. It is required for NMI access to the @@ -17,14 +16,11 @@ */ volatile unsigned long cmos_lock = 0; EXPORT_SYMBOL(cmos_lock); -#else -/* - * x86-64 systems only exists since 2002. - * This will work up to Dec 31, 2100 - */ -# define CMOS_YEARS_OFFS 2000 #endif +/* For two digit years assume time is always after that */ +#define CMOS_YEARS_OFFS 2000 + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); --
Could you please explain what magic math does the 2030 -> 2038 extension ? According to the code the 1970 comparison works until 2069: year += 1900; if (year < 1970) year += 100; I keep the patch nevertheless as it removes ifdeffery, but I change the commit log to something sensible and remove the year < 1970 check as well as it is not longer necessary. Thanks, tglx --
Hmm, yes on rechecking I also don't know how I got the original conclusion. -Andi --
We tend to assume the RTC clock is BCD, so print a warning
if it claims to be binary.
Signed-off-by: Andi Kleen <ak@suse.de>
Index: linux/arch/x86/kernel/rtc.c
===================================================================
--- linux.orig/arch/x86/kernel/rtc.c
+++ linux/arch/x86/kernel/rtc.c
@@ -94,6 +94,8 @@ int mach_set_rtc_mmss(unsigned long nowt
unsigned long mach_get_cmos_time(void)
{
+ unsigned status;
+ static int warned;
unsigned int year, mon, day, hour, min, sec, century = 0;
/*
@@ -119,7 +121,13 @@ unsigned long mach_get_cmos_time(void)
century = CMOS_READ(acpi_gbl_FADT.century);
#endif
- if (RTC_ALWAYS_BCD || !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)) {
+ status = CMOS_READ(RTC_CONTROL);
+ if (RTC_ALWAYS_BCD && (status & RTC_DM_BINARY) && !warned) {
+ printk(KERN_INFO "RTC clock reports binary. Ignored\n");
+ warned = 1;
+ }
+
+ if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) {
BCD_TO_BIN(sec);
BCD_TO_BIN(min);
BCD_TO_BIN(hour);
--
Applied. FYI, I changed it to a WARN_ON_ONCE. That will make reports more likely. Thanks, tglx --
It should operate in BCD mode. Signed-off-by: Andi Kleen <ak@suse.de> Index: linux/include/asm-x86/mc146818rtc.h =================================================================== --- linux.orig/include/asm-x86/mc146818rtc.h +++ linux/include/asm-x86/mc146818rtc.h @@ -11,7 +11,7 @@ #ifndef RTC_PORT #define RTC_PORT(x) (0x70 + (x)) -#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#define RTC_ALWAYS_BCD 1 /* RTC operates in BCD mode */ #endif #if defined(CONFIG_X86_32) && defined(__HAVE_ARCH_CMPXCHG) --
Not that it matters much, see comment in the code. v2: Fix compilation on !ACPI, pointed out by tglx Signed-off-by: Andi Kleen <ak@suse.de> --- arch/x86/kernel/rtc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) Index: linux/arch/x86/kernel/rtc.c =================================================================== --- linux.orig/arch/x86/kernel/rtc.c +++ linux/arch/x86/kernel/rtc.c @@ -112,8 +112,11 @@ unsigned long mach_get_cmos_time(void) mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); -#if defined(CONFIG_ACPI) && defined(CONFIG_X86_64) - /* CHECKME: Is this really 64bit only ??? */ +#ifdef CONFIG_ACPI + /* + * On 32bit not strictly needed because the world ends in 2038 + * and the code can handle that with the 2 digit heuristics. + */ if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && acpi_gbl_FADT.century) century = CMOS_READ(acpi_gbl_FADT.century); --
I checked that whole rtc / BCD logic again. We always set RTC_ALWAYS_BCD:
#ifndef RTC_PORT
#define RTC_PORT(x) (0x70 + (x))
#define RTC_ALWAYS_BCD 1 /* RTC operates in BCD mode */
#endif
Nothing ever defines RTC_PORT and RTC_ALWAYS_BCD
This should probably go here:
if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
acpi_gbl_FADT.century) {
--->
}
It does not matter much, because BCD_TO_BIN(0) is 0, but it makes a
lot of sense.
Thanks,
tglx
--
Please see the second version of the patch series. This means I didn't drop it completely, but added a warning about it not agreeing with the status register. If this warning never triggers it can be dropped eventually, if it triggers RTC_ALWAYS_BCD should be unset. -Andi --
#define RTC_ALWAYS_BCD 1 is there since Linux 1.0 and got never changed for x86. So the warning comes a bit late :) Later on the #ifdef RTC_PORT was introduced to share the header in include/linux across architectures. When the header got copied to include/i386 and elsewhere this just was never removed. Thanks, tglx --
> So the warning comes a bit late :) I suspect if this was wrong before it would not have been noticed because user space hwclock would work around it. The warning certainly won't hurt. Anyways if you feel strongly about this (I don't) then drop this patch, but apply the other ones in the series. The main one I consider important is the change to the 2000 offset for 32bit to extend the 32bit lifetime. -Andi --
And how exaclty does it work around ? By setting the binary cmos clock I'm not opposing the patch, I merily asked for a removal of the never Picked the whole lot up. Thanks, tglx --
By reading the value directly from CMOS I suppose and checking the BCD bit and then setting the clock to the correct value [all theoretical; i have not checked the hwclock code if it does that or not. It might be wrong. Just a hypothesis.] -Andi --
