diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2015-10-02 11:17:19 +0200 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2015-11-08 14:12:27 +0100 |
commit | f97cfddc886bc8f9d4302447f8773239bed854c1 (patch) | |
tree | 7a616bc4375f23432347448790baa4a6ead0fdf3 /drivers/rtc/rtc-pcf2127.c | |
parent | 24417829936d82b03b156e0d036c3b8f25aa93fd (diff) | |
download | lwn-f97cfddc886bc8f9d4302447f8773239bed854c1.tar.gz lwn-f97cfddc886bc8f9d4302447f8773239bed854c1.zip |
rtc: pcf2127: fix reading uninitialized value on RTC_READ_VL ioctl
The flag reported on the RTC_READ_VL ioctl is only initialized when the
date is read out. So the voltage low value doesn't represent reality but
the status at the time the date was read (or 0 if the date was not read
yet).
Moreover when userspace requests a value via an ioctl there is no added
benefit to also make a prosa representation of this (and other) values
appear in the kernel log so remove the calls to dev_info and the driver
data members to track their state.
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc/rtc-pcf2127.c')
-rw-r--r-- | drivers/rtc/rtc-pcf2127.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index a26bae60826c..d83b2d8e3c2b 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -24,7 +24,10 @@ #define PCF2127_REG_CTRL1 (0x00) /* Control Register 1 */ #define PCF2127_REG_CTRL2 (0x01) /* Control Register 2 */ + #define PCF2127_REG_CTRL3 (0x02) /* Control Register 3 */ +#define PCF2127_REG_CTRL3_BLF BIT(2) + #define PCF2127_REG_SC (0x03) /* datetime */ #define PCF2127_REG_MN (0x04) #define PCF2127_REG_HR (0x05) @@ -39,8 +42,6 @@ static struct i2c_driver pcf2127_driver; struct pcf2127 { struct rtc_device *rtc; - int voltage_low; /* indicates if a low_voltage was detected */ - int oscillator_failed; /* OSF was detected and date is unreliable */ }; /* @@ -49,7 +50,6 @@ struct pcf2127 { */ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm) { - struct pcf2127 *pcf2127 = i2c_get_clientdata(client); unsigned char buf[10] = { PCF2127_REG_CTRL1 }; /* read registers */ @@ -59,18 +59,15 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm) return -EIO; } - if (buf[PCF2127_REG_CTRL3] & 0x04) { - pcf2127->voltage_low = 1; + if (buf[PCF2127_REG_CTRL3] & PCF2127_REG_CTRL3_BLF) dev_info(&client->dev, "low voltage detected, check/replace RTC battery.\n"); - } if (buf[PCF2127_REG_SC] & PCF2127_OSF) { /* * no need clear the flag here, * it will be cleared once the new date is saved */ - pcf2127->oscillator_failed = 1; dev_warn(&client->dev, "oscillator stop detected, date/time is not reliable\n"); return -EINVAL; @@ -107,7 +104,6 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm) static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm) { - struct pcf2127 *pcf2127 = i2c_get_clientdata(client); unsigned char buf[8]; int i = 0, err; @@ -141,9 +137,6 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm) return -EIO; } - /* clear OSF flag in client data */ - pcf2127->oscillator_failed = 0; - return 0; } @@ -151,17 +144,28 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm) static int pcf2127_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { - struct pcf2127 *pcf2127 = i2c_get_clientdata(to_i2c_client(dev)); + struct i2c_client *client = to_i2c_client(dev); + unsigned char buf = PCF2127_REG_CTRL3; + int touser; + int ret; switch (cmd) { case RTC_VL_READ: - if (pcf2127->voltage_low) - dev_info(dev, "low voltage detected, check/replace battery\n"); - if (pcf2127->oscillator_failed) - dev_info(dev, "oscillator stop detected, date/time is not reliable\n"); + ret = i2c_master_send(client, &buf, 1); + if (!ret) + ret = -EIO; + if (ret < 0) + return ret; + + ret = i2c_master_recv(client, &buf, 1); + if (!ret) + ret = -EIO; + if (ret < 0) + return ret; + + touser = buf & PCF2127_REG_CTRL3_BLF ? 1 : 0; - if (copy_to_user((void __user *)arg, &pcf2127->voltage_low, - sizeof(int))) + if (copy_to_user((void __user *)arg, &touser, sizeof(int))) return -EFAULT; return 0; default: |