diff options
Diffstat (limited to 'drivers/rtc/rtc-dev.c')
-rw-r--r-- | drivers/rtc/rtc-dev.c | 25 |
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 | |||
83 | static void rtc_uie_timer(unsigned long data) | 85 | static 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 |