aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-pcf2127.c
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2015-10-02 05:17:19 -0400
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2015-11-08 08:12:27 -0500
commitf97cfddc886bc8f9d4302447f8773239bed854c1 (patch)
tree7a616bc4375f23432347448790baa4a6ead0fdf3 /drivers/rtc/rtc-pcf2127.c
parent24417829936d82b03b156e0d036c3b8f25aa93fd (diff)
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.c40
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 @@
24 24
25#define PCF2127_REG_CTRL1 (0x00) /* Control Register 1 */ 25#define PCF2127_REG_CTRL1 (0x00) /* Control Register 1 */
26#define PCF2127_REG_CTRL2 (0x01) /* Control Register 2 */ 26#define PCF2127_REG_CTRL2 (0x01) /* Control Register 2 */
27
27#define PCF2127_REG_CTRL3 (0x02) /* Control Register 3 */ 28#define PCF2127_REG_CTRL3 (0x02) /* Control Register 3 */
29#define PCF2127_REG_CTRL3_BLF BIT(2)
30
28#define PCF2127_REG_SC (0x03) /* datetime */ 31#define PCF2127_REG_SC (0x03) /* datetime */
29#define PCF2127_REG_MN (0x04) 32#define PCF2127_REG_MN (0x04)
30#define PCF2127_REG_HR (0x05) 33#define PCF2127_REG_HR (0x05)
@@ -39,8 +42,6 @@ static struct i2c_driver pcf2127_driver;
39 42
40struct pcf2127 { 43struct pcf2127 {
41 struct rtc_device *rtc; 44 struct rtc_device *rtc;
42 int voltage_low; /* indicates if a low_voltage was detected */
43 int oscillator_failed; /* OSF was detected and date is unreliable */
44}; 45};
45 46
46/* 47/*
@@ -49,7 +50,6 @@ struct pcf2127 {
49 */ 50 */
50static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm) 51static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm)
51{ 52{
52 struct pcf2127 *pcf2127 = i2c_get_clientdata(client);
53 unsigned char buf[10] = { PCF2127_REG_CTRL1 }; 53 unsigned char buf[10] = { PCF2127_REG_CTRL1 };
54 54
55 /* read registers */ 55 /* read registers */
@@ -59,18 +59,15 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm)
59 return -EIO; 59 return -EIO;
60 } 60 }
61 61
62 if (buf[PCF2127_REG_CTRL3] & 0x04) { 62 if (buf[PCF2127_REG_CTRL3] & PCF2127_REG_CTRL3_BLF)
63 pcf2127->voltage_low = 1;
64 dev_info(&client->dev, 63 dev_info(&client->dev,
65 "low voltage detected, check/replace RTC battery.\n"); 64 "low voltage detected, check/replace RTC battery.\n");
66 }
67 65
68 if (buf[PCF2127_REG_SC] & PCF2127_OSF) { 66 if (buf[PCF2127_REG_SC] & PCF2127_OSF) {
69 /* 67 /*
70 * no need clear the flag here, 68 * no need clear the flag here,
71 * it will be cleared once the new date is saved 69 * it will be cleared once the new date is saved
72 */ 70 */
73 pcf2127->oscillator_failed = 1;
74 dev_warn(&client->dev, 71 dev_warn(&client->dev,
75 "oscillator stop detected, date/time is not reliable\n"); 72 "oscillator stop detected, date/time is not reliable\n");
76 return -EINVAL; 73 return -EINVAL;
@@ -107,7 +104,6 @@ static int pcf2127_get_datetime(struct i2c_client *client, struct rtc_time *tm)
107 104
108static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm) 105static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)
109{ 106{
110 struct pcf2127 *pcf2127 = i2c_get_clientdata(client);
111 unsigned char buf[8]; 107 unsigned char buf[8];
112 int i = 0, err; 108 int i = 0, err;
113 109
@@ -141,9 +137,6 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)
141 return -EIO; 137 return -EIO;
142 } 138 }
143 139
144 /* clear OSF flag in client data */
145 pcf2127->oscillator_failed = 0;
146
147 return 0; 140 return 0;
148} 141}
149 142
@@ -151,17 +144,28 @@ static int pcf2127_set_datetime(struct i2c_client *client, struct rtc_time *tm)
151static int pcf2127_rtc_ioctl(struct device *dev, 144static int pcf2127_rtc_ioctl(struct device *dev,
152 unsigned int cmd, unsigned long arg) 145 unsigned int cmd, unsigned long arg)
153{ 146{
154 struct pcf2127 *pcf2127 = i2c_get_clientdata(to_i2c_client(dev)); 147 struct i2c_client *client = to_i2c_client(dev);
148 unsigned char buf = PCF2127_REG_CTRL3;
149 int touser;
150 int ret;
155 151
156 switch (cmd) { 152 switch (cmd) {
157 case RTC_VL_READ: 153 case RTC_VL_READ:
158 if (pcf2127->voltage_low) 154 ret = i2c_master_send(client, &buf, 1);
159 dev_info(dev, "low voltage detected, check/replace battery\n"); 155 if (!ret)
160 if (pcf2127->oscillator_failed) 156 ret = -EIO;
161 dev_info(dev, "oscillator stop detected, date/time is not reliable\n"); 157 if (ret < 0)
158 return ret;
159
160 ret = i2c_master_recv(client, &buf, 1);
161 if (!ret)
162 ret = -EIO;
163 if (ret < 0)
164 return ret;
165
166 touser = buf & PCF2127_REG_CTRL3_BLF ? 1 : 0;
162 167
163 if (copy_to_user((void __user *)arg, &pcf2127->voltage_low, 168 if (copy_to_user((void __user *)arg, &touser, sizeof(int)))
164 sizeof(int)))
165 return -EFAULT; 169 return -EFAULT;
166 return 0; 170 return 0;
167 default: 171 default: