Skip to content

Commit

Permalink
V4L/DVB (9721): cx18: Change to singlethreaded global work queue thre…
Browse files Browse the repository at this point in the history
…ad 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>
  • Loading branch information
Andy Walls authored and Mauro Carvalho Chehab committed Dec 30, 2008
1 parent ee2d64f commit 18b5dc2
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
25 changes: 24 additions & 1 deletion drivers/media/video/cx18/cx18-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ struct cx18 *cx18_cards[CX18_MAX_CARDS];
/* Protects cx18_cards_active */
DEFINE_SPINLOCK(cx18_cards_lock);

/* Queue for deferrable IRQ handling work for all cx18 cards in system */
struct workqueue_struct *cx18_work_queue;

/* add your revision and whatnot here */
static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
Expand Down Expand Up @@ -920,6 +923,13 @@ int cx18_init_on_first_open(struct cx18 *cx)
return 0;
}

static void cx18_cancel_epu_work_orders(struct cx18 *cx)
{
int i;
for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++)
cancel_work_sync(&cx->epu_work_order[i].work);
}

static void cx18_remove(struct pci_dev *pci_dev)
{
struct cx18 *cx = pci_get_drvdata(pci_dev);
Expand All @@ -937,7 +947,7 @@ static void cx18_remove(struct pci_dev *pci_dev)

cx18_halt_firmware(cx);

flush_scheduled_work();
cx18_cancel_epu_work_orders(cx);

cx18_streams_cleanup(cx, 1);

Expand Down Expand Up @@ -981,8 +991,17 @@ static int module_start(void)
printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n");
}

cx18_work_queue = create_singlethread_workqueue("cx18");
if (cx18_work_queue == NULL) {
printk(KERN_ERR
"cx18: Unable to create work hander thread\n");
return -ENOMEM;
}

if (pci_register_driver(&cx18_pci_driver)) {
printk(KERN_ERR "cx18: Error detecting PCI card\n");
destroy_workqueue(cx18_work_queue);
cx18_work_queue = NULL;
return -ENODEV;
}
printk(KERN_INFO "cx18: End initialization\n");
Expand All @@ -995,11 +1014,15 @@ static void module_cleanup(void)

pci_unregister_driver(&cx18_pci_driver);

destroy_workqueue(cx18_work_queue);
cx18_work_queue = NULL;

for (i = 0; i < cx18_cards_active; i++) {
if (cx18_cards[i] == NULL)
continue;
kfree(cx18_cards[i]);
}

}

module_init(module_start);
Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/cx18/cx18-driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ extern struct cx18 *cx18_cards[];
extern int cx18_cards_active;
extern int cx18_first_minor;
extern spinlock_t cx18_cards_lock;
extern struct workqueue_struct *cx18_work_queue;

/*==============Prototypes==================*/

Expand Down
2 changes: 1 addition & 1 deletion drivers/media/video/cx18/cx18-mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
*/
submit = epu_cmd_irq(cx, order, stale);
if (submit > 0) {
schedule_work(&order->work);
queue_work(cx18_work_queue, &order->work);
}
}

Expand Down

0 comments on commit 18b5dc2

Please sign in to comment.