diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-vr41xx.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index e9f9c5489468..af7596ef29e2 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -97,6 +97,7 @@ static DEFINE_SPINLOCK(rtc_lock); | |||
97 | static char rtc_name[] = "RTC"; | 97 | static char rtc_name[] = "RTC"; |
98 | static unsigned long periodic_frequency; | 98 | static unsigned long periodic_frequency; |
99 | static unsigned long periodic_count; | 99 | static unsigned long periodic_count; |
100 | static unsigned int alarm_enabled; | ||
100 | 101 | ||
101 | struct resource rtc_resource[2] = { | 102 | struct resource rtc_resource[2] = { |
102 | { .name = rtc_name, | 103 | { .name = rtc_name, |
@@ -188,6 +189,7 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
188 | low = rtc1_read(ECMPLREG); | 189 | low = rtc1_read(ECMPLREG); |
189 | mid = rtc1_read(ECMPMREG); | 190 | mid = rtc1_read(ECMPMREG); |
190 | high = rtc1_read(ECMPHREG); | 191 | high = rtc1_read(ECMPHREG); |
192 | wkalrm->enabled = alarm_enabled; | ||
191 | 193 | ||
192 | spin_unlock_irq(&rtc_lock); | 194 | spin_unlock_irq(&rtc_lock); |
193 | 195 | ||
@@ -206,10 +208,18 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) | |||
206 | 208 | ||
207 | spin_lock_irq(&rtc_lock); | 209 | spin_lock_irq(&rtc_lock); |
208 | 210 | ||
211 | if (alarm_enabled) | ||
212 | disable_irq(ELAPSEDTIME_IRQ); | ||
213 | |||
209 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); | 214 | rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); |
210 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); | 215 | rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); |
211 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); | 216 | rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); |
212 | 217 | ||
218 | if (wkalrm->enabled) | ||
219 | enable_irq(ELAPSEDTIME_IRQ); | ||
220 | |||
221 | alarm_enabled = wkalrm->enabled; | ||
222 | |||
213 | spin_unlock_irq(&rtc_lock); | 223 | spin_unlock_irq(&rtc_lock); |
214 | 224 | ||
215 | return 0; | 225 | return 0; |
@@ -221,10 +231,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long | |||
221 | 231 | ||
222 | switch (cmd) { | 232 | switch (cmd) { |
223 | case RTC_AIE_ON: | 233 | case RTC_AIE_ON: |
224 | enable_irq(ELAPSEDTIME_IRQ); | 234 | spin_lock_irq(&rtc_lock); |
235 | |||
236 | if (!alarm_enabled) { | ||
237 | enable_irq(ELAPSEDTIME_IRQ); | ||
238 | alarm_enabled = 1; | ||
239 | } | ||
240 | |||
241 | spin_unlock_irq(&rtc_lock); | ||
225 | break; | 242 | break; |
226 | case RTC_AIE_OFF: | 243 | case RTC_AIE_OFF: |
227 | disable_irq(ELAPSEDTIME_IRQ); | 244 | spin_lock_irq(&rtc_lock); |
245 | |||
246 | if (alarm_enabled) { | ||
247 | disable_irq(ELAPSEDTIME_IRQ); | ||
248 | alarm_enabled = 0; | ||
249 | } | ||
250 | |||
251 | spin_unlock_irq(&rtc_lock); | ||
228 | break; | 252 | break; |
229 | case RTC_PIE_ON: | 253 | case RTC_PIE_ON: |
230 | enable_irq(RTCLONG1_IRQ); | 254 | enable_irq(RTCLONG1_IRQ); |