[media] pwc: Rework locking

While testing gtk-v4l's new ctrl event code, I hit the following deadlock
in the pwc driver:

Thread 1:
-Does a VIDIOC_G_CTRL
-video2_ioctl takes the modlock
-video2_ioctl calls v4l2_g_ctrl
-v4l2_g_ctrl takes the ctrl_handler lock
-v4l2_g_ctrl calls pwc_g_volatile_ctrl
-pwc_g_volatile_ctrl releases the modlock as the usb transfer can take a
 significant amount of time and we don't want to block DQBUF / QBUF too long
Thread 2:
-Does a VIDIOC_FOO_CTRL
-video2_ioctl takes the modlock
-video2_ioctl calls v4l2_foo_ctrl
-v4l2_foo_ctrl blocks while trying to take the ctrl_handler lock
Thread 1:
-Blocks while trying to re-take the modlock, as its caller will eventually
 unlock that

Now we have thread 1 waiting for the modlock while holding the ctrl_handler
lock and thread 2 waiting for the ctrl_handler lock while holding the
modlock -> deadlock.

Conclusion:
1) We cannot unlock modlock from pwc_s_ctrl / pwc_g_volatile_ctrl,
   but this can cause QBUF / DQBUF to block for up to a full second
2) After evaluating various option I came to the conclusion that pwc should
   stop using the v4l2 core locking, and instead do its own locking

Thus this patch stops pwc using the v4l2 core locking, and replaces that with
it doing its own locking where necessary.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 04e9524..c2594f4 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -202,11 +202,9 @@
 {
 	struct video_device vdev;
 	struct v4l2_device v4l2_dev;
-	struct mutex modlock;
 
 	/* Pointer to our usb_device, may be NULL after unplug */
 	struct usb_device *udev;
-	/* Protects the setting of udev to NULL by our disconnect handler */
 	struct mutex udevlock;
 
 	/* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
@@ -217,6 +215,7 @@
 
 	/*** Video data ***/
 	struct file *capt_file;	/* file doing video capture */
+	struct mutex capt_file_lock;
 	int vendpoint;		/* video isoc endpoint */
 	int vcinterface;	/* video control interface */
 	int valternate;		/* alternate interface needed */
@@ -350,6 +349,8 @@
 extern int pwc_trace;
 #endif
 
+int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file);
+
 /** Functions in pwc-misc.c */
 /* sizes in pixels */
 extern const struct pwc_coord pwc_image_sizes[PSZ_MAX];