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/riva | |
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/riva')
-rw-r--r-- | drivers/video/riva/fbdev.c | 19 | ||||
-rw-r--r-- | drivers/video/riva/rivafb.h | 3 |
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) | |||
1101 | static int rivafb_open(struct fb_info *info, int user) | 1101 | static 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) | |||
1127 | static int rivafb_release(struct fb_info *info, int user) | 1128 | static 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; |