aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-03 16:58:03 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-03 16:58:03 -0400
commitf744a0547ac5055a3e9eb20bfe7ff29077a32c16 (patch)
treea68d7403a072a2667183af0a5132466accb0eae1
parentdbc55faa64c12f4c9fab6e2bd131d771bc026ed1 (diff)
parent1fb4a17f6e47d86b25bfc4fd9df4301bca09c999 (diff)
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: V4L/DVB (5822): Fix the return value in ttpci_budget_init() V4L/DVB (5818): CinergyT2: fix flush_workqueue() vs work->func() deadlock V4L/DVB (5816): Cx88-blackbird: fix vidioc_g_tuner never ending list of tuners V4L/DVB (5808): Bttv: fix v4l1 breaking the driver
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c66
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c13
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c2
4 files changed, 49 insertions, 34 deletions
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 6aba5b39ed14..b40af48a2edb 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -118,6 +118,7 @@ struct cinergyt2 {
118 struct dvb_demux demux; 118 struct dvb_demux demux;
119 struct usb_device *udev; 119 struct usb_device *udev;
120 struct mutex sem; 120 struct mutex sem;
121 struct mutex wq_sem;
121 struct dvb_adapter adapter; 122 struct dvb_adapter adapter;
122 struct dvb_device *fedev; 123 struct dvb_device *fedev;
123 struct dmxdev dmxdev; 124 struct dmxdev dmxdev;
@@ -482,14 +483,14 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
482 struct cinergyt2 *cinergyt2 = dvbdev->priv; 483 struct cinergyt2 *cinergyt2 = dvbdev->priv;
483 int err = -ERESTARTSYS; 484 int err = -ERESTARTSYS;
484 485
485 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) 486 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
486 return -ERESTARTSYS; 487 goto out;
487 488
488 if ((err = dvb_generic_open(inode, file))) { 489 if (mutex_lock_interruptible(&cinergyt2->sem))
489 mutex_unlock(&cinergyt2->sem); 490 goto out_unlock1;
490 return err;
491 }
492 491
492 if ((err = dvb_generic_open(inode, file)))
493 goto out_unlock2;
493 494
494 if ((file->f_flags & O_ACCMODE) != O_RDONLY) { 495 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
495 cinergyt2_sleep(cinergyt2, 0); 496 cinergyt2_sleep(cinergyt2, 0);
@@ -498,8 +499,12 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
498 499
499 atomic_inc(&cinergyt2->inuse); 500 atomic_inc(&cinergyt2->inuse);
500 501
502out_unlock2:
501 mutex_unlock(&cinergyt2->sem); 503 mutex_unlock(&cinergyt2->sem);
502 return 0; 504out_unlock1:
505 mutex_unlock(&cinergyt2->wq_sem);
506out:
507 return err;
503} 508}
504 509
505static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) 510static void cinergyt2_unregister(struct cinergyt2 *cinergyt2)
@@ -519,15 +524,17 @@ static int cinergyt2_release (struct inode *inode, struct file *file)
519 struct dvb_device *dvbdev = file->private_data; 524 struct dvb_device *dvbdev = file->private_data;
520 struct cinergyt2 *cinergyt2 = dvbdev->priv; 525 struct cinergyt2 *cinergyt2 = dvbdev->priv;
521 526
522 mutex_lock(&cinergyt2->sem); 527 mutex_lock(&cinergyt2->wq_sem);
523 528
524 if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { 529 if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) {
525 cancel_delayed_work(&cinergyt2->query_work); 530 cancel_rearming_delayed_work(&cinergyt2->query_work);
526 flush_scheduled_work(); 531
532 mutex_lock(&cinergyt2->sem);
527 cinergyt2_sleep(cinergyt2, 1); 533 cinergyt2_sleep(cinergyt2, 1);
534 mutex_unlock(&cinergyt2->sem);
528 } 535 }
529 536
530 mutex_unlock(&cinergyt2->sem); 537 mutex_unlock(&cinergyt2->wq_sem);
531 538
532 if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { 539 if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) {
533 warn("delayed unregister in release"); 540 warn("delayed unregister in release");
@@ -838,13 +845,13 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
838 845
839static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) 846static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
840{ 847{
841 cancel_delayed_work(&cinergyt2->rc_query_work); 848 cancel_rearming_delayed_work(&cinergyt2->rc_query_work);
842 input_unregister_device(cinergyt2->rc_input_dev); 849 input_unregister_device(cinergyt2->rc_input_dev);
843} 850}
844 851
845static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) 852static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2)
846{ 853{
847 cancel_delayed_work(&cinergyt2->rc_query_work); 854 cancel_rearming_delayed_work(&cinergyt2->rc_query_work);
848} 855}
849 856
850static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) 857static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2)
@@ -907,6 +914,7 @@ static int cinergyt2_probe (struct usb_interface *intf,
907 usb_set_intfdata (intf, (void *) cinergyt2); 914 usb_set_intfdata (intf, (void *) cinergyt2);
908 915
909 mutex_init(&cinergyt2->sem); 916 mutex_init(&cinergyt2->sem);
917 mutex_init(&cinergyt2->wq_sem);
910 init_waitqueue_head (&cinergyt2->poll_wq); 918 init_waitqueue_head (&cinergyt2->poll_wq);
911 INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query); 919 INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query);
912 920
@@ -974,11 +982,8 @@ static void cinergyt2_disconnect (struct usb_interface *intf)
974{ 982{
975 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); 983 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
976 984
977 flush_scheduled_work();
978
979 cinergyt2_unregister_rc(cinergyt2); 985 cinergyt2_unregister_rc(cinergyt2);
980 986 cancel_rearming_delayed_work(&cinergyt2->query_work);
981 cancel_delayed_work(&cinergyt2->query_work);
982 wake_up_interruptible(&cinergyt2->poll_wq); 987 wake_up_interruptible(&cinergyt2->poll_wq);
983 988
984 cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); 989 cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
@@ -992,21 +997,21 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
992{ 997{
993 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); 998 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
994 999
995 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) 1000 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
996 return -ERESTARTSYS; 1001 return -ERESTARTSYS;
997 1002
998 if (1) { 1003 if (1) {
999 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
1000
1001 cinergyt2_suspend_rc(cinergyt2); 1004 cinergyt2_suspend_rc(cinergyt2);
1002 cancel_delayed_work(&cinergyt2->query_work); 1005 cancel_rearming_delayed_work(&cinergyt2->query_work);
1006
1007 mutex_lock(&cinergyt2->sem);
1003 if (cinergyt2->streaming) 1008 if (cinergyt2->streaming)
1004 cinergyt2_stop_stream_xfer(cinergyt2); 1009 cinergyt2_stop_stream_xfer(cinergyt2);
1005 flush_scheduled_work();
1006 cinergyt2_sleep(cinergyt2, 1); 1010 cinergyt2_sleep(cinergyt2, 1);
1011 mutex_unlock(&cinergyt2->sem);
1007 } 1012 }
1008 1013
1009 mutex_unlock(&cinergyt2->sem); 1014 mutex_unlock(&cinergyt2->wq_sem);
1010 return 0; 1015 return 0;
1011} 1016}
1012 1017
@@ -1014,9 +1019,15 @@ static int cinergyt2_resume (struct usb_interface *intf)
1014{ 1019{
1015 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); 1020 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
1016 struct dvbt_set_parameters_msg *param = &cinergyt2->param; 1021 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
1022 int err = -ERESTARTSYS;
1017 1023
1018 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) 1024 if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
1019 return -ERESTARTSYS; 1025 goto out;
1026
1027 if (mutex_lock_interruptible(&cinergyt2->sem))
1028 goto out_unlock1;
1029
1030 err = 0;
1020 1031
1021 if (!cinergyt2->sleeping) { 1032 if (!cinergyt2->sleeping) {
1022 cinergyt2_sleep(cinergyt2, 0); 1033 cinergyt2_sleep(cinergyt2, 0);
@@ -1029,7 +1040,10 @@ static int cinergyt2_resume (struct usb_interface *intf)
1029 cinergyt2_resume_rc(cinergyt2); 1040 cinergyt2_resume_rc(cinergyt2);
1030 1041
1031 mutex_unlock(&cinergyt2->sem); 1042 mutex_unlock(&cinergyt2->sem);
1032 return 0; 1043out_unlock1:
1044 mutex_unlock(&cinergyt2->wq_sem);
1045out:
1046 return err;
1033} 1047}
1034 1048
1035static const struct usb_device_id cinergyt2_table [] __devinitdata = { 1049static const struct usb_device_id cinergyt2_table [] __devinitdata = {
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 2557ac9620d0..b611f2b1f8bc 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -529,7 +529,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
529 if (bi->type != BUDGET_FS_ACTIVY) 529 if (bi->type != BUDGET_FS_ACTIVY)
530 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); 530 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
531 531
532 if (budget_register(budget) == 0) 532 if ((ret = budget_register(budget)) == 0)
533 return 0; /* Everything OK */ 533 return 0; /* Everything OK */
534 534
535 /* An error occurred, cleanup resources */ 535 /* An error occurred, cleanup resources */
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 1c38723d3169..b1fedb0f6431 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -1331,7 +1331,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
1331 1331
1332/* Call with btv->lock down. */ 1332/* Call with btv->lock down. */
1333static void 1333static void
1334set_input(struct bttv *btv, unsigned int input) 1334set_input(struct bttv *btv, unsigned int input, unsigned int norm)
1335{ 1335{
1336 unsigned long flags; 1336 unsigned long flags;
1337 1337
@@ -1350,7 +1350,7 @@ set_input(struct bttv *btv, unsigned int input)
1350 } 1350 }
1351 audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ? 1351 audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
1352 TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN)); 1352 TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
1353 set_tvnorm(btv,btv->tvnorm); 1353 set_tvnorm(btv, norm);
1354 i2c_vidiocschan(btv); 1354 i2c_vidiocschan(btv);
1355} 1355}
1356 1356
@@ -1441,7 +1441,7 @@ static void bttv_reinit_bt848(struct bttv *btv)
1441 1441
1442 init_bt848(btv); 1442 init_bt848(btv);
1443 btv->pll.pll_current = -1; 1443 btv->pll.pll_current = -1;
1444 set_input(btv,btv->input); 1444 set_input(btv, btv->input, btv->tvnorm);
1445} 1445}
1446 1446
1447static int get_control(struct bttv *btv, struct v4l2_control *c) 1447static int get_control(struct bttv *btv, struct v4l2_control *c)
@@ -2011,8 +2011,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
2011 return 0; 2011 return 0;
2012 } 2012 }
2013 2013
2014 btv->tvnorm = v->norm; 2014 set_input(btv, v->channel, v->norm);
2015 set_input(btv,v->channel);
2016 mutex_unlock(&btv->lock); 2015 mutex_unlock(&btv->lock);
2017 return 0; 2016 return 0;
2018 } 2017 }
@@ -2148,7 +2147,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
2148 if (*i > bttv_tvcards[btv->c.type].video_inputs) 2147 if (*i > bttv_tvcards[btv->c.type].video_inputs)
2149 return -EINVAL; 2148 return -EINVAL;
2150 mutex_lock(&btv->lock); 2149 mutex_lock(&btv->lock);
2151 set_input(btv,*i); 2150 set_input(btv, *i, btv->tvnorm);
2152 mutex_unlock(&btv->lock); 2151 mutex_unlock(&btv->lock);
2153 return 0; 2152 return 0;
2154 } 2153 }
@@ -4780,7 +4779,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4780 bt848_hue(btv,32768); 4779 bt848_hue(btv,32768);
4781 bt848_sat(btv,32768); 4780 bt848_sat(btv,32768);
4782 audio_mute(btv, 1); 4781 audio_mute(btv, 1);
4783 set_input(btv,0); 4782 set_input(btv, 0, btv->tvnorm);
4784 bttv_crop_reset(&btv->crop[0], btv->tvnorm); 4783 bttv_crop_reset(&btv->crop[0], btv->tvnorm);
4785 btv->crop[1] = btv->crop[0]; /* current = default */ 4784 btv->crop[1] = btv->crop[0]; /* current = default */
4786 disclaim_vbi_lines(btv); 4785 disclaim_vbi_lines(btv);
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index b0466b88f52c..a80b1cb1abe8 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1034,6 +1034,8 @@ static int vidioc_g_tuner (struct file *file, void *priv,
1034 1034
1035 if (unlikely(UNSET == core->tuner_type)) 1035 if (unlikely(UNSET == core->tuner_type))
1036 return -EINVAL; 1036 return -EINVAL;
1037 if (0 != t->index)
1038 return -EINVAL;
1037 1039
1038 strcpy(t->name, "Television"); 1040 strcpy(t->name, "Television");
1039 t->type = V4L2_TUNER_ANALOG_TV; 1041 t->type = V4L2_TUNER_ANALOG_TV;