[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>
This commit is contained in:
Jiri Slaby
2007-02-12 00:55:11 -08:00
committed by Linus Torvalds
parent 52e7c922f3
commit c4f28e54d6
7 changed files with 63 additions and 36 deletions
+2 -1
View File
@@ -264,7 +264,8 @@ struct i810fb_par {
struct heap_data cursor_heap;
struct vgastate state;
struct i810fb_i2c_chan chan[3];
atomic_t use_count;
struct mutex open_lock;
unsigned int use_count;
u32 pseudo_palette[17];
unsigned long mmio_start_phys;
u8 __iomem *mmio_start_virtual;
+16 -11
View File
@@ -1235,9 +1235,9 @@ static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue,
static int i810fb_open(struct fb_info *info, int user)
{
struct i810fb_par *par = info->par;
u32 count = atomic_read(&par->use_count);
if (count == 0) {
mutex_lock(&par->open_lock);
if (par->use_count == 0) {
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_CMAP;
par->state.vgabase = par->mmio_start_virtual;
@@ -1246,7 +1246,8 @@ static int i810fb_open(struct fb_info *info, int user)
i810_save_vga_state(par);
}
atomic_inc(&par->use_count);
par->use_count++;
mutex_unlock(&par->open_lock);
return 0;
}
@@ -1254,18 +1255,20 @@ static int i810fb_open(struct fb_info *info, int user)
static int i810fb_release(struct fb_info *info, int user)
{
struct i810fb_par *par = info->par;
u32 count;
count = atomic_read(&par->use_count);
if (count == 0)
return -EINVAL;
if (count == 1) {
mutex_lock(&par->open_lock);
if (par->use_count == 0) {
mutex_unlock(&par->open_lock);
return -EINVAL;
}
if (par->use_count == 1) {
i810_restore_vga_state(par);
restore_vga(&par->state);
}
atomic_dec(&par->use_count);
par->use_count--;
mutex_unlock(&par->open_lock);
return 0;
}
@@ -1752,6 +1755,8 @@ static void __devinit i810_init_monspecs(struct fb_info *info)
static void __devinit i810_init_defaults(struct i810fb_par *par,
struct fb_info *info)
{
mutex_init(&par->open_lock);
if (voffset)
v_offset_default = voffset;
else if (par->aperture.size > 32 * 1024 * 1024)