X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Frtc%2Frtc-dev.c;h=90dfa0df747acb9314b4ed115c2eec0dee1eae0d;hb=450c622e9ff19888818d4e2c4d31adb97a5242b2;hp=362400db2e8b9c64d10a28716258040556efc406;hpb=d691eb901e044065de10756ea78a5758d457c7fd;p=linux-2.6 diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 362400db2e..90dfa0df74 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -26,10 +26,7 @@ static int rtc_dev_open(struct inode *inode, struct file *file) struct rtc_device, char_dev); const struct rtc_class_ops *ops = rtc->ops; - /* We keep the lock as long as the device is in use - * and return immediately if busy - */ - if (!(mutex_trylock(&rtc->char_lock))) + if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) return -EBUSY; file->private_data = rtc; @@ -43,8 +40,8 @@ static int rtc_dev_open(struct inode *inode, struct file *file) return 0; } - /* something has gone wrong, release the lock */ - mutex_unlock(&rtc->char_lock); + /* something has gone wrong */ + clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); return err; } @@ -142,7 +139,7 @@ static int set_uie(struct rtc_device *rtc) static ssize_t rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct rtc_device *rtc = to_rtc_device(file->private_data); + struct rtc_device *rtc = file->private_data; DECLARE_WAITQUEUE(wait, current); unsigned long data; @@ -196,7 +193,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) static unsigned int rtc_dev_poll(struct file *file, poll_table *wait) { - struct rtc_device *rtc = to_rtc_device(file->private_data); + struct rtc_device *rtc = file->private_data; unsigned long data; poll_wait(file, &rtc->irq_queue, wait); @@ -233,7 +230,8 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, break; case RTC_PIE_ON: - if (!capable(CAP_SYS_RESOURCE)) + if (rtc->irq_freq > rtc->max_user_freq && + !capable(CAP_SYS_RESOURCE)) return -EACCES; break; } @@ -248,6 +246,15 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, /* if the driver does not provide the ioctl interface * or if that particular ioctl was not implemented * (-ENOIOCTLCMD), we will try to emulate here. + * + * Drivers *SHOULD NOT* provide ioctl implementations + * for these requests. Instead, provide methods to + * support the following code, so that the RTC's main + * features are accessible without using ioctls. + * + * RTC and alarm times will be in UTC, by preference, + * but dual-booting with MS-Windows implies RTCs must + * use the local wall clock time. */ switch (cmd) { @@ -396,7 +403,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, static int rtc_dev_release(struct inode *inode, struct file *file) { - struct rtc_device *rtc = to_rtc_device(file->private_data); + struct rtc_device *rtc = file->private_data; #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL clear_uie(rtc); @@ -404,13 +411,13 @@ static int rtc_dev_release(struct inode *inode, struct file *file) if (rtc->ops->release) rtc->ops->release(rtc->dev.parent); - mutex_unlock(&rtc->char_lock); + clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); return 0; } static int rtc_dev_fasync(int fd, struct file *file, int on) { - struct rtc_device *rtc = to_rtc_device(file->private_data); + struct rtc_device *rtc = file->private_data; return fasync_helper(fd, file, on, &rtc->async_queue); } @@ -439,7 +446,6 @@ void rtc_dev_prepare(struct rtc_device *rtc) rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); - mutex_init(&rtc->char_lock); #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL INIT_WORK(&rtc->uie_task, rtc_uie_task); setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);