@@ -66,6 +66,8 @@
#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
+#define M41T80_DEFAULT_TIME 1262304000 /* 2010-01-01 00:00:00 UTC */
+
#define DRV_VERSION "0.05"
static const struct i2c_device_id m41t80_id[] = {
@@ -121,7 +123,7 @@ static int m41t80_get_datetime(struct i2c_client *client,
/* assume 20YY not 19YY, and ignore the Century Bit */
tm->tm_year = bcd2bin(buf[M41T80_REG_YEAR]) + 100;
- return 0;
+ return rtc_valid_tm(tm);
}
/* Sets the given date and time to the real time clock. */
@@ -364,7 +366,7 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->time.tm_isdst = -1;
t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
- return 0;
+ return rtc_valid_tm((struct rtc_time *)t);
}
static struct rtc_class_ops m41t80_rtc_ops = {
@@ -806,21 +808,50 @@ static int m41t80_probe(struct i2c_client *client,
if (rc & M41T80_ALHOUR_HT) {
if (clientdata->features & M41T80_FEATURE_HT) {
- m41t80_get_datetime(client, &tm);
dev_info(&client->dev, "HT bit was set!\n");
- dev_info(&client->dev,
- "Power Down at "
- "%04i-%02i-%02i %02i:%02i:%02i\n",
- tm.tm_year + 1900,
- tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
- tm.tm_min, tm.tm_sec);
+
+ /* Show power down time only if it is valid */
+ if (m41t80_get_datetime(client, &tm) == 0) {
+ dev_info(&client->dev,
+ "Power Down at "
+ "%04i-%02i-%02i %02i:%02i:%02i\n",
+ tm.tm_year + 1900,
+ tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
+ tm.tm_min, tm.tm_sec);
+ }
}
+ /* Clear the HT bit */
if (i2c_smbus_write_byte_data(client,
M41T80_REG_ALARM_HOUR,
rc & ~M41T80_ALHOUR_HT) < 0)
goto ht_err;
}
+ /*
+ * check if RTC time is valid, if it is not valid, set it to known
+ * default. The check is done here to make sure HT bit is
+ * already checked and cleared before time is set.
+ */
+ if (m41t80_get_datetime(client, &tm) != 0) {
+ dev_err(&client->dev,
+ "Invalid date %04i-%02i-%02i %02i:%02i:%02i\n",
+ tm.tm_year + 1900,
+ tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
+ tm.tm_min, tm.tm_sec);
+
+ rtc_time_to_tm(M41T80_DEFAULT_TIME, &tm);
+
+ dev_err(&client->dev,
+ "Date defaulted to %04i-%02i-%02i %02i:%02i:%02i\n",
+ tm.tm_year + 1900,
+ tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
+ tm.tm_min, tm.tm_sec);
+
+ if (m41t80_set_datetime(client, &tm) != 0) {
+ goto exit;
+ }
+ }
+
/* Make sure ST (stop) bit is cleared */
rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
if (rc < 0)
From 57e07fc70021602ea02c0842817ba1a4e06c0ee7 Mon Sep 17 00:00:00 2001 From: Richard Retanubun <RichardRetanubun@RuggedCom.com> Date: Fri, 13 Aug 2010 14:45:16 -0400 Subject: [PATCH] rtc-m41t80: Check stored time validitiy during device probe. When the battery is gone on rtc-m41t80, data integrity is always in question. Check the validity of the returned date time. In addition, if the time is found to be invalid during device probe, initialize the date time to a sane default value. --- The checking validity during reads are already mainlined with commit b485fe5ea1008db02abff9ef15be4f31b52df4f7 My change simply adds a typecast to remove compiler warning for m41t80_rtc_read_alarm The valid time check during device probe is what I am proposing, what the default time should be is probably up for debate I made it a #def to make it easy to customize. drivers/rtc/rtc-m41t80.c | 49 +++++++++++++++++++++++++++++++++++++-------- 1 files changed, 40 insertions(+), 9 deletions(-) -- 1.7.1