aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/pwc/pwc-if.c75
-rw-r--r--drivers/media/video/pwc/pwc.h4
2 files changed, 33 insertions, 46 deletions
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 01ff643e682d..df639268566f 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -144,17 +144,15 @@ static struct {
144 144
145/***/ 145/***/
146 146
147static int pwc_video_open(struct file *file);
148static int pwc_video_close(struct file *file); 147static int pwc_video_close(struct file *file);
149static ssize_t pwc_video_read(struct file *file, char __user *buf, 148static ssize_t pwc_video_read(struct file *file, char __user *buf,
150 size_t count, loff_t *ppos); 149 size_t count, loff_t *ppos);
151static unsigned int pwc_video_poll(struct file *file, poll_table *wait); 150static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
152static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); 151static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
153static void pwc_video_release(struct video_device *vfd);
154 152
155static const struct v4l2_file_operations pwc_fops = { 153static const struct v4l2_file_operations pwc_fops = {
156 .owner = THIS_MODULE, 154 .owner = THIS_MODULE,
157 .open = pwc_video_open, 155 .open = v4l2_fh_open,
158 .release = pwc_video_close, 156 .release = pwc_video_close,
159 .read = pwc_video_read, 157 .read = pwc_video_read,
160 .poll = pwc_video_poll, 158 .poll = pwc_video_poll,
@@ -163,7 +161,7 @@ static const struct v4l2_file_operations pwc_fops = {
163}; 161};
164static struct video_device pwc_template = { 162static struct video_device pwc_template = {
165 .name = "Philips Webcam", /* Filled in later */ 163 .name = "Philips Webcam", /* Filled in later */
166 .release = pwc_video_release, 164 .release = video_device_release_empty,
167 .fops = &pwc_fops, 165 .fops = &pwc_fops,
168 .ioctl_ops = &pwc_ioctl_ops, 166 .ioctl_ops = &pwc_ioctl_ops,
169}; 167};
@@ -644,25 +642,9 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
644/***************************************************************************/ 642/***************************************************************************/
645/* Video4Linux functions */ 643/* Video4Linux functions */
646 644
647static int pwc_video_open(struct file *file) 645static void pwc_video_release(struct v4l2_device *v)
648{ 646{
649 struct video_device *vdev = video_devdata(file); 647 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
650 struct pwc_device *pdev;
651
652 PWC_DEBUG_OPEN(">> video_open called(vdev = 0x%p).\n", vdev);
653
654 pdev = video_get_drvdata(vdev);
655 if (!pdev->udev)
656 return -ENODEV;
657
658 file->private_data = vdev;
659 PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
660 return 0;
661}
662
663static void pwc_video_release(struct video_device *vfd)
664{
665 struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev);
666 int hint; 648 int hint;
667 649
668 /* search device_hint[] table if we occupy a slot, by any chance */ 650 /* search device_hint[] table if we occupy a slot, by any chance */
@@ -685,26 +667,19 @@ static void pwc_video_release(struct video_device *vfd)
685 667
686static int pwc_video_close(struct file *file) 668static int pwc_video_close(struct file *file)
687{ 669{
688 struct video_device *vdev = file->private_data; 670 struct pwc_device *pdev = video_drvdata(file);
689 struct pwc_device *pdev;
690
691 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
692 671
693 pdev = video_get_drvdata(vdev);
694 if (pdev->capt_file == file) { 672 if (pdev->capt_file == file) {
695 vb2_queue_release(&pdev->vb_queue); 673 vb2_queue_release(&pdev->vb_queue);
696 pdev->capt_file = NULL; 674 pdev->capt_file = NULL;
697 } 675 }
698 676 return v4l2_fh_release(file);
699 PWC_DEBUG_OPEN("<< video_close()\n");
700 return 0;
701} 677}
702 678
703static ssize_t pwc_video_read(struct file *file, char __user *buf, 679static ssize_t pwc_video_read(struct file *file, char __user *buf,
704 size_t count, loff_t *ppos) 680 size_t count, loff_t *ppos)
705{ 681{
706 struct video_device *vdev = file->private_data; 682 struct pwc_device *pdev = video_drvdata(file);
707 struct pwc_device *pdev = video_get_drvdata(vdev);
708 683
709 if (!pdev->udev) 684 if (!pdev->udev)
710 return -ENODEV; 685 return -ENODEV;
@@ -721,8 +696,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
721 696
722static unsigned int pwc_video_poll(struct file *file, poll_table *wait) 697static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
723{ 698{
724 struct video_device *vdev = file->private_data; 699 struct pwc_device *pdev = video_drvdata(file);
725 struct pwc_device *pdev = video_get_drvdata(vdev);
726 700
727 if (!pdev->udev) 701 if (!pdev->udev)
728 return POLL_ERR; 702 return POLL_ERR;
@@ -732,8 +706,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
732 706
733static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 707static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
734{ 708{
735 struct video_device *vdev = file->private_data; 709 struct pwc_device *pdev = video_drvdata(file);
736 struct pwc_device *pdev = video_get_drvdata(vdev);
737 710
738 if (pdev->capt_file != file) 711 if (pdev->capt_file != file)
739 return -EBUSY; 712 return -EBUSY;
@@ -1185,9 +1158,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1185 1158
1186 /* Init video_device structure */ 1159 /* Init video_device structure */
1187 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); 1160 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
1188 pdev->vdev.parent = &intf->dev;
1189 pdev->vdev.lock = &pdev->modlock; 1161 pdev->vdev.lock = &pdev->modlock;
1190 strcpy(pdev->vdev.name, name); 1162 strcpy(pdev->vdev.name, name);
1163 set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
1191 video_set_drvdata(&pdev->vdev, pdev); 1164 video_set_drvdata(&pdev->vdev, pdev);
1192 1165
1193 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); 1166 pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
@@ -1211,9 +1184,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1211 if (hint < MAX_DEV_HINTS) 1184 if (hint < MAX_DEV_HINTS)
1212 device_hint[hint].pdev = pdev; 1185 device_hint[hint].pdev = pdev;
1213 1186
1214 PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
1215 usb_set_intfdata(intf, pdev);
1216
1217#ifdef CONFIG_USB_PWC_DEBUG 1187#ifdef CONFIG_USB_PWC_DEBUG
1218 /* Query sensor type */ 1188 /* Query sensor type */
1219 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { 1189 if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
@@ -1239,15 +1209,24 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1239 goto err_free_mem; 1209 goto err_free_mem;
1240 } 1210 }
1241 1211
1242 pdev->vdev.ctrl_handler = &pdev->ctrl_handler;
1243
1244 /* And powerdown the camera until streaming starts */ 1212 /* And powerdown the camera until streaming starts */
1245 pwc_camera_power(pdev, 0); 1213 pwc_camera_power(pdev, 0);
1246 1214
1215 /* Register the v4l2_device structure */
1216 pdev->v4l2_dev.release = pwc_video_release;
1217 rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
1218 if (rc) {
1219 PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
1220 goto err_free_controls;
1221 }
1222
1223 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
1224 pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
1225
1247 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); 1226 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1248 if (rc < 0) { 1227 if (rc < 0) {
1249 PWC_ERROR("Failed to register as video device (%d).\n", rc); 1228 PWC_ERROR("Failed to register as video device (%d).\n", rc);
1250 goto err_free_controls; 1229 goto err_unregister_v4l2_dev;
1251 } 1230 }
1252 rc = pwc_create_sysfs_files(pdev); 1231 rc = pwc_create_sysfs_files(pdev);
1253 if (rc) 1232 if (rc)
@@ -1290,10 +1269,11 @@ err_video_unreg:
1290 if (hint < MAX_DEV_HINTS) 1269 if (hint < MAX_DEV_HINTS)
1291 device_hint[hint].pdev = NULL; 1270 device_hint[hint].pdev = NULL;
1292 video_unregister_device(&pdev->vdev); 1271 video_unregister_device(&pdev->vdev);
1272err_unregister_v4l2_dev:
1273 v4l2_device_unregister(&pdev->v4l2_dev);
1293err_free_controls: 1274err_free_controls:
1294 v4l2_ctrl_handler_free(&pdev->ctrl_handler); 1275 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
1295err_free_mem: 1276err_free_mem:
1296 usb_set_intfdata(intf, NULL);
1297 kfree(pdev); 1277 kfree(pdev);
1298 return rc; 1278 return rc;
1299} 1279}
@@ -1301,12 +1281,12 @@ err_free_mem:
1301/* The user yanked out the cable... */ 1281/* The user yanked out the cable... */
1302static void usb_pwc_disconnect(struct usb_interface *intf) 1282static void usb_pwc_disconnect(struct usb_interface *intf)
1303{ 1283{
1304 struct pwc_device *pdev = usb_get_intfdata(intf); 1284 struct v4l2_device *v = usb_get_intfdata(intf);
1285 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
1305 1286
1306 mutex_lock(&pdev->udevlock); 1287 mutex_lock(&pdev->udevlock);
1307 mutex_lock(&pdev->modlock); 1288 mutex_lock(&pdev->modlock);
1308 1289
1309 usb_set_intfdata(intf, NULL);
1310 /* No need to keep the urbs around after disconnection */ 1290 /* No need to keep the urbs around after disconnection */
1311 pwc_isoc_cleanup(pdev); 1291 pwc_isoc_cleanup(pdev);
1312 pwc_cleanup_queued_bufs(pdev); 1292 pwc_cleanup_queued_bufs(pdev);
@@ -1317,11 +1297,14 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1317 1297
1318 pwc_remove_sysfs_files(pdev); 1298 pwc_remove_sysfs_files(pdev);
1319 video_unregister_device(&pdev->vdev); 1299 video_unregister_device(&pdev->vdev);
1300 v4l2_device_unregister(&pdev->v4l2_dev);
1320 1301
1321#ifdef CONFIG_USB_PWC_INPUT_EVDEV 1302#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1322 if (pdev->button_dev) 1303 if (pdev->button_dev)
1323 input_unregister_device(pdev->button_dev); 1304 input_unregister_device(pdev->button_dev);
1324#endif 1305#endif
1306
1307 v4l2_device_put(&pdev->v4l2_dev);
1325} 1308}
1326 1309
1327 1310
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 0e4e2d7b7872..dd75b9dbe829 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -35,8 +35,11 @@
35#include <asm/errno.h> 35#include <asm/errno.h>
36#include <linux/videodev2.h> 36#include <linux/videodev2.h>
37#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
38#include <media/v4l2-device.h>
38#include <media/v4l2-ioctl.h> 39#include <media/v4l2-ioctl.h>
39#include <media/v4l2-ctrls.h> 40#include <media/v4l2-ctrls.h>
41#include <media/v4l2-fh.h>
42#include <media/v4l2-event.h>
40#include <media/videobuf2-vmalloc.h> 43#include <media/videobuf2-vmalloc.h>
41#ifdef CONFIG_USB_PWC_INPUT_EVDEV 44#ifdef CONFIG_USB_PWC_INPUT_EVDEV
42#include <linux/input.h> 45#include <linux/input.h>
@@ -198,6 +201,7 @@ struct pwc_frame_buf
198struct pwc_device 201struct pwc_device
199{ 202{
200 struct video_device vdev; 203 struct video_device vdev;
204 struct v4l2_device v4l2_dev;
201 struct mutex modlock; 205 struct mutex modlock;
202 206
203 /* Pointer to our usb_device, may be NULL after unplug */ 207 /* Pointer to our usb_device, may be NULL after unplug */