linux-rtc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mastro Gippo <gipmad@gmail.com>
To: linux-rtc@vger.kernel.org
Subject: Infinite loop on edge cases
Date: Tue, 9 Apr 2019 10:46:21 +0200	[thread overview]
Message-ID: <CADjOgT_w8uHnoBe+i0_RJW4R2ZJM5-za0T9YPk0gPNwMUHQoHQ@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1176 bytes --]

Hello, I have been testing the latest RTC drivers on an OpenWrt build
on a MTK7688 SOC and I got an infinite loop on boot that would block
the entire system.
Basically, if I don't have a RTC connected, any read would return
0xFF. That may be also be a problem of the I2C driver, that instead of
generating an error just returns that value. But this may happen in
other cases, like if we add an EEPROM or another IC with the same
address as the RTC, or the RTC IC fails in some unpredictable way.
The current implementation of that piece of code has some bad
practices that lead to infinite loops due to this error.
Since on these RTCs the byte at address 0x00 will never be 0xFF (check
the datasheet), I added a sanity check for this special case.
A better way to do this would be to add a retry counter when setting
the CH bit, but that's  an even more edge case that will probably
never happen.
The same infinite loop will happen on other RTC ICs that do a similar
check in other parts of code, but I don't have them so I can't edit
the code and test it.
The code has been tested and works; please consider merging it.
Thanks,
Best regards
Cristiano Griletti - Mastro Gippo

[-- Attachment #2: 0001-Fixed-infinite-loop-if-RTC-is-broken-disconnected.patch --]
[-- Type: application/octet-stream, Size: 1841 bytes --]

From 57c81bb7c9c15d8d1f29ec1e5e2c5cdc980fb943 Mon Sep 17 00:00:00 2001
From: Cristiano Griletti - Mastro Gippo <gipmad@gmail.com>
Date: Mon, 8 Apr 2019 17:10:09 +0200
Subject: [PATCH] Fixed infinite loop if RTC is broken/disconnected

If the RTC IC is missing or there's some other kind of error in the I2C bus reading wrong data, reading address 0x00 may always return 0xFF without returning an [err] code at line 1710.
When this happens, we get stuck in an infinite loop, stopping the device from booting and continuously printing this error:
"rtc-ds1307 0-0068: SET TIME!"
I added a sanity check of the byte returned from address 0x00, as it can never be 0xFF in normal operation and that can only mean that there's a read error (see datasheet).
This has been tested only with DS1307, but I'm sure the same bug will happen on the other devices where there is a "goto read_rtc;" (lines 1755 and 1788). I don't have the hardware to test them so I didn't touch that code.
---
 drivers/rtc/rtc-ds1307.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 07530fe..db56539 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -1727,9 +1727,16 @@ static int ds1307_probe(struct i2c_client *client,
 	case m41t11:
 		/* clock halted?  turn it on, so clock can tick. */
 		if (tmp & DS1307_BIT_CH) {
-			regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
-			dev_warn(ds1307->dev, "SET TIME!\n");
-			goto read_rtc;
+			if (tmp == 0xFF) {
+				/* read error; avoid loop. */
+				dev_dbg(ds1307->dev, "read error DS1307_REG_SECS\n", err);
+				goto exit;
+			}
+			else {
+				regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
+				dev_warn(ds1307->dev, "SET TIME!\n");
+				goto read_rtc;
+			}
 		}
 		break;
 	case ds_1308:
-- 
1.8.3.1


             reply	other threads:[~2019-04-09  8:46 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-09  8:46 Mastro Gippo [this message]
     [not found] <CADjOgT97-8PM1=Nm+Mk4jw_8vzt3i9KXUohDAkUsptxS7JuU6Q@mail.gmail.com>
2019-04-09  9:01 ` Infinite loop on edge cases Alexandre Belloni
2019-04-09 10:46   ` Mastro Gippo
2019-04-09 11:27     ` Alexandre Belloni
2019-04-09 14:35       ` Mastro Gippo
2019-04-15 15:34         ` Alexandre Belloni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CADjOgT_w8uHnoBe+i0_RJW4R2ZJM5-za0T9YPk0gPNwMUHQoHQ@mail.gmail.com \
    --to=gipmad@gmail.com \
    --cc=linux-rtc@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).