Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e13f9e3 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (5404): Merges VBI & YUV handling into a single work queue.

parent 037c86c5
Loading
Loading
Loading
Loading
+7 −18
Original line number Diff line number Diff line
@@ -628,21 +628,13 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
	itv->lock = SPIN_LOCK_UNLOCKED;
	itv->dma_reg_lock = SPIN_LOCK_UNLOCKED;

	itv->vbi.work_queues = create_workqueue("ivtv_vbi");
	if (itv->vbi.work_queues == NULL) {
		IVTV_ERR("Could not create VBI workqueue\n");
	itv->irq_work_queues = create_workqueue(itv->name);
	if (itv->irq_work_queues == NULL) {
		IVTV_ERR("Could not create ivtv workqueue\n");
		return -1;
	}

	itv->yuv_info.work_queues = create_workqueue("ivtv_yuv");
	if (itv->yuv_info.work_queues == NULL) {
		IVTV_ERR("Could not create YUV workqueue\n");
		destroy_workqueue(itv->vbi.work_queues);
		return -1;
	}

	INIT_WORK(&itv->vbi.work_queue, vbi_work_handler);
	INIT_WORK(&itv->yuv_info.work_queue, ivtv_yuv_work_handler);
	INIT_WORK(&itv->irq_work_queue, ivtv_irq_work_handler);

	/* start counting open_id at 1 */
	itv->open_id = 1;
@@ -1241,8 +1233,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
	if (itv->has_cx23415)
		release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
      free_workqueue:
	destroy_workqueue(itv->vbi.work_queues);
	destroy_workqueue(itv->yuv_info.work_queues);
	destroy_workqueue(itv->irq_work_queues);
      err:
	if (retval == 0)
		retval = -ENODEV;
@@ -1284,10 +1275,8 @@ static void ivtv_remove(struct pci_dev *pci_dev)

	/* Stop all Work Queues */
	IVTV_DEBUG_INFO(" Stop Work Queues.\n");
	flush_workqueue(itv->vbi.work_queues);
	flush_workqueue(itv->yuv_info.work_queues);
	destroy_workqueue(itv->vbi.work_queues);
	destroy_workqueue(itv->yuv_info.work_queues);
	flush_workqueue(itv->irq_work_queues);
	destroy_workqueue(itv->irq_work_queues);

	IVTV_DEBUG_INFO(" Stopping Firmware.\n");
	ivtv_halt_firmware(itv);
+23 −23
Original line number Diff line number Diff line
@@ -386,7 +386,6 @@ struct ivtv_mailbox_data {
#define IVTV_F_I_DMA		   0 	/* DMA in progress */
#define IVTV_F_I_UDMA		   1 	/* UDMA in progress */
#define IVTV_F_I_UDMA_PENDING	   2 	/* UDMA pending */

#define IVTV_F_I_SPEED_CHANGE	   3 	/* A speed change is in progress */
#define IVTV_F_I_EOS		   4 	/* End of encoder stream reached */
#define IVTV_F_I_RADIO_USER	   5 	/* The radio tuner is selected */
@@ -399,6 +398,8 @@ struct ivtv_mailbox_data {
#define IVTV_F_I_DECODING_YUV	   12 	/* this stream is YUV frame decoding */
#define IVTV_F_I_ENC_PAUSED	   13 	/* the encoder is paused */
#define IVTV_F_I_VALID_DEC_TIMINGS 14 	/* last_dec_timing is valid */
#define IVTV_F_I_WORK_HANDLER_VBI  15	/* there is work to be done for VBI */
#define IVTV_F_I_WORK_HANDLER_YUV  16	/* there is work to be done for YUV */

/* Event notifications */
#define IVTV_F_I_EV_DEC_STOPPED	   28	/* decoder stopped event */
@@ -612,8 +613,6 @@ struct yuv_playback_info

	u32 yuv_forced_update;
	int update_frame;
	struct workqueue_struct *work_queues;
	struct work_struct work_queue;
	struct yuv_frame_info new_frame_info[4];
	struct yuv_frame_info old_frame_info;
	struct yuv_frame_info old_frame_info_args;
@@ -676,8 +675,6 @@ struct vbi_info {
	struct ivtv_buffer sliced_mpeg_buf;
	u32 inserted_frame;

	struct workqueue_struct *work_queues;
	struct work_struct work_queue;
	u32 start[2], count;
	u32 raw_size;
	u32 sliced_size;
@@ -734,6 +731,9 @@ struct ivtv {

	u32 base_addr;
	u32 irqmask;

	struct workqueue_struct *irq_work_queues;
	struct work_struct irq_work_queue;
	struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */

	struct vbi_info vbi;
+23 −3
Original line number Diff line number Diff line
@@ -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);
	}
}

+2 −0
Original line number Diff line number Diff line
@@ -20,5 +20,7 @@
 */

irqreturn_t ivtv_irq_handler(int irq, void *dev_id);

void ivtv_irq_work_handler(struct work_struct *work);
void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock);
void ivtv_unfinished_dma(unsigned long arg);
+2 −9
Original line number Diff line number Diff line
@@ -32,11 +32,6 @@ static int odd_parity(u8 c)
	return c & 1;
}

void vbi_schedule_work(struct ivtv *itv)
{
	queue_work(itv->vbi.work_queues, &itv->vbi.work_queue);
}

static void passthrough_vbi_data(struct ivtv *itv, int cnt)
{
	int wss = 0;
@@ -454,12 +449,10 @@ void ivtv_disable_vbi(struct ivtv *itv)
	itv->vbi.cc_pos = 0;
}

void vbi_work_handler(struct work_struct *work)

void vbi_work_handler(struct ivtv *itv)
{
	struct vbi_info *info = container_of(work, struct vbi_info, work_queue);
	struct ivtv *itv = container_of(info, struct ivtv, vbi);
	struct v4l2_sliced_vbi_data data;
	DEFINE_WAIT(wait);

	/* Lock */
	if (itv->output_mode == OUT_PASSTHROUGH) {
Loading