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