V4L/DVB (10645): vivi: introduce v4l2_device and do several cleanups

- add v4l2_device
- remove BKL
- make the debug parameter settable on the fly
- set bus_info in querycap

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 0f25d68..625e966 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -33,12 +33,13 @@
 #include <linux/videodev.h>
 #endif
 #include <linux/interrupt.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
 #include <linux/kthread.h>
 #include <linux/highmem.h>
 #include <linux/freezer.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include "font.h"
 
 #define VIVI_MODULE_NAME "vivi"
 
@@ -47,18 +48,32 @@
 #define WAKE_DENOMINATOR 1001
 #define BUFFER_TIMEOUT     msecs_to_jiffies(500)  /* 0.5 seconds */
 
-#include "font.h"
-
 #define VIVI_MAJOR_VERSION 0
-#define VIVI_MINOR_VERSION 5
+#define VIVI_MINOR_VERSION 6
 #define VIVI_RELEASE 0
 #define VIVI_VERSION \
 	KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
 
-/* Declare static vars that will be used as parameters */
-static unsigned int vid_limit = 16;	/* Video memory limit, in Mb */
-static int video_nr = -1;		/* /dev/videoN, -1 for autodetect */
-static int n_devs = 1;			/* Number of virtual devices */
+MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
+MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static unsigned video_nr = -1;
+module_param(video_nr, uint, 0644);
+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
+
+static unsigned n_devs = 1;
+module_param(n_devs, uint, 0644);
+MODULE_PARM_DESC(n_devs, "number of video devices to create");
+
+static unsigned debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+static unsigned int vid_limit = 16;
+module_param(vid_limit, uint, 0644);
+MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
+
 
 /* supported controls */
 static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -112,11 +127,8 @@
 
 static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
 
-#define dprintk(dev, level, fmt, arg...)				\
-	do {								\
-		if (dev->vfd->debug >= (level))				\
-			printk(KERN_DEBUG "vivi: " fmt , ## arg);	\
-	} while (0)
+#define dprintk(dev, level, fmt, arg...) \
+	v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
 
 /* ------------------------------------------------------------------
 	Basic structures
@@ -206,6 +218,7 @@
 
 struct vivi_dev {
 	struct list_head           vivi_devlist;
+	struct v4l2_device 	   v4l2_dev;
 
 	spinlock_t                 slock;
 	struct mutex		   mutex;
@@ -656,7 +669,7 @@
 	dma_q->kthread = kthread_run(vivi_thread, fh, "vivi");
 
 	if (IS_ERR(dma_q->kthread)) {
-		printk(KERN_ERR "vivi: kernel_thread() failed\n");
+		v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
 		return PTR_ERR(dma_q->kthread);
 	}
 	/* Wakes thread */
@@ -799,8 +812,12 @@
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *cap)
 {
+	struct vivi_fh  *fh  = priv;
+	struct vivi_dev *dev = fh->dev;
+
 	strcpy(cap->driver, "vivi");
 	strcpy(cap->card, "vivi");
+	strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
 	cap->version = VIVI_VERSION;
 	cap->capabilities =	V4L2_CAP_VIDEO_CAPTURE |
 				V4L2_CAP_STREAMING     |
@@ -1124,32 +1141,21 @@
 
 static int vivi_open(struct file *file)
 {
-	int minor = video_devdata(file)->minor;
-	struct vivi_dev *dev;
+	struct vivi_dev *dev = video_drvdata(file);
 	struct vivi_fh *fh = NULL;
 	int i;
 	int retval = 0;
 
-	printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
-
-	lock_kernel();
-	list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
-		if (dev->vfd->minor == minor)
-			goto found;
-	unlock_kernel();
-	return -ENODEV;
-
-found:
 	mutex_lock(&dev->mutex);
 	dev->users++;
 
 	if (dev->users > 1) {
 		dev->users--;
-		retval = -EBUSY;
-		goto unlock;
+		mutex_unlock(&dev->mutex);
+		return -EBUSY;
 	}
 
-	dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor,
+	dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num,
 		v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
 
 	/* allocate + initialize per filehandle data */
@@ -1157,14 +1163,11 @@
 	if (NULL == fh) {
 		dev->users--;
 		retval = -ENOMEM;
-		goto unlock;
 	}
-unlock:
 	mutex_unlock(&dev->mutex);
-	if (retval) {
-		unlock_kernel();
+
+	if (retval)
 		return retval;
-	}
 
 	file->private_data = fh;
 	fh->dev      = dev;
@@ -1193,7 +1196,6 @@
 			sizeof(struct vivi_buffer), fh);
 
 	vivi_start_thread(fh);
-	unlock_kernel();
 
 	return 0;
 }
@@ -1249,32 +1251,6 @@
 	return 0;
 }
 
-static int vivi_release(void)
-{
-	struct vivi_dev *dev;
-	struct list_head *list;
-
-	while (!list_empty(&vivi_devlist)) {
-		list = vivi_devlist.next;
-		list_del(list);
-		dev = list_entry(list, struct vivi_dev, vivi_devlist);
-
-		if (-1 != dev->vfd->minor) {
-			printk(KERN_INFO "%s: unregistering /dev/video%d\n",
-				VIVI_MODULE_NAME, dev->vfd->num);
-			video_unregister_device(dev->vfd);
-		} else {
-			printk(KERN_INFO "%s: releasing /dev/video%d\n",
-				VIVI_MODULE_NAME, dev->vfd->num);
-			video_device_release(dev->vfd);
-		}
-
-		kfree(dev);
-	}
-
-	return 0;
-}
-
 static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct vivi_fh  *fh = file->private_data;
@@ -1337,10 +1313,91 @@
 	.tvnorms              = V4L2_STD_525_60,
 	.current_norm         = V4L2_STD_NTSC_M,
 };
+
 /* -----------------------------------------------------------------
 	Initialization and module stuff
    ------------------------------------------------------------------*/
 
+static int vivi_release(void)
+{
+	struct vivi_dev *dev;
+	struct list_head *list;
+
+	while (!list_empty(&vivi_devlist)) {
+		list = vivi_devlist.next;
+		list_del(list);
+		dev = list_entry(list, struct vivi_dev, vivi_devlist);
+
+		v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n",
+			dev->vfd->num);
+		video_unregister_device(dev->vfd);
+		v4l2_device_unregister(&dev->v4l2_dev);
+		kfree(dev);
+	}
+
+	return 0;
+}
+
+static int __init vivi_create_instance(int i)
+{
+	struct vivi_dev *dev;
+	struct video_device *vfd;
+	int ret;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+			"%s-%03d", VIVI_MODULE_NAME, i);
+	ret = v4l2_device_register(NULL, &dev->v4l2_dev);
+	if (ret)
+		goto free_dev;
+
+	/* init video dma queues */
+	INIT_LIST_HEAD(&dev->vidq.active);
+	init_waitqueue_head(&dev->vidq.wq);
+
+	/* initialize locks */
+	spin_lock_init(&dev->slock);
+	mutex_init(&dev->mutex);
+
+	ret = -ENOMEM;
+	vfd = video_device_alloc();
+	if (!vfd)
+		goto unreg_dev;
+
+	*vfd = vivi_template;
+
+	ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
+	if (ret < 0)
+		goto rel_vdev;
+
+	video_set_drvdata(vfd, dev);
+
+	/* Now that everything is fine, let's add it to device list */
+	list_add_tail(&dev->vivi_devlist, &vivi_devlist);
+
+	snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
+			vivi_template.name, vfd->num);
+
+	if (video_nr >= 0)
+		video_nr++;
+
+	dev->vfd = vfd;
+	v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",
+			vfd->num);
+	return 0;
+
+rel_vdev:
+	video_device_release(vfd);
+unreg_dev:
+	v4l2_device_unregister(&dev->v4l2_dev);
+free_dev:
+	kfree(dev);
+	return ret;
+}
+
 /* This routine allocates from 1 to n_devs virtual drivers.
 
    The real maximum number of virtual drivers will depend on how many drivers
@@ -1349,72 +1406,33 @@
  */
 static int __init vivi_init(void)
 {
-	int ret = -ENOMEM, i;
-	struct vivi_dev *dev;
-	struct video_device *vfd;
+	int ret, i;
 
 	if (n_devs <= 0)
 		n_devs = 1;
 
 	for (i = 0; i < n_devs; i++) {
-		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-		if (!dev)
-			break;
-
-		/* init video dma queues */
-		INIT_LIST_HEAD(&dev->vidq.active);
-		init_waitqueue_head(&dev->vidq.wq);
-
-		/* initialize locks */
-		spin_lock_init(&dev->slock);
-		mutex_init(&dev->mutex);
-
-		vfd = video_device_alloc();
-		if (!vfd) {
-			kfree(dev);
-			break;
-		}
-
-		*vfd = vivi_template;
-
-		ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
-		if (ret < 0) {
-			video_device_release(vfd);
-			kfree(dev);
-
-			/* If some registers succeeded, keep driver */
+		ret = vivi_create_instance(i);
+		if (ret) {
+			/* If some instantiations succeeded, keep driver */
 			if (i)
 				ret = 0;
-
 			break;
 		}
-
-		/* Now that everything is fine, let's add it to device list */
-		list_add_tail(&dev->vivi_devlist, &vivi_devlist);
-
-		snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
-			 vivi_template.name, vfd->minor);
-
-		if (video_nr >= 0)
-			video_nr++;
-
-		dev->vfd = vfd;
-		printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n",
-			VIVI_MODULE_NAME, vfd->num);
 	}
 
 	if (ret < 0) {
-		vivi_release();
 		printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
-	} else {
-		printk(KERN_INFO "Video Technology Magazine Virtual Video "
+		return ret;
+	}
+
+	printk(KERN_INFO "Video Technology Magazine Virtual Video "
 			"Capture Board ver %u.%u.%u successfully loaded.\n",
 			(VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
 			VIVI_VERSION & 0xFF);
 
-		/* n_devs will reflect the actual number of allocated devices */
-		n_devs = i;
-	}
+	/* n_devs will reflect the actual number of allocated devices */
+	n_devs = i;
 
 	return ret;
 }
@@ -1426,19 +1444,3 @@
 
 module_init(vivi_init);
 module_exit(vivi_exit);
-
-MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
-MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
-MODULE_LICENSE("Dual BSD/GPL");
-
-module_param(video_nr, uint, 0444);
-MODULE_PARM_DESC(video_nr, "video iminor start number");
-
-module_param(n_devs, uint, 0444);
-MODULE_PARM_DESC(n_devs, "number of video devices to create");
-
-module_param_named(debug, vivi_template.debug, int, 0444);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");