--- /dev/null
+From ecb4a353d3afd45b9bb30c85d03ee113a0589079 Mon Sep 17 00:00:00 2001
+From: Baruch Siach <baruch@tkos.co.il>
+Date: Wed, 5 Dec 2018 17:00:09 +0200
+Subject: rtc: pcf8523: don't return invalid date when battery is low
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Baruch Siach <baruch@tkos.co.il>
+
+commit ecb4a353d3afd45b9bb30c85d03ee113a0589079 upstream.
+
+The RTC_VL_READ ioctl reports the low battery condition. Still,
+pcf8523_rtc_read_time() happily returns invalid dates in this case.
+Check the battery health on pcf8523_rtc_read_time() to avoid that.
+
+Reported-by: Erik Čuk <erik.cuk@domel.com>
+Signed-off-by: Baruch Siach <baruch@tkos.co.il>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-pcf8523.c | 32 ++++++++++++++++++++++++--------
+ 1 file changed, 24 insertions(+), 8 deletions(-)
+
+--- a/drivers/rtc/rtc-pcf8523.c
++++ b/drivers/rtc/rtc-pcf8523.c
+@@ -82,6 +82,18 @@ static int pcf8523_write(struct i2c_clie
+ return 0;
+ }
+
++static int pcf8523_voltage_low(struct i2c_client *client)
++{
++ u8 value;
++ int err;
++
++ err = pcf8523_read(client, REG_CONTROL3, &value);
++ if (err < 0)
++ return err;
++
++ return !!(value & REG_CONTROL3_BLF);
++}
++
+ static int pcf8523_select_capacitance(struct i2c_client *client, bool high)
+ {
+ u8 value;
+@@ -164,6 +176,14 @@ static int pcf8523_rtc_read_time(struct
+ struct i2c_msg msgs[2];
+ int err;
+
++ err = pcf8523_voltage_low(client);
++ if (err < 0) {
++ return err;
++ } else if (err > 0) {
++ dev_err(dev, "low voltage detected, time is unreliable\n");
++ return -EINVAL;
++ }
++
+ msgs[0].addr = client->addr;
+ msgs[0].flags = 0;
+ msgs[0].len = 1;
+@@ -248,17 +268,13 @@ static int pcf8523_rtc_ioctl(struct devi
+ unsigned long arg)
+ {
+ struct i2c_client *client = to_i2c_client(dev);
+- u8 value;
+- int ret = 0, err;
++ int ret;
+
+ switch (cmd) {
+ case RTC_VL_READ:
+- err = pcf8523_read(client, REG_CONTROL3, &value);
+- if (err < 0)
+- return err;
+-
+- if (value & REG_CONTROL3_BLF)
+- ret = 1;
++ ret = pcf8523_voltage_low(client);
++ if (ret < 0)
++ return ret;
+
+ if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
+ return -EFAULT;