diff options
| author | Alessandro Zummo <a.zummo@towertech.it> | 2009-01-04 12:00:54 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-04 13:33:20 -0800 | 
| commit | 099e657625e801adf82054c8050dde5aceb68452 (patch) | |
| tree | d6c28df68ab390fa237b8339c6081e4db380aa5f /drivers/rtc/rtc-dev.c | |
| parent | 54566b2c1594c2326a645a3551f9d989f7ba3c5e (diff) | |
| download | olio-linux-3.10-099e657625e801adf82054c8050dde5aceb68452.tar.xz olio-linux-3.10-099e657625e801adf82054c8050dde5aceb68452.zip  | |
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 ecdea44ae4e..45152f4952d 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)  	spin_unlock_irqrestore(&rtc->irq_lock, flags);  } -static void clear_uie(struct rtc_device *rtc) +static int clear_uie(struct rtc_device *rtc)  {  	spin_lock_irq(&rtc->irq_lock); -	if (rtc->irq_active) { +	if (rtc->uie_irq_active) {  		rtc->stop_uie_polling = 1;  		if (rtc->uie_timer_active) {  			spin_unlock_irq(&rtc->irq_lock); @@ -108,9 +108,10 @@ static void clear_uie(struct rtc_device *rtc)  			flush_scheduled_work();  			spin_lock_irq(&rtc->irq_lock);  		} -		rtc->irq_active = 0; +		rtc->uie_irq_active = 0;  	}  	spin_unlock_irq(&rtc->irq_lock); +	return 0;  }  static int set_uie(struct rtc_device *rtc) @@ -122,8 +123,8 @@ static int set_uie(struct rtc_device *rtc)  	if (err)  		return err;  	spin_lock_irq(&rtc->irq_lock); -	if (!rtc->irq_active) { -		rtc->irq_active = 1; +	if (!rtc->uie_irq_active) { +		rtc->uie_irq_active = 1;  		rtc->stop_uie_polling = 0;  		rtc->oldsecs = tm.tm_sec;  		rtc->uie_task_active = 1; @@ -134,6 +135,16 @@ static int set_uie(struct rtc_device *rtc)  	spin_unlock_irq(&rtc->irq_lock);  	return 0;  } + +int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled) +{ +	if (enabled) +		return set_uie(rtc); +	else +		return clear_uie(rtc); +} +EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul); +  #endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */  static ssize_t @@ -357,6 +368,22 @@ static long rtc_dev_ioctl(struct file *file,  		err = rtc_irq_set_state(rtc, NULL, 0);  		break; +	case RTC_AIE_ON: +		mutex_unlock(&rtc->ops_lock); +		return rtc_alarm_irq_enable(rtc, 1); + +	case RTC_AIE_OFF: +		mutex_unlock(&rtc->ops_lock); +		return rtc_alarm_irq_enable(rtc, 0); + +	case RTC_UIE_ON: +		mutex_unlock(&rtc->ops_lock); +		return rtc_update_irq_enable(rtc, 1); + +	case RTC_UIE_OFF: +		mutex_unlock(&rtc->ops_lock); +		return rtc_update_irq_enable(rtc, 0); +  	case RTC_IRQP_SET:  		err = rtc_irq_set_freq(rtc, NULL, arg);  		break; @@ -401,17 +428,6 @@ static long rtc_dev_ioctl(struct file *file,  			err = -EFAULT;  		return err; -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL -	case RTC_UIE_OFF: -		mutex_unlock(&rtc->ops_lock); -		clear_uie(rtc); -		return 0; - -	case RTC_UIE_ON: -		mutex_unlock(&rtc->ops_lock); -		err = set_uie(rtc); -		return err; -#endif  	default:  		err = -ENOTTY;  		break; @@ -440,7 +456,10 @@ static int rtc_dev_release(struct inode *inode, struct file *file)  	 * Leave the alarm alone; it may be set to trigger a system wakeup  	 * later, or be used by kernel code, and is a one-shot event anyway.  	 */ + +	/* Keep ioctl until all drivers are converted */  	rtc_dev_ioctl(file, RTC_UIE_OFF, 0); +	rtc_update_irq_enable(rtc, 0);  	rtc_irq_set_state(rtc, NULL, 0);  	if (rtc->ops->release)  |