diff mbox series

rtc: rs5c372: Fix read the time from RTC is illegal When reading time from an uninitialized RTC chip, The value may be illegal

Message ID 20210521024026.28472-1-qxj511mail@gmail.com
State Changes Requested
Headers show
Series rtc: rs5c372: Fix read the time from RTC is illegal When reading time from an uninitialized RTC chip, The value may be illegal | expand

Commit Message

qxj511mail@gmail.com May 21, 2021, 2:40 a.m. UTC
From: qiuxiaojin <qiuxiaojin@cvte.com>

Signed-off-by: qiuxiaojin <qiuxiaojin@cvte.com>
---
 drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

kernel test robot May 22, 2021, 5:22 p.m. UTC | #1
Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on abelloni/rtc-next]
[also build test ERROR on v5.13-rc2 next-20210521]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/qxj511mail-gmail-com/rtc-rs5c372-Fix-read-the-time-from-RTC-is-illegal-When-reading-time-from-an-uninitialized-RTC-chip-The-value-may-be-ille/20210522-202320
base:   https://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git rtc-next
config: x86_64-randconfig-s031-20210522 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-341-g8af24329-dirty
        # https://github.com/0day-ci/linux/commit/62c495535e38dc184558713e6c007071f50f516c
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review qxj511mail-gmail-com/rtc-rs5c372-Fix-read-the-time-from-RTC-is-illegal-When-reading-time-from-an-uninitialized-RTC-chip-The-value-may-be-ille/20210522-202320
        git checkout 62c495535e38dc184558713e6c007071f50f516c
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/rtc/rtc-rs5c372.c: In function 'rs5c372_rtc_read_time':
>> drivers/rtc/rtc-rs5c372.c:261:3: error: implicit declaration of function 'rs5c372_rtc_set_time'; did you mean 'rs5c372_rtc_read_time'? [-Werror=implicit-function-declaration]
     261 |   rs5c372_rtc_set_time(dev, tm);
         |   ^~~~~~~~~~~~~~~~~~~~
         |   rs5c372_rtc_read_time
   drivers/rtc/rtc-rs5c372.c: At top level:
>> drivers/rtc/rtc-rs5c372.c:273:12: error: static declaration of 'rs5c372_rtc_set_time' follows non-static declaration
     273 | static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm)
         |            ^~~~~~~~~~~~~~~~~~~~
   drivers/rtc/rtc-rs5c372.c:261:3: note: previous implicit declaration of 'rs5c372_rtc_set_time' was here
     261 |   rs5c372_rtc_set_time(dev, tm);
         |   ^~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +261 drivers/rtc/rtc-rs5c372.c

   208	
   209	static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
   210	{
   211		struct i2c_client *client = to_i2c_client(dev);
   212		struct rs5c372	*rs5c = i2c_get_clientdata(client);
   213		int		status = rs5c_get_regs(rs5c);
   214		unsigned char ctrl2 = rs5c->regs[RS5C_REG_CTRL2];
   215		int flags_utime = 0;
   216	
   217		if (status < 0)
   218			return status;
   219	
   220		switch (rs5c->type) {
   221		case rtc_r2025sd:
   222		case rtc_r2221tl:
   223			if ((rs5c->type == rtc_r2025sd && !(ctrl2 & R2x2x_CTRL2_XSTP)) ||
   224			    (rs5c->type == rtc_r2221tl &&  (ctrl2 & R2x2x_CTRL2_XSTP))) {
   225				dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n");
   226				return -EINVAL;
   227			}
   228			break;
   229		default:
   230			if (ctrl2 & RS5C_CTRL2_XSTP) {
   231				dev_warn(&client->dev, "rtc oscillator interruption detected. Please reset the rtc clock.\n");
   232				return -EINVAL;
   233			}
   234		}
   235	
   236		tm->tm_sec = bcd2bin(rs5c->regs[RS5C372_REG_SECS] & 0x7f);
   237		tm->tm_min = bcd2bin(rs5c->regs[RS5C372_REG_MINS] & 0x7f);
   238		tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]);
   239	
   240		tm->tm_wday = bcd2bin(rs5c->regs[RS5C372_REG_WDAY] & 0x07);
   241		tm->tm_mday = bcd2bin(rs5c->regs[RS5C372_REG_DAY] & 0x3f);
   242	
   243		if (tm->tm_mday < 1) {
   244			// The value read from the register may be zero, which is an illegal value
   245			flags_utime = flags_utime + 1;
   246			tm->tm_mday = 1;
   247		}
   248	
   249		/* tm->tm_mon is zero-based */
   250		tm->tm_mon = bcd2bin(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1;
   251	
   252		if (tm->tm_mon < 0) {
   253			flags_utime = flags_utime + 1;
   254			tm->tm_mon = 0;
   255		}
   256	
   257		/* year is 1900 + tm->tm_year */
   258		tm->tm_year = bcd2bin(rs5c->regs[RS5C372_REG_YEAR]) + 100;
   259	
   260		if (flags_utime > 0) {
 > 261			rs5c372_rtc_set_time(dev, tm);
   262		}
   263	
   264		dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
   265			"mday=%d, mon=%d, year=%d, wday=%d\n",
   266			__func__,
   267			tm->tm_sec, tm->tm_min, tm->tm_hour,
   268			tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
   269	
   270		return 0;
   271	}
   272	
 > 273	static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm)
   274	{
   275		struct i2c_client *client = to_i2c_client(dev);
   276		struct rs5c372	*rs5c = i2c_get_clientdata(client);
   277		unsigned char	buf[7];
   278		unsigned char	ctrl2;
   279		int		addr;
   280	
   281		dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d "
   282			"mday=%d, mon=%d, year=%d, wday=%d\n",
   283			__func__,
   284			tm->tm_sec, tm->tm_min, tm->tm_hour,
   285			tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
   286	
   287		addr   = RS5C_ADDR(RS5C372_REG_SECS);
   288		buf[0] = bin2bcd(tm->tm_sec);
   289		buf[1] = bin2bcd(tm->tm_min);
   290		buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour);
   291		buf[3] = bin2bcd(tm->tm_wday);
   292		buf[4] = bin2bcd(tm->tm_mday);
   293		buf[5] = bin2bcd(tm->tm_mon + 1);
   294		buf[6] = bin2bcd(tm->tm_year - 100);
   295	
   296		if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) {
   297			dev_dbg(&client->dev, "%s: write error in line %i\n",
   298				__func__, __LINE__);
   299			return -EIO;
   300		}
   301	
   302		addr = RS5C_ADDR(RS5C_REG_CTRL2);
   303		ctrl2 = i2c_smbus_read_byte_data(client, addr);
   304	
   305		/* clear rtc warning bits */
   306		switch (rs5c->type) {
   307		case rtc_r2025sd:
   308		case rtc_r2221tl:
   309			ctrl2 &= ~(R2x2x_CTRL2_VDET | R2x2x_CTRL2_PON);
   310			if (rs5c->type == rtc_r2025sd)
   311				ctrl2 |= R2x2x_CTRL2_XSTP;
   312			else
   313				ctrl2 &= ~R2x2x_CTRL2_XSTP;
   314			break;
   315		default:
   316			ctrl2 &= ~RS5C_CTRL2_XSTP;
   317			break;
   318		}
   319	
   320		if (i2c_smbus_write_byte_data(client, addr, ctrl2) < 0) {
   321			dev_dbg(&client->dev, "%s: write error in line %i\n",
   322				__func__, __LINE__);
   323			return -EIO;
   324		}
   325	
   326		return 0;
   327	}
   328	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 3bd6eaa0dcf6..39b123497807 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -212,6 +212,7 @@  static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	struct rs5c372	*rs5c = i2c_get_clientdata(client);
 	int		status = rs5c_get_regs(rs5c);
 	unsigned char ctrl2 = rs5c->regs[RS5C_REG_CTRL2];
+	int flags_utime = 0;
 
 	if (status < 0)
 		return status;
@@ -239,12 +240,27 @@  static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	tm->tm_wday = bcd2bin(rs5c->regs[RS5C372_REG_WDAY] & 0x07);
 	tm->tm_mday = bcd2bin(rs5c->regs[RS5C372_REG_DAY] & 0x3f);
 
+	if (tm->tm_mday < 1) {
+		// The value read from the register may be zero, which is an illegal value
+		flags_utime = flags_utime + 1;
+		tm->tm_mday = 1;
+	}
+
 	/* tm->tm_mon is zero-based */
 	tm->tm_mon = bcd2bin(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1;
 
+	if (tm->tm_mon < 0) {
+		flags_utime = flags_utime + 1;
+		tm->tm_mon = 0;
+	}
+
 	/* year is 1900 + tm->tm_year */
 	tm->tm_year = bcd2bin(rs5c->regs[RS5C372_REG_YEAR]) + 100;
 
+	if (flags_utime > 0) {
+		rs5c372_rtc_set_time(dev, tm);
+	}
+
 	dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
 		"mday=%d, mon=%d, year=%d, wday=%d\n",
 		__func__,