diff options
Diffstat (limited to 'drivers/rtc/rtc-dev.c')
| -rw-r--r-- | drivers/rtc/rtc-dev.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index ecdea44ae4e5..45152f4952d6 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
| @@ -92,10 +92,10 @@ static void rtc_uie_timer(unsigned long data) | |||
| 92 | spin_unlock_irqrestore(&rtc->irq_lock, flags); | 92 | spin_unlock_irqrestore(&rtc->irq_lock, flags); |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static void clear_uie(struct rtc_device *rtc) | 95 | static int clear_uie(struct rtc_device *rtc) |
| 96 | { | 96 | { |
| 97 | spin_lock_irq(&rtc->irq_lock); | 97 | spin_lock_irq(&rtc->irq_lock); |
| 98 | if (rtc->irq_active) { | 98 | if (rtc->uie_irq_active) { |
| 99 | rtc->stop_uie_polling = 1; | 99 | rtc->stop_uie_polling = 1; |
| 100 | if (rtc->uie_timer_active) { | 100 | if (rtc->uie_timer_active) { |
| 101 | spin_unlock_irq(&rtc->irq_lock); | 101 | spin_unlock_irq(&rtc->irq_lock); |
| @@ -108,9 +108,10 @@ static void clear_uie(struct rtc_device *rtc) | |||
| 108 | flush_scheduled_work(); | 108 | flush_scheduled_work(); |
| 109 | spin_lock_irq(&rtc->irq_lock); | 109 | spin_lock_irq(&rtc->irq_lock); |
| 110 | } | 110 | } |
| 111 | rtc->irq_active = 0; | 111 | rtc->uie_irq_active = 0; |
| 112 | } | 112 | } |
| 113 | spin_unlock_irq(&rtc->irq_lock); | 113 | spin_unlock_irq(&rtc->irq_lock); |
| 114 | return 0; | ||
| 114 | } | 115 | } |
| 115 | 116 | ||
| 116 | static int set_uie(struct rtc_device *rtc) | 117 | static int set_uie(struct rtc_device *rtc) |
| @@ -122,8 +123,8 @@ static int set_uie(struct rtc_device *rtc) | |||
| 122 | if (err) | 123 | if (err) |
| 123 | return err; | 124 | return err; |
| 124 | spin_lock_irq(&rtc->irq_lock); | 125 | spin_lock_irq(&rtc->irq_lock); |
| 125 | if (!rtc->irq_active) { | 126 | if (!rtc->uie_irq_active) { |
| 126 | rtc->irq_active = 1; | 127 | rtc->uie_irq_active = 1; |
| 127 | rtc->stop_uie_polling = 0; | 128 | rtc->stop_uie_polling = 0; |
| 128 | rtc->oldsecs = tm.tm_sec; | 129 | rtc->oldsecs = tm.tm_sec; |
| 129 | rtc->uie_task_active = 1; | 130 | rtc->uie_task_active = 1; |
| @@ -134,6 +135,16 @@ static int set_uie(struct rtc_device *rtc) | |||
| 134 | spin_unlock_irq(&rtc->irq_lock); | 135 | spin_unlock_irq(&rtc->irq_lock); |
| 135 | return 0; | 136 | return 0; |
| 136 | } | 137 | } |
| 138 | |||
| 139 | int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled) | ||
| 140 | { | ||
| 141 | if (enabled) | ||
| 142 | return set_uie(rtc); | ||
| 143 | else | ||
| 144 | return clear_uie(rtc); | ||
| 145 | } | ||
| 146 | EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul); | ||
| 147 | |||
| 137 | #endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ | 148 | #endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ |
| 138 | 149 | ||
| 139 | static ssize_t | 150 | static ssize_t |
| @@ -357,6 +368,22 @@ static long rtc_dev_ioctl(struct file *file, | |||
| 357 | err = rtc_irq_set_state(rtc, NULL, 0); | 368 | err = rtc_irq_set_state(rtc, NULL, 0); |
| 358 | break; | 369 | break; |
| 359 | 370 | ||
| 371 | case RTC_AIE_ON: | ||
| 372 | mutex_unlock(&rtc->ops_lock); | ||
| 373 | return rtc_alarm_irq_enable(rtc, 1); | ||
| 374 | |||
| 375 | case RTC_AIE_OFF: | ||
| 376 | mutex_unlock(&rtc->ops_lock); | ||
| 377 | return rtc_alarm_irq_enable(rtc, 0); | ||
| 378 | |||
| 379 | case RTC_UIE_ON: | ||
| 380 | mutex_unlock(&rtc->ops_lock); | ||
| 381 | return rtc_update_irq_enable(rtc, 1); | ||
| 382 | |||
| 383 | case RTC_UIE_OFF: | ||
| 384 | mutex_unlock(&rtc->ops_lock); | ||
| 385 | return rtc_update_irq_enable(rtc, 0); | ||
| 386 | |||
| 360 | case RTC_IRQP_SET: | 387 | case RTC_IRQP_SET: |
| 361 | err = rtc_irq_set_freq(rtc, NULL, arg); | 388 | err = rtc_irq_set_freq(rtc, NULL, arg); |
| 362 | break; | 389 | break; |
| @@ -401,17 +428,6 @@ static long rtc_dev_ioctl(struct file *file, | |||
| 401 | err = -EFAULT; | 428 | err = -EFAULT; |
| 402 | return err; | 429 | return err; |
| 403 | 430 | ||
| 404 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | ||
| 405 | case RTC_UIE_OFF: | ||
| 406 | mutex_unlock(&rtc->ops_lock); | ||
| 407 | clear_uie(rtc); | ||
| 408 | return 0; | ||
| 409 | |||
| 410 | case RTC_UIE_ON: | ||
| 411 | mutex_unlock(&rtc->ops_lock); | ||
| 412 | err = set_uie(rtc); | ||
| 413 | return err; | ||
| 414 | #endif | ||
| 415 | default: | 431 | default: |
| 416 | err = -ENOTTY; | 432 | err = -ENOTTY; |
| 417 | break; | 433 | break; |
| @@ -440,7 +456,10 @@ static int rtc_dev_release(struct inode *inode, struct file *file) | |||
| 440 | * Leave the alarm alone; it may be set to trigger a system wakeup | 456 | * Leave the alarm alone; it may be set to trigger a system wakeup |
| 441 | * later, or be used by kernel code, and is a one-shot event anyway. | 457 | * later, or be used by kernel code, and is a one-shot event anyway. |
| 442 | */ | 458 | */ |
| 459 | |||
| 460 | /* Keep ioctl until all drivers are converted */ | ||
| 443 | rtc_dev_ioctl(file, RTC_UIE_OFF, 0); | 461 | rtc_dev_ioctl(file, RTC_UIE_OFF, 0); |
| 462 | rtc_update_irq_enable(rtc, 0); | ||
| 444 | rtc_irq_set_state(rtc, NULL, 0); | 463 | rtc_irq_set_state(rtc, NULL, 0); |
| 445 | 464 | ||
| 446 | if (rtc->ops->release) | 465 | if (rtc->ops->release) |
