aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-dev.c
diff options
context:
space:
mode:
authorAlessandro Zummo <alessandro.zummo@towertech.it>2007-10-16 04:28:15 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:13 -0400
commitd691eb901e044065de10756ea78a5758d457c7fd (patch)
tree3b166f4d54bba5677a04b885d0da52c28db3a8a3 /drivers/rtc/rtc-dev.c
parent16a72c455a67bb23eed7292a31c6ba17729e78e6 (diff)
RTC: periodic irq fix
Add kernel/kernel and kernel/user locking for the periodic irq feature of the rtc class. PIE ioctls are also supported. Signed-off-by: Alessandro Zummo <a.zummo@towertech.it> Cc: David Brownell <david-b@pacbell.net> 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.c33
1 files changed, 11 insertions, 22 deletions
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 005fff3a3508..362400db2e8b 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -238,17 +238,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
238 break; 238 break;
239 } 239 }
240 240
241 /* avoid conflicting IRQ users */
242 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
243 spin_lock_irq(&rtc->irq_task_lock);
244 if (rtc->irq_task)
245 err = -EBUSY;
246 spin_unlock_irq(&rtc->irq_task_lock);
247
248 if (err < 0)
249 return err;
250 }
251
252 /* try the driver's ioctl interface */ 241 /* try the driver's ioctl interface */
253 if (ops->ioctl) { 242 if (ops->ioctl) {
254 err = ops->ioctl(rtc->dev.parent, cmd, arg); 243 err = ops->ioctl(rtc->dev.parent, cmd, arg);
@@ -338,18 +327,20 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
338 err = rtc_set_time(rtc, &tm); 327 err = rtc_set_time(rtc, &tm);
339 break; 328 break;
340 329
341 case RTC_IRQP_READ: 330 case RTC_PIE_ON:
342 if (ops->irq_set_freq) 331 err = rtc_irq_set_state(rtc, NULL, 1);
343 err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); 332 break;
344 else 333
345 err = -ENOTTY; 334 case RTC_PIE_OFF:
335 err = rtc_irq_set_state(rtc, NULL, 0);
346 break; 336 break;
347 337
348 case RTC_IRQP_SET: 338 case RTC_IRQP_SET:
349 if (ops->irq_set_freq) 339 err = rtc_irq_set_freq(rtc, NULL, arg);
350 err = rtc_irq_set_freq(rtc, rtc->irq_task, arg); 340 break;
351 else 341
352 err = -ENOTTY; 342 case RTC_IRQP_READ:
343 err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
353 break; 344 break;
354 345
355#if 0 346#if 0
@@ -449,8 +440,6 @@ void rtc_dev_prepare(struct rtc_device *rtc)
449 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); 440 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
450 441
451 mutex_init(&rtc->char_lock); 442 mutex_init(&rtc->char_lock);
452 spin_lock_init(&rtc->irq_lock);
453 init_waitqueue_head(&rtc->irq_queue);
454#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 443#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
455 INIT_WORK(&rtc->uie_task, rtc_uie_task); 444 INIT_WORK(&rtc->uie_task, rtc_uie_task);
456 setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); 445 setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);