From c4f28e54d61278203c2bb2aea0679e0a738235d2 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 12 Feb 2007 00:55:11 -0800 Subject: [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 Acked-by: Denis Oliver Kropp Cc: James Simmons Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/vga16fb.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers/video/vga16fb.c') diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index 6aff63d5b29..ec4c7dc54a6 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -70,7 +70,8 @@ struct vga16fb_par { unsigned char ClockingMode; /* Seq-Controller:01h */ } vga_state; struct vgastate state; - atomic_t ref_count; + struct mutex open_lock; + unsigned int ref_count; int palette_blanked, vesa_blanked, mode, isVGA; u8 misc, pel_msk, vss, clkdiv; u8 crtc[VGA_CRT_C]; @@ -300,28 +301,33 @@ static void vga16fb_clock_chip(struct vga16fb_par *par, static int vga16fb_open(struct fb_info *info, int user) { struct vga16fb_par *par = info->par; - int cnt = atomic_read(&par->ref_count); - if (!cnt) { + mutex_lock(&par->open_lock); + if (!par->ref_count) { memset(&par->state, 0, sizeof(struct vgastate)); par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE | VGA_SAVE_CMAP; save_vga(&par->state); } - atomic_inc(&par->ref_count); + par->ref_count++; + mutex_unlock(&par->open_lock); + return 0; } static int vga16fb_release(struct fb_info *info, int user) { struct vga16fb_par *par = info->par; - int cnt = atomic_read(&par->ref_count); - if (!cnt) + mutex_lock(&par->open_lock); + if (!par->ref_count) { + mutex_unlock(&par->open_lock); return -EINVAL; - if (cnt == 1) + } + if (par->ref_count == 1) restore_vga(&par->state); - atomic_dec(&par->ref_count); + par->ref_count--; + mutex_unlock(&par->open_lock); return 0; } @@ -1357,6 +1363,7 @@ static int __init vga16fb_probe(struct platform_device *dev) printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base); par = info->par; + mutex_init(&par->open_lock); par->isVGA = ORIG_VIDEO_ISVGA; par->palette_blanked = 0; par->vesa_blanked = 0; -- cgit v1.2.3