aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx18/cx18-driver.c10
-rw-r--r--drivers/media/video/cx18/cx18-driver.h2
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c37
-rw-r--r--drivers/media/video/cx18/cx18-irq.c8
-rw-r--r--drivers/media/video/cx18/cx18-streams.c6
5 files changed, 26 insertions, 37 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index d7879fb1d21f..6799eab8b6ac 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -449,12 +449,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
449 449
450 spin_lock_init(&cx->lock); 450 spin_lock_init(&cx->lock);
451 451
452 cx->work_queue = create_singlethread_workqueue(cx->name);
453 if (cx->work_queue == NULL) {
454 CX18_ERR("Could not create work queue\n");
455 return -1;
456 }
457
458 INIT_WORK(&cx->work, cx18_work_handler); 452 INIT_WORK(&cx->work, cx18_work_handler);
459 453
460 /* start counting open_id at 1 */ 454 /* start counting open_id at 1 */
@@ -837,7 +831,6 @@ free_map:
837free_mem: 831free_mem:
838 release_mem_region(cx->base_addr, CX18_MEM_SIZE); 832 release_mem_region(cx->base_addr, CX18_MEM_SIZE);
839free_workqueue: 833free_workqueue:
840 destroy_workqueue(cx->work_queue);
841err: 834err:
842 if (retval == 0) 835 if (retval == 0)
843 retval = -ENODEV; 836 retval = -ENODEV;
@@ -938,8 +931,7 @@ static void cx18_remove(struct pci_dev *pci_dev)
938 931
939 cx18_halt_firmware(cx); 932 cx18_halt_firmware(cx);
940 933
941 flush_workqueue(cx->work_queue); 934 flush_scheduled_work();
942 destroy_workqueue(cx->work_queue);
943 935
944 cx18_streams_cleanup(cx, 1); 936 cx18_streams_cleanup(cx, 1);
945 937
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index fe9e5bb979e0..04f1c624da7c 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -207,7 +207,6 @@ struct cx18_options {
207#define CX18_F_I_WORK_HANDLER_DVB 18 /* work to be done for DVB */ 207#define CX18_F_I_WORK_HANDLER_DVB 18 /* work to be done for DVB */
208#define CX18_F_I_INITED 21 /* set after first open */ 208#define CX18_F_I_INITED 21 /* set after first open */
209#define CX18_F_I_FAILED 22 /* set if first open failed */ 209#define CX18_F_I_FAILED 22 /* set if first open failed */
210#define CX18_F_I_WORK_INITED 23 /* worker thread initialized */
211 210
212/* These are the VBI types as they appear in the embedded VBI private packets. */ 211/* These are the VBI types as they appear in the embedded VBI private packets. */
213#define CX18_SLICED_TYPE_TELETEXT_B (1) 212#define CX18_SLICED_TYPE_TELETEXT_B (1)
@@ -435,7 +434,6 @@ struct cx18 {
435 /* when the current DMA is finished this queue is woken up */ 434 /* when the current DMA is finished this queue is woken up */
436 wait_queue_head_t dma_waitq; 435 wait_queue_head_t dma_waitq;
437 436
438 struct workqueue_struct *work_queue;
439 struct work_struct work; 437 struct work_struct work;
440 438
441 /* i2c */ 439 /* i2c */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 4542e2e5e3d7..4845f732ef48 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -109,20 +109,23 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
109 if (!demux->dmx.frontend) 109 if (!demux->dmx.frontend)
110 return -EINVAL; 110 return -EINVAL;
111 111
112 if (stream) { 112 if (!stream)
113 mutex_lock(&stream->dvb.feedlock); 113 return -EINVAL;
114 if (stream->dvb.feeding++ == 0) { 114
115 CX18_DEBUG_INFO("Starting Transport DMA\n"); 115 mutex_lock(&stream->dvb.feedlock);
116 ret = cx18_start_v4l2_encode_stream(stream); 116 if (stream->dvb.feeding++ == 0) {
117 if (ret < 0) { 117 CX18_DEBUG_INFO("Starting Transport DMA\n");
118 CX18_DEBUG_INFO( 118 set_bit(CX18_F_S_STREAMING, &stream->s_flags);
119 "Failed to start Transport DMA\n"); 119 ret = cx18_start_v4l2_encode_stream(stream);
120 stream->dvb.feeding--; 120 if (ret < 0) {
121 } 121 CX18_DEBUG_INFO("Failed to start Transport DMA\n");
122 } else 122 stream->dvb.feeding--;
123 ret = 0; 123 if (stream->dvb.feeding == 0)
124 mutex_unlock(&stream->dvb.feedlock); 124 clear_bit(CX18_F_S_STREAMING, &stream->s_flags);
125 } 125 }
126 } else
127 ret = 0;
128 mutex_unlock(&stream->dvb.feedlock);
126 129
127 return ret; 130 return ret;
128} 131}
@@ -313,9 +316,11 @@ void cx18_dvb_work_handler(struct cx18 *cx)
313 dvb_dmx_swfilter(&s->dvb.demux, buf->buf, 316 dvb_dmx_swfilter(&s->dvb.demux, buf->buf,
314 buf->bytesused); 317 buf->bytesused);
315 318
316 cx18_enqueue(s, buf, &s->q_free);
317 cx18_buf_sync_for_device(s, buf); 319 cx18_buf_sync_for_device(s, buf);
318 if (s->handle == CX18_INVALID_TASK_HANDLE) /* FIXME: improve */ 320 cx18_enqueue(s, buf, &s->q_free);
321
322 if (s->handle == CX18_INVALID_TASK_HANDLE ||
323 !test_bit(CX18_F_S_STREAMING, &s->s_flags))
319 continue; 324 continue;
320 325
321 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, 326 cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle,
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c
index 5fbfbd0f1493..33f56c61ca74 100644
--- a/drivers/media/video/cx18/cx18-irq.c
+++ b/drivers/media/video/cx18/cx18-irq.c
@@ -34,12 +34,6 @@
34void cx18_work_handler(struct work_struct *work) 34void cx18_work_handler(struct work_struct *work)
35{ 35{
36 struct cx18 *cx = container_of(work, struct cx18, work); 36 struct cx18 *cx = container_of(work, struct cx18, work);
37 if (test_and_clear_bit(CX18_F_I_WORK_INITED, &cx->i_flags)) {
38 struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
39 /* This thread must use the FIFO scheduler as it
40 * is realtime sensitive. */
41 sched_setscheduler(current, SCHED_FIFO, &param);
42 }
43 if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags)) 37 if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags))
44 cx18_dvb_work_handler(cx); 38 cx18_dvb_work_handler(cx);
45} 39}
@@ -194,7 +188,7 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id)
194 epu_cmd(cx, sw1); 188 epu_cmd(cx, sw1);
195 189
196 if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags)) 190 if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags))
197 queue_work(cx->work_queue, &cx->work); 191 schedule_work(&cx->work);
198 192
199 return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; 193 return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE;
200} 194}
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index e5ff7705b7a1..c7d431f49238 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -560,9 +560,6 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
560 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); 560 CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n");
561 } 561 }
562 562
563 /* Tell the CX23418 it can't use our buffers anymore */
564 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
565
566 if (s->type != CX18_ENC_STREAM_TYPE_TS) 563 if (s->type != CX18_ENC_STREAM_TYPE_TS)
567 atomic_dec(&cx->ana_capturing); 564 atomic_dec(&cx->ana_capturing);
568 atomic_dec(&cx->tot_capturing); 565 atomic_dec(&cx->tot_capturing);
@@ -570,6 +567,9 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
570 /* Clear capture and no-read bits */ 567 /* Clear capture and no-read bits */
571 clear_bit(CX18_F_S_STREAMING, &s->s_flags); 568 clear_bit(CX18_F_S_STREAMING, &s->s_flags);
572 569
570 /* Tell the CX23418 it can't use our buffers anymore */
571 cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle);
572
573 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); 573 cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
574 s->handle = CX18_INVALID_TASK_HANDLE; 574 s->handle = CX18_INVALID_TASK_HANDLE;
575 575