aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-16 15:15:01 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:08 -0500
commit18b5dc2ed7f0ede825dd1f93fefc7a61aba866e3 (patch)
tree761c2ec7a83df283680636cf264528c2c9ea8cf6 /drivers/media
parentee2d64f5ccc71b5c5191e92ea91a12b65f9ca060 (diff)
V4L/DVB (9721): cx18: Change to singlethreaded global work queue thread for deferable work
Change to singlethreaded global work queue thread for deferable work, instead of the kernel default multithreaded work queue. This ensures execution of deferable work is always in the proper order, so caputred buffers don't get reordered. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/cx18/cx18-driver.c25
-rw-r--r--drivers/media/video/cx18/cx18-driver.h1
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c2
3 files changed, 26 insertions, 2 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 434cc7fdee36..752ca908ccb1 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -56,6 +56,9 @@ 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
59/* add your revision and whatnot here */ 62/* add your revision and whatnot here */
60static struct pci_device_id cx18_pci_tbl[] __devinitdata = { 63static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
61 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, 64 {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -920,6 +923,13 @@ int cx18_init_on_first_open(struct cx18 *cx)
920 return 0; 923 return 0;
921} 924}
922 925
926static void cx18_cancel_epu_work_orders(struct cx18 *cx)
927{
928 int i;
929 for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++)
930 cancel_work_sync(&cx->epu_work_order[i].work);
931}
932
923static void cx18_remove(struct pci_dev *pci_dev) 933static void cx18_remove(struct pci_dev *pci_dev)
924{ 934{
925 struct cx18 *cx = pci_get_drvdata(pci_dev); 935 struct cx18 *cx = pci_get_drvdata(pci_dev);
@@ -937,7 +947,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
937 947
938 cx18_halt_firmware(cx); 948 cx18_halt_firmware(cx);
939 949
940 flush_scheduled_work(); 950 cx18_cancel_epu_work_orders(cx);
941 951
942 cx18_streams_cleanup(cx, 1); 952 cx18_streams_cleanup(cx, 1);
943 953
@@ -981,8 +991,17 @@ static int module_start(void)
981 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n"); 991 printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
982 } 992 }
983 993
994 cx18_work_queue = create_singlethread_workqueue("cx18");
995 if (cx18_work_queue == NULL) {
996 printk(KERN_ERR
997 "cx18: Unable to create work hander thread\n");
998 return -ENOMEM;
999 }
1000
984 if (pci_register_driver(&cx18_pci_driver)) { 1001 if (pci_register_driver(&cx18_pci_driver)) {
985 printk(KERN_ERR "cx18: Error detecting PCI card\n"); 1002 printk(KERN_ERR "cx18: Error detecting PCI card\n");
1003 destroy_workqueue(cx18_work_queue);
1004 cx18_work_queue = NULL;
986 return -ENODEV; 1005 return -ENODEV;
987 } 1006 }
988 printk(KERN_INFO "cx18: End initialization\n"); 1007 printk(KERN_INFO "cx18: End initialization\n");
@@ -995,11 +1014,15 @@ static void module_cleanup(void)
995 1014
996 pci_unregister_driver(&cx18_pci_driver); 1015 pci_unregister_driver(&cx18_pci_driver);
997 1016
1017 destroy_workqueue(cx18_work_queue);
1018 cx18_work_queue = NULL;
1019
998 for (i = 0; i < cx18_cards_active; i++) { 1020 for (i = 0; i < cx18_cards_active; i++) {
999 if (cx18_cards[i] == NULL) 1021 if (cx18_cards[i] == NULL)
1000 continue; 1022 continue;
1001 kfree(cx18_cards[i]); 1023 kfree(cx18_cards[i]);
1002 } 1024 }
1025
1003} 1026}
1004 1027
1005module_init(module_start); 1028module_init(module_start);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 5ebf84b78ca8..f8929eb72ad0 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -486,6 +486,7 @@ extern struct cx18 *cx18_cards[];
486extern int cx18_cards_active; 486extern int cx18_cards_active;
487extern int cx18_first_minor; 487extern int cx18_first_minor;
488extern spinlock_t cx18_cards_lock; 488extern spinlock_t cx18_cards_lock;
489extern struct workqueue_struct *cx18_work_queue;
489 490
490/*==============Prototypes==================*/ 491/*==============Prototypes==================*/
491 492
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index 3d210d2ffdad..d49c7c27c18f 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -409,7 +409,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
409 */ 409 */
410 submit = epu_cmd_irq(cx, order, stale); 410 submit = epu_cmd_irq(cx, order, stale);
411 if (submit > 0) { 411 if (submit > 0) {
412 schedule_work(&order->work); 412 queue_work(cx18_work_queue, &order->work);
413 } 413 }
414} 414}
415 415