aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2016-03-06 10:27:53 -0500
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2016-03-14 12:08:38 -0400
commitfc1dcb0b39dbb10d3290f2fcd6e154670f699166 (patch)
treefc0252ddaa4eada3cb9150607bbddf80bfffa68d /drivers/rtc
parent95c60c1c8f51521e7f2174fd0fff4dae6d522b83 (diff)
rtc: ds3232: use rtc->ops_lock to protect alarm operations
ds3232->mutex is used to protect for alarm operations which need to access status and control registers. But we can use rtc->ops_lock instead. rtc->ops_lock is held when most of rtc_class_ops methods are called, so we only need to explicitly acquire it from irq handler in order to protect form concurrent accesses. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-ds3232.c25
1 files changed, 4 insertions, 21 deletions
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c
index 9857287215a9..7edc889729c5 100644
--- a/drivers/rtc/rtc-ds3232.c
+++ b/drivers/rtc/rtc-ds3232.c
@@ -52,11 +52,6 @@ struct ds3232 {
52 int irq; 52 int irq;
53 struct rtc_device *rtc; 53 struct rtc_device *rtc;
54 54
55 /* The mutex protects alarm operations, and prevents a race
56 * between the enable_irq() in the workqueue and the free_irq()
57 * in the remove function.
58 */
59 struct mutex mutex;
60 bool suspended; 55 bool suspended;
61}; 56};
62 57
@@ -187,8 +182,6 @@ static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
187 int ret; 182 int ret;
188 u8 buf[4]; 183 u8 buf[4];
189 184
190 mutex_lock(&ds3232->mutex);
191
192 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat); 185 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
193 if (ret) 186 if (ret)
194 goto out; 187 goto out;
@@ -215,7 +208,6 @@ static int ds3232_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
215 208
216 ret = 0; 209 ret = 0;
217out: 210out:
218 mutex_unlock(&ds3232->mutex);
219 return ret; 211 return ret;
220} 212}
221 213
@@ -233,8 +225,6 @@ static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
233 if (ds3232->irq <= 0) 225 if (ds3232->irq <= 0)
234 return -EINVAL; 226 return -EINVAL;
235 227
236 mutex_lock(&ds3232->mutex);
237
238 buf[0] = bin2bcd(alarm->time.tm_sec); 228 buf[0] = bin2bcd(alarm->time.tm_sec);
239 buf[1] = bin2bcd(alarm->time.tm_min); 229 buf[1] = bin2bcd(alarm->time.tm_min);
240 buf[2] = bin2bcd(alarm->time.tm_hour); 230 buf[2] = bin2bcd(alarm->time.tm_hour);
@@ -267,7 +257,6 @@ static int ds3232_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
267 ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control); 257 ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
268 } 258 }
269out: 259out:
270 mutex_unlock(&ds3232->mutex);
271 return ret; 260 return ret;
272} 261}
273 262
@@ -277,11 +266,9 @@ static int ds3232_update_alarm(struct device *dev, unsigned int enabled)
277 int control; 266 int control;
278 int ret; 267 int ret;
279 268
280 mutex_lock(&ds3232->mutex);
281
282 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control); 269 ret = regmap_read(ds3232->regmap, DS3232_REG_CR, &control);
283 if (ret) 270 if (ret)
284 goto unlock; 271 return ret;
285 272
286 if (enabled) 273 if (enabled)
287 /* enable alarm1 interrupt */ 274 /* enable alarm1 interrupt */
@@ -291,9 +278,6 @@ static int ds3232_update_alarm(struct device *dev, unsigned int enabled)
291 control &= ~(DS3232_REG_CR_A1IE); 278 control &= ~(DS3232_REG_CR_A1IE);
292 ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control); 279 ret = regmap_write(ds3232->regmap, DS3232_REG_CR, control);
293 280
294unlock:
295 mutex_unlock(&ds3232->mutex);
296
297 return ret; 281 return ret;
298} 282}
299 283
@@ -311,10 +295,11 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
311{ 295{
312 struct device *dev = dev_id; 296 struct device *dev = dev_id;
313 struct ds3232 *ds3232 = dev_get_drvdata(dev); 297 struct ds3232 *ds3232 = dev_get_drvdata(dev);
298 struct mutex *lock = &ds3232->rtc->ops_lock;
314 int ret; 299 int ret;
315 int stat, control; 300 int stat, control;
316 301
317 mutex_lock(&ds3232->mutex); 302 mutex_lock(lock);
318 303
319 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat); 304 ret = regmap_read(ds3232->regmap, DS3232_REG_SR, &stat);
320 if (ret) 305 if (ret)
@@ -352,7 +337,7 @@ static irqreturn_t ds3232_irq(int irq, void *dev_id)
352 } 337 }
353 338
354unlock: 339unlock:
355 mutex_unlock(&ds3232->mutex); 340 mutex_unlock(lock);
356 341
357 return IRQ_HANDLED; 342 return IRQ_HANDLED;
358} 343}
@@ -380,8 +365,6 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
380 ds3232->dev = dev; 365 ds3232->dev = dev;
381 dev_set_drvdata(dev, ds3232); 366 dev_set_drvdata(dev, ds3232);
382 367
383 mutex_init(&ds3232->mutex);
384
385 ret = ds3232_check_rtc_status(dev); 368 ret = ds3232_check_rtc_status(dev);
386 if (ret) 369 if (ret)
387 return ret; 370 return ret;