diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2016-03-06 10:27:49 -0500 |
---|---|---|
committer | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2016-03-14 12:08:36 -0400 |
commit | dfc2532b55a4989930d0d67cdf83da9ccb2a1b5b (patch) | |
tree | ddc9ef52096c2089f12a3a58451e0f8621a1d38d /drivers/rtc | |
parent | 080481f54ef621211d6c75a03dc652fb6ed04222 (diff) |
rtc: ds3232: fix read on /dev/rtc after RTC_AIE_ON
The rtctest (tools/testing/selftests/timers/rtctest.c) found that
reading ds3232 rtc device immediately return the value 0x20 (RTC_AF)
without waiting alarm interrupt.
This is because alarm_irq_enable() of ds3232 driver changes RTC_AF
flag in rtc->irq_data. So calling ioctl with RTC_AIE_ON generates
invalid value in rtc device.
The lower-level driver should not touch rtc->irq_data directly.
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 | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index ca43bfcbb846..6bf7848c1576 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c | |||
@@ -272,7 +272,7 @@ out: | |||
272 | return ret; | 272 | return ret; |
273 | } | 273 | } |
274 | 274 | ||
275 | static void ds3232_update_alarm(struct device *dev) | 275 | static void ds3232_update_alarm(struct device *dev, unsigned int enabled) |
276 | { | 276 | { |
277 | struct ds3232 *ds3232 = dev_get_drvdata(dev); | 277 | struct ds3232 *ds3232 = dev_get_drvdata(dev); |
278 | int control; | 278 | int control; |
@@ -302,7 +302,7 @@ static void ds3232_update_alarm(struct device *dev) | |||
302 | if (ret) | 302 | if (ret) |
303 | goto unlock; | 303 | goto unlock; |
304 | 304 | ||
305 | if (ds3232->rtc->irq_data & (RTC_AF | RTC_UF)) | 305 | if (enabled || (ds3232->rtc->irq_data & RTC_UF)) |
306 | /* enable alarm1 interrupt */ | 306 | /* enable alarm1 interrupt */ |
307 | control |= DS3232_REG_CR_A1IE; | 307 | control |= DS3232_REG_CR_A1IE; |
308 | else | 308 | else |
@@ -321,12 +321,8 @@ static int ds3232_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
321 | if (ds3232->irq <= 0) | 321 | if (ds3232->irq <= 0) |
322 | return -EINVAL; | 322 | return -EINVAL; |
323 | 323 | ||
324 | if (enabled) | 324 | ds3232_update_alarm(dev, enabled); |
325 | ds3232->rtc->irq_data |= RTC_AF; | ||
326 | else | ||
327 | ds3232->rtc->irq_data &= ~RTC_AF; | ||
328 | 325 | ||
329 | ds3232_update_alarm(dev); | ||
330 | return 0; | 326 | return 0; |
331 | } | 327 | } |
332 | 328 | ||