diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2007-11-28 19:22:03 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-29 12:24:54 -0500 |
| commit | 8853c202b4a91713dbfb4d9b6e1c87cc2aa12392 (patch) | |
| tree | a6c9621d3067eebc17c2ce53fa45e7513ee832a6 /drivers | |
| parent | 08b633070ad5fa17a837428a601c32cf3db6aafd (diff) | |
RTC: convert mutex to bitfield
RTC code is using mutex to assure exclusive access to /dev/rtc. This is
however wrong usage, as it leaves the mutex locked when returning into
userspace, which is unacceptable.
Convert rtc->char_lock into bit operation.
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Acked-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')
| -rw-r--r-- | drivers/rtc/interface.c | 4 | ||||
| -rw-r--r-- | drivers/rtc/rtc-dev.c | 12 |
2 files changed, 6 insertions, 10 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index de0da545c7a1..a4f56e95cf96 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
| @@ -293,7 +293,7 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) | |||
| 293 | return -EINVAL; | 293 | return -EINVAL; |
| 294 | 294 | ||
| 295 | /* Cannot register while the char dev is in use */ | 295 | /* Cannot register while the char dev is in use */ |
| 296 | if (!(mutex_trylock(&rtc->char_lock))) | 296 | if (test_and_set_bit(RTC_DEV_BUSY, &rtc->flags)) |
| 297 | return -EBUSY; | 297 | return -EBUSY; |
| 298 | 298 | ||
| 299 | spin_lock_irq(&rtc->irq_task_lock); | 299 | spin_lock_irq(&rtc->irq_task_lock); |
| @@ -303,7 +303,7 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) | |||
| 303 | } | 303 | } |
| 304 | spin_unlock_irq(&rtc->irq_task_lock); | 304 | spin_unlock_irq(&rtc->irq_task_lock); |
| 305 | 305 | ||
| 306 | mutex_unlock(&rtc->char_lock); | 306 | clear_bit(RTC_DEV_BUSY, &rtc->flags); |
| 307 | 307 | ||
| 308 | return retval; | 308 | return retval; |
| 309 | } | 309 | } |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 814583bd2fe7..ae1bf177d625 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) | |||
| 26 | struct rtc_device, char_dev); | 26 | struct rtc_device, char_dev); |
| 27 | const struct rtc_class_ops *ops = rtc->ops; | 27 | const struct rtc_class_ops *ops = rtc->ops; |
| 28 | 28 | ||
| 29 | /* We keep the lock as long as the device is in use | 29 | if (test_and_set_bit(RTC_DEV_BUSY, &rtc->flags)) |
| 30 | * and return immediately if busy | ||
| 31 | */ | ||
| 32 | if (!(mutex_trylock(&rtc->char_lock))) | ||
| 33 | return -EBUSY; | 30 | return -EBUSY; |
| 34 | 31 | ||
| 35 | file->private_data = rtc; | 32 | file->private_data = rtc; |
| @@ -43,8 +40,8 @@ static int rtc_dev_open(struct inode *inode, struct file *file) | |||
| 43 | return 0; | 40 | return 0; |
| 44 | } | 41 | } |
| 45 | 42 | ||
| 46 | /* something has gone wrong, release the lock */ | 43 | /* something has gone wrong */ |
| 47 | mutex_unlock(&rtc->char_lock); | 44 | clear_bit(RTC_DEV_BUSY, &rtc->flags); |
| 48 | return err; | 45 | return err; |
| 49 | } | 46 | } |
| 50 | 47 | ||
| @@ -405,7 +402,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file) | |||
| 405 | if (rtc->ops->release) | 402 | if (rtc->ops->release) |
| 406 | rtc->ops->release(rtc->dev.parent); | 403 | rtc->ops->release(rtc->dev.parent); |
| 407 | 404 | ||
| 408 | mutex_unlock(&rtc->char_lock); | 405 | clear_bit(RTC_DEV_BUSY, &rtc->flags); |
| 409 | return 0; | 406 | return 0; |
| 410 | } | 407 | } |
| 411 | 408 | ||
| @@ -440,7 +437,6 @@ void rtc_dev_prepare(struct rtc_device *rtc) | |||
| 440 | 437 | ||
| 441 | rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); | 438 | rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); |
| 442 | 439 | ||
| 443 | mutex_init(&rtc->char_lock); | ||
| 444 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | 440 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
| 445 | INIT_WORK(&rtc->uie_task, rtc_uie_task); | 441 | INIT_WORK(&rtc->uie_task, rtc_uie_task); |
| 446 | setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); | 442 | setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); |
