Commit 60c66b6f authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] tlg2300: allow multiple opens

Due to a poor administration of the driver state it wasn't possible to open
a video or vbi device multiple times.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Acked-by: default avatarHuang Shijie <shijie8@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent d4de6e40
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#define POSEIDON_STATE_ANALOG (0x0001) #define POSEIDON_STATE_ANALOG (0x0001)
#define POSEIDON_STATE_FM (0x0002) #define POSEIDON_STATE_FM (0x0002)
#define POSEIDON_STATE_DVBT (0x0004) #define POSEIDON_STATE_DVBT (0x0004)
#define POSEIDON_STATE_VBI (0x0008)
#define POSEIDON_STATE_DISCONNECT (0x0080) #define POSEIDON_STATE_DISCONNECT (0x0080)
#define PM_SUSPEND_DELAY 3 #define PM_SUSPEND_DELAY 3
......
...@@ -1352,12 +1352,14 @@ static int pd_video_open(struct file *file) ...@@ -1352,12 +1352,14 @@ static int pd_video_open(struct file *file)
mutex_lock(&pd->lock); mutex_lock(&pd->lock);
usb_autopm_get_interface(pd->interface); usb_autopm_get_interface(pd->interface);
if (vfd->vfl_type == VFL_TYPE_GRABBER if (pd->state && !(pd->state & POSEIDON_STATE_ANALOG)) {
&& !(pd->state & POSEIDON_STATE_ANALOG)) { ret = -EBUSY;
front = kzalloc(sizeof(struct front_face), GFP_KERNEL); goto out;
if (!front) }
goto out; front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
if (!front)
goto out;
if (vfd->vfl_type == VFL_TYPE_GRABBER) {
pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */ pd->cur_transfer_mode = usb_transfer_mode;/* bulk or iso */
init_video_context(&pd->video_data.context); init_video_context(&pd->video_data.context);
...@@ -1368,7 +1370,6 @@ static int pd_video_open(struct file *file) ...@@ -1368,7 +1370,6 @@ static int pd_video_open(struct file *file)
goto out; goto out;
} }
pd->state |= POSEIDON_STATE_ANALOG;
front->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; front->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
pd->video_data.users++; pd->video_data.users++;
set_debug_mode(vfd, debug_mode); set_debug_mode(vfd, debug_mode);
...@@ -1379,13 +1380,7 @@ static int pd_video_open(struct file *file) ...@@ -1379,13 +1380,7 @@ static int pd_video_open(struct file *file)
V4L2_FIELD_INTERLACED,/* video is interlacd */ V4L2_FIELD_INTERLACED,/* video is interlacd */
sizeof(struct videobuf_buffer),/*it's enough*/ sizeof(struct videobuf_buffer),/*it's enough*/
front, NULL); front, NULL);
} else if (vfd->vfl_type == VFL_TYPE_VBI } else {
&& !(pd->state & POSEIDON_STATE_VBI)) {
front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
if (!front)
goto out;
pd->state |= POSEIDON_STATE_VBI;
front->type = V4L2_BUF_TYPE_VBI_CAPTURE; front->type = V4L2_BUF_TYPE_VBI_CAPTURE;
pd->vbi_data.front = front; pd->vbi_data.front = front;
pd->vbi_data.users++; pd->vbi_data.users++;
...@@ -1396,19 +1391,15 @@ static int pd_video_open(struct file *file) ...@@ -1396,19 +1391,15 @@ static int pd_video_open(struct file *file)
V4L2_FIELD_NONE, /* vbi is NONE mode */ V4L2_FIELD_NONE, /* vbi is NONE mode */
sizeof(struct videobuf_buffer), sizeof(struct videobuf_buffer),
front, NULL); front, NULL);
} else {
/* maybe add FM support here */
log("other ");
ret = -EINVAL;
goto out;
} }
front->pd = pd; pd->state |= POSEIDON_STATE_ANALOG;
front->curr_frame = NULL; front->pd = pd;
front->curr_frame = NULL;
INIT_LIST_HEAD(&front->active); INIT_LIST_HEAD(&front->active);
spin_lock_init(&front->queue_lock); spin_lock_init(&front->queue_lock);
file->private_data = front; file->private_data = front;
kref_get(&pd->kref); kref_get(&pd->kref);
mutex_unlock(&pd->lock); mutex_unlock(&pd->lock);
...@@ -1429,8 +1420,6 @@ static int pd_video_release(struct file *file) ...@@ -1429,8 +1420,6 @@ static int pd_video_release(struct file *file)
mutex_lock(&pd->lock); mutex_lock(&pd->lock);
if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { if (front->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
pd->state &= ~POSEIDON_STATE_ANALOG;
/* stop the device, and free the URBs */ /* stop the device, and free the URBs */
usb_transfer_stop(&pd->video_data); usb_transfer_stop(&pd->video_data);
free_all_urb(&pd->video_data); free_all_urb(&pd->video_data);
...@@ -1442,10 +1431,11 @@ static int pd_video_release(struct file *file) ...@@ -1442,10 +1431,11 @@ static int pd_video_release(struct file *file)
pd->file_for_stream = NULL; pd->file_for_stream = NULL;
pd->video_data.users--; pd->video_data.users--;
} else if (front->type == V4L2_BUF_TYPE_VBI_CAPTURE) { } else if (front->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
pd->state &= ~POSEIDON_STATE_VBI;
pd->vbi_data.front = NULL; pd->vbi_data.front = NULL;
pd->vbi_data.users--; pd->vbi_data.users--;
} }
if (!pd->vbi_data.users && !pd->video_data.users)
pd->state &= ~POSEIDON_STATE_ANALOG;
videobuf_stop(&front->q); videobuf_stop(&front->q);
videobuf_mmap_free(&front->q); videobuf_mmap_free(&front->q);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment