diff options
-rw-r--r-- | drivers/media/video/pwc/pwc-if.c | 75 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc.h | 4 |
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 | ||
147 | static int pwc_video_open(struct file *file); | ||
148 | static int pwc_video_close(struct file *file); | 147 | static int pwc_video_close(struct file *file); |
149 | static ssize_t pwc_video_read(struct file *file, char __user *buf, | 148 | static 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); |
151 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); | 150 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); |
152 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); | 151 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); |
153 | static void pwc_video_release(struct video_device *vfd); | ||
154 | 152 | ||
155 | static const struct v4l2_file_operations pwc_fops = { | 153 | static 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 | }; |
164 | static struct video_device pwc_template = { | 162 | static 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 | ||
647 | static int pwc_video_open(struct file *file) | 645 | static 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 | |||
663 | static 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 | ||
686 | static int pwc_video_close(struct file *file) | 668 | static 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 | ||
703 | static ssize_t pwc_video_read(struct file *file, char __user *buf, | 679 | static 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 | ||
722 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait) | 697 | static 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 | ||
733 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) | 707 | static 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); |
1272 | err_unregister_v4l2_dev: | ||
1273 | v4l2_device_unregister(&pdev->v4l2_dev); | ||
1293 | err_free_controls: | 1274 | err_free_controls: |
1294 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); | 1275 | v4l2_ctrl_handler_free(&pdev->ctrl_handler); |
1295 | err_free_mem: | 1276 | err_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... */ |
1302 | static void usb_pwc_disconnect(struct usb_interface *intf) | 1282 | static 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 | |||
198 | struct pwc_device | 201 | struct 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 */ |