diff options
author | Alessandro Zummo <a.zummo@towertech.it> | 2009-01-04 15:00:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-04 16:33:20 -0500 |
commit | 099e657625e801adf82054c8050dde5aceb68452 (patch) | |
tree | d6c28df68ab390fa237b8339c6081e4db380aa5f /drivers/rtc/rtc-dev.c | |
parent | 54566b2c1594c2326a645a3551f9d989f7ba3c5e (diff) |
rtc: add alarm/update irq interfaces
Add standard interfaces for alarm/update irqs enabling. Drivers are no
more required to implement equivalent ioctl code as rtc-dev will provide
it.
UIE emulation should now be handled correctly and will work even for those
RTC drivers who cannot be configured to do both UIE and AIE.
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: David Brownell <david-b@pacbell.net>
Cc: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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) |