diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2016-03-06 10:27:53 -0500 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2016-03-14 12:08:38 -0400 |
commit | fc1dcb0b39dbb10d3290f2fcd6e154670f699166 (patch) | |
tree | fc0252ddaa4eada3cb9150607bbddf80bfffa68d /drivers/rtc | |
parent | 95c60c1c8f51521e7f2174fd0fff4dae6d522b83 (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.c | 25 |
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; |
217 | out: | 210 | out: |
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 | } |
269 | out: | 259 | out: |
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 | ||
294 | unlock: | ||
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 | ||
354 | unlock: | 339 | unlock: |
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; |