aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx231xx
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@hauppauge.com>2010-07-06 18:24:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:17:13 -0400
commit761f6cf6425e8024b983ddfa905a4c0002718fbe (patch)
tree466f3f955b14c3647af49a5d8313d3a923d46633 /drivers/media/video/cx231xx
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>
Diffstat (limited to 'drivers/media/video/cx231xx')
-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)
97}; 97};
98 98
99static LIST_HEAD(cx231xx_extension_devlist); 99static LIST_HEAD(cx231xx_extension_devlist);
100static DEFINE_MUTEX(cx231xx_extension_devlist_lock);
101 100
102int cx231xx_register_extension(struct cx231xx_ops *ops) 101int cx231xx_register_extension(struct cx231xx_ops *ops)
103{ 102{
104 struct cx231xx *dev = NULL; 103 struct cx231xx *dev = NULL;
105 104
106 mutex_lock(&cx231xx_devlist_mutex); 105 mutex_lock(&cx231xx_devlist_mutex);
107 mutex_lock(&cx231xx_extension_devlist_lock);
108 list_add_tail(&ops->next, &cx231xx_extension_devlist); 106 list_add_tail(&ops->next, &cx231xx_extension_devlist);
109 list_for_each_entry(dev, &cx231xx_devlist, devlist) 107 list_for_each_entry(dev, &cx231xx_devlist, devlist)
110 ops->init(dev); 108 ops->init(dev);
111 109
112 printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name); 110 printk(KERN_INFO DRIVER_NAME ": %s initialized\n", ops->name);
113 mutex_unlock(&cx231xx_extension_devlist_lock);
114 mutex_unlock(&cx231xx_devlist_mutex); 111 mutex_unlock(&cx231xx_devlist_mutex);
115 return 0; 112 return 0;
116} 113}
@@ -125,10 +122,8 @@ void cx231xx_unregister_extension(struct cx231xx_ops *ops)
125 ops->fini(dev); 122 ops->fini(dev);
126 123
127 124
128 mutex_lock(&cx231xx_extension_devlist_lock);
129 printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name); 125 printk(KERN_INFO DRIVER_NAME ": %s removed\n", ops->name);
130 list_del(&ops->next); 126 list_del(&ops->next);
131 mutex_unlock(&cx231xx_extension_devlist_lock);
132 mutex_unlock(&cx231xx_devlist_mutex); 127 mutex_unlock(&cx231xx_devlist_mutex);
133} 128}
134EXPORT_SYMBOL(cx231xx_unregister_extension); 129EXPORT_SYMBOL(cx231xx_unregister_extension);
@@ -137,28 +132,28 @@ void cx231xx_init_extension(struct cx231xx *dev)
137{ 132{
138 struct cx231xx_ops *ops = NULL; 133 struct cx231xx_ops *ops = NULL;
139 134
140 mutex_lock(&cx231xx_extension_devlist_lock); 135 mutex_lock(&cx231xx_devlist_mutex);
141 if (!list_empty(&cx231xx_extension_devlist)) { 136 if (!list_empty(&cx231xx_extension_devlist)) {
142 list_for_each_entry(ops, &cx231xx_extension_devlist, next) { 137 list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
143 if (ops->init) 138 if (ops->init)
144 ops->init(dev); 139 ops->init(dev);
145 } 140 }
146 } 141 }
147 mutex_unlock(&cx231xx_extension_devlist_lock); 142 mutex_unlock(&cx231xx_devlist_mutex);
148} 143}
149 144
150void cx231xx_close_extension(struct cx231xx *dev) 145void cx231xx_close_extension(struct cx231xx *dev)
151{ 146{
152 struct cx231xx_ops *ops = NULL; 147 struct cx231xx_ops *ops = NULL;
153 148
154 mutex_lock(&cx231xx_extension_devlist_lock); 149 mutex_lock(&cx231xx_devlist_mutex);
155 if (!list_empty(&cx231xx_extension_devlist)) { 150 if (!list_empty(&cx231xx_extension_devlist)) {
156 list_for_each_entry(ops, &cx231xx_extension_devlist, next) { 151 list_for_each_entry(ops, &cx231xx_extension_devlist, next) {
157 if (ops->fini) 152 if (ops->fini)
158 ops->fini(dev); 153 ops->fini(dev);
159 } 154 }
160 } 155 }
161 mutex_unlock(&cx231xx_extension_devlist_lock); 156 mutex_unlock(&cx231xx_devlist_mutex);
162} 157}
163 158
164/**************************************************************** 159/****************************************************************
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)
565 dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq; 565 dev->cx231xx_set_analog_freq = cx231xx_set_analog_freq;
566 dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner; 566 dev->cx231xx_reset_analog_tuner = cx231xx_reset_analog_tuner;
567 567
568 mutex_lock(&dev->lock);
568 cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE); 569 cx231xx_set_mode(dev, CX231XX_DIGITAL_MODE);
569 cx231xx_demod_reset(dev); 570 cx231xx_demod_reset(dev);
570 /* init frontend */ 571 /* init frontend */
@@ -707,15 +708,18 @@ static int dvb_init(struct cx231xx *dev)
707 if (result < 0) 708 if (result < 0)
708 goto out_free; 709 goto out_free;
709 710
710 cx231xx_set_mode(dev, CX231XX_SUSPEND); 711
711 printk(KERN_INFO "Successfully loaded cx231xx-dvb\n"); 712 printk(KERN_INFO "Successfully loaded cx231xx-dvb\n");
712 return 0;
713 713
714out_free: 714ret:
715 cx231xx_set_mode(dev, CX231XX_SUSPEND); 715 cx231xx_set_mode(dev, CX231XX_SUSPEND);
716 mutex_unlock(&dev->lock);
717 return result;
718
719out_free:
716 kfree(dvb); 720 kfree(dvb);
717 dev->dvb = NULL; 721 dev->dvb = NULL;
718 return result; 722 goto ret;
719} 723}
720 724
721static int dvb_fini(struct cx231xx *dev) 725static int dvb_fini(struct cx231xx *dev)