aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index addf9545e9bf..1a7b983f8297 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -78,6 +78,7 @@ static void flush_request_modules(struct cx8802_dev *dev)
78 78
79 79
80static LIST_HEAD(cx8802_devlist); 80static LIST_HEAD(cx8802_devlist);
81static DEFINE_MUTEX(cx8802_mutex);
81/* ------------------------------------------------------------------ */ 82/* ------------------------------------------------------------------ */
82 83
83static int cx8802_start_dma(struct cx8802_dev *dev, 84static int cx8802_start_dma(struct cx8802_dev *dev,
@@ -474,7 +475,7 @@ static int cx8802_init_common(struct cx8802_dev *dev)
474 return -EIO; 475 return -EIO;
475 } 476 }
476 477
477 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); 478 dev->pci_rev = dev->pci->revision;
478 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); 479 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
479 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " 480 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
480 "latency: %d, mmio: 0x%llx\n", dev->core->name, 481 "latency: %d, mmio: 0x%llx\n", dev->core->name,
@@ -624,13 +625,11 @@ static int cx8802_request_acquire(struct cx8802_driver *drv)
624 625
625 if (drv->advise_acquire) 626 if (drv->advise_acquire)
626 { 627 {
627 mutex_lock(&drv->core->lock);
628 core->active_ref++; 628 core->active_ref++;
629 if (core->active_type_id == CX88_BOARD_NONE) { 629 if (core->active_type_id == CX88_BOARD_NONE) {
630 core->active_type_id = drv->type_id; 630 core->active_type_id = drv->type_id;
631 drv->advise_acquire(drv); 631 drv->advise_acquire(drv);
632 } 632 }
633 mutex_unlock(&drv->core->lock);
634 633
635 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); 634 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
636 } 635 }
@@ -643,14 +642,12 @@ static int cx8802_request_release(struct cx8802_driver *drv)
643{ 642{
644 struct cx88_core *core = drv->core; 643 struct cx88_core *core = drv->core;
645 644
646 mutex_lock(&drv->core->lock);
647 if (drv->advise_release && --core->active_ref == 0) 645 if (drv->advise_release && --core->active_ref == 0)
648 { 646 {
649 drv->advise_release(drv); 647 drv->advise_release(drv);
650 core->active_type_id = CX88_BOARD_NONE; 648 core->active_type_id = CX88_BOARD_NONE;
651 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); 649 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
652 } 650 }
653 mutex_unlock(&drv->core->lock);
654 651
655 return 0; 652 return 0;
656} 653}
@@ -693,6 +690,8 @@ int cx8802_register_driver(struct cx8802_driver *drv)
693 return err; 690 return err;
694 } 691 }
695 692
693 mutex_lock(&cx8802_mutex);
694
696 list_for_each_entry(dev, &cx8802_devlist, devlist) { 695 list_for_each_entry(dev, &cx8802_devlist, devlist) {
697 printk(KERN_INFO 696 printk(KERN_INFO
698 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", 697 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -702,8 +701,10 @@ int cx8802_register_driver(struct cx8802_driver *drv)
702 701
703 /* Bring up a new struct for each driver instance */ 702 /* Bring up a new struct for each driver instance */
704 driver = kzalloc(sizeof(*drv),GFP_KERNEL); 703 driver = kzalloc(sizeof(*drv),GFP_KERNEL);
705 if (driver == NULL) 704 if (driver == NULL) {
706 return -ENOMEM; 705 err = -ENOMEM;
706 goto out;
707 }
707 708
708 /* Snapshot of the driver registration data */ 709 /* Snapshot of the driver registration data */
709 drv->core = dev->core; 710 drv->core = dev->core;
@@ -713,21 +714,23 @@ int cx8802_register_driver(struct cx8802_driver *drv)
713 drv->request_release = cx8802_request_release; 714 drv->request_release = cx8802_request_release;
714 memcpy(driver, drv, sizeof(*driver)); 715 memcpy(driver, drv, sizeof(*driver));
715 716
717 mutex_lock(&drv->core->lock);
716 err = drv->probe(driver); 718 err = drv->probe(driver);
717 if (err == 0) { 719 if (err == 0) {
718 i++; 720 i++;
719 mutex_lock(&drv->core->lock);
720 list_add_tail(&driver->drvlist, &dev->drvlist); 721 list_add_tail(&driver->drvlist, &dev->drvlist);
721 mutex_unlock(&drv->core->lock);
722 } else { 722 } else {
723 printk(KERN_ERR 723 printk(KERN_ERR
724 "%s/2: cx8802 probe failed, err = %d\n", 724 "%s/2: cx8802 probe failed, err = %d\n",
725 dev->core->name, err); 725 dev->core->name, err);
726 } 726 }
727 727 mutex_unlock(&drv->core->lock);
728 } 728 }
729 729
730 return i ? 0 : -ENODEV; 730 err = i ? 0 : -ENODEV;
731out:
732 mutex_unlock(&cx8802_mutex);
733 return err;
731} 734}
732 735
733int cx8802_unregister_driver(struct cx8802_driver *drv) 736int cx8802_unregister_driver(struct cx8802_driver *drv)
@@ -741,6 +744,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
741 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", 744 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
742 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); 745 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
743 746
747 mutex_lock(&cx8802_mutex);
748
744 list_for_each_entry(dev, &cx8802_devlist, devlist) { 749 list_for_each_entry(dev, &cx8802_devlist, devlist) {
745 printk(KERN_INFO 750 printk(KERN_INFO
746 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n", 751 "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -748,6 +753,8 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
748 dev->pci->subsystem_device, dev->core->board.name, 753 dev->pci->subsystem_device, dev->core->board.name,
749 dev->core->boardnr); 754 dev->core->boardnr);
750 755
756 mutex_lock(&dev->core->lock);
757
751 list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) { 758 list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
752 /* only unregister the correct driver type */ 759 /* only unregister the correct driver type */
753 if (d->type_id != drv->type_id) 760 if (d->type_id != drv->type_id)
@@ -755,17 +762,18 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
755 762
756 err = d->remove(d); 763 err = d->remove(d);
757 if (err == 0) { 764 if (err == 0) {
758 mutex_lock(&drv->core->lock);
759 list_del(&d->drvlist); 765 list_del(&d->drvlist);
760 mutex_unlock(&drv->core->lock);
761 kfree(d); 766 kfree(d);
762 } else 767 } else
763 printk(KERN_ERR "%s/2: cx8802 driver remove " 768 printk(KERN_ERR "%s/2: cx8802 driver remove "
764 "failed (%d)\n", dev->core->name, err); 769 "failed (%d)\n", dev->core->name, err);
765 } 770 }
766 771
772 mutex_unlock(&dev->core->lock);
767 } 773 }
768 774
775 mutex_unlock(&cx8802_mutex);
776
769 return err; 777 return err;
770} 778}
771 779
@@ -803,7 +811,9 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
803 goto fail_free; 811 goto fail_free;
804 812
805 INIT_LIST_HEAD(&dev->drvlist); 813 INIT_LIST_HEAD(&dev->drvlist);
814 mutex_lock(&cx8802_mutex);
806 list_add_tail(&dev->devlist,&cx8802_devlist); 815 list_add_tail(&dev->devlist,&cx8802_devlist);
816 mutex_unlock(&cx8802_mutex);
807 817
808 /* now autoload cx88-dvb or cx88-blackbird */ 818 /* now autoload cx88-dvb or cx88-blackbird */
809 request_modules(dev); 819 request_modules(dev);
@@ -827,6 +837,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
827 837
828 flush_request_modules(dev); 838 flush_request_modules(dev);
829 839
840 mutex_lock(&dev->core->lock);
841
830 if (!list_empty(&dev->drvlist)) { 842 if (!list_empty(&dev->drvlist)) {
831 struct cx8802_driver *drv, *tmp; 843 struct cx8802_driver *drv, *tmp;
832 int err; 844 int err;
@@ -838,9 +850,7 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
838 list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) { 850 list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
839 err = drv->remove(drv); 851 err = drv->remove(drv);
840 if (err == 0) { 852 if (err == 0) {
841 mutex_lock(&drv->core->lock);
842 list_del(&drv->drvlist); 853 list_del(&drv->drvlist);
843 mutex_unlock(&drv->core->lock);
844 } else 854 } else
845 printk(KERN_ERR "%s/2: cx8802 driver remove " 855 printk(KERN_ERR "%s/2: cx8802 driver remove "
846 "failed (%d)\n", dev->core->name, err); 856 "failed (%d)\n", dev->core->name, err);
@@ -848,6 +858,8 @@ static void __devexit cx8802_remove(struct pci_dev *pci_dev)
848 } 858 }
849 } 859 }
850 860
861 mutex_unlock(&dev->core->lock);
862
851 /* Destroy any 8802 reference. */ 863 /* Destroy any 8802 reference. */
852 dev->core->dvbdev = NULL; 864 dev->core->dvbdev = NULL;
853 865