Patchwork rtc-isl12022: set write enable and start the RTC already in probe function

login
register
mail settings
Submitter Roman Fietze
Date Jan. 10, 2011, 9:55 a.m.
Message ID <201101101055.44794.roman.fietze@telemotive.de>
Download mbox | patch
Permalink /patch/78109/
State New
Headers show

Comments

Roman Fietze - Jan. 10, 2011, 9:55 a.m.
Hello Alessandro, hello list members,

When using rtc-isl12022 with brand new boards and RTC chips we
detected the problem described in the patch. Any comments are welcome.


From 93bb2ee41aa65550163c61218e7ffee802fcda79 Mon Sep 17 00:00:00 2001
From: Roman Fietze <roman.fietze@telemotive.de>
Date: Mon, 10 Jan 2011 10:17:31 +0100
Subject: [PATCH] rtc-isl12022: set write enable and start the RTC already in probe function

This RTC chip is delivered by the manufacturer in the not running
state. Delaying the RTC initialization to the first set_datetime
function call, as it was done up to know, caused problems when the
kernels tries to read a stopped RTC multiple times to detect a seconds
boundary, when booting up a new board the very first time.

The solution is to move the initialization of the RTC to the driver's
probe function.

Signed-off-by: Roman Fietze <roman.fietze@telemotive.de>
---
 drivers/rtc/rtc-isl12022.c |   77 +++++++++++++++++++++----------------------
 1 files changed, 38 insertions(+), 39 deletions(-)

Patch

diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c
index ddbc797..834450f 100644
--- a/drivers/rtc/rtc-isl12022.c
+++ b/drivers/rtc/rtc-isl12022.c
@@ -16,7 +16,7 @@ 
 #include <linux/rtc.h>
 #include <linux/slab.h>
 
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
 
 /* ISL register offsets */
 #define ISL12022_REG_SC		0x00
@@ -157,7 +157,6 @@  static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm)
 
 static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 {
-	struct isl12022 *isl12022 = i2c_get_clientdata(client);
 	size_t i;
 	int ret;
 	uint8_t buf[ISL12022_REG_DW + 1];
@@ -168,43 +167,6 @@  static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm)
 		tm->tm_sec, tm->tm_min, tm->tm_hour,
 		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
 
-	if (!isl12022->write_enabled) {
-
-		ret = isl12022_read_regs(client, ISL12022_REG_INT, buf, 1);
-		if (ret)
-			return ret;
-
-		/* Check if WRTC (write rtc enable) is set factory default is
-		 * 0 (not set) */
-		if (!(buf[0] & ISL12022_INT_WRTC)) {
-			dev_info(&client->dev,
-				 "init write enable and 24 hour format\n");
-
-			/* Set the write enable bit. */
-			ret = isl12022_write_reg(client,
-						 ISL12022_REG_INT,
-						 buf[0] | ISL12022_INT_WRTC);
-			if (ret)
-				return ret;
-
-			/* Write to any RTC register to start RTC, we use the
-			 * HR register, setting the MIL bit to use the 24 hour
-			 * format. */
-			ret = isl12022_read_regs(client, ISL12022_REG_HR,
-						 buf, 1);
-			if (ret)
-				return ret;
-
-			ret = isl12022_write_reg(client,
-						 ISL12022_REG_HR,
-						 buf[0] | ISL12022_HR_MIL);
-			if (ret)
-				return ret;
-		}
-
-		isl12022->write_enabled = 1;
-	}
-
 	/* hours, minutes and seconds */
 	buf[ISL12022_REG_SC] = bin2bcd(tm->tm_sec);
 	buf[ISL12022_REG_MN] = bin2bcd(tm->tm_min);
@@ -250,6 +212,7 @@  static int isl12022_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 {
 	struct isl12022 *isl12022;
+	uint8_t buf[ISL12022_REG_DW + 1];
 
 	int ret = 0;
 
@@ -274,6 +237,42 @@  static int isl12022_probe(struct i2c_client *client,
 		goto exit_kfree;
 	}
 
+	if (!isl12022->write_enabled) {
+
+		ret = isl12022_read_regs(client, ISL12022_REG_INT, buf, 1);
+		if (ret)
+			return ret;
+
+		/* Check if WRTC (write rtc enable) is set, factory default is
+		 * 0 (not set) */
+		if (!(buf[0] & ISL12022_INT_WRTC)) {
+			dev_info(&client->dev,
+				 "init write enable and 24 hour format\n");
+
+			/* Set the write enable bit. */
+			ret = isl12022_write_reg(client,
+						 ISL12022_REG_INT,
+						 buf[0] | ISL12022_INT_WRTC);
+			if (ret)
+				return ret;
+
+			/* Write to any RTC register to start RTC, we use the
+			 * HR register, setting the MIL bit to use the 24 hour
+			 * format. */
+			ret = isl12022_read_regs(client, ISL12022_REG_HR,
+						 buf, 1);
+			if (ret)
+				return ret;
+			ret = isl12022_write_reg(client,
+						 ISL12022_REG_HR,
+						 buf[0] | ISL12022_HR_MIL);
+			if (ret)
+				return ret;
+		}
+
+		isl12022->write_enabled = 1;
+	}
+
 	return 0;
 
 exit_kfree: