aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-05-24 02:24:52 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-05-24 02:24:52 -0400
commitd08fe475120e3f17df37656d0644c0f17a797852 (patch)
tree64f0324afa9e884d8f0d738930a2495ba411c897 /drivers/media/video/cx88
parentfb66c5238547495b4a79f590b20400683702448a (diff)
parentd762f4383100c2a87b1a3f2d678cd3b5425655b4 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into rmobile-latest
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c41
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c42
-rw-r--r--drivers/media/video/cx88/cx88-video.c7
-rw-r--r--drivers/media/video/cx88/cx88.h11
5 files changed, 63 insertions, 40 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index bca307eb1e24..11e49bbc4a66 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1060,18 +1060,21 @@ static int mpeg_open(struct file *file)
1060 1060
1061 /* Make sure we can acquire the hardware */ 1061 /* Make sure we can acquire the hardware */
1062 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 1062 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1063 if (drv) { 1063 if (!drv) {
1064 err = drv->request_acquire(drv); 1064 dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
1065 if(err != 0) { 1065 mutex_unlock(&dev->core->lock);
1066 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err); 1066 return -ENODEV;
1067 mutex_unlock(&dev->core->lock); 1067 }
1068 return err; 1068
1069 } 1069 err = drv->request_acquire(drv);
1070 if (err != 0) {
1071 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
1072 mutex_unlock(&dev->core->lock);
1073 return err;
1070 } 1074 }
1071 1075
1072 if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { 1076 if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) {
1073 if (drv) 1077 drv->request_release(drv);
1074 drv->request_release(drv);
1075 mutex_unlock(&dev->core->lock); 1078 mutex_unlock(&dev->core->lock);
1076 return -EINVAL; 1079 return -EINVAL;
1077 } 1080 }
@@ -1080,8 +1083,7 @@ static int mpeg_open(struct file *file)
1080 /* allocate + initialize per filehandle data */ 1083 /* allocate + initialize per filehandle data */
1081 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 1084 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
1082 if (NULL == fh) { 1085 if (NULL == fh) {
1083 if (drv) 1086 drv->request_release(drv);
1084 drv->request_release(drv);
1085 mutex_unlock(&dev->core->lock); 1087 mutex_unlock(&dev->core->lock);
1086 return -ENOMEM; 1088 return -ENOMEM;
1087 } 1089 }
@@ -1099,7 +1101,7 @@ static int mpeg_open(struct file *file)
1099 cx88_set_scale(dev->core, dev->width, dev->height, 1101 cx88_set_scale(dev->core, dev->width, dev->height,
1100 fh->mpegq.field); 1102 fh->mpegq.field);
1101 1103
1102 atomic_inc(&dev->core->mpeg_users); 1104 dev->core->mpeg_users++;
1103 mutex_unlock(&dev->core->lock); 1105 mutex_unlock(&dev->core->lock);
1104 return 0; 1106 return 0;
1105} 1107}
@@ -1110,7 +1112,9 @@ static int mpeg_release(struct file *file)
1110 struct cx8802_dev *dev = fh->dev; 1112 struct cx8802_dev *dev = fh->dev;
1111 struct cx8802_driver *drv = NULL; 1113 struct cx8802_driver *drv = NULL;
1112 1114
1113 if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1) 1115 mutex_lock(&dev->core->lock);
1116
1117 if (dev->mpeg_active && dev->core->mpeg_users == 1)
1114 blackbird_stop_codec(dev); 1118 blackbird_stop_codec(dev);
1115 1119
1116 cx8802_cancel_buffers(fh->dev); 1120 cx8802_cancel_buffers(fh->dev);
@@ -1119,17 +1123,18 @@ static int mpeg_release(struct file *file)
1119 1123
1120 videobuf_mmap_free(&fh->mpegq); 1124 videobuf_mmap_free(&fh->mpegq);
1121 1125
1122 mutex_lock(&dev->core->lock);
1123 file->private_data = NULL; 1126 file->private_data = NULL;
1124 kfree(fh); 1127 kfree(fh);
1125 mutex_unlock(&dev->core->lock);
1126 1128
1127 /* Make sure we release the hardware */ 1129 /* Make sure we release the hardware */
1128 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); 1130 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1131 WARN_ON(!drv);
1129 if (drv) 1132 if (drv)
1130 drv->request_release(drv); 1133 drv->request_release(drv);
1131 1134
1132 atomic_dec(&dev->core->mpeg_users); 1135 dev->core->mpeg_users--;
1136
1137 mutex_unlock(&dev->core->lock);
1133 1138
1134 return 0; 1139 return 0;
1135} 1140}
@@ -1334,11 +1339,9 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1334 blackbird_register_video(dev); 1339 blackbird_register_video(dev);
1335 1340
1336 /* initial device configuration: needed ? */ 1341 /* initial device configuration: needed ? */
1337 mutex_lock(&dev->core->lock);
1338// init_controls(core); 1342// init_controls(core);
1339 cx88_set_tvnorm(core,core->tvnorm); 1343 cx88_set_tvnorm(core,core->tvnorm);
1340 cx88_video_mux(core,0); 1344 cx88_video_mux(core,0);
1341 mutex_unlock(&dev->core->lock);
1342 1345
1343 return 0; 1346 return 0;
1344 1347
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 7b8c9d3b6efc..c69df7ebb6a7 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -133,6 +133,7 @@ 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);
137 if (drv) { 138 if (drv) {
138 if (acquire){ 139 if (acquire){
@@ -143,6 +144,7 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
143 dev->frontends.active_fe_id = 0; 144 dev->frontends.active_fe_id = 0;
144 } 145 }
145 } 146 }
147 mutex_unlock(&dev->core->lock);
146 148
147 return ret; 149 return ret;
148} 150}
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
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 287a41ee1c4f..cef4f282e5aa 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -824,7 +824,7 @@ static int video_open(struct file *file)
824 call_all(core, tuner, s_radio); 824 call_all(core, tuner, s_radio);
825 } 825 }
826 826
827 atomic_inc(&core->users); 827 core->users++;
828 mutex_unlock(&core->lock); 828 mutex_unlock(&core->lock);
829 829
830 return 0; 830 return 0;
@@ -922,7 +922,8 @@ static int video_release(struct file *file)
922 file->private_data = NULL; 922 file->private_data = NULL;
923 kfree(fh); 923 kfree(fh);
924 924
925 if(atomic_dec_and_test(&dev->core->users)) 925 dev->core->users--;
926 if (!dev->core->users)
926 call_all(dev->core, core, s_power, 0); 927 call_all(dev->core, core, s_power, 0);
927 mutex_unlock(&dev->core->lock); 928 mutex_unlock(&dev->core->lock);
928 929
@@ -1832,7 +1833,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1832 dev->core = core; 1833 dev->core = core;
1833 1834
1834 /* print pci info */ 1835 /* print pci info */
1835 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1836 dev->pci_rev = pci_dev->revision;
1836 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1837 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1837 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1838 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1838 "latency: %d, mmio: 0x%llx\n", core->name, 1839 "latency: %d, mmio: 0x%llx\n", core->name,
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 9b3742a7746c..a399a8b086ba 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -389,8 +389,8 @@ struct cx88_core {
389 struct mutex lock; 389 struct mutex lock;
390 /* various v4l controls */ 390 /* various v4l controls */
391 u32 freq; 391 u32 freq;
392 atomic_t users; 392 int users;
393 atomic_t mpeg_users; 393 int mpeg_users;
394 394
395 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ 395 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
396 struct cx8802_dev *dvbdev; 396 struct cx8802_dev *dvbdev;
@@ -505,6 +505,8 @@ struct cx8802_driver {
505 int (*suspend)(struct pci_dev *pci_dev, pm_message_t state); 505 int (*suspend)(struct pci_dev *pci_dev, pm_message_t state);
506 int (*resume)(struct pci_dev *pci_dev); 506 int (*resume)(struct pci_dev *pci_dev);
507 507
508 /* Callers to the following functions must hold core->lock */
509
508 /* MPEG 8802 -> mini driver - Driver probe and configuration */ 510 /* MPEG 8802 -> mini driver - Driver probe and configuration */
509 int (*probe)(struct cx8802_driver *drv); 511 int (*probe)(struct cx8802_driver *drv);
510 int (*remove)(struct cx8802_driver *drv); 512 int (*remove)(struct cx8802_driver *drv);
@@ -561,8 +563,9 @@ struct cx8802_dev {
561 /* for switching modulation types */ 563 /* for switching modulation types */
562 unsigned char ts_gen_cntrl; 564 unsigned char ts_gen_cntrl;
563 565
564 /* List of attached drivers */ 566 /* List of attached drivers; must hold core->lock to access */
565 struct list_head drvlist; 567 struct list_head drvlist;
568
566 struct work_struct request_module_wk; 569 struct work_struct request_module_wk;
567}; 570};
568 571
@@ -685,6 +688,8 @@ int cx88_audio_thread(void *data);
685 688
686int cx8802_register_driver(struct cx8802_driver *drv); 689int cx8802_register_driver(struct cx8802_driver *drv);
687int cx8802_unregister_driver(struct cx8802_driver *drv); 690int cx8802_unregister_driver(struct cx8802_driver *drv);
691
692/* Caller must hold core->lock */
688struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); 693struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
689 694
690/* ----------------------------------------------------------- */ 695/* ----------------------------------------------------------- */