diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2007-02-12 03:55:11 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-12 12:48:42 -0500 |
commit | c4f28e54d61278203c2bb2aea0679e0a738235d2 (patch) | |
tree | d92cf0718084a4e659444741443ee38afb847836 /drivers/video/neofb.c | |
parent | 52e7c922f37907ab3cf3445b916fbbc53cbd6c75 (diff) |
[PATCH] Video: fb, add true ref_count atomicity
Some of fb drivers uses atomic_t in bad manner, since there are still some
race-prone gaps. Use mutexes to protect open/close code sections with
ref_count testing and finally use simple uint.
Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Acked-by: Denis Oliver Kropp <dok@directfb.org>
Cc: James Simmons <jsimmons@infradead.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/neofb.c')
-rw-r--r-- | drivers/video/neofb.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 459ca553ffc0..395ccedde9a6 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
@@ -556,14 +556,16 @@ static int | |||
556 | neofb_open(struct fb_info *info, int user) | 556 | neofb_open(struct fb_info *info, int user) |
557 | { | 557 | { |
558 | struct neofb_par *par = info->par; | 558 | struct neofb_par *par = info->par; |
559 | int cnt = atomic_read(&par->ref_count); | ||
560 | 559 | ||
561 | if (!cnt) { | 560 | mutex_lock(&par->open_lock); |
561 | if (!par->ref_count) { | ||
562 | memset(&par->state, 0, sizeof(struct vgastate)); | 562 | memset(&par->state, 0, sizeof(struct vgastate)); |
563 | par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS; | 563 | par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS; |
564 | save_vga(&par->state); | 564 | save_vga(&par->state); |
565 | } | 565 | } |
566 | atomic_inc(&par->ref_count); | 566 | par->ref_count++; |
567 | mutex_unlock(&par->open_lock); | ||
568 | |||
567 | return 0; | 569 | return 0; |
568 | } | 570 | } |
569 | 571 | ||
@@ -571,14 +573,18 @@ static int | |||
571 | neofb_release(struct fb_info *info, int user) | 573 | neofb_release(struct fb_info *info, int user) |
572 | { | 574 | { |
573 | struct neofb_par *par = info->par; | 575 | struct neofb_par *par = info->par; |
574 | int cnt = atomic_read(&par->ref_count); | ||
575 | 576 | ||
576 | if (!cnt) | 577 | mutex_lock(&par->open_lock); |
578 | if (!par->ref_count) { | ||
579 | mutex_unlock(&par->open_lock); | ||
577 | return -EINVAL; | 580 | return -EINVAL; |
578 | if (cnt == 1) { | 581 | } |
582 | if (par->ref_count == 1) { | ||
579 | restore_vga(&par->state); | 583 | restore_vga(&par->state); |
580 | } | 584 | } |
581 | atomic_dec(&par->ref_count); | 585 | par->ref_count--; |
586 | mutex_unlock(&par->open_lock); | ||
587 | |||
582 | return 0; | 588 | return 0; |
583 | } | 589 | } |
584 | 590 | ||
@@ -2047,6 +2053,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st | |||
2047 | 2053 | ||
2048 | info->fix.accel = id->driver_data; | 2054 | info->fix.accel = id->driver_data; |
2049 | 2055 | ||
2056 | mutex_init(&par->open_lock); | ||
2050 | par->pci_burst = !nopciburst; | 2057 | par->pci_burst = !nopciburst; |
2051 | par->lcd_stretch = !nostretch; | 2058 | par->lcd_stretch = !nostretch; |
2052 | par->libretto = libretto; | 2059 | par->libretto = libretto; |