aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/test-drivers/vivid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/test-drivers/vivid')
-rw-r--r--drivers/media/test-drivers/vivid/vivid-core.c66
-rw-r--r--drivers/media/test-drivers/vivid/vivid-core.h1
-rw-r--r--drivers/media/test-drivers/vivid/vivid-ctrls.c29
-rw-r--r--drivers/media/test-drivers/vivid/vivid-kthread-cap.c6
-rw-r--r--drivers/media/test-drivers/vivid/vivid-kthread-out.c6
-rw-r--r--drivers/media/test-drivers/vivid/vivid-kthread-touch.c6
-rw-r--r--drivers/media/test-drivers/vivid/vivid-sdr-cap.c6
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-cap.c18
-rw-r--r--drivers/media/test-drivers/vivid/vivid-vid-out.c18
9 files changed, 96 insertions, 60 deletions
diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
index aa8d350fd682..0dc65ef3aa14 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.c
+++ b/drivers/media/test-drivers/vivid/vivid-core.c
@@ -547,11 +547,13 @@ static int vivid_s_fmt_cap_mplane(struct file *file, void *priv,
return vidioc_s_fmt_vid_cap_mplane(file, priv, f);
}
-static bool vivid_is_in_use(struct video_device *vdev)
+static bool vivid_is_in_use(bool valid, struct video_device *vdev)
{
unsigned long flags;
bool res;
+ if (!valid)
+ return false;
spin_lock_irqsave(&vdev->fh_lock, flags);
res = !list_empty(&vdev->fh_list);
spin_unlock_irqrestore(&vdev->fh_lock, flags);
@@ -560,20 +562,46 @@ static bool vivid_is_in_use(struct video_device *vdev)
static bool vivid_is_last_user(struct vivid_dev *dev)
{
- unsigned uses = vivid_is_in_use(&dev->vid_cap_dev) +
- vivid_is_in_use(&dev->vid_out_dev) +
- vivid_is_in_use(&dev->vbi_cap_dev) +
- vivid_is_in_use(&dev->vbi_out_dev) +
- vivid_is_in_use(&dev->sdr_cap_dev) +
- vivid_is_in_use(&dev->radio_rx_dev) +
- vivid_is_in_use(&dev->radio_tx_dev) +
- vivid_is_in_use(&dev->meta_cap_dev) +
- vivid_is_in_use(&dev->meta_out_dev) +
- vivid_is_in_use(&dev->touch_cap_dev);
+ unsigned int uses =
+ vivid_is_in_use(dev->has_vid_cap, &dev->vid_cap_dev) +
+ vivid_is_in_use(dev->has_vid_out, &dev->vid_out_dev) +
+ vivid_is_in_use(dev->has_vbi_cap, &dev->vbi_cap_dev) +
+ vivid_is_in_use(dev->has_vbi_out, &dev->vbi_out_dev) +
+ vivid_is_in_use(dev->has_radio_rx, &dev->radio_rx_dev) +
+ vivid_is_in_use(dev->has_radio_tx, &dev->radio_tx_dev) +
+ vivid_is_in_use(dev->has_sdr_cap, &dev->sdr_cap_dev) +
+ vivid_is_in_use(dev->has_meta_cap, &dev->meta_cap_dev) +
+ vivid_is_in_use(dev->has_meta_out, &dev->meta_out_dev) +
+ vivid_is_in_use(dev->has_touch_cap, &dev->touch_cap_dev);
return uses == 1;
}
+static void vivid_reconnect(struct vivid_dev *dev)
+{
+ if (dev->has_vid_cap)
+ set_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
+ if (dev->has_vid_out)
+ set_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
+ if (dev->has_vbi_cap)
+ set_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
+ if (dev->has_vbi_out)
+ set_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
+ if (dev->has_radio_rx)
+ set_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
+ if (dev->has_radio_tx)
+ set_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
+ if (dev->has_sdr_cap)
+ set_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
+ if (dev->has_meta_cap)
+ set_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
+ if (dev->has_meta_out)
+ set_bit(V4L2_FL_REGISTERED, &dev->meta_out_dev.flags);
+ if (dev->has_touch_cap)
+ set_bit(V4L2_FL_REGISTERED, &dev->touch_cap_dev.flags);
+ dev->disconnect_error = false;
+}
+
static int vivid_fop_release(struct file *file)
{
struct vivid_dev *dev = video_drvdata(file);
@@ -581,23 +609,15 @@ static int vivid_fop_release(struct file *file)
mutex_lock(&dev->mutex);
if (!no_error_inj && v4l2_fh_is_singular_file(file) &&
- !video_is_registered(vdev) && vivid_is_last_user(dev)) {
+ dev->disconnect_error && !video_is_registered(vdev) &&
+ vivid_is_last_user(dev)) {
/*
* I am the last user of this driver, and a disconnect
* was forced (since this video_device is unregistered),
* so re-register all video_device's again.
*/
v4l2_info(&dev->v4l2_dev, "reconnect\n");
- set_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->meta_out_dev.flags);
- set_bit(V4L2_FL_REGISTERED, &dev->touch_cap_dev.flags);
+ vivid_reconnect(dev);
}
mutex_unlock(&dev->mutex);
if (file->private_data == dev->overlay_cap_owner)
@@ -1968,6 +1988,8 @@ static int vivid_remove(struct platform_device *pdev)
if (!dev)
continue;
+ if (dev->disconnect_error)
+ vivid_reconnect(dev);
#ifdef CONFIG_MEDIA_CONTROLLER
media_device_unregister(&dev->mdev);
#endif
diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h
index 99e69b8f770f..9c2d1470b597 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.h
+++ b/drivers/media/test-drivers/vivid/vivid-core.h
@@ -303,6 +303,7 @@ struct vivid_dev {
struct fb_fix_screeninfo fb_fix;
/* Error injection */
+ bool disconnect_error;
bool queue_setup_error;
bool buf_prepare_error;
bool start_streaming_error;
diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c b/drivers/media/test-drivers/vivid/vivid-ctrls.c
index 334130568dcb..11e3b5617f52 100644
--- a/drivers/media/test-drivers/vivid/vivid-ctrls.c
+++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c
@@ -107,14 +107,27 @@ static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case VIVID_CID_DISCONNECT:
v4l2_info(&dev->v4l2_dev, "disconnect\n");
- clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
- clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
- clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
- clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
- clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
- clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
- clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
- clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
+ dev->disconnect_error = true;
+ if (dev->has_vid_cap)
+ clear_bit(V4L2_FL_REGISTERED, &dev->vid_cap_dev.flags);
+ if (dev->has_vid_out)
+ clear_bit(V4L2_FL_REGISTERED, &dev->vid_out_dev.flags);
+ if (dev->has_vbi_cap)
+ clear_bit(V4L2_FL_REGISTERED, &dev->vbi_cap_dev.flags);
+ if (dev->has_vbi_out)
+ clear_bit(V4L2_FL_REGISTERED, &dev->vbi_out_dev.flags);
+ if (dev->has_radio_rx)
+ clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
+ if (dev->has_radio_tx)
+ clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
+ if (dev->has_sdr_cap)
+ clear_bit(V4L2_FL_REGISTERED, &dev->sdr_cap_dev.flags);
+ if (dev->has_meta_cap)
+ clear_bit(V4L2_FL_REGISTERED, &dev->meta_cap_dev.flags);
+ if (dev->has_meta_out)
+ clear_bit(V4L2_FL_REGISTERED, &dev->meta_out_dev.flags);
+ if (dev->has_touch_cap)
+ clear_bit(V4L2_FL_REGISTERED, &dev->touch_cap_dev.flags);
break;
case VIVID_CID_BUTTON:
dev->button_pressed = 30;
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
index 01a9d671b947..67fb3c00f9ad 100644
--- a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
@@ -819,7 +819,7 @@ static int vivid_thread_vid_cap(void *data)
break;
if (!mutex_trylock(&dev->mutex)) {
- schedule_timeout_uninterruptible(1);
+ schedule();
continue;
}
@@ -888,7 +888,9 @@ static int vivid_thread_vid_cap(void *data)
next_jiffies_since_start = jiffies_since_start;
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
- schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+ while (jiffies - cur_jiffies < wait_jiffies &&
+ !kthread_should_stop())
+ schedule();
}
dprintk(dev, 1, "Video Capture Thread End\n");
return 0;
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-out.c b/drivers/media/test-drivers/vivid/vivid-kthread-out.c
index 6780687978f9..79c57d14ac4e 100644
--- a/drivers/media/test-drivers/vivid/vivid-kthread-out.c
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-out.c
@@ -167,7 +167,7 @@ static int vivid_thread_vid_out(void *data)
break;
if (!mutex_trylock(&dev->mutex)) {
- schedule_timeout_uninterruptible(1);
+ schedule();
continue;
}
@@ -233,7 +233,9 @@ static int vivid_thread_vid_out(void *data)
next_jiffies_since_start = jiffies_since_start;
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
- schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+ while (jiffies - cur_jiffies < wait_jiffies &&
+ !kthread_should_stop())
+ schedule();
}
dprintk(dev, 1, "Video Output Thread End\n");
return 0;
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-touch.c b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
index 674507b5ccb5..38fdfee79498 100644
--- a/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
@@ -69,7 +69,7 @@ static int vivid_thread_touch_cap(void *data)
break;
if (!mutex_trylock(&dev->mutex)) {
- schedule_timeout_uninterruptible(1);
+ schedule();
continue;
}
cur_jiffies = jiffies;
@@ -128,7 +128,9 @@ static int vivid_thread_touch_cap(void *data)
next_jiffies_since_start = jiffies_since_start;
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
- schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+ while (jiffies - cur_jiffies < wait_jiffies &&
+ !kthread_should_stop())
+ schedule();
}
dprintk(dev, 1, "Touch Capture Thread End\n");
return 0;
diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
index 2b7522e16efc..a1e52708b7ca 100644
--- a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
@@ -142,7 +142,7 @@ static int vivid_thread_sdr_cap(void *data)
break;
if (!mutex_trylock(&dev->mutex)) {
- schedule_timeout_uninterruptible(1);
+ schedule();
continue;
}
@@ -201,7 +201,9 @@ static int vivid_thread_sdr_cap(void *data)
next_jiffies_since_start = jiffies_since_start;
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
- schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
+ while (jiffies - cur_jiffies < wait_jiffies &&
+ !kthread_should_stop())
+ schedule();
}
dprintk(dev, 1, "SDR Capture Thread End\n");
return 0;
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
index eadf28ab1e39..b9caa4b26209 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -1107,11 +1107,9 @@ int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
((compose->width + 7) / 8) * compose->height))
return -EFAULT;
}
- if (clipcount && win->clips) {
- if (copy_to_user(win->clips, dev->clips_cap,
- clipcount * sizeof(dev->clips_cap[0])))
- return -EFAULT;
- }
+ if (clipcount && win->clips)
+ memcpy(win->clips, dev->clips_cap,
+ clipcount * sizeof(dev->clips_cap[0]));
return 0;
}
@@ -1141,9 +1139,8 @@ int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
if (win->clipcount > MAX_CLIPS)
win->clipcount = MAX_CLIPS;
if (win->clipcount) {
- if (copy_from_user(dev->try_clips_cap, win->clips,
- win->clipcount * sizeof(dev->clips_cap[0])))
- return -EFAULT;
+ memcpy(dev->try_clips_cap, win->clips,
+ win->clipcount * sizeof(dev->clips_cap[0]));
for (i = 0; i < win->clipcount; i++) {
struct v4l2_rect *r = &dev->try_clips_cap[i].c;
@@ -1166,9 +1163,8 @@ int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
return -EINVAL;
}
}
- if (copy_to_user(win->clips, dev->try_clips_cap,
- win->clipcount * sizeof(dev->clips_cap[0])))
- return -EFAULT;
+ memcpy(win->clips, dev->try_clips_cap,
+ win->clipcount * sizeof(dev->clips_cap[0]));
}
return 0;
}
diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.c b/drivers/media/test-drivers/vivid/vivid-vid-out.c
index ee3446e3217c..ac1e981e8342 100644
--- a/drivers/media/test-drivers/vivid/vivid-vid-out.c
+++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c
@@ -857,11 +857,9 @@ int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv,
((dev->compose_out.width + 7) / 8) * dev->compose_out.height))
return -EFAULT;
}
- if (clipcount && win->clips) {
- if (copy_to_user(win->clips, dev->clips_out,
- clipcount * sizeof(dev->clips_out[0])))
- return -EFAULT;
- }
+ if (clipcount && win->clips)
+ memcpy(win->clips, dev->clips_out,
+ clipcount * sizeof(dev->clips_out[0]));
return 0;
}
@@ -891,9 +889,8 @@ int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv,
if (win->clipcount > MAX_CLIPS)
win->clipcount = MAX_CLIPS;
if (win->clipcount) {
- if (copy_from_user(dev->try_clips_out, win->clips,
- win->clipcount * sizeof(dev->clips_out[0])))
- return -EFAULT;
+ memcpy(dev->try_clips_out, win->clips,
+ win->clipcount * sizeof(dev->clips_out[0]));
for (i = 0; i < win->clipcount; i++) {
struct v4l2_rect *r = &dev->try_clips_out[i].c;
@@ -916,9 +913,8 @@ int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv,
return -EINVAL;
}
}
- if (copy_to_user(win->clips, dev->try_clips_out,
- win->clipcount * sizeof(dev->clips_out[0])))
- return -EFAULT;
+ memcpy(win->clips, dev->try_clips_out,
+ win->clipcount * sizeof(dev->clips_out[0]));
}
return 0;
}