mirror of
https://github.com/adulau/aha.git
synced 2025-01-04 23:23:18 +00:00
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>
This commit is contained in:
parent
13563f44a2
commit
f68d0cf567
5 changed files with 26 additions and 37 deletions
|
@ -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 @@ 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;
|
||||
|
@ -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, ¶m);
|
||||
}
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue