diff options
author | Andy Walls <awalls@radix.net> | 2008-11-05 19:19:15 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:38:01 -0500 |
commit | f68d0cf56761128e85ebc98d8de4776b89c30279 (patch) | |
tree | 3c0af57cc1909728bef2397b2e9a58305fdea301 | |
parent | 13563f44a27a07dfade36662903037edbf8a6e01 (diff) |
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: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 10 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-dvb.c | 37 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-irq.c | 8 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 6 |
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: | |||
837 | free_mem: | 831 | free_mem: |
838 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); | 832 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); |
839 | free_workqueue: | 833 | free_workqueue: |
840 | destroy_workqueue(cx->work_queue); | ||
841 | err: | 834 | err: |
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 @@ | |||
34 | void cx18_work_handler(struct work_struct *work) | 34 | void 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, ¶m); | ||
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 | ||