aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorArnaud Ebalard <arno@natisbad.org>2014-12-10 18:54:08 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 20:41:16 -0500
commit10df1e6787647f381a90689a5285555275f1a3a3 (patch)
treee6b6f545b69c5578e81207be99daca41c917bca6 /drivers/rtc
parentb5f4184d1439b6c5b36f54804b194f0b93a5b232 (diff)
drivers/rtc/rtc-isl12057.c: add proper handling of oscillator failure bit
As suggested by Uwe, instead of clearing oscillator failure bit unconditionally at driver load, this patch adds proper handling of the flag. The driver now returns -ENODATA when reading time from the device and oscillator failure bit is set. The flag is now cleared only when the a new time value is pushed to the device. Signed-off-by: Arnaud Ebalard <arno@natisbad.org> Reported-by: Uwe Kleine-König <uwe@kleine-koenig.org> Acked-by: Uwe Kleine-König <uwe@kleine-koenig.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Peter Huewe <peter.huewe@infineon.com> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: Thierry Reding <treding@nvidia.com> Cc: Mark Brown <broonie@kernel.org> Cc: Grant Likely <grant.likely@linaro.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-isl12057.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/drivers/rtc/rtc-isl12057.c b/drivers/rtc/rtc-isl12057.c
index b538fabfcfd3..fe562820a54a 100644
--- a/drivers/rtc/rtc-isl12057.c
+++ b/drivers/rtc/rtc-isl12057.c
@@ -164,17 +164,32 @@ static int isl12057_rtc_read_time(struct device *dev, struct rtc_time *tm)
164{ 164{
165 struct isl12057_rtc_data *data = dev_get_drvdata(dev); 165 struct isl12057_rtc_data *data = dev_get_drvdata(dev);
166 u8 regs[ISL12057_RTC_SEC_LEN]; 166 u8 regs[ISL12057_RTC_SEC_LEN];
167 unsigned int sr;
167 int ret; 168 int ret;
168 169
169 mutex_lock(&data->lock); 170 mutex_lock(&data->lock);
171 ret = regmap_read(data->regmap, ISL12057_REG_SR, &sr);
172 if (ret) {
173 dev_err(dev, "%s: unable to read oscillator status flag\n",
174 __func__);
175 goto out;
176 } else {
177 if (sr & ISL12057_REG_SR_OSF) {
178 ret = -ENODATA;
179 goto out;
180 }
181 }
182
170 ret = regmap_bulk_read(data->regmap, ISL12057_REG_RTC_SC, regs, 183 ret = regmap_bulk_read(data->regmap, ISL12057_REG_RTC_SC, regs,
171 ISL12057_RTC_SEC_LEN); 184 ISL12057_RTC_SEC_LEN);
185 if (ret)
186 dev_err(dev, "%s: unable to read RTC time\n", __func__);
187
188out:
172 mutex_unlock(&data->lock); 189 mutex_unlock(&data->lock);
173 190
174 if (ret) { 191 if (ret)
175 dev_err(dev, "%s: RTC read failed\n", __func__);
176 return ret; 192 return ret;
177 }
178 193
179 isl12057_rtc_regs_to_tm(tm, regs); 194 isl12057_rtc_regs_to_tm(tm, regs);
180 195
@@ -194,10 +209,22 @@ static int isl12057_rtc_set_time(struct device *dev, struct rtc_time *tm)
194 mutex_lock(&data->lock); 209 mutex_lock(&data->lock);
195 ret = regmap_bulk_write(data->regmap, ISL12057_REG_RTC_SC, regs, 210 ret = regmap_bulk_write(data->regmap, ISL12057_REG_RTC_SC, regs,
196 ISL12057_RTC_SEC_LEN); 211 ISL12057_RTC_SEC_LEN);
197 mutex_unlock(&data->lock); 212 if (ret) {
213 dev_err(dev, "%s: writing RTC time failed\n", __func__);
214 goto out;
215 }
198 216
199 if (ret) 217 /*
200 dev_err(dev, "%s: RTC write failed\n", __func__); 218 * Now that RTC time has been updated, let's clear oscillator
219 * failure flag, if needed.
220 */
221 ret = regmap_update_bits(data->regmap, ISL12057_REG_SR,
222 ISL12057_REG_SR_OSF, 0);
223 if (ret < 0)
224 dev_err(dev, "Unable to clear oscillator failure bit\n");
225
226out:
227 mutex_unlock(&data->lock);
201 228
202 return ret; 229 return ret;
203} 230}
@@ -219,14 +246,6 @@ static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap)
219 return ret; 246 return ret;
220 } 247 }
221 248
222 /* Clear oscillator failure bit if needed */
223 ret = regmap_update_bits(regmap, ISL12057_REG_SR,
224 ISL12057_REG_SR_OSF, 0);
225 if (ret < 0) {
226 dev_err(dev, "Unable to clear oscillator failure bit\n");
227 return ret;
228 }
229
230 /* Clear alarm bit if needed */ 249 /* Clear alarm bit if needed */
231 ret = regmap_update_bits(regmap, ISL12057_REG_SR, 250 ret = regmap_update_bits(regmap, ISL12057_REG_SR,
232 ISL12057_REG_SR_A1F, 0); 251 ISL12057_REG_SR_A1F, 0);