Lines 78-83
static void flush_request_modules(struct cx8802_dev *dev)
Link Here
|
78 |
|
78 |
|
79 |
|
79 |
|
80 |
static LIST_HEAD(cx8802_devlist); |
80 |
static LIST_HEAD(cx8802_devlist); |
|
|
81 |
static DEFINE_MUTEX(cx8802_mutex); |
81 |
/* ------------------------------------------------------------------ */ |
82 |
/* ------------------------------------------------------------------ */ |
82 |
|
83 |
|
83 |
static int cx8802_start_dma(struct cx8802_dev *dev, |
84 |
static int cx8802_start_dma(struct cx8802_dev *dev, |
Lines 624-636
static int cx8802_request_acquire(struct cx8802_driver *drv)
Link Here
|
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 |
} |
Lines 643-656
static int cx8802_request_release(struct cx8802_driver *drv)
Link Here
|
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 |
} |
Lines 693-698
int cx8802_register_driver(struct cx8802_driver *drv)
Link Here
|
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", |
Lines 702-709
int cx8802_register_driver(struct cx8802_driver *drv)
Link Here
|
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; |
Lines 713-733
int cx8802_register_driver(struct cx8802_driver *drv)
Link Here
|
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; |
|
|
731 |
out: |
732 |
mutex_unlock(&cx8802_mutex); |
733 |
return err; |
731 |
} |
734 |
} |
732 |
|
735 |
|
733 |
int cx8802_unregister_driver(struct cx8802_driver *drv) |
736 |
int cx8802_unregister_driver(struct cx8802_driver *drv) |
Lines 741-746
int cx8802_unregister_driver(struct cx8802_driver *drv)
Link Here
|
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", |
Lines 748-753
int cx8802_unregister_driver(struct cx8802_driver *drv)
Link Here
|
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) |
Lines 755-771
int cx8802_unregister_driver(struct cx8802_driver *drv)
Link Here
|
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 |
|
Lines 803-809
static int __devinit cx8802_probe(struct pci_dev *pci_dev,
Link Here
|
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); |
Lines 827-832
static void __devexit cx8802_remove(struct pci_dev *pci_dev)
Link Here
|
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; |
Lines 838-846
static void __devexit cx8802_remove(struct pci_dev *pci_dev)
Link Here
|
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); |
Lines 848-853
static void __devexit cx8802_remove(struct pci_dev *pci_dev)
Link Here
|
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 |
|