Skip to content

Commit

Permalink
V4L/DVB (9592): cx18: Use default kernel work queue; fix streaming fl…
Browse files Browse the repository at this point in the history
…ag for work handler

cx18: Use default kernel work queue; fix streaming flag for work handler.
Eliminate cx18 specific work queue and use the kernel default work queue.
Fixed the F_STREAMING_FLAG for the TS stream so cx18_dvb_work_handler()
can know when it is not safe to send MDLs to the firmware.

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 13563f4 commit f68d0cf
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 37 deletions.
10 changes: 1 addition & 9 deletions drivers/media/video/cx18/cx18-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)

spin_lock_init(&cx->lock);

cx->work_queue = create_singlethread_workqueue(cx->name);
if (cx->work_queue == NULL) {
CX18_ERR("Could not create work queue\n");
return -1;
}

INIT_WORK(&cx->work, cx18_work_handler);

/* start counting open_id at 1 */
Expand Down Expand Up @@ -837,7 +831,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueue:
destroy_workqueue(cx->work_queue);
err:
if (retval == 0)
retval = -ENODEV;
Expand Down Expand Up @@ -938,8 +931,7 @@ static void cx18_remove(struct pci_dev *pci_dev)

cx18_halt_firmware(cx);

flush_workqueue(cx->work_queue);
destroy_workqueue(cx->work_queue);
flush_scheduled_work();

cx18_streams_cleanup(cx, 1);

Expand Down
2 changes: 0 additions & 2 deletions drivers/media/video/cx18/cx18-driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,6 @@ struct cx18_options {
#define CX18_F_I_WORK_HANDLER_DVB 18 /* work to be done for DVB */
#define CX18_F_I_INITED 21 /* set after first open */
#define CX18_F_I_FAILED 22 /* set if first open failed */
#define CX18_F_I_WORK_INITED 23 /* worker thread initialized */

/* These are the VBI types as they appear in the embedded VBI private packets. */
#define CX18_SLICED_TYPE_TELETEXT_B (1)
Expand Down Expand Up @@ -435,7 +434,6 @@ struct cx18 {
/* when the current DMA is finished this queue is woken up */
wait_queue_head_t dma_waitq;

struct workqueue_struct *work_queue;
struct work_struct work;

/* i2c */
Expand Down
37 changes: 21 additions & 16 deletions drivers/media/video/cx18/cx18-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,23 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
if (!demux->dmx.frontend)
return -EINVAL;

if (stream) {
mutex_lock(&stream->dvb.feedlock);
if (stream->dvb.feeding++ == 0) {
CX18_DEBUG_INFO("Starting Transport DMA\n");
ret = cx18_start_v4l2_encode_stream(stream);
if (ret < 0) {
CX18_DEBUG_INFO(
"Failed to start Transport DMA\n");
stream->dvb.feeding--;
}
} else
ret = 0;
mutex_unlock(&stream->dvb.feedlock);
}
if (!stream)
return -EINVAL;

mutex_lock(&stream->dvb.feedlock);
if (stream->dvb.feeding++ == 0) {
CX18_DEBUG_INFO("Starting Transport DMA\n");
set_bit(CX18_F_S_STREAMING, &stream->s_flags);
ret = cx18_start_v4l2_encode_stream(stream);
if (ret < 0) {
CX18_DEBUG_INFO("Failed to start Transport DMA\n");
stream->dvb.feeding--;
if (stream->dvb.feeding == 0)
clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
}
} else
ret = 0;
mutex_unlock(&stream->dvb.feedlock);

return ret;
}
Expand Down Expand Up @@ -313,9 +316,11 @@ void cx18_dvb_work_handler(struct cx18 *cx)
dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
buf->bytesused);

cx18_enqueue(s, buf, &s->q_free);
cx18_buf_sync_for_device(s, buf);
if (s->handle == CX18_INVALID_TASK_HANDLE) /* FIXME: improve */
cx18_enqueue(s, buf, &s->q_free);

if (s->handle == CX18_INVALID_TASK_HANDLE ||
!test_bit(CX18_F_S_STREAMING, &s->s_flags))
continue;

cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
Expand Down
8 changes: 1 addition & 7 deletions drivers/media/video/cx18/cx18-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@
void cx18_work_handler(struct work_struct *work)
{
struct cx18 *cx = container_of(work, struct cx18, work);
if (test_and_clear_bit(CX18_F_I_WORK_INITED, &cx->i_flags)) {
struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
/* This thread must use the FIFO scheduler as it
* is realtime sensitive. */
sched_setscheduler(current, SCHED_FIFO, &param);
}
if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags))
cx18_dvb_work_handler(cx);
}
Expand Down Expand Up @@ -194,7 +188,7 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
epu_cmd(cx, sw1);

if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags))
queue_work(cx->work_queue, &cx->work);
schedule_work(&cx->work);

return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
}
6 changes: 3 additions & 3 deletions drivers/media/video/cx18/cx18-streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,16 +560,16 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
}

/* Tell the CX23418 it can't use our buffers anymore */
cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);

if (s->type != CX18_ENC_STREAM_TYPE_TS)
atomic_dec(&cx->ana_capturing);
atomic_dec(&cx->tot_capturing);

/* Clear capture and no-read bits */
clear_bit(CX18_F_S_STREAMING, &s->s_flags);

/* Tell the CX23418 it can't use our buffers anymore */
cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);

cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
s->handle = CX18_INVALID_TASK_HANDLE;

Expand Down

0 comments on commit f68d0cf

Please sign in to comment.