aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-03-10 04:52:02 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-04-27 14:44:24 -0400
commit1e13f9e3f1501cc167e40a2adf07e6e4705cb331 (patch)
treed55c1c1a50b865752867919c6de715adfd9a56d5 /drivers
parent037c86c53362b0b3dda6201c9f62f64c9d17abb6 (diff)
V4L/DVB (5404): Merges VBI & YUV handling into a single work queue.
Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c25
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h46
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c26
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.h3
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c6
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.h2
8 files changed, 60 insertions, 61 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 162a1e8fcdc8..ad0c1628ef96 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -628,21 +628,13 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
628 itv->lock = SPIN_LOCK_UNLOCKED; 628 itv->lock = SPIN_LOCK_UNLOCKED;
629 itv->dma_reg_lock = SPIN_LOCK_UNLOCKED; 629 itv->dma_reg_lock = SPIN_LOCK_UNLOCKED;
630 630
631 itv->vbi.work_queues = create_workqueue("ivtv_vbi"); 631 itv->irq_work_queues = create_workqueue(itv->name);
632 if (itv->vbi.work_queues == NULL) { 632 if (itv->irq_work_queues == NULL) {
633 IVTV_ERR("Could not create VBI workqueue\n"); 633 IVTV_ERR("Could not create ivtv workqueue\n");
634 return -1; 634 return -1;
635 } 635 }
636 636
637 itv->yuv_info.work_queues = create_workqueue("ivtv_yuv"); 637 INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler);
638 if (itv->yuv_info.work_queues == NULL) {
639 IVTV_ERR("Could not create YUV workqueue\n");
640 destroy_workqueue(itv->vbi.work_queues);
641 return -1;
642 }
643
644 INIT_WORK(&itv->vbi.work_queue, vbi_work_handler);
645 INIT_WORK(&itv->yuv_info.work_queue, ivtv_yuv_work_handler);
646 638
647 /* start counting open_id at 1 */ 639 /* start counting open_id at 1 */
648 itv->open_id = 1; 640 itv->open_id = 1;
@@ -1241,8 +1233,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
1241 if (itv->has_cx23415) 1233 if (itv->has_cx23415)
1242 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); 1234 release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
1243 free_workqueue: 1235 free_workqueue:
1244 destroy_workqueue(itv->vbi.work_queues); 1236 destroy_workqueue(itv->irq_work_queues);
1245 destroy_workqueue(itv->yuv_info.work_queues);
1246 err: 1237 err:
1247 if (retval == 0) 1238 if (retval == 0)
1248 retval = -ENODEV; 1239 retval = -ENODEV;
@@ -1284,10 +1275,8 @@ static void ivtv_remove(struct pci_dev *pci_dev)
1284 1275
1285 /* Stop all Work Queues */ 1276 /* Stop all Work Queues */
1286 IVTV_DEBUG_INFO(" Stop Work Queues.\n"); 1277 IVTV_DEBUG_INFO(" Stop Work Queues.\n");
1287 flush_workqueue(itv->vbi.work_queues); 1278 flush_workqueue(itv->irq_work_queues);
1288 flush_workqueue(itv->yuv_info.work_queues); 1279 destroy_workqueue(itv->irq_work_queues);
1289 destroy_workqueue(itv->vbi.work_queues);
1290 destroy_workqueue(itv->yuv_info.work_queues);
1291 1280
1292 IVTV_DEBUG_INFO(" Stopping Firmware.\n"); 1281 IVTV_DEBUG_INFO(" Stopping Firmware.\n");
1293 ivtv_halt_firmware(itv); 1282 ivtv_halt_firmware(itv);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 236e3532f569..1b2f7a6d311e 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -383,28 +383,29 @@ struct ivtv_mailbox_data {
383#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */ 383#define IVTV_F_S_APPL_IO 8 /* this stream is used read/written by an application */
384 384
385/* per-ivtv, i_flags */ 385/* per-ivtv, i_flags */
386#define IVTV_F_I_DMA 0 /* DMA in progress */ 386#define IVTV_F_I_DMA 0 /* DMA in progress */
387#define IVTV_F_I_UDMA 1 /* UDMA in progress */ 387#define IVTV_F_I_UDMA 1 /* UDMA in progress */
388#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */ 388#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */
389 389#define IVTV_F_I_SPEED_CHANGE 3 /* A speed change is in progress */
390#define IVTV_F_I_SPEED_CHANGE 3 /* A speed change is in progress */ 390#define IVTV_F_I_EOS 4 /* End of encoder stream reached */
391#define IVTV_F_I_EOS 4 /* End of encoder stream reached */ 391#define IVTV_F_I_RADIO_USER 5 /* The radio tuner is selected */
392#define IVTV_F_I_RADIO_USER 5 /* The radio tuner is selected */ 392#define IVTV_F_I_DIG_RST 6 /* Reset digitizer */
393#define IVTV_F_I_DIG_RST 6 /* Reset digitizer */ 393#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */
394#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */ 394#define IVTV_F_I_ENC_VBI 8 /* VBI DMA */
395#define IVTV_F_I_ENC_VBI 8 /* VBI DMA */ 395#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */
396#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */ 396#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */
397#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */ 397#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */
398#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */ 398#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
399#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ 399#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
400#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
401#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */ 400#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
401#define IVTV_F_I_WORK_HANDLER_VBI 15 /* there is work to be done for VBI */
402#define IVTV_F_I_WORK_HANDLER_YUV 16 /* there is work to be done for YUV */
402 403
403/* Event notifications */ 404/* Event notifications */
404#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ 405#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
405#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */ 406#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */
406#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */ 407#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */
407#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */ 408#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */
408 409
409/* Scatter-Gather array element, used in DMA transfers */ 410/* Scatter-Gather array element, used in DMA transfers */
410struct ivtv_SG_element { 411struct ivtv_SG_element {
@@ -612,8 +613,6 @@ struct yuv_playback_info
612 613
613 u32 yuv_forced_update; 614 u32 yuv_forced_update;
614 int update_frame; 615 int update_frame;
615 struct workqueue_struct *work_queues;
616 struct work_struct work_queue;
617 struct yuv_frame_info new_frame_info[4]; 616 struct yuv_frame_info new_frame_info[4];
618 struct yuv_frame_info old_frame_info; 617 struct yuv_frame_info old_frame_info;
619 struct yuv_frame_info old_frame_info_args; 618 struct yuv_frame_info old_frame_info_args;
@@ -676,8 +675,6 @@ struct vbi_info {
676 struct ivtv_buffer sliced_mpeg_buf; 675 struct ivtv_buffer sliced_mpeg_buf;
677 u32 inserted_frame; 676 u32 inserted_frame;
678 677
679 struct workqueue_struct *work_queues;
680 struct work_struct work_queue;
681 u32 start[2], count; 678 u32 start[2], count;
682 u32 raw_size; 679 u32 raw_size;
683 u32 sliced_size; 680 u32 sliced_size;
@@ -734,6 +731,9 @@ struct ivtv {
734 731
735 u32 base_addr; 732 u32 base_addr;
736 u32 irqmask; 733 u32 irqmask;
734
735 struct workqueue_struct *irq_work_queues;
736 struct work_struct irq_work_queue;
737 struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */ 737 struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */
738 738
739 struct vbi_info vbi; 739 struct vbi_info vbi;
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index 0656e18b7c7e..c3a047b381b3 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -27,6 +27,7 @@
27#include "ivtv-ioctl.h" 27#include "ivtv-ioctl.h"
28#include "ivtv-mailbox.h" 28#include "ivtv-mailbox.h"
29#include "ivtv-vbi.h" 29#include "ivtv-vbi.h"
30#include "ivtv-yuv.h"
30 31
31#define DMA_MAGIC_COOKIE 0x000001fe 32#define DMA_MAGIC_COOKIE 0x000001fe
32 33
@@ -49,6 +50,19 @@ static inline int ivtv_use_pio(struct ivtv_stream *s)
49 (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set); 50 (SLICED_VBI_PIO && s->type == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set);
50} 51}
51 52
53void ivtv_irq_work_handler(struct work_struct *work)
54{
55 struct ivtv *itv = container_of(work, struct ivtv, irq_work_queue);
56
57 DEFINE_WAIT(wait);
58
59 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
60 vbi_work_handler(itv);
61
62 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
63 ivtv_yuv_work_handler(itv);
64}
65
52/* Determine the required DMA size, setup enough buffers in the predma queue and 66/* Determine the required DMA size, setup enough buffers in the predma queue and
53 actually copy the data from the card to the buffers in case a PIO transfer is 67 actually copy the data from the card to the buffers in case a PIO transfer is
54 required for this stream. 68 required for this stream.
@@ -643,6 +657,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
643 } 657 }
644 if (frame != (itv->lastVsyncFrame & 1)) { 658 if (frame != (itv->lastVsyncFrame & 1)) {
645 struct ivtv_stream *s = ivtv_get_output_stream(itv); 659 struct ivtv_stream *s = ivtv_get_output_stream(itv);
660 int work = 0;
646 661
647 itv->lastVsyncFrame += 1; 662 itv->lastVsyncFrame += 1;
648 if (frame == 0) { 663 if (frame == 0) {
@@ -661,8 +676,10 @@ static void ivtv_irq_vsync(struct ivtv *itv)
661 wake_up(&s->waitq); 676 wake_up(&s->waitq);
662 677
663 /* Send VBI to saa7127 */ 678 /* Send VBI to saa7127 */
664 if (frame) 679 if (frame) {
665 vbi_schedule_work(itv); 680 set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
681 work = 1;
682 }
666 683
667 /* Check if we need to update the yuv registers */ 684 /* Check if we need to update the yuv registers */
668 if ((itv->yuv_info.yuv_forced_update || itv->yuv_info.new_frame_info[last_dma_frame].update) && last_dma_frame != -1) { 685 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)
673 itv->yuv_info.update_frame = last_dma_frame; 690 itv->yuv_info.update_frame = last_dma_frame;
674 itv->yuv_info.new_frame_info[last_dma_frame].update = 0; 691 itv->yuv_info.new_frame_info[last_dma_frame].update = 0;
675 itv->yuv_info.yuv_forced_update = 0; 692 itv->yuv_info.yuv_forced_update = 0;
676 queue_work(itv->yuv_info.work_queues, &itv->yuv_info.work_queue); 693 set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
694 work = 1;
677 } 695 }
678 } 696 }
697 if (work)
698 queue_work(itv->irq_work_queues, &itv->irq_work_queue);
679 } 699 }
680} 700}
681 701
diff --git a/drivers/media/video/ivtv/ivtv-irq.h b/drivers/media/video/ivtv/ivtv-irq.h
index ed96205e87a2..a43348a30309 100644
--- a/drivers/media/video/ivtv/ivtv-irq.h
+++ b/drivers/media/video/ivtv/ivtv-irq.h
@@ -20,5 +20,7 @@
20 */ 20 */
21 21
22irqreturn_t ivtv_irq_handler(int irq, void *dev_id); 22irqreturn_t ivtv_irq_handler(int irq, void *dev_id);
23
24void ivtv_irq_work_handler(struct work_struct *work);
23void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock); 25void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
24void ivtv_unfinished_dma(unsigned long arg); 26void ivtv_unfinished_dma(unsigned long arg);
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index b53ca508dacc..5efa5a867818 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -32,11 +32,6 @@ static int odd_parity(u8 c)
32 return c & 1; 32 return c & 1;
33} 33}
34 34
35void vbi_schedule_work(struct ivtv *itv)
36{
37 queue_work(itv->vbi.work_queues, &itv->vbi.work_queue);
38}
39
40static void passthrough_vbi_data(struct ivtv *itv, int cnt) 35static void passthrough_vbi_data(struct ivtv *itv, int cnt)
41{ 36{
42 int wss = 0; 37 int wss = 0;
@@ -454,12 +449,10 @@ void ivtv_disable_vbi(struct ivtv *itv)
454 itv->vbi.cc_pos = 0; 449 itv->vbi.cc_pos = 0;
455} 450}
456 451
457void vbi_work_handler(struct work_struct *work) 452
453void vbi_work_handler(struct ivtv *itv)
458{ 454{
459 struct vbi_info *info = container_of(work, struct vbi_info, work_queue);
460 struct ivtv *itv = container_of(info, struct ivtv, vbi);
461 struct v4l2_sliced_vbi_data data; 455 struct v4l2_sliced_vbi_data data;
462 DEFINE_WAIT(wait);
463 456
464 /* Lock */ 457 /* Lock */
465 if (itv->output_mode == OUT_PASSTHROUGH) { 458 if (itv->output_mode == OUT_PASSTHROUGH) {
diff --git a/drivers/media/video/ivtv/ivtv-vbi.h b/drivers/media/video/ivtv/ivtv-vbi.h
index c897e9bd4f92..cdaea697b3ec 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.h
+++ b/drivers/media/video/ivtv/ivtv-vbi.h
@@ -23,5 +23,4 @@ void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
23int ivtv_used_line(struct ivtv *itv, int line, int field); 23int ivtv_used_line(struct ivtv *itv, int line, int field);
24void ivtv_disable_vbi(struct ivtv *itv); 24void ivtv_disable_vbi(struct ivtv *itv);
25void ivtv_set_vbi(unsigned long arg); 25void ivtv_set_vbi(unsigned long arg);
26void vbi_work_handler(struct work_struct *work); 26void vbi_work_handler(struct ivtv *itv);
27void vbi_schedule_work(struct ivtv *itv);
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index e49ecef93046..c962303e891c 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -804,12 +804,8 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
804} 804}
805 805
806/* Update the scaling register to the requested value */ 806/* Update the scaling register to the requested value */
807void ivtv_yuv_work_handler (struct work_struct *work) 807void ivtv_yuv_work_handler (struct ivtv *itv)
808{ 808{
809 struct yuv_playback_info *info = container_of(work, struct yuv_playback_info, work_queue);
810 struct ivtv *itv = container_of(info, struct ivtv, yuv_info);
811 DEFINE_WAIT(wait);
812
813 struct yuv_frame_info window; 809 struct yuv_frame_info window;
814 u32 yuv_update; 810 u32 yuv_update;
815 811
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h
index 31128733e784..88972d3f77c4 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.h
+++ b/drivers/media/video/ivtv/ivtv-yuv.h
@@ -21,4 +21,4 @@
21int ivtv_yuv_filter_check(struct ivtv *itv); 21int ivtv_yuv_filter_check(struct ivtv *itv);
22int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); 22int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args);
23void ivtv_yuv_close(struct ivtv *itv); 23void ivtv_yuv_close(struct ivtv *itv);
24void ivtv_yuv_work_handler (struct work_struct *work); 24void ivtv_yuv_work_handler (struct ivtv *itv);