diff options
-rw-r--r-- | drivers/media/video/cx88/cx88-blackbird.c | 3 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 3 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 11 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 9 |
4 files changed, 20 insertions, 6 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index bca307eb1e24..b93fbd39a39e 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -1122,10 +1122,11 @@ static int mpeg_release(struct file *file) | |||
1122 | mutex_lock(&dev->core->lock); | 1122 | mutex_lock(&dev->core->lock); |
1123 | file->private_data = NULL; | 1123 | file->private_data = NULL; |
1124 | kfree(fh); | 1124 | kfree(fh); |
1125 | mutex_unlock(&dev->core->lock); | ||
1126 | 1125 | ||
1127 | /* Make sure we release the hardware */ | 1126 | /* Make sure we release the hardware */ |
1128 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); | 1127 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); |
1128 | mutex_unlock(&dev->core->lock); | ||
1129 | |||
1129 | if (drv) | 1130 | if (drv) |
1130 | drv->request_release(drv); | 1131 | drv->request_release(drv); |
1131 | 1132 | ||
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 7b8c9d3b6efc..84002bc80db5 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -133,7 +133,10 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) | |||
133 | return -EINVAL; | 133 | return -EINVAL; |
134 | } | 134 | } |
135 | 135 | ||
136 | mutex_lock(&dev->core->lock); | ||
136 | drv = cx8802_get_driver(dev, CX88_MPEG_DVB); | 137 | drv = cx8802_get_driver(dev, CX88_MPEG_DVB); |
138 | mutex_unlock(&dev->core->lock); | ||
139 | |||
137 | if (drv) { | 140 | if (drv) { |
138 | if (acquire){ | 141 | if (acquire){ |
139 | dev->frontends.active_fe_id = fe_id; | 142 | dev->frontends.active_fe_id = fe_id; |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 9b500e691a5c..a092c3a4c56d 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -748,6 +748,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) | |||
748 | dev->pci->subsystem_device, dev->core->board.name, | 748 | dev->pci->subsystem_device, dev->core->board.name, |
749 | dev->core->boardnr); | 749 | dev->core->boardnr); |
750 | 750 | ||
751 | mutex_lock(&dev->core->lock); | ||
752 | |||
751 | list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) { | 753 | list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) { |
752 | /* only unregister the correct driver type */ | 754 | /* only unregister the correct driver type */ |
753 | if (d->type_id != drv->type_id) | 755 | if (d->type_id != drv->type_id) |
@@ -755,15 +757,14 @@ int cx8802_unregister_driver(struct cx8802_driver *drv) | |||
755 | 757 | ||
756 | err = d->remove(d); | 758 | err = d->remove(d); |
757 | if (err == 0) { | 759 | if (err == 0) { |
758 | mutex_lock(&drv->core->lock); | ||
759 | list_del(&d->drvlist); | 760 | list_del(&d->drvlist); |
760 | mutex_unlock(&drv->core->lock); | ||
761 | kfree(d); | 761 | kfree(d); |
762 | } else | 762 | } else |
763 | printk(KERN_ERR "%s/2: cx8802 driver remove " | 763 | printk(KERN_ERR "%s/2: cx8802 driver remove " |
764 | "failed (%d)\n", dev->core->name, err); | 764 | "failed (%d)\n", dev->core->name, err); |
765 | } | 765 | } |
766 | 766 | ||
767 | mutex_unlock(&dev->core->lock); | ||
767 | } | 768 | } |
768 | 769 | ||
769 | return err; | 770 | return err; |
@@ -827,6 +828,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) | |||
827 | 828 | ||
828 | flush_request_modules(dev); | 829 | flush_request_modules(dev); |
829 | 830 | ||
831 | mutex_lock(&dev->core->lock); | ||
832 | |||
830 | if (!list_empty(&dev->drvlist)) { | 833 | if (!list_empty(&dev->drvlist)) { |
831 | struct cx8802_driver *drv, *tmp; | 834 | struct cx8802_driver *drv, *tmp; |
832 | int err; | 835 | int err; |
@@ -838,9 +841,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) | |||
838 | list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { | 841 | list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { |
839 | err = drv->remove(drv); | 842 | err = drv->remove(drv); |
840 | if (err == 0) { | 843 | if (err == 0) { |
841 | mutex_lock(&drv->core->lock); | ||
842 | list_del(&drv->drvlist); | 844 | list_del(&drv->drvlist); |
843 | mutex_unlock(&drv->core->lock); | ||
844 | } else | 845 | } else |
845 | printk(KERN_ERR "%s/2: cx8802 driver remove " | 846 | printk(KERN_ERR "%s/2: cx8802 driver remove " |
846 | "failed (%d)\n", dev->core->name, err); | 847 | "failed (%d)\n", dev->core->name, err); |
@@ -848,6 +849,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev) | |||
848 | } | 849 | } |
849 | } | 850 | } |
850 | 851 | ||
852 | mutex_unlock(&dev->core->lock); | ||
853 | |||
851 | /* Destroy any 8802 reference. */ | 854 | /* Destroy any 8802 reference. */ |
852 | dev->core->dvbdev = NULL; | 855 | dev->core->dvbdev = NULL; |
853 | 856 | ||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 9b3742a7746c..e3d56c235203 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -506,7 +506,11 @@ struct cx8802_driver { | |||
506 | int (*resume)(struct pci_dev *pci_dev); | 506 | int (*resume)(struct pci_dev *pci_dev); |
507 | 507 | ||
508 | /* MPEG 8802 -> mini driver - Driver probe and configuration */ | 508 | /* MPEG 8802 -> mini driver - Driver probe and configuration */ |
509 | |||
510 | /* Caller must _not_ hold core->lock */ | ||
509 | int (*probe)(struct cx8802_driver *drv); | 511 | int (*probe)(struct cx8802_driver *drv); |
512 | |||
513 | /* Caller must hold core->lock */ | ||
510 | int (*remove)(struct cx8802_driver *drv); | 514 | int (*remove)(struct cx8802_driver *drv); |
511 | 515 | ||
512 | /* MPEG 8802 -> mini driver - Access for hardware control */ | 516 | /* MPEG 8802 -> mini driver - Access for hardware control */ |
@@ -561,8 +565,9 @@ struct cx8802_dev { | |||
561 | /* for switching modulation types */ | 565 | /* for switching modulation types */ |
562 | unsigned char ts_gen_cntrl; | 566 | unsigned char ts_gen_cntrl; |
563 | 567 | ||
564 | /* List of attached drivers */ | 568 | /* List of attached drivers; must hold core->lock to access */ |
565 | struct list_head drvlist; | 569 | struct list_head drvlist; |
570 | |||
566 | struct work_struct request_module_wk; | 571 | struct work_struct request_module_wk; |
567 | }; | 572 | }; |
568 | 573 | ||
@@ -685,6 +690,8 @@ int cx88_audio_thread(void *data); | |||
685 | 690 | ||
686 | int cx8802_register_driver(struct cx8802_driver *drv); | 691 | int cx8802_register_driver(struct cx8802_driver *drv); |
687 | int cx8802_unregister_driver(struct cx8802_driver *drv); | 692 | int cx8802_unregister_driver(struct cx8802_driver *drv); |
693 | |||
694 | /* Caller must hold core->lock */ | ||
688 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); | 695 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); |
689 | 696 | ||
690 | /* ----------------------------------------------------------- */ | 697 | /* ----------------------------------------------------------- */ |