aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Risolia <luca.risolia@studio.unibo.it>2007-06-13 14:11:15 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-07-18 13:24:09 -0400
commit4052fcc7ba32ebd54cc907991cb855d909ce9d1c (patch)
tree2f1049c2f26d1067fa4e15d74392013c2c091505
parent3b2ae0be9e246974db65a5bf4ccd2de328f3dede (diff)
V4L/DVB (5767): ZC0301 driver updates
- Make the driver depend on V4L2 only (KConfig) - Better and safe locking mechanism of the device structure on open(), close() and disconnect() - Use kref for handling device deallocation - Generic cleanups Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/zc0301/Kconfig2
-rw-r--r--drivers/media/video/zc0301/zc0301.h21
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c147
-rw-r--r--drivers/media/video/zc0301/zc0301_pas202bcb.c1
-rw-r--r--drivers/media/video/zc0301/zc0301_pb0330.c1
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h2
6 files changed, 91 insertions, 83 deletions
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig
index 47cd93f9c7de..edb00293cd59 100644
--- a/drivers/media/video/zc0301/Kconfig
+++ b/drivers/media/video/zc0301/Kconfig
@@ -1,6 +1,6 @@
1config USB_ZC0301 1config USB_ZC0301
2 tristate "USB ZC0301[P] Image Processor and Control Chip support" 2 tristate "USB ZC0301[P] Image Processor and Control Chip support"
3 depends on VIDEO_V4L1 3 depends on VIDEO_V4L2
4 ---help--- 4 ---help---
5 Say Y here if you want support for cameras based on the ZC0301 or 5 Say Y here if you want support for cameras based on the ZC0301 or
6 ZC0301P Image Processors and Control Chips. 6 ZC0301P Image Processors and Control Chips.
diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h
index 710f12eb9126..a2de50efa31a 100644
--- a/drivers/media/video/zc0301/zc0301.h
+++ b/drivers/media/video/zc0301/zc0301.h
@@ -36,6 +36,7 @@
36#include <linux/rwsem.h> 36#include <linux/rwsem.h>
37#include <linux/stddef.h> 37#include <linux/stddef.h>
38#include <linux/string.h> 38#include <linux/string.h>
39#include <linux/kref.h>
39 40
40#include "zc0301_sensor.h" 41#include "zc0301_sensor.h"
41 42
@@ -98,7 +99,7 @@ struct zc0301_module_param {
98 u16 frame_timeout; 99 u16 frame_timeout;
99}; 100};
100 101
101static DECLARE_RWSEM(zc0301_disconnect); 102static DECLARE_RWSEM(zc0301_dev_lock);
102 103
103struct zc0301_device { 104struct zc0301_device {
104 struct video_device* v4ldev; 105 struct video_device* v4ldev;
@@ -121,12 +122,14 @@ struct zc0301_device {
121 122
122 struct zc0301_module_param module_param; 123 struct zc0301_module_param module_param;
123 124
125 struct kref kref;
124 enum zc0301_dev_state state; 126 enum zc0301_dev_state state;
125 u8 users; 127 u8 users;
126 128
127 struct mutex dev_mutex, fileop_mutex; 129 struct completion probe;
130 struct mutex open_mutex, fileop_mutex;
128 spinlock_t queue_lock; 131 spinlock_t queue_lock;
129 wait_queue_head_t open, wait_frame, wait_stream; 132 wait_queue_head_t wait_open, wait_frame, wait_stream;
130}; 133};
131 134
132/*****************************************************************************/ 135/*****************************************************************************/
@@ -156,8 +159,8 @@ do { \
156 else if ((level) == 2) \ 159 else if ((level) == 2) \
157 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ 160 dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
158 else if ((level) >= 3) \ 161 else if ((level) >= 3) \
159 dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ 162 dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \
160 __FUNCTION__, __LINE__ , ## args); \ 163 __FILE__, __FUNCTION__, __LINE__ , ## args); \
161 } \ 164 } \
162} while (0) 165} while (0)
163# define KDBG(level, fmt, args...) \ 166# define KDBG(level, fmt, args...) \
@@ -166,8 +169,8 @@ do { \
166 if ((level) == 1 || (level) == 2) \ 169 if ((level) == 1 || (level) == 2) \
167 pr_info("zc0301: " fmt "\n", ## args); \ 170 pr_info("zc0301: " fmt "\n", ## args); \
168 else if ((level) == 3) \ 171 else if ((level) == 3) \
169 pr_debug("zc0301: [%s:%d] " fmt "\n", __FUNCTION__, \ 172 pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \
170 __LINE__ , ## args); \ 173 __FUNCTION__, __LINE__ , ## args); \
171 } \ 174 } \
172} while (0) 175} while (0)
173# define V4LDBG(level, name, cmd) \ 176# define V4LDBG(level, name, cmd) \
@@ -183,8 +186,8 @@ do { \
183 186
184#undef PDBG 187#undef PDBG
185#define PDBG(fmt, args...) \ 188#define PDBG(fmt, args...) \
186dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ 189dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __FUNCTION__, \
187 __FUNCTION__, __LINE__ , ## args) 190 __LINE__ , ## args)
188 191
189#undef PDBGG 192#undef PDBGG
190#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ 193#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index f1120551c70c..703b741e46df 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -49,11 +49,11 @@
49 49
50#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \ 50#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \
51 "Image Processor and Control Chip" 51 "Image Processor and Control Chip"
52#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia" 52#define ZC0301_MODULE_AUTHOR "(C) 2006-2007 Luca Risolia"
53#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" 53#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
54#define ZC0301_MODULE_LICENSE "GPL" 54#define ZC0301_MODULE_LICENSE "GPL"
55#define ZC0301_MODULE_VERSION "1:1.07" 55#define ZC0301_MODULE_VERSION "1:1.10"
56#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 7) 56#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 10)
57 57
58/*****************************************************************************/ 58/*****************************************************************************/
59 59
@@ -573,7 +573,8 @@ static int zc0301_init(struct zc0301_device* cam)
573 int err = 0; 573 int err = 0;
574 574
575 if (!(cam->state & DEV_INITIALIZED)) { 575 if (!(cam->state & DEV_INITIALIZED)) {
576 init_waitqueue_head(&cam->open); 576 mutex_init(&cam->open_mutex);
577 init_waitqueue_head(&cam->wait_open);
577 qctrl = s->qctrl; 578 qctrl = s->qctrl;
578 rect = &(s->cropcap.defrect); 579 rect = &(s->cropcap.defrect);
579 cam->compression.quality = ZC0301_COMPRESSION_QUALITY; 580 cam->compression.quality = ZC0301_COMPRESSION_QUALITY;
@@ -634,59 +635,73 @@ static int zc0301_init(struct zc0301_device* cam)
634 return 0; 635 return 0;
635} 636}
636 637
638/*****************************************************************************/
637 639
638static void zc0301_release_resources(struct zc0301_device* cam) 640static void zc0301_release_resources(struct kref *kref)
639{ 641{
642 struct zc0301_device *cam = container_of(kref, struct zc0301_device,
643 kref);
640 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor); 644 DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
641 video_set_drvdata(cam->v4ldev, NULL); 645 video_set_drvdata(cam->v4ldev, NULL);
642 video_unregister_device(cam->v4ldev); 646 video_unregister_device(cam->v4ldev);
647 usb_put_dev(cam->usbdev);
643 kfree(cam->control_buffer); 648 kfree(cam->control_buffer);
649 kfree(cam);
644} 650}
645 651
646/*****************************************************************************/
647 652
648static int zc0301_open(struct inode* inode, struct file* filp) 653static int zc0301_open(struct inode* inode, struct file* filp)
649{ 654{
650 struct zc0301_device* cam; 655 struct zc0301_device* cam;
651 int err = 0; 656 int err = 0;
652 657
653 /* 658 if (!down_read_trylock(&zc0301_dev_lock))
654 This is the only safe way to prevent race conditions with
655 disconnect
656 */
657 if (!down_read_trylock(&zc0301_disconnect))
658 return -ERESTARTSYS; 659 return -ERESTARTSYS;
659 660
660 cam = video_get_drvdata(video_devdata(filp)); 661 cam = video_get_drvdata(video_devdata(filp));
661 662
662 if (mutex_lock_interruptible(&cam->dev_mutex)) { 663 if (wait_for_completion_interruptible(&cam->probe)) {
663 up_read(&zc0301_disconnect); 664 up_read(&zc0301_dev_lock);
664 return -ERESTARTSYS; 665 return -ERESTARTSYS;
665 } 666 }
666 667
668 kref_get(&cam->kref);
669
670 if (mutex_lock_interruptible(&cam->open_mutex)) {
671 kref_put(&cam->kref, zc0301_release_resources);
672 up_read(&zc0301_dev_lock);
673 return -ERESTARTSYS;
674 }
675
676 if (cam->state & DEV_DISCONNECTED) {
677 DBG(1, "Device not present");
678 err = -ENODEV;
679 goto out;
680 }
681
667 if (cam->users) { 682 if (cam->users) {
668 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor); 683 DBG(2, "Device /dev/video%d is busy...", cam->v4ldev->minor);
684 DBG(3, "Simultaneous opens are not supported");
669 if ((filp->f_flags & O_NONBLOCK) || 685 if ((filp->f_flags & O_NONBLOCK) ||
670 (filp->f_flags & O_NDELAY)) { 686 (filp->f_flags & O_NDELAY)) {
671 err = -EWOULDBLOCK; 687 err = -EWOULDBLOCK;
672 goto out; 688 goto out;
673 } 689 }
674 mutex_unlock(&cam->dev_mutex); 690 DBG(2, "A blocking open() has been requested. Wait for the "
675 err = wait_event_interruptible_exclusive(cam->open, 691 "device to be released...");
676 cam->state & DEV_DISCONNECTED 692 up_read(&zc0301_dev_lock);
693 err = wait_event_interruptible_exclusive(cam->wait_open,
694 (cam->state & DEV_DISCONNECTED)
677 || !cam->users); 695 || !cam->users);
678 if (err) { 696 down_read(&zc0301_dev_lock);
679 up_read(&zc0301_disconnect); 697 if (err)
680 return err; 698 goto out;
681 }
682 if (cam->state & DEV_DISCONNECTED) { 699 if (cam->state & DEV_DISCONNECTED) {
683 up_read(&zc0301_disconnect); 700 err = -ENODEV;
684 return -ENODEV; 701 goto out;
685 } 702 }
686 mutex_lock(&cam->dev_mutex);
687 } 703 }
688 704
689
690 if (cam->state & DEV_MISCONFIGURED) { 705 if (cam->state & DEV_MISCONFIGURED) {
691 err = zc0301_init(cam); 706 err = zc0301_init(cam);
692 if (err) { 707 if (err) {
@@ -711,36 +726,32 @@ static int zc0301_open(struct inode* inode, struct file* filp)
711 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor); 726 DBG(3, "Video device /dev/video%d is open", cam->v4ldev->minor);
712 727
713out: 728out:
714 mutex_unlock(&cam->dev_mutex); 729 mutex_unlock(&cam->open_mutex);
715 up_read(&zc0301_disconnect); 730 if (err)
731 kref_put(&cam->kref, zc0301_release_resources);
732 up_read(&zc0301_dev_lock);
716 return err; 733 return err;
717} 734}
718 735
719 736
720static int zc0301_release(struct inode* inode, struct file* filp) 737static int zc0301_release(struct inode* inode, struct file* filp)
721{ 738{
722 struct zc0301_device* cam = video_get_drvdata(video_devdata(filp)); 739 struct zc0301_device* cam;
723 740
724 mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */ 741 down_write(&zc0301_dev_lock);
725 742
726 zc0301_stop_transfer(cam); 743 cam = video_get_drvdata(video_devdata(filp));
727 744
745 zc0301_stop_transfer(cam);
728 zc0301_release_buffers(cam); 746 zc0301_release_buffers(cam);
729
730 if (cam->state & DEV_DISCONNECTED) {
731 zc0301_release_resources(cam);
732 usb_put_dev(cam->usbdev);
733 mutex_unlock(&cam->dev_mutex);
734 kfree(cam);
735 return 0;
736 }
737
738 cam->users--; 747 cam->users--;
739 wake_up_interruptible_nr(&cam->open, 1); 748 wake_up_interruptible_nr(&cam->wait_open, 1);
740 749
741 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor); 750 DBG(3, "Video device /dev/video%d closed", cam->v4ldev->minor);
742 751
743 mutex_unlock(&cam->dev_mutex); 752 kref_put(&cam->kref, zc0301_release_resources);
753
754 up_write(&zc0301_dev_lock);
744 755
745 return 0; 756 return 0;
746} 757}
@@ -775,7 +786,7 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
775 DBG(3, "Close and open the device again to choose the read " 786 DBG(3, "Close and open the device again to choose the read "
776 "method"); 787 "method");
777 mutex_unlock(&cam->fileop_mutex); 788 mutex_unlock(&cam->fileop_mutex);
778 return -EINVAL; 789 return -EBUSY;
779 } 790 }
780 791
781 if (cam->io == IO_NONE) { 792 if (cam->io == IO_NONE) {
@@ -953,7 +964,12 @@ static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma)
953 return -EIO; 964 return -EIO;
954 } 965 }
955 966
956 if (cam->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) || 967 if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
968 mutex_unlock(&cam->fileop_mutex);
969 return -EACCES;
970 }
971
972 if (cam->io != IO_MMAP ||
957 size != PAGE_ALIGN(cam->frame[0].buf.length)) { 973 size != PAGE_ALIGN(cam->frame[0].buf.length)) {
958 mutex_unlock(&cam->fileop_mutex); 974 mutex_unlock(&cam->fileop_mutex);
959 return -EINVAL; 975 return -EINVAL;
@@ -984,7 +1000,6 @@ static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma)
984 1000
985 vma->vm_ops = &zc0301_vm_ops; 1001 vma->vm_ops = &zc0301_vm_ops;
986 vma->vm_private_data = &cam->frame[i]; 1002 vma->vm_private_data = &cam->frame[i];
987
988 zc0301_vm_open(vma); 1003 zc0301_vm_open(vma);
989 1004
990 mutex_unlock(&cam->fileop_mutex); 1005 mutex_unlock(&cam->fileop_mutex);
@@ -1211,7 +1226,7 @@ zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
1211 if (cam->frame[i].vma_use_count) { 1226 if (cam->frame[i].vma_use_count) {
1212 DBG(3, "VIDIOC_S_CROP failed. " 1227 DBG(3, "VIDIOC_S_CROP failed. "
1213 "Unmap the buffers first."); 1228 "Unmap the buffers first.");
1214 return -EINVAL; 1229 return -EBUSY;
1215 } 1230 }
1216 1231
1217 if (!s->set_crop) { 1232 if (!s->set_crop) {
@@ -1434,7 +1449,7 @@ zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
1434 if (cam->frame[i].vma_use_count) { 1449 if (cam->frame[i].vma_use_count) {
1435 DBG(3, "VIDIOC_S_FMT failed. " 1450 DBG(3, "VIDIOC_S_FMT failed. "
1436 "Unmap the buffers first."); 1451 "Unmap the buffers first.");
1437 return -EINVAL; 1452 return -EBUSY;
1438 } 1453 }
1439 1454
1440 if (cam->stream == STREAM_ON) 1455 if (cam->stream == STREAM_ON)
@@ -1544,14 +1559,14 @@ zc0301_vidioc_reqbufs(struct zc0301_device* cam, void __user * arg)
1544 if (cam->io == IO_READ) { 1559 if (cam->io == IO_READ) {
1545 DBG(3, "Close and open the device again to choose the mmap " 1560 DBG(3, "Close and open the device again to choose the mmap "
1546 "I/O method"); 1561 "I/O method");
1547 return -EINVAL; 1562 return -EBUSY;
1548 } 1563 }
1549 1564
1550 for (i = 0; i < cam->nbuffers; i++) 1565 for (i = 0; i < cam->nbuffers; i++)
1551 if (cam->frame[i].vma_use_count) { 1566 if (cam->frame[i].vma_use_count) {
1552 DBG(3, "VIDIOC_REQBUFS failed. " 1567 DBG(3, "VIDIOC_REQBUFS failed. "
1553 "Previous buffers are still mapped."); 1568 "Previous buffers are still mapped.");
1554 return -EINVAL; 1569 return -EBUSY;
1555 } 1570 }
1556 1571
1557 if (cam->stream == STREAM_ON) 1572 if (cam->stream == STREAM_ON)
@@ -1699,9 +1714,6 @@ zc0301_vidioc_streamon(struct zc0301_device* cam, void __user * arg)
1699 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP) 1714 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
1700 return -EINVAL; 1715 return -EINVAL;
1701 1716
1702 if (list_empty(&cam->inqueue))
1703 return -EINVAL;
1704
1705 cam->stream = STREAM_ON; 1717 cam->stream = STREAM_ON;
1706 1718
1707 DBG(3, "Stream on"); 1719 DBG(3, "Stream on");
@@ -1949,8 +1961,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1949 goto fail; 1961 goto fail;
1950 } 1962 }
1951 1963
1952 mutex_init(&cam->dev_mutex);
1953
1954 DBG(2, "ZC0301[P] Image Processor and Control Chip detected " 1964 DBG(2, "ZC0301[P] Image Processor and Control Chip detected "
1955 "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct); 1965 "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct);
1956 1966
@@ -1982,7 +1992,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1982 cam->v4ldev->release = video_device_release; 1992 cam->v4ldev->release = video_device_release;
1983 video_set_drvdata(cam->v4ldev, cam); 1993 video_set_drvdata(cam->v4ldev, cam);
1984 1994
1985 mutex_lock(&cam->dev_mutex); 1995 init_completion(&cam->probe);
1986 1996
1987 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, 1997 err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
1988 video_nr[dev_nr]); 1998 video_nr[dev_nr]);
@@ -1992,7 +2002,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
1992 DBG(1, "Free /dev/videoX node not found"); 2002 DBG(1, "Free /dev/videoX node not found");
1993 video_nr[dev_nr] = -1; 2003 video_nr[dev_nr] = -1;
1994 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; 2004 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
1995 mutex_unlock(&cam->dev_mutex); 2005 complete_all(&cam->probe);
1996 goto fail; 2006 goto fail;
1997 } 2007 }
1998 2008
@@ -2004,8 +2014,10 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
2004 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0; 2014 dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
2005 2015
2006 usb_set_intfdata(intf, cam); 2016 usb_set_intfdata(intf, cam);
2017 kref_init(&cam->kref);
2018 usb_get_dev(cam->usbdev);
2007 2019
2008 mutex_unlock(&cam->dev_mutex); 2020 complete_all(&cam->probe);
2009 2021
2010 return 0; 2022 return 0;
2011 2023
@@ -2022,40 +2034,31 @@ fail:
2022 2034
2023static void zc0301_usb_disconnect(struct usb_interface* intf) 2035static void zc0301_usb_disconnect(struct usb_interface* intf)
2024{ 2036{
2025 struct zc0301_device* cam = usb_get_intfdata(intf); 2037 struct zc0301_device* cam;
2026
2027 if (!cam)
2028 return;
2029 2038
2030 down_write(&zc0301_disconnect); 2039 down_write(&zc0301_dev_lock);
2031 2040
2032 mutex_lock(&cam->dev_mutex); 2041 cam = usb_get_intfdata(intf);
2033 2042
2034 DBG(2, "Disconnecting %s...", cam->v4ldev->name); 2043 DBG(2, "Disconnecting %s...", cam->v4ldev->name);
2035 2044
2036 wake_up_interruptible_all(&cam->open);
2037
2038 if (cam->users) { 2045 if (cam->users) {
2039 DBG(2, "Device /dev/video%d is open! Deregistration and " 2046 DBG(2, "Device /dev/video%d is open! Deregistration and "
2040 "memory deallocation are deferred on close.", 2047 "memory deallocation are deferred.",
2041 cam->v4ldev->minor); 2048 cam->v4ldev->minor);
2042 cam->state |= DEV_MISCONFIGURED; 2049 cam->state |= DEV_MISCONFIGURED;
2043 zc0301_stop_transfer(cam); 2050 zc0301_stop_transfer(cam);
2044 cam->state |= DEV_DISCONNECTED; 2051 cam->state |= DEV_DISCONNECTED;
2045 wake_up_interruptible(&cam->wait_frame); 2052 wake_up_interruptible(&cam->wait_frame);
2046 wake_up(&cam->wait_stream); 2053 wake_up(&cam->wait_stream);
2047 usb_get_dev(cam->usbdev); 2054 } else
2048 } else {
2049 cam->state |= DEV_DISCONNECTED; 2055 cam->state |= DEV_DISCONNECTED;
2050 zc0301_release_resources(cam);
2051 }
2052 2056
2053 mutex_unlock(&cam->dev_mutex); 2057 wake_up_interruptible_all(&cam->wait_open);
2054 2058
2055 if (!cam->users) 2059 kref_put(&cam->kref, zc0301_release_resources);
2056 kfree(cam);
2057 2060
2058 up_write(&zc0301_disconnect); 2061 up_write(&zc0301_dev_lock);
2059} 2062}
2060 2063
2061 2064
diff --git a/drivers/media/video/zc0301/zc0301_pas202bcb.c b/drivers/media/video/zc0301/zc0301_pas202bcb.c
index 3efb92a0d0da..24b0dfba357e 100644
--- a/drivers/media/video/zc0301/zc0301_pas202bcb.c
+++ b/drivers/media/video/zc0301/zc0301_pas202bcb.c
@@ -327,6 +327,7 @@ static struct zc0301_sensor pas202bcb = {
327 .height = 480, 327 .height = 480,
328 .pixelformat = V4L2_PIX_FMT_JPEG, 328 .pixelformat = V4L2_PIX_FMT_JPEG,
329 .priv = 8, 329 .priv = 8,
330 .colorspace = V4L2_COLORSPACE_JPEG,
330 }, 331 },
331}; 332};
332 333
diff --git a/drivers/media/video/zc0301/zc0301_pb0330.c b/drivers/media/video/zc0301/zc0301_pb0330.c
index 5784b1d1491c..9519aba3612e 100644
--- a/drivers/media/video/zc0301/zc0301_pb0330.c
+++ b/drivers/media/video/zc0301/zc0301_pb0330.c
@@ -157,6 +157,7 @@ static struct zc0301_sensor pb0330 = {
157 .height = 480, 157 .height = 480,
158 .pixelformat = V4L2_PIX_FMT_JPEG, 158 .pixelformat = V4L2_PIX_FMT_JPEG,
159 .priv = 8, 159 .priv = 8,
160 .colorspace = V4L2_COLORSPACE_JPEG,
160 }, 161 },
161}; 162};
162 163
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index 44e82cff9319..70fe6fc6cdd5 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -23,7 +23,7 @@
23#define _ZC0301_SENSOR_H_ 23#define _ZC0301_SENSOR_H_
24 24
25#include <linux/usb.h> 25#include <linux/usb.h>
26#include <linux/videodev.h> 26#include <linux/videodev2.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/stddef.h> 28#include <linux/stddef.h>
29#include <linux/errno.h> 29#include <linux/errno.h>