diff options
Diffstat (limited to 'drivers/rtc/interface.c')
| -rw-r--r-- | drivers/rtc/interface.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 925006d3310..cb2f0728fd7 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
| @@ -209,9 +209,8 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) | |||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | if (err) | 211 | if (err) |
| 212 | return err; | 212 | /* nothing */; |
| 213 | 213 | else if (!rtc->ops) | |
| 214 | if (!rtc->ops) | ||
| 215 | err = -ENODEV; | 214 | err = -ENODEV; |
| 216 | else if (!rtc->ops->alarm_irq_enable) | 215 | else if (!rtc->ops->alarm_irq_enable) |
| 217 | err = -EINVAL; | 216 | err = -EINVAL; |
| @@ -229,6 +228,12 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) | |||
| 229 | if (err) | 228 | if (err) |
| 230 | return err; | 229 | return err; |
| 231 | 230 | ||
| 231 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | ||
| 232 | if (enabled == 0 && rtc->uie_irq_active) { | ||
| 233 | mutex_unlock(&rtc->ops_lock); | ||
| 234 | return rtc_dev_update_irq_enable_emul(rtc, 0); | ||
| 235 | } | ||
| 236 | #endif | ||
| 232 | /* make sure we're changing state */ | 237 | /* make sure we're changing state */ |
| 233 | if (rtc->uie_rtctimer.enabled == enabled) | 238 | if (rtc->uie_rtctimer.enabled == enabled) |
| 234 | goto out; | 239 | goto out; |
| @@ -248,6 +253,16 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) | |||
| 248 | 253 | ||
| 249 | out: | 254 | out: |
| 250 | mutex_unlock(&rtc->ops_lock); | 255 | mutex_unlock(&rtc->ops_lock); |
| 256 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | ||
| 257 | /* | ||
| 258 | * Enable emulation if the driver did not provide | ||
| 259 | * the update_irq_enable function pointer or if returned | ||
| 260 | * -EINVAL to signal that it has been configured without | ||
| 261 | * interrupts or that are not available at the moment. | ||
| 262 | */ | ||
| 263 | if (err == -EINVAL) | ||
| 264 | err = rtc_dev_update_irq_enable_emul(rtc, enabled); | ||
| 265 | #endif | ||
| 251 | return err; | 266 | return err; |
| 252 | 267 | ||
| 253 | } | 268 | } |
| @@ -263,7 +278,7 @@ EXPORT_SYMBOL_GPL(rtc_update_irq_enable); | |||
| 263 | * | 278 | * |
| 264 | * Triggers the registered irq_task function callback. | 279 | * Triggers the registered irq_task function callback. |
| 265 | */ | 280 | */ |
| 266 | static void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) | 281 | void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) |
| 267 | { | 282 | { |
| 268 | unsigned long flags; | 283 | unsigned long flags; |
| 269 | 284 | ||
| @@ -464,6 +479,9 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) | |||
| 464 | int err = 0; | 479 | int err = 0; |
| 465 | unsigned long flags; | 480 | unsigned long flags; |
| 466 | 481 | ||
| 482 | if (freq <= 0) | ||
| 483 | return -EINVAL; | ||
| 484 | |||
| 467 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 485 | spin_lock_irqsave(&rtc->irq_task_lock, flags); |
| 468 | if (rtc->irq_task != NULL && task == NULL) | 486 | if (rtc->irq_task != NULL && task == NULL) |
| 469 | err = -EBUSY; | 487 | err = -EBUSY; |
