summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@hauppauge.com>2010-07-06 19:24:19 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-21 01:17:13 -0200
commit761f6cf6425e8024b983ddfa905a4c0002718fbe (patch)
tree466f3f955b14c3647af49a5d8313d3a923d46633
parentd78148fba47c7c79f3d14db1abe29172b45ab9c8 (diff)
[media] cx231xx: fix race condition in DVB initialization
Fix case where analog calls come in while the DVB side of the board is still initializing. This patch is actually just an exact port of the same patch made by Mauro to em28xx in hg rev 14762. Signed-off-by: Devin Heitmueller <dheitmueller@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c13
-rw-r--r--drivers/media/video/cx231xx/cx231xx-dvb.c12
2 files changed, 12 insertions, 13 deletions
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index b75e9e7dd502..44f3c3e5e105 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -97,20 +97,17 @@ void cx231xx_add_into_devlist(struct cx231xx *dev)
};
static LIST_HEAD(cx231xx_extension_devlist);
-static DEFINE_MUTEX(cx231xx_extension_devlist_lock);
int cx231xx_register_extension(struct cx231xx_ops *ops)
{
struct cx231xx *dev = NULL;
mutex_lock(&cx231xx_devlist_mutex);
- mutex_lock(&cx231xx_extension_devlist_lock);
list_add_tail(&ops->next, &cx231xx_extension_devlist);
list_for_each_entry(dev, &cx231xx_devlist, devlist)
ops->init(dev);
printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name);
- mutex_unlock(&cx231xx_extension_devlist_lock);
mutex_unlock(&cx231xx_devlist_mutex);
return 0;
}
@@ -125,10 +122,8 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops)
ops->fini(dev);
- mutex_lock(&cx231xx_extension_devlist_lock);
printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name);
list_del(&ops->next);
- mutex_unlock(&cx231xx_extension_devlist_lock);
mutex_unlock(&cx231xx_devlist_mutex);
}
EXPORT_SYMBOL(cx231xx_unregister_extension);
@@ -137,28 +132,28 @@ void cx231xx_init_extension(struct cx231xx *dev)
{
struct cx231xx_ops *ops = NULL;
- mutex_lock(&cx231xx_extension_devlist_lock);
+ mutex_lock(&cx231xx_devlist_mutex);
if (!list_empty(&cx231xx_extension_devlist)) {
list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
if (ops->init)
ops->init(dev);
}
}
- mutex_unlock(&cx231xx_extension_devlist_lock);
+ mutex_unlock(&cx231xx_devlist_mutex);
}
void cx231xx_close_extension(struct cx231xx *dev)
{
struct cx231xx_ops *ops = NULL;
- mutex_lock(&cx231xx_extension_devlist_lock);
+ mutex_lock(&cx231xx_devlist_mutex);
if (!list_empty(&cx231xx_extension_devlist)) {
list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
if (ops->fini)
ops->fini(dev);
}
}
- mutex_unlock(&cx231xx_extension_devlist_lock);
+ mutex_unlock(&cx231xx_devlist_mutex);
}
/****************************************************************
diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c
index 3ff99e9f4a1f..2cc286208c3b 100644
--- a/drivers/media/video/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/video/cx231xx/cx231xx-dvb.c
@@ -565,6 +565,7 @@ static int dvb_init(struct cx231xx *dev)
dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
+ mutex_lock(&dev->lock);
cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
cx231xx_demod_reset(dev);
/* init frontend */
@@ -707,15 +708,18 @@ static int dvb_init(struct cx231xx *dev)
if (result < 0)
goto out_free;
- cx231xx_set_mode(dev, CX231XX_SUSPEND);
+
printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
- return 0;
-out_free:
+ret:
cx231xx_set_mode(dev, CX231XX_SUSPEND);
+ mutex_unlock(&dev->lock);
+ return result;
+
+out_free:
kfree(dvb);
dev->dvb = NULL;
- return result;
+ goto ret;
}
static int dvb_fini(struct cx231xx *dev)