diff options
author | Andy Walls <awalls@radix.net> | 2008-11-25 19:43:05 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:38:19 -0500 |
commit | 572bfea71b0fb2efb36407b4e284c1e7962d4779 (patch) | |
tree | ad0d800d0963151e187c40a2d1a6e4c5ac38f39e /drivers/media/video/cx18/cx18-driver.c | |
parent | 9af0ef27a06f3e8976b90a4ed4758e25ea0f2df5 (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.c | 33 |
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 */ |
57 | DEFINE_SPINLOCK(cx18_cards_lock); | 57 | DEFINE_SPINLOCK(cx18_cards_lock); |
58 | 58 | ||
59 | /* Queue for deferrable IRQ handling work for all cx18 cards in system */ | ||
60 | struct workqueue_struct *cx18_work_queue; | ||
61 | |||
62 | /* add your revision and whatnot here */ | 59 | /* add your revision and whatnot here */ |
63 | static struct pci_device_id cx18_pci_tbl[] __devinitdata = { | 60 | static 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: | |||
830 | free_mem: | 830 | free_mem: |
831 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); | 831 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); |
832 | free_workqueue: | 832 | free_workqueue: |
833 | destroy_workqueue(cx->work_queue); | ||
833 | err: | 834 | err: |
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; |