Commit f68d0cf5 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

V4L/DVB (9592): cx18: Use default kernel work queue; fix streaming flag 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: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 13563f44
......@@ -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 */
......@@ -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;
......@@ -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);
......
......@@ -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)
......@@ -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 */
......
......@@ -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;
}
......@@ -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,
......
......@@ -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);
}
......@@ -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;
}
......@@ -560,9 +560,6 @@ 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);
......@@ -570,6 +567,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
/* 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment