Skip to content

Commit

Permalink
V4L/DVB: em28xx: fix locks during dvb init sequence
Browse files Browse the repository at this point in the history
Serialize DVB initialization, to avoid it to happen while analog
initialization is still happening.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Mauro Carvalho Chehab committed May 19, 2010
1 parent d922b8e commit 5013318
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 13 deletions.
13 changes: 4 additions & 9 deletions drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1178,21 +1178,18 @@ void em28xx_add_into_devlist(struct em28xx *dev)
*/

static LIST_HEAD(em28xx_extension_devlist);
static DEFINE_MUTEX(em28xx_extension_devlist_lock);

int em28xx_register_extension(struct em28xx_ops *ops)
{
struct em28xx *dev = NULL;

mutex_lock(&em28xx_devlist_mutex);
mutex_lock(&em28xx_extension_devlist_lock);
list_add_tail(&ops->next, &em28xx_extension_devlist);
list_for_each_entry(dev, &em28xx_devlist, devlist) {
if (dev)
ops->init(dev);
}
printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
mutex_unlock(&em28xx_extension_devlist_lock);
mutex_unlock(&em28xx_devlist_mutex);
return 0;
}
Expand All @@ -1208,10 +1205,8 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
ops->fini(dev);
}

mutex_lock(&em28xx_extension_devlist_lock);
printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
list_del(&ops->next);
mutex_unlock(&em28xx_extension_devlist_lock);
mutex_unlock(&em28xx_devlist_mutex);
}
EXPORT_SYMBOL(em28xx_unregister_extension);
Expand All @@ -1220,26 +1215,26 @@ void em28xx_init_extension(struct em28xx *dev)
{
struct em28xx_ops *ops = NULL;

mutex_lock(&em28xx_extension_devlist_lock);
mutex_lock(&em28xx_devlist_mutex);
if (!list_empty(&em28xx_extension_devlist)) {
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
if (ops->init)
ops->init(dev);
}
}
mutex_unlock(&em28xx_extension_devlist_lock);
mutex_unlock(&em28xx_devlist_mutex);
}

void em28xx_close_extension(struct em28xx *dev)
{
struct em28xx_ops *ops = NULL;

mutex_lock(&em28xx_extension_devlist_lock);
mutex_lock(&em28xx_devlist_mutex);
if (!list_empty(&em28xx_extension_devlist)) {
list_for_each_entry(ops, &em28xx_extension_devlist, next) {
if (ops->fini)
ops->fini(dev);
}
}
mutex_unlock(&em28xx_extension_devlist_lock);
mutex_unlock(&em28xx_devlist_mutex);
}
10 changes: 6 additions & 4 deletions drivers/media/video/em28xx/em28xx-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ static int dvb_init(struct em28xx *dev)
}
dev->dvb = dvb;

mutex_lock(&dev->lock);
em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
/* init frontend */
switch (dev->model) {
Expand Down Expand Up @@ -590,15 +591,16 @@ static int dvb_init(struct em28xx *dev)
if (result < 0)
goto out_free;

em28xx_set_mode(dev, EM28XX_SUSPEND);
em28xx_info("Successfully loaded em28xx-dvb\n");
return 0;
ret:
em28xx_set_mode(dev, EM28XX_SUSPEND);
mutex_unlock(&dev->lock);
return result;

out_free:
em28xx_set_mode(dev, EM28XX_SUSPEND);
kfree(dvb);
dev->dvb = NULL;
return result;
goto ret;
}

static int dvb_fini(struct em28xx *dev)
Expand Down

0 comments on commit 5013318

Please sign in to comment.