From 1e13f9e3f1501cc167e40a2adf07e6e4705cb331 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 10 Mar 2007 06:52:02 -0300 Subject: V4L/DVB (5404): Merges VBI & YUV handling into a single work queue. Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-irq.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'drivers/media/video/ivtv/ivtv-irq.c') diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 0656e18b7c7..c3a047b381b 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c @@ -27,6 +27,7 @@ #include "ivtv-ioctl.h" #include "ivtv-mailbox.h" #include "ivtv-vbi.h" +#include "ivtv-yuv.h" #define DMA_MAGIC_COOKIE 0x000001fe @@ -49,6 +50,19 @@ static inline int ivtv_use_pio(struct ivtv_stream *s) (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set); } +void ivtv_irq_work_handler(struct work_struct *work) +{ + struct ivtv *itv = container_of(work, struct ivtv, irq_work_queue); + + DEFINE_WAIT(wait); + + if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags)) + vbi_work_handler(itv); + + if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags)) + ivtv_yuv_work_handler(itv); +} + /* Determine the required DMA size, setup enough buffers in the predma queue and actually copy the data from the card to the buffers in case a PIO transfer is required for this stream. @@ -643,6 +657,7 @@ static void ivtv_irq_vsync(struct ivtv *itv) } if (frame != (itv->lastVsyncFrame & 1)) { struct ivtv_stream *s = ivtv_get_output_stream(itv); + int work = 0; itv->lastVsyncFrame += 1; if (frame == 0) { @@ -661,8 +676,10 @@ static void ivtv_irq_vsync(struct ivtv *itv) wake_up(&s->waitq); /* Send VBI to saa7127 */ - if (frame) - vbi_schedule_work(itv); + if (frame) { + set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags); + work = 1; + } /* Check if we need to update the yuv registers */ if ((itv->yuv_info.yuv_forced_update || itv->yuv_info.new_frame_info[last_dma_frame].update) && last_dma_frame != -1) { @@ -673,9 +690,12 @@ static void ivtv_irq_vsync(struct ivtv *itv) itv->yuv_info.update_frame = last_dma_frame; itv->yuv_info.new_frame_info[last_dma_frame].update = 0; itv->yuv_info.yuv_forced_update = 0; - queue_work(itv->yuv_info.work_queues, &itv->yuv_info.work_queue); + set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags); + work = 1; } } + if (work) + queue_work(itv->irq_work_queues, &itv->irq_work_queue); } } -- cgit v1.2.3