aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/i810
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2007-02-12 03:55:11 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-12 12:48:42 -0500
commitc4f28e54d61278203c2bb2aea0679e0a738235d2 (patch)
treed92cf0718084a4e659444741443ee38afb847836 /drivers/video/i810
parent52e7c922f37907ab3cf3445b916fbbc53cbd6c75 (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.h3
-rw-r--r--drivers/video/i810/i810_main.c25
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 {
264 struct heap_data cursor_heap; 264 struct heap_data cursor_heap;
265 struct vgastate state; 265 struct vgastate state;
266 struct i810fb_i2c_chan chan[3]; 266 struct i810fb_i2c_chan chan[3];
267 atomic_t use_count; 267 struct mutex open_lock;
268 unsigned int use_count;
268 u32 pseudo_palette[17]; 269 u32 pseudo_palette[17];
269 unsigned long mmio_start_phys; 270 unsigned long mmio_start_phys;
270 u8 __iomem *mmio_start_virtual; 271 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,
1235static int i810fb_open(struct fb_info *info, int user) 1235static int i810fb_open(struct fb_info *info, int user)
1236{ 1236{
1237 struct i810fb_par *par = info->par; 1237 struct i810fb_par *par = info->par;
1238 u32 count = atomic_read(&par->use_count); 1238
1239 1239 mutex_lock(&par->open_lock);
1240 if (count == 0) { 1240 if (par->use_count == 0) {
1241 memset(&par->state, 0, sizeof(struct vgastate)); 1241 memset(&par->state, 0, sizeof(struct vgastate));
1242 par->state.flags = VGA_SAVE_CMAP; 1242 par->state.flags = VGA_SAVE_CMAP;
1243 par->state.vgabase = par->mmio_start_virtual; 1243 par->state.vgabase = par->mmio_start_virtual;
@@ -1246,7 +1246,8 @@ static int i810fb_open(struct fb_info *info, int user)
1246 i810_save_vga_state(par); 1246 i810_save_vga_state(par);
1247 } 1247 }
1248 1248
1249 atomic_inc(&par->use_count); 1249 par->use_count++;
1250 mutex_unlock(&par->open_lock);
1250 1251
1251 return 0; 1252 return 0;
1252} 1253}
@@ -1254,18 +1255,20 @@ static int i810fb_open(struct fb_info *info, int user)
1254static int i810fb_release(struct fb_info *info, int user) 1255static int i810fb_release(struct fb_info *info, int user)
1255{ 1256{
1256 struct i810fb_par *par = info->par; 1257 struct i810fb_par *par = info->par;
1257 u32 count; 1258
1258 1259 mutex_lock(&par->open_lock);
1259 count = atomic_read(&par->use_count); 1260 if (par->use_count == 0) {
1260 if (count == 0) 1261 mutex_unlock(&par->open_lock);
1261 return -EINVAL; 1262 return -EINVAL;
1263 }
1262 1264
1263 if (count == 1) { 1265 if (par->use_count == 1) {
1264 i810_restore_vga_state(par); 1266 i810_restore_vga_state(par);
1265 restore_vga(&par->state); 1267 restore_vga(&par->state);
1266 } 1268 }
1267 1269
1268 atomic_dec(&par->use_count); 1270 par->use_count--;
1271 mutex_unlock(&par->open_lock);
1269 1272
1270 return 0; 1273 return 0;
1271} 1274}
@@ -1752,6 +1755,8 @@ static void __devinit i810_init_monspecs(struct fb_info *info)
1752static void __devinit i810_init_defaults(struct i810fb_par *par, 1755static void __devinit i810_init_defaults(struct i810fb_par *par,
1753 struct fb_info *info) 1756 struct fb_info *info)
1754{ 1757{
1758 mutex_init(&par->open_lock);
1759
1755 if (voffset) 1760 if (voffset)
1756 v_offset_default = voffset; 1761 v_offset_default = voffset;
1757 else if (par->aperture.size > 32 * 1024 * 1024) 1762 else if (par->aperture.size > 32 * 1024 * 1024)