aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-streams.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-04-15 19:45:10 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 17:20:44 -0400
commit21a278b85d3c6b8064af0c03aec3205e28aad3b7 (patch)
treeefa0ee9cdfc303b03faf5b080b7f5721cf13c765 /drivers/media/video/cx18/cx18-streams.c
parent40c5520f55924ba87090d0d93222baad74202559 (diff)
V4L/DVB (11619): cx18: Simplify the work handler for outgoing mailbox commands
Simplify the way outgoing work handler gets scheduled to send empty buffers back to the firmware for use. Also reduced the memory required for scheduling this outgoing work, by using a single, per stream work object. 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-streams.c')
-rw-r--r--drivers/media/video/cx18/cx18-streams.c82
1 files changed, 5 insertions, 77 deletions
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index e1934e9cfdc8..41a1b2618aac 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -124,6 +124,8 @@ static void cx18_stream_init(struct cx18 *cx, int type)
124 cx18_queue_init(&s->q_busy); 124 cx18_queue_init(&s->q_busy);
125 spin_lock_init(&s->q_full.lock); 125 spin_lock_init(&s->q_full.lock);
126 cx18_queue_init(&s->q_full); 126 cx18_queue_init(&s->q_full);
127
128 INIT_WORK(&s->out_work_order, cx18_out_work_handler);
127} 129}
128 130
129static int cx18_prep_dev(struct cx18 *cx, int type) 131static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -477,86 +479,12 @@ void _cx18_stream_load_fw_queue(struct cx18_stream *s)
477 && q == &s->q_busy); 479 && q == &s->q_busy);
478} 480}
479 481
480static inline
481void free_out_work_order(struct cx18_out_work_order *order)
482{
483 atomic_set(&order->pending, 0);
484}
485
486void cx18_out_work_handler(struct work_struct *work) 482void cx18_out_work_handler(struct work_struct *work)
487{ 483{
488 struct cx18_out_work_order *order = 484 struct cx18_stream *s =
489 container_of(work, struct cx18_out_work_order, work); 485 container_of(work, struct cx18_stream, out_work_order);
490 struct cx18_stream *s = order->s;
491 struct cx18_buffer *buf = order->buf;
492
493 free_out_work_order(order);
494
495 if (buf == NULL)
496 _cx18_stream_load_fw_queue(s);
497 else
498 _cx18_stream_put_buf_fw(s, buf);
499}
500
501static
502struct cx18_out_work_order *alloc_out_work_order(struct cx18 *cx)
503{
504 int i;
505 struct cx18_out_work_order *order = NULL;
506
507 for (i = 0; i < CX18_MAX_OUT_WORK_ORDERS; i++) {
508 /*
509 * We need "pending" to be atomic to inspect & set its contents
510 * 1. "pending" is only set to 1 here, but needs multiple access
511 * protection
512 * 2. work handler threads only clear "pending" and only
513 * on one, particular work order at a time, per handler thread.
514 */
515 if (atomic_add_unless(&cx->out_work_order[i].pending, 1, 1)) {
516 order = &cx->out_work_order[i];
517 break;
518 }
519 }
520 return order;
521}
522
523struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
524 struct cx18_buffer *buf)
525{
526 struct cx18 *cx = s->cx;
527 struct cx18_out_work_order *order;
528
529 order = alloc_out_work_order(cx);
530 if (order == NULL) {
531 CX18_DEBUG_WARN("No blank, outgoing-mailbox, deferred-work, "
532 "order forms available; sending buffer %u back "
533 "to the firmware immediately for stream %s\n",
534 buf->id, s->name);
535 return _cx18_stream_put_buf_fw(s, buf);
536 }
537 order->s = s;
538 order->buf = buf;
539 queue_work(cx->out_work_queue, &order->work);
540 return NULL;
541}
542
543void cx18_stream_load_fw_queue(struct cx18_stream *s)
544{
545 struct cx18 *cx = s->cx;
546 struct cx18_out_work_order *order;
547 486
548 order = alloc_out_work_order(cx); 487 _cx18_stream_load_fw_queue(s);
549 if (order == NULL) {
550 CX18_DEBUG_WARN("No blank, outgoing-mailbox, deferred-work, "
551 "order forms available; filling the firmware "
552 "buffer queue immediately for stream %s\n",
553 s->name);
554 _cx18_stream_load_fw_queue(s);
555 return;
556 }
557 order->s = s;
558 order->buf = NULL; /* Indicates to load the fw queue */
559 queue_work(cx->out_work_queue, &order->work);
560} 488}
561 489
562int cx18_start_v4l2_encode_stream(struct cx18_stream *s) 490int cx18_start_v4l2_encode_stream(struct cx18_stream *s)