[media] ivtv: switch to the v4l core lock
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
4d68e700d6
commit
cdc037817c
|
@ -268,11 +268,13 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
|
|||
}
|
||||
|
||||
/* wait for more data to arrive */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
/* New buffers might have become available before we were added to the waitqueue */
|
||||
if (!s->q_full.buffers)
|
||||
schedule();
|
||||
finish_wait(&s->waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (signal_pending(current)) {
|
||||
/* return if a signal was received */
|
||||
IVTV_DEBUG_INFO("User stopped %s\n", s->name);
|
||||
|
@ -507,9 +509,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_
|
|||
|
||||
IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name);
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
rc = ivtv_start_capture(id);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
|
||||
|
@ -584,9 +584,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
|
|||
set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
|
||||
|
||||
/* Start decoder (returns 0 if already started) */
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
rc = ivtv_start_decoding(id, itv->speed);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
if (rc) {
|
||||
IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
|
||||
|
||||
|
@ -627,11 +625,13 @@ retry:
|
|||
break;
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
return -EAGAIN;
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
/* New buffers might have become free before we were added to the waitqueue */
|
||||
if (!s->q_free.buffers)
|
||||
schedule();
|
||||
finish_wait(&s->waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (signal_pending(current)) {
|
||||
IVTV_DEBUG_INFO("User stopped %s\n", s->name);
|
||||
return -EINTR;
|
||||
|
@ -686,12 +686,14 @@ retry:
|
|||
if (mode == OUT_YUV)
|
||||
ivtv_yuv_setup_stream_frame(itv);
|
||||
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
while (!(got_sig = signal_pending(current)) &&
|
||||
test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
|
||||
schedule();
|
||||
}
|
||||
finish_wait(&itv->dma_waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (got_sig) {
|
||||
IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
|
||||
return -EINTR;
|
||||
|
@ -756,9 +758,7 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
|
|||
if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
|
||||
int rc;
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
rc = ivtv_start_capture(id);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
if (rc) {
|
||||
IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
|
||||
s->name, rc);
|
||||
|
@ -861,7 +861,6 @@ int ivtv_v4l2_close(struct file *filp)
|
|||
|
||||
IVTV_DEBUG_FILE("close %s\n", s->name);
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
/* Stop radio */
|
||||
if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
|
||||
v4l2_fh_is_singular_file(filp)) {
|
||||
|
@ -893,7 +892,6 @@ int ivtv_v4l2_close(struct file *filp)
|
|||
/* Easy case first: this stream was never claimed by us */
|
||||
if (s->id != id->open_id) {
|
||||
kfree(id);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -914,21 +912,25 @@ int ivtv_v4l2_close(struct file *filp)
|
|||
ivtv_stop_capture(id, 0);
|
||||
}
|
||||
kfree(id);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
||||
int ivtv_v4l2_open(struct file *filp)
|
||||
{
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
struct video_device *vdev = video_devdata(filp);
|
||||
#endif
|
||||
struct ivtv_stream *s = video_get_drvdata(vdev);
|
||||
struct ivtv *itv = s->itv;
|
||||
struct ivtv_open_id *item;
|
||||
int res = 0;
|
||||
|
||||
IVTV_DEBUG_FILE("open %s\n", s->name);
|
||||
|
||||
if (ivtv_init_on_first_open(itv)) {
|
||||
IVTV_ERR("Failed to initialize on device %s\n",
|
||||
video_device_node_name(vdev));
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
/* Unless ivtv_fw_debug is set, error out if firmware dead. */
|
||||
if (ivtv_fw_debug) {
|
||||
|
@ -1017,28 +1019,6 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ivtv_v4l2_open(struct file *filp)
|
||||
{
|
||||
int res;
|
||||
struct ivtv *itv = NULL;
|
||||
struct ivtv_stream *s = NULL;
|
||||
struct video_device *vdev = video_devdata(filp);
|
||||
|
||||
s = video_get_drvdata(vdev);
|
||||
itv = s->itv;
|
||||
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (ivtv_init_on_first_open(itv)) {
|
||||
IVTV_ERR("Failed to initialize on device %s\n",
|
||||
video_device_node_name(vdev));
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return -ENXIO;
|
||||
}
|
||||
res = ivtv_serialized_open(s, filp);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ivtv_mute(struct ivtv *itv)
|
||||
{
|
||||
if (atomic_read(&itv->capturing))
|
||||
|
|
|
@ -179,6 +179,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
|
|||
ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
|
||||
|
||||
/* Wait for any DMA to finish */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
while (test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
|
||||
got_sig = signal_pending(current);
|
||||
|
@ -188,6 +189,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
|
|||
schedule();
|
||||
}
|
||||
finish_wait(&itv->dma_waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
if (got_sig)
|
||||
return -EINTR;
|
||||
|
||||
|
@ -1107,6 +1109,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
|
|||
* happens within the first 100 lines of the top field.
|
||||
* Make 4 attempts to sync to the decoder before giving up.
|
||||
*/
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
for (f = 0; f < 4; f++) {
|
||||
prepare_to_wait(&itv->vsync_waitq, &wait,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
|
@ -1115,6 +1118,7 @@ void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
|
|||
schedule_timeout(msecs_to_jiffies(25));
|
||||
}
|
||||
finish_wait(&itv->vsync_waitq, &wait);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
|
||||
if (f == 4)
|
||||
IVTV_WARN("Mode change failed to sync to decoder\n");
|
||||
|
@ -1842,8 +1846,7 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(filp);
|
||||
long ret;
|
||||
|
@ -1855,21 +1858,6 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct ivtv_open_id *id = fh2id(filp->private_data);
|
||||
struct ivtv *itv = id->itv;
|
||||
long res;
|
||||
|
||||
/* DQEVENT can block, so this should not run with the serialize lock */
|
||||
if (cmd == VIDIOC_DQEVENT)
|
||||
return ivtv_serialized_ioctl(itv, filp, cmd, arg);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
|
||||
.vidioc_querycap = ivtv_querycap,
|
||||
.vidioc_s_audio = ivtv_s_audio,
|
||||
|
|
|
@ -214,6 +214,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
|
|||
s->vdev->fops = ivtv_stream_info[type].fops;
|
||||
s->vdev->release = video_device_release;
|
||||
s->vdev->tvnorms = V4L2_STD_ALL;
|
||||
s->vdev->lock = &itv->serialize_lock;
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
|
||||
ivtv_set_funcs(s->vdev);
|
||||
return 0;
|
||||
|
|
|
@ -1149,23 +1149,37 @@ int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src)
|
|||
{
|
||||
struct yuv_playback_info *yi = &itv->yuv_info;
|
||||
struct ivtv_dma_frame dma_args;
|
||||
int res;
|
||||
|
||||
ivtv_yuv_setup_stream_frame(itv);
|
||||
|
||||
/* We only need to supply source addresses for this */
|
||||
dma_args.y_source = src;
|
||||
dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
|
||||
return ivtv_yuv_udma_frame(itv, &dma_args);
|
||||
/* Wait for frame DMA. Note that serialize_lock is locked,
|
||||
so to allow other processes to access the driver while
|
||||
we are waiting unlock first and later lock again. */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
res = ivtv_yuv_udma_frame(itv, &dma_args);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* IVTV_IOC_DMA_FRAME ioctl handler */
|
||||
int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
|
||||
{
|
||||
/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
|
||||
int res;
|
||||
|
||||
/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
|
||||
ivtv_yuv_next_free(itv);
|
||||
ivtv_yuv_setup_frame(itv, args);
|
||||
return ivtv_yuv_udma_frame(itv, args);
|
||||
/* Wait for frame DMA. Note that serialize_lock is locked,
|
||||
so to allow other processes to access the driver while
|
||||
we are waiting unlock first and later lock again. */
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
res = ivtv_yuv_udma_frame(itv, args);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ivtv_yuv_close(struct ivtv *itv)
|
||||
|
@ -1174,7 +1188,9 @@ void ivtv_yuv_close(struct ivtv *itv)
|
|||
int h_filter, v_filter_1, v_filter_2;
|
||||
|
||||
IVTV_DEBUG_YUV("ivtv_yuv_close\n");
|
||||
mutex_unlock(&itv->serialize_lock);
|
||||
ivtv_waitq(&itv->vsync_waitq);
|
||||
mutex_lock(&itv->serialize_lock);
|
||||
|
||||
yi->running = 0;
|
||||
atomic_set(&yi->next_dma_frame, -1);
|
||||
|
|
Loading…
Reference in a new issue