aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-dev.c')
-rw-r--r--drivers/rtc/rtc-dev.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index dcf5f86461f7..828b329e08e0 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -62,7 +62,9 @@ static void rtc_uie_task(struct work_struct *work)
62 int err; 62 int err;
63 63
64 err = rtc_read_time(&rtc->class_dev, &tm); 64 err = rtc_read_time(&rtc->class_dev, &tm);
65 spin_lock_irq(&rtc->irq_lock); 65
66 local_irq_disable();
67 spin_lock(&rtc->irq_lock);
66 if (rtc->stop_uie_polling || err) { 68 if (rtc->stop_uie_polling || err) {
67 rtc->uie_task_active = 0; 69 rtc->uie_task_active = 0;
68 } else if (rtc->oldsecs != tm.tm_sec) { 70 } else if (rtc->oldsecs != tm.tm_sec) {
@@ -75,11 +77,11 @@ static void rtc_uie_task(struct work_struct *work)
75 } else if (schedule_work(&rtc->uie_task) == 0) { 77 } else if (schedule_work(&rtc->uie_task) == 0) {
76 rtc->uie_task_active = 0; 78 rtc->uie_task_active = 0;
77 } 79 }
78 spin_unlock_irq(&rtc->irq_lock); 80 spin_unlock(&rtc->irq_lock);
79 if (num) 81 if (num)
80 rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); 82 rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF);
83 local_irq_enable();
81} 84}
82
83static void rtc_uie_timer(unsigned long data) 85static void rtc_uie_timer(unsigned long data)
84{ 86{
85 struct rtc_device *rtc = (struct rtc_device *)data; 87 struct rtc_device *rtc = (struct rtc_device *)data;
@@ -215,7 +217,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
215 struct rtc_wkalrm alarm; 217 struct rtc_wkalrm alarm;
216 void __user *uarg = (void __user *) arg; 218 void __user *uarg = (void __user *) arg;
217 219
218 /* check that the calles has appropriate permissions 220 /* check that the calling task has appropriate permissions
219 * for certain ioctls. doing this check here is useful 221 * for certain ioctls. doing this check here is useful
220 * to avoid duplicate code in each driver. 222 * to avoid duplicate code in each driver.
221 */ 223 */
@@ -239,10 +241,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
239 241
240 /* avoid conflicting IRQ users */ 242 /* avoid conflicting IRQ users */
241 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { 243 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
242 spin_lock(&rtc->irq_task_lock); 244 spin_lock_irq(&rtc->irq_task_lock);
243 if (rtc->irq_task) 245 if (rtc->irq_task)
244 err = -EBUSY; 246 err = -EBUSY;
245 spin_unlock(&rtc->irq_task_lock); 247 spin_unlock_irq(&rtc->irq_task_lock);
246 248
247 if (err < 0) 249 if (err < 0)
248 return err; 250 return err;
@@ -300,6 +302,17 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
300 302
301 err = rtc_set_time(class_dev, &tm); 303 err = rtc_set_time(class_dev, &tm);
302 break; 304 break;
305
306 case RTC_IRQP_READ:
307 if (ops->irq_set_freq)
308 err = put_user(rtc->irq_freq, (unsigned long *) arg);
309 break;
310
311 case RTC_IRQP_SET:
312 if (ops->irq_set_freq)
313 err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg);
314 break;
315
303#if 0 316#if 0
304 case RTC_EPOCH_SET: 317 case RTC_EPOCH_SET:
305#ifndef rtc_epoch 318#ifndef rtc_epoch