The recent change to validate the RTC turned out to be overly tight.

While it cures the problem on the reporters machine it breaks machines
with Intel chipsets which use bit 0-5 of the D register. So check only
for bit 6 being 0 which is the case on these Intel machines as well.

Fixes: 211e5db19d15 ("rtc: mc146818: Detect and handle broken RTCs")
Reported-by: Serge Belyshev <belys...@depni.sinp.msu.ru>
Reported-by: Dirk Gouders <d...@gouders.net>
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 drivers/rtc/rtc-cmos.c         |    8 ++++++++
 drivers/rtc/rtc-mc146818-lib.c |    7 +++++++
 2 files changed, 15 insertions(+)

--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -805,6 +805,14 @@ cmos_do_probe(struct device *dev, struct
 
        spin_lock_irq(&rtc_lock);
 
+       /* Ensure that the RTC is accessible. Bit 6 must be 0! */
+       if ((CMOS_READ(RTC_VALID) & 0x40) != 0) {
+               spin_unlock_irq(&rtc_lock);
+               dev_warn(dev, "not accessible\n");
+               retval = -ENXIO;
+               goto cleanup1;
+       }
+
        if (!(flags & CMOS_RTC_FLAGS_NOFREQ)) {
                /* force periodic irq to CMOS reset default of 1024Hz;
                 *
--- a/drivers/rtc/rtc-mc146818-lib.c
+++ b/drivers/rtc/rtc-mc146818-lib.c
@@ -21,6 +21,13 @@ unsigned int mc146818_get_time(struct rt
 
 again:
        spin_lock_irqsave(&rtc_lock, flags);
+       /* Ensure that the RTC is accessible. Bit 6 must be 0! */
+       if (WARN_ON_ONCE((CMOS_READ(RTC_VALID) & 0x40) != 0)) {
+               spin_unlock_irqrestore(&rtc_lock, flags);
+               memset(time, 0xff, sizeof(*time));
+               return 0;
+       }
+
        /*
         * Check whether there is an update in progress during which the
         * readout is unspecified. The maximum update time is ~2ms. Poll

Reply via email to