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/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 { | |||
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, | |||
1235 | static int i810fb_open(struct fb_info *info, int user) | 1235 | static 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) | |||
1254 | static int i810fb_release(struct fb_info *info, int user) | 1255 | static 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) | |||
1752 | static void __devinit i810_init_defaults(struct i810fb_par *par, | 1755 | static 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) |