aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-driver.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-25 19:43:05 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:19 -0500
commit572bfea71b0fb2efb36407b4e284c1e7962d4779 (patch)
treead0d800d0963151e187c40a2d1a6e4c5ac38f39e /drivers/media/video/cx18/cx18-driver.c
parent9af0ef27a06f3e8976b90a4ed4758e25ea0f2df5 (diff)
V4L/DVB (9776): cx18: Change to per CX23418 device work queues for deferrable work handling
cx18: Change to per CX23418 device work queues for deferrable work handling. Needed to support 2.6.22 and earlier kernels that can't selectively cancel work orders. Also will provide slightly better performance on SMP systems. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-driver.c')
-rw-r--r--drivers/media/video/cx18/cx18-driver.c33
1 files changed, 12 insertions, 21 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index fbcbb500ca74..a893caff0aa9 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -56,9 +56,6 @@ struct cx18 *cx18_cards[CX18_MAX_CARDS];
56/* Protects cx18_cards_active */ 56/* Protects cx18_cards_active */
57DEFINE_SPINLOCK(cx18_cards_lock); 57DEFINE_SPINLOCK(cx18_cards_lock);
58 58
59/* Queue for deferrable IRQ handling work for all cx18 cards in system */
60struct workqueue_struct *cx18_work_queue;
61
62/* add your revision and whatnot here */ 59/* add your revision and whatnot here */
63static struct pci_device_id cx18_pci_tbl[] __devinitdata = { 60static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
64 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, 61 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -446,6 +443,12 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
446 443
447 spin_lock_init(&cx->lock); 444 spin_lock_init(&cx->lock);
448 445
446 cx->work_queue = create_singlethread_workqueue(cx->name);
447 if (cx->work_queue == NULL) {
448 CX18_ERR("Unable to create work hander thread\n");
449 return -ENOMEM;
450 }
451
449 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { 452 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) {
450 cx->epu_work_order[i].cx = cx; 453 cx->epu_work_order[i].cx = cx;
451 cx->epu_work_order[i].str = cx->epu_debug_str; 454 cx->epu_work_order[i].str = cx->epu_debug_str;
@@ -655,12 +658,9 @@ static int __devinit cx18_probe(struct pci_dev *dev,
655 658
656 /* PCI Device Setup */ 659 /* PCI Device Setup */
657 retval = cx18_setup_pci(cx, dev, pci_id); 660 retval = cx18_setup_pci(cx, dev, pci_id);
658 if (retval != 0) { 661 if (retval != 0)
659 if (retval == -EIO) 662 goto free_workqueue;
660 goto free_workqueue; 663
661 else if (retval == -ENXIO)
662 goto free_mem;
663 }
664 /* save cx in the pci struct for later use */ 664 /* save cx in the pci struct for later use */
665 pci_set_drvdata(dev, cx); 665 pci_set_drvdata(dev, cx);
666 666
@@ -830,6 +830,7 @@ free_map:
830free_mem: 830free_mem:
831 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 831 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
832free_workqueue: 832free_workqueue:
833 destroy_workqueue(cx->work_queue);
833err: 834err:
834 if (retval == 0) 835 if (retval == 0)
835 retval = -ENODEV; 836 retval = -ENODEV;
@@ -938,6 +939,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
938 939
939 cx18_cancel_epu_work_orders(cx); 940 cx18_cancel_epu_work_orders(cx);
940 941
942 destroy_workqueue(cx->work_queue);
943
941 cx18_streams_cleanup(cx, 1); 944 cx18_streams_cleanup(cx, 1);
942 945
943 exit_cx18_i2c(cx); 946 exit_cx18_i2c(cx);
@@ -979,17 +982,8 @@ static int module_start(void)
979 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n"); 982 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
980 } 983 }
981 984
982 cx18_work_queue = create_singlethread_workqueue("cx18");
983 if (cx18_work_queue == NULL) {
984 printk(KERN_ERR
985 "cx18: Unable to create work hander thread\n");
986 return -ENOMEM;
987 }
988
989 if (pci_register_driver(&cx18_pci_driver)) { 985 if (pci_register_driver(&cx18_pci_driver)) {
990 printk(KERN_ERR "cx18: Error detecting PCI card\n"); 986 printk(KERN_ERR "cx18: Error detecting PCI card\n");
991 destroy_workqueue(cx18_work_queue);
992 cx18_work_queue = NULL;
993 return -ENODEV; 987 return -ENODEV;
994 } 988 }
995 printk(KERN_INFO "cx18: End initialization\n"); 989 printk(KERN_INFO "cx18: End initialization\n");
@@ -1002,9 +996,6 @@ static void module_cleanup(void)
1002 996
1003 pci_unregister_driver(&cx18_pci_driver); 997 pci_unregister_driver(&cx18_pci_driver);
1004 998
1005 destroy_workqueue(cx18_work_queue);
1006 cx18_work_queue = NULL;
1007
1008 for (i = 0; i < cx18_cards_active; i++) { 999 for (i = 0; i < cx18_cards_active; i++) {
1009 if (cx18_cards[i] == NULL) 1000 if (cx18_cards[i] == NULL)
1010 continue; 1001 continue;