V4L/DVB (5410): Add VIDIOC_G/S_PRIORITY support to ivtv.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 1b2f7a6..ce28923 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -502,6 +502,7 @@
 struct ivtv_open_id {
 	u32 open_id;
 	int type;
+	enum v4l2_priority prio;
 	struct ivtv *itv;
 };
 
@@ -732,6 +733,7 @@
 	u32 base_addr;
 	u32 irqmask;
 
+	struct v4l2_prio_state prio;
 	struct workqueue_struct *irq_work_queues;
 	struct work_struct irq_work_queue;
 	struct timer_list dma_timer; /* Timer used to catch unfinished DMAs */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 2f38bb1..1637097 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -766,6 +766,8 @@
 
 	IVTV_DEBUG_IOCTL("close() of %s\n", s->name);
 
+	v4l2_prio_close(&itv->prio, &id->prio);
+
 	/* Easy case first: this stream was never claimed by us */
 	if (s->id != id->open_id) {
 		kfree(id);
@@ -849,6 +851,7 @@
 	}
 	item->itv = itv;
 	item->type = y;
+	v4l2_prio_open(&itv->prio, &item->prio);
 
 	item->open_id = itv->open_id++;
 	filp->private_data = item;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 0e8b639..6f80941 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -703,6 +703,21 @@
 	if (filp) id = (struct ivtv_open_id *)filp->private_data;
 
 	switch (cmd) {
+	case VIDIOC_G_PRIORITY:
+	{
+		enum v4l2_priority *p = arg;
+
+		*p = v4l2_prio_max(&itv->prio);
+		break;
+	}
+
+	case VIDIOC_S_PRIORITY:
+	{
+		enum v4l2_priority *prio = arg;
+
+		return v4l2_prio_change(&itv->prio, &id->prio, *prio);
+	}
+
 	case VIDIOC_QUERYCAP:{
 		struct v4l2_capability *vcap = arg;
 
@@ -1441,9 +1456,29 @@
 {
 	struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
 	struct ivtv *itv = id->itv;
+	int ret;
 
 	IVTV_DEBUG_IOCTL("v4l2 ioctl 0x%08x\n", cmd);
 
+	/* check priority */
+	switch (cmd) {
+	case VIDIOC_S_CTRL:
+	case VIDIOC_S_STD:
+	case VIDIOC_S_INPUT:
+	case VIDIOC_S_OUTPUT:
+	case VIDIOC_S_TUNER:
+	case VIDIOC_S_FREQUENCY:
+	case VIDIOC_S_FMT:
+	case VIDIOC_S_CROP:
+	case VIDIOC_S_AUDIO:
+	case VIDIOC_S_AUDOUT:
+	case VIDIOC_S_EXT_CTRLS:
+	case VIDIOC_S_FBUF:
+		ret = v4l2_prio_check(&itv->prio, &id->prio);
+		if (ret)
+			return ret;
+	}
+
 	switch (cmd) {
 	case VIDIOC_DBG_G_REGISTER:
 	case VIDIOC_DBG_S_REGISTER:
@@ -1452,6 +1487,8 @@
 	case VIDIOC_INT_RESET:
 		return ivtv_internal_ioctls(filp, cmd, arg);
 
+	case VIDIOC_G_PRIORITY:
+	case VIDIOC_S_PRIORITY:
 	case VIDIOC_QUERYCAP:
 	case VIDIOC_ENUMINPUT:
 	case VIDIOC_G_INPUT: