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) ...@@ -449,12 +449,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
spin_lock_init(&cx->lock); 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); INIT_WORK(&cx->work, cx18_work_handler);
/* start counting open_id at 1 */ /* start counting open_id at 1 */
...@@ -837,7 +831,6 @@ static int __devinit cx18_probe(struct pci_dev *dev, ...@@ -837,7 +831,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
free_mem: free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE); release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueue: free_workqueue:
destroy_workqueue(cx->work_queue);
err: err:
if (retval == 0) if (retval == 0)
retval = -ENODEV; retval = -ENODEV;
...@@ -938,8 +931,7 @@ static void cx18_remove(struct pci_dev *pci_dev) ...@@ -938,8 +931,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
cx18_halt_firmware(cx); cx18_halt_firmware(cx);
flush_workqueue(cx->work_queue); flush_scheduled_work();
destroy_workqueue(cx->work_queue);
cx18_streams_cleanup(cx, 1); cx18_streams_cleanup(cx, 1);
......
...@@ -207,7 +207,6 @@ struct cx18_options { ...@@ -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_WORK_HANDLER_DVB 18 /* work to be done for DVB */
#define CX18_F_I_INITED 21 /* set after first open */ #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_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. */ /* These are the VBI types as they appear in the embedded VBI private packets. */
#define CX18_SLICED_TYPE_TELETEXT_B (1) #define CX18_SLICED_TYPE_TELETEXT_B (1)
...@@ -435,7 +434,6 @@ struct cx18 { ...@@ -435,7 +434,6 @@ struct cx18 {
/* when the current DMA is finished this queue is woken up */ /* when the current DMA is finished this queue is woken up */
wait_queue_head_t dma_waitq; wait_queue_head_t dma_waitq;
struct workqueue_struct *work_queue;
struct work_struct work; struct work_struct work;
/* i2c */ /* i2c */
......
...@@ -109,20 +109,23 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) ...@@ -109,20 +109,23 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
if (!demux->dmx.frontend) if (!demux->dmx.frontend)
return -EINVAL; return -EINVAL;
if (stream) { if (!stream)
mutex_lock(&stream->dvb.feedlock); return -EINVAL;
if (stream->dvb.feeding++ == 0) {
CX18_DEBUG_INFO("Starting Transport DMA\n"); mutex_lock(&stream->dvb.feedlock);
ret = cx18_start_v4l2_encode_stream(stream); if (stream->dvb.feeding++ == 0) {
if (ret < 0) { CX18_DEBUG_INFO("Starting Transport DMA\n");
CX18_DEBUG_INFO( set_bit(CX18_F_S_STREAMING, &stream->s_flags);
"Failed to start Transport DMA\n"); ret = cx18_start_v4l2_encode_stream(stream);
stream->dvb.feeding--; if (ret < 0) {
} CX18_DEBUG_INFO("Failed to start Transport DMA\n");
} else stream->dvb.feeding--;
ret = 0; if (stream->dvb.feeding == 0)
mutex_unlock(&stream->dvb.feedlock); clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
} }
} else
ret = 0;
mutex_unlock(&stream->dvb.feedlock);
return ret; return ret;
} }
...@@ -313,9 +316,11 @@ void cx18_dvb_work_handler(struct cx18 *cx) ...@@ -313,9 +316,11 @@ void cx18_dvb_work_handler(struct cx18 *cx)
dvb_dmx_swfilter(&s->dvb.demux, buf->buf, dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
buf->bytesused); buf->bytesused);
cx18_enqueue(s, buf, &s->q_free);
cx18_buf_sync_for_device(s, buf); 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; continue;
cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
......
...@@ -34,12 +34,6 @@ ...@@ -34,12 +34,6 @@
void cx18_work_handler(struct work_struct *work) void cx18_work_handler(struct work_struct *work)
{ {
struct cx18 *cx = container_of(work, struct cx18, 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)) if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags))
cx18_dvb_work_handler(cx); cx18_dvb_work_handler(cx);
} }
...@@ -194,7 +188,7 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) ...@@ -194,7 +188,7 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
epu_cmd(cx, sw1); epu_cmd(cx, sw1);
if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags)) 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; 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) ...@@ -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"); 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) if (s->type != CX18_ENC_STREAM_TYPE_TS)
atomic_dec(&cx->ana_capturing); atomic_dec(&cx->ana_capturing);
atomic_dec(&cx->tot_capturing); atomic_dec(&cx->tot_capturing);
...@@ -570,6 +567,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) ...@@ -570,6 +567,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
/* Clear capture and no-read bits */ /* Clear capture and no-read bits */
clear_bit(CX18_F_S_STREAMING, &s->s_flags); 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); cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
s->handle = CX18_INVALID_TASK_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