diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-03-10 04:52:02 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-04-27 14:44:24 -0400 |
commit | 1e13f9e3f1501cc167e40a2adf07e6e4705cb331 (patch) | |
tree | d55c1c1a50b865752867919c6de715adfd9a56d5 /drivers | |
parent | 037c86c53362b0b3dda6201c9f62f64c9d17abb6 (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.c | 25 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 46 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.c | 26 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.h | 2 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-vbi.c | 11 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-vbi.h | 3 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.c | 6 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-yuv.h | 2 |
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 */ |
410 | struct ivtv_SG_element { | 411 | struct 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 | ||
53 | void 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 | ||
22 | irqreturn_t ivtv_irq_handler(int irq, void *dev_id); | 22 | irqreturn_t ivtv_irq_handler(int irq, void *dev_id); |
23 | |||
24 | void ivtv_irq_work_handler(struct work_struct *work); | ||
23 | void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock); | 25 | void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock); |
24 | void ivtv_unfinished_dma(unsigned long arg); | 26 | void 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 | ||
35 | void vbi_schedule_work(struct ivtv *itv) | ||
36 | { | ||
37 | queue_work(itv->vbi.work_queues, &itv->vbi.work_queue); | ||
38 | } | ||
39 | |||
40 | static void passthrough_vbi_data(struct ivtv *itv, int cnt) | 35 | static 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 | ||
457 | void vbi_work_handler(struct work_struct *work) | 452 | |
453 | void 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, | |||
23 | int ivtv_used_line(struct ivtv *itv, int line, int field); | 23 | int ivtv_used_line(struct ivtv *itv, int line, int field); |
24 | void ivtv_disable_vbi(struct ivtv *itv); | 24 | void ivtv_disable_vbi(struct ivtv *itv); |
25 | void ivtv_set_vbi(unsigned long arg); | 25 | void ivtv_set_vbi(unsigned long arg); |
26 | void vbi_work_handler(struct work_struct *work); | 26 | void vbi_work_handler(struct ivtv *itv); |
27 | void 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 */ |
807 | void ivtv_yuv_work_handler (struct work_struct *work) | 807 | void 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 @@ | |||
21 | int ivtv_yuv_filter_check(struct ivtv *itv); | 21 | int ivtv_yuv_filter_check(struct ivtv *itv); |
22 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); | 22 | int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); |
23 | void ivtv_yuv_close(struct ivtv *itv); | 23 | void ivtv_yuv_close(struct ivtv *itv); |
24 | void ivtv_yuv_work_handler (struct work_struct *work); | 24 | void ivtv_yuv_work_handler (struct ivtv *itv); |