aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/riva
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/riva
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/riva')
-rw-r--r--drivers/video/riva/fbdev.c19
-rw-r--r--drivers/video/riva/rivafb.h3
2 files changed, 14 insertions, 8 deletions
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 1a13966b7d5b..7c19b5c2a541 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1101,10 +1101,10 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
1101static int rivafb_open(struct fb_info *info, int user) 1101static int rivafb_open(struct fb_info *info, int user)
1102{ 1102{
1103 struct riva_par *par = info->par; 1103 struct riva_par *par = info->par;
1104 int cnt = atomic_read(&par->ref_count);
1105 1104
1106 NVTRACE_ENTER(); 1105 NVTRACE_ENTER();
1107 if (!cnt) { 1106 mutex_lock(&par->open_lock);
1107 if (!par->ref_count) {
1108#ifdef CONFIG_X86 1108#ifdef CONFIG_X86
1109 memset(&par->state, 0, sizeof(struct vgastate)); 1109 memset(&par->state, 0, sizeof(struct vgastate));
1110 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS; 1110 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
@@ -1119,7 +1119,8 @@ static int rivafb_open(struct fb_info *info, int user)
1119 1119
1120 riva_save_state(par, &par->initial_state); 1120 riva_save_state(par, &par->initial_state);
1121 } 1121 }
1122 atomic_inc(&par->ref_count); 1122 par->ref_count++;
1123 mutex_unlock(&par->open_lock);
1123 NVTRACE_LEAVE(); 1124 NVTRACE_LEAVE();
1124 return 0; 1125 return 0;
1125} 1126}
@@ -1127,12 +1128,14 @@ static int rivafb_open(struct fb_info *info, int user)
1127static int rivafb_release(struct fb_info *info, int user) 1128static int rivafb_release(struct fb_info *info, int user)
1128{ 1129{
1129 struct riva_par *par = info->par; 1130 struct riva_par *par = info->par;
1130 int cnt = atomic_read(&par->ref_count);
1131 1131
1132 NVTRACE_ENTER(); 1132 NVTRACE_ENTER();
1133 if (!cnt) 1133 mutex_lock(&par->open_lock);
1134 if (!par->ref_count) {
1135 mutex_unlock(&par->open_lock);
1134 return -EINVAL; 1136 return -EINVAL;
1135 if (cnt == 1) { 1137 }
1138 if (par->ref_count == 1) {
1136 par->riva.LockUnlock(&par->riva, 0); 1139 par->riva.LockUnlock(&par->riva, 0);
1137 par->riva.LoadStateExt(&par->riva, &par->initial_state.ext); 1140 par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
1138 riva_load_state(par, &par->initial_state); 1141 riva_load_state(par, &par->initial_state);
@@ -1141,7 +1144,8 @@ static int rivafb_release(struct fb_info *info, int user)
1141#endif 1144#endif
1142 par->riva.LockUnlock(&par->riva, 1); 1145 par->riva.LockUnlock(&par->riva, 1);
1143 } 1146 }
1144 atomic_dec(&par->ref_count); 1147 par->ref_count--;
1148 mutex_unlock(&par->open_lock);
1145 NVTRACE_LEAVE(); 1149 NVTRACE_LEAVE();
1146 return 0; 1150 return 0;
1147} 1151}
@@ -1999,6 +2003,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
1999 goto err_disable_device; 2003 goto err_disable_device;
2000 } 2004 }
2001 2005
2006 mutex_init(&default_par->open_lock);
2002 default_par->riva.Architecture = riva_get_arch(pd); 2007 default_par->riva.Architecture = riva_get_arch(pd);
2003 2008
2004 default_par->Chipset = (pd->vendor << 16) | pd->device; 2009 default_par->Chipset = (pd->vendor << 16) | pd->device;
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
index 7fa13fc9c413..48ead6d72f24 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/riva/rivafb.h
@@ -53,7 +53,8 @@ struct riva_par {
53#ifdef CONFIG_X86 53#ifdef CONFIG_X86
54 struct vgastate state; 54 struct vgastate state;
55#endif 55#endif
56 atomic_t ref_count; 56 struct mutex open_lock;
57 unsigned int ref_count;
57 unsigned char *EDID; 58 unsigned char *EDID;
58 unsigned int Chipset; 59 unsigned int Chipset;
59 int forceCRTC; 60 int forceCRTC;