X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Frtc%2Frtc-dev.c;h=2011567005f99a55b5072b1b7600fc616a1bd5a7;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=61a58259c93fe04ed5a502435763a921f3d57cc5;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 61a58259c..201156700 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -48,93 +48,6 @@ static int rtc_dev_open(struct inode *inode, struct file *file) return err; } -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL -/* - * Routine to poll RTC seconds field for change as often as possible, - * after first RTC_UIE use timer to reduce polling - */ -static void rtc_uie_task(void *data) -{ - struct rtc_device *rtc = data; - struct rtc_time tm; - int num = 0; - int err; - - err = rtc_read_time(&rtc->class_dev, &tm); - spin_lock_irq(&rtc->irq_lock); - if (rtc->stop_uie_polling || err) { - rtc->uie_task_active = 0; - } else if (rtc->oldsecs != tm.tm_sec) { - num = (tm.tm_sec + 60 - rtc->oldsecs) % 60; - rtc->oldsecs = tm.tm_sec; - rtc->uie_timer.expires = jiffies + HZ - (HZ/10); - rtc->uie_timer_active = 1; - rtc->uie_task_active = 0; - add_timer(&rtc->uie_timer); - } else if (schedule_work(&rtc->uie_task) == 0) { - rtc->uie_task_active = 0; - } - spin_unlock_irq(&rtc->irq_lock); - if (num) - rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); -} - -static void rtc_uie_timer(unsigned long data) -{ - struct rtc_device *rtc = (struct rtc_device *)data; - unsigned long flags; - - spin_lock_irqsave(&rtc->irq_lock, flags); - rtc->uie_timer_active = 0; - rtc->uie_task_active = 1; - if ((schedule_work(&rtc->uie_task) == 0)) - rtc->uie_task_active = 0; - spin_unlock_irqrestore(&rtc->irq_lock, flags); -} - -static void clear_uie(struct rtc_device *rtc) -{ - spin_lock_irq(&rtc->irq_lock); - if (rtc->irq_active) { - rtc->stop_uie_polling = 1; - if (rtc->uie_timer_active) { - spin_unlock_irq(&rtc->irq_lock); - del_timer_sync(&rtc->uie_timer); - spin_lock_irq(&rtc->irq_lock); - rtc->uie_timer_active = 0; - } - if (rtc->uie_task_active) { - spin_unlock_irq(&rtc->irq_lock); - flush_scheduled_work(); - spin_lock_irq(&rtc->irq_lock); - } - rtc->irq_active = 0; - } - spin_unlock_irq(&rtc->irq_lock); -} - -static int set_uie(struct rtc_device *rtc) -{ - struct rtc_time tm; - int err; - - err = rtc_read_time(&rtc->class_dev, &tm); - if (err) - return err; - spin_lock_irq(&rtc->irq_lock); - if (!rtc->irq_active) { - rtc->irq_active = 1; - rtc->stop_uie_polling = 0; - rtc->oldsecs = tm.tm_sec; - rtc->uie_task_active = 1; - if (schedule_work(&rtc->uie_task) == 0) - rtc->uie_task_active = 0; - } - rtc->irq_data = 0; - spin_unlock_irq(&rtc->irq_lock); - return 0; -} -#endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ static ssize_t rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -214,28 +127,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, struct rtc_wkalrm alarm; void __user *uarg = (void __user *) arg; - /* check that the calles has appropriate permissions - * for certain ioctls. doing this check here is useful - * to avoid duplicate code in each driver. - */ - switch (cmd) { - case RTC_EPOCH_SET: - case RTC_SET_TIME: - if (!capable(CAP_SYS_TIME)) - return -EACCES; - break; - - case RTC_IRQP_SET: - if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) - return -EACCES; - break; - - case RTC_PIE_ON: - if (!capable(CAP_SYS_RESOURCE)) - return -EACCES; - break; - } - /* avoid conflicting IRQ users */ if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) { spin_lock(&rtc->irq_task_lock); @@ -294,6 +185,9 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, break; case RTC_SET_TIME: + if (!capable(CAP_SYS_TIME)) + return -EACCES; + if (copy_from_user(&tm, uarg, sizeof(tm))) return -EFAULT; @@ -309,6 +203,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, err = -EINVAL; break; } + if (!capable(CAP_SYS_TIME)) { + err = -EACCES; + break; + } rtc_epoch = arg; err = 0; #endif @@ -334,14 +232,6 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, return -EFAULT; break; -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - case RTC_UIE_OFF: - clear_uie(rtc); - return 0; - - case RTC_UIE_ON: - return set_uie(rtc); -#endif default: err = -ENOTTY; break; @@ -354,9 +244,6 @@ static int rtc_dev_release(struct inode *inode, struct file *file) { struct rtc_device *rtc = to_rtc_device(file->private_data); -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - clear_uie(rtc); -#endif if (rtc->ops->release) rtc->ops->release(rtc->class_dev.dev); @@ -397,10 +284,6 @@ static int rtc_dev_add_device(struct class_device *class_dev, mutex_init(&rtc->char_lock); spin_lock_init(&rtc->irq_lock); init_waitqueue_head(&rtc->irq_queue); -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - INIT_WORK(&rtc->uie_task, rtc_uie_task, rtc); - setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); -#endif cdev_init(&rtc->char_dev, &rtc_dev_fops); rtc->char_dev.owner = rtc->owner;