summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-05 19:19:15 -0500
committerAndy Walls <awalls@radix.net>2008-11-05 19:19:15 -0500
commit5c9a58b88f61db125e53c96ba49bada98fe466f0 (patch)
tree7b5c7ae70fa35929370d8150550ba0387344d94f /linux/drivers/media
parent94703235501e112e7496efe5bce32671e121d98f (diff)
downloadmediapointer-dvb-s2-5c9a58b88f61db125e53c96ba49bada98fe466f0.tar.gz
mediapointer-dvb-s2-5c9a58b88f61db125e53c96ba49bada98fe466f0.tar.bz2
cx18: Use default kernel work queue; fix streaming flag for work handler
From: Andy Walls <awalls@radix.net> 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. Priority: high Signed-off-by: Andy Walls <awalls@radix.net>
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/video/cx18/cx18-driver.c10
-rw-r--r--linux/drivers/media/video/cx18/cx18-driver.h2
-rw-r--r--linux/drivers/media/video/cx18/cx18-dvb.c37
-rw-r--r--linux/drivers/media/video/cx18/cx18-irq.c8
-rw-r--r--linux/drivers/media/video/cx18/cx18-streams.c6
5 files changed, 26 insertions, 37 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c
index 446a132df..62d88d284 100644
--- a/linux/drivers/media/video/cx18/cx18-driver.c
+++ b/linux/drivers/media/video/cx18/cx18-driver.c
@@ -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;
- }
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
INIT_WORK(&cx->work, cx18_work_handler);
#else
@@ -841,7 +835,6 @@ free_map:
free_mem:
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
free_workqueue:
- destroy_workqueue(cx->work_queue);
err:
if (retval == 0)
retval = -ENODEV;
@@ -942,8 +935,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);
diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h
index fe9e5bb97..04f1c624d 100644
--- a/linux/drivers/media/video/cx18/cx18-driver.h
+++ b/linux/drivers/media/video/cx18/cx18-driver.h
@@ -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 */
diff --git a/linux/drivers/media/video/cx18/cx18-dvb.c b/linux/drivers/media/video/cx18/cx18-dvb.c
index 4542e2e5e..4845f732e 100644
--- a/linux/drivers/media/video/cx18/cx18-dvb.c
+++ b/linux/drivers/media/video/cx18/cx18-dvb.c
@@ -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,
diff --git a/linux/drivers/media/video/cx18/cx18-irq.c b/linux/drivers/media/video/cx18/cx18-irq.c
index aff5a3abd..0c1ee93b5 100644
--- a/linux/drivers/media/video/cx18/cx18-irq.c
+++ b/linux/drivers/media/video/cx18/cx18-irq.c
@@ -40,12 +40,6 @@ void cx18_work_handler(void *arg)
{
struct cx18 *cx = arg;
#endif
- 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);
}
@@ -204,7 +198,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;
}
diff --git a/linux/drivers/media/video/cx18/cx18-streams.c b/linux/drivers/media/video/cx18/cx18-streams.c
index 8ead4025e..d29a0b61b 100644
--- a/linux/drivers/media/video/cx18/cx18-streams.c
+++ b/linux/drivers/media/video/cx18/cx18-streams.c
@@ -587,9 +587,6 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
#endif
}
- /* 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);
@@ -597,6 +594,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;