diff options
author | Jiri Slaby | 2007-02-12 00:55:11 -0800 |
---|---|---|
committer | Linus Torvalds | 2007-02-12 09:48:42 -0800 |
commit | c4f28e54d61278203c2bb2aea0679e0a738235d2 (patch) | |
tree | d92cf0718084a4e659444741443ee38afb847836 /drivers/video/i810 | |
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/i810')
-rw-r--r-- | drivers/video/i810/i810.h | 3 | ||||
-rw-r--r-- | drivers/video/i810/i810_main.c | 25 |
2 files changed, 17 insertions, 11 deletions
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h index 579195c2bea3..aa65ffce915b 100644 --- a/drivers/video/i810/i810.h +++ b/drivers/video/i810/i810.h @@ -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; diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index b55a12d95eb2..e343c0da9618 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c @@ -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) + + mutex_lock(&par->open_lock); + if (par->use_count == 0) { + mutex_unlock(&par->open_lock); return -EINVAL; + } - if (count == 1) { + 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) |