Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB: em28xx: fix locks during dvb init sequence

Serialize DVB initialization, to avoid it to happen while analog
initialization is still happening.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

+10 -13
+4 -9
drivers/media/video/em28xx/em28xx-core.c
··· 1178 1178 */ 1179 1179 1180 1180 static LIST_HEAD(em28xx_extension_devlist); 1181 - static DEFINE_MUTEX(em28xx_extension_devlist_lock); 1182 1181 1183 1182 int em28xx_register_extension(struct em28xx_ops *ops) 1184 1183 { 1185 1184 struct em28xx *dev = NULL; 1186 1185 1187 1186 mutex_lock(&em28xx_devlist_mutex); 1188 - mutex_lock(&em28xx_extension_devlist_lock); 1189 1187 list_add_tail(&ops->next, &em28xx_extension_devlist); 1190 1188 list_for_each_entry(dev, &em28xx_devlist, devlist) { 1191 1189 if (dev) 1192 1190 ops->init(dev); 1193 1191 } 1194 1192 printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); 1195 - mutex_unlock(&em28xx_extension_devlist_lock); 1196 1193 mutex_unlock(&em28xx_devlist_mutex); 1197 1194 return 0; 1198 1195 } ··· 1205 1208 ops->fini(dev); 1206 1209 } 1207 1210 1208 - mutex_lock(&em28xx_extension_devlist_lock); 1209 1211 printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); 1210 1212 list_del(&ops->next); 1211 - mutex_unlock(&em28xx_extension_devlist_lock); 1212 1213 mutex_unlock(&em28xx_devlist_mutex); 1213 1214 } 1214 1215 EXPORT_SYMBOL(em28xx_unregister_extension); ··· 1215 1220 { 1216 1221 struct em28xx_ops *ops = NULL; 1217 1222 1218 - mutex_lock(&em28xx_extension_devlist_lock); 1223 + mutex_lock(&em28xx_devlist_mutex); 1219 1224 if (!list_empty(&em28xx_extension_devlist)) { 1220 1225 list_for_each_entry(ops, &em28xx_extension_devlist, next) { 1221 1226 if (ops->init) 1222 1227 ops->init(dev); 1223 1228 } 1224 1229 } 1225 - mutex_unlock(&em28xx_extension_devlist_lock); 1230 + mutex_unlock(&em28xx_devlist_mutex); 1226 1231 } 1227 1232 1228 1233 void em28xx_close_extension(struct em28xx *dev) 1229 1234 { 1230 1235 struct em28xx_ops *ops = NULL; 1231 1236 1232 - mutex_lock(&em28xx_extension_devlist_lock); 1237 + mutex_lock(&em28xx_devlist_mutex); 1233 1238 if (!list_empty(&em28xx_extension_devlist)) { 1234 1239 list_for_each_entry(ops, &em28xx_extension_devlist, next) { 1235 1240 if (ops->fini) 1236 1241 ops->fini(dev); 1237 1242 } 1238 1243 } 1239 - mutex_unlock(&em28xx_extension_devlist_lock); 1244 + mutex_unlock(&em28xx_devlist_mutex); 1240 1245 }
+6 -4
drivers/media/video/em28xx/em28xx-dvb.c
··· 467 467 } 468 468 dev->dvb = dvb; 469 469 470 + mutex_lock(&dev->lock); 470 471 em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 471 472 /* init frontend */ 472 473 switch (dev->model) { ··· 591 590 if (result < 0) 592 591 goto out_free; 593 592 594 - em28xx_set_mode(dev, EM28XX_SUSPEND); 595 593 em28xx_info("Successfully loaded em28xx-dvb\n"); 596 - return 0; 594 + ret: 595 + em28xx_set_mode(dev, EM28XX_SUSPEND); 596 + mutex_unlock(&dev->lock); 597 + return result; 597 598 598 599 out_free: 599 - em28xx_set_mode(dev, EM28XX_SUSPEND); 600 600 kfree(dvb); 601 601 dev->dvb = NULL; 602 - return result; 602 + goto ret; 603 603 } 604 604 605 605 static int dvb_fini(struct em28xx *dev)