mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-13 23:47:04 +07:00
[media] pwc: use the new vb2 helpers
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
cc4b7e7f57
commit
2e43dec0ee
@ -136,19 +136,13 @@ static int leds[2] = { 100, 0 };
|
||||
|
||||
/***/
|
||||
|
||||
static int pwc_video_close(struct file *file);
|
||||
static ssize_t pwc_video_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
|
||||
static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
|
||||
|
||||
static const struct v4l2_file_operations pwc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = v4l2_fh_open,
|
||||
.release = pwc_video_close,
|
||||
.read = pwc_video_read,
|
||||
.poll = pwc_video_poll,
|
||||
.mmap = pwc_video_mmap,
|
||||
.release = vb2_fop_release,
|
||||
.read = vb2_fop_read,
|
||||
.poll = vb2_fop_poll,
|
||||
.mmap = vb2_fop_mmap,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
};
|
||||
static struct video_device pwc_template = {
|
||||
@ -562,17 +556,6 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
|
||||
/***************************************************************************/
|
||||
/* Video4Linux functions */
|
||||
|
||||
int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file)
|
||||
{
|
||||
if (pdev->capt_file != NULL &&
|
||||
pdev->capt_file != file)
|
||||
return -EBUSY;
|
||||
|
||||
pdev->capt_file = file;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pwc_video_release(struct v4l2_device *v)
|
||||
{
|
||||
struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
|
||||
@ -583,113 +566,6 @@ static void pwc_video_release(struct v4l2_device *v)
|
||||
kfree(pdev);
|
||||
}
|
||||
|
||||
static int pwc_video_close(struct file *file)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
|
||||
/*
|
||||
* If we're still streaming vb2_queue_release will call stream_stop
|
||||
* so we must take both the v4l2_lock and the vb_queue_lock.
|
||||
*/
|
||||
if (mutex_lock_interruptible(&pdev->v4l2_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock)) {
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
if (pdev->capt_file == file) {
|
||||
vb2_queue_release(&pdev->vb_queue);
|
||||
pdev->capt_file = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
return v4l2_fh_release(file);
|
||||
}
|
||||
|
||||
static ssize_t pwc_video_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int lock_v4l2 = 0;
|
||||
ssize_t ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* stream_start will get called so we must take the v4l2_lock */
|
||||
if (pdev->vb_queue.fileio == NULL)
|
||||
lock_v4l2 = 1;
|
||||
|
||||
/* Use try_lock, since we're taking the locks in the *wrong* order! */
|
||||
if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock)) {
|
||||
ret = -ERESTARTSYS;
|
||||
goto out;
|
||||
}
|
||||
ret = vb2_read(&pdev->vb_queue, buf, count, ppos,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
if (lock_v4l2)
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
out:
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
struct vb2_queue *q = &pdev->vb_queue;
|
||||
unsigned long req_events = poll_requested_events(wait);
|
||||
unsigned int ret = POLL_ERR;
|
||||
int lock_v4l2 = 0;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return POLL_ERR;
|
||||
|
||||
/* Will this start fileio and thus call start_stream? */
|
||||
if ((req_events & (POLLIN | POLLRDNORM)) &&
|
||||
q->num_buffers == 0 && !q->streaming && q->fileio == NULL) {
|
||||
if (pwc_test_n_set_capt_file(pdev, file))
|
||||
goto out;
|
||||
lock_v4l2 = 1;
|
||||
}
|
||||
|
||||
/* Use try_lock, since we're taking the locks in the *wrong* order! */
|
||||
if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock))
|
||||
goto out;
|
||||
ret = vb2_poll(&pdev->vb_queue, file, wait);
|
||||
if (lock_v4l2)
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
out:
|
||||
if (!pdev->udev)
|
||||
ret |= POLLHUP;
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_mmap(&pdev->vb_queue, vma);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Videobuf2 operations */
|
||||
|
||||
@ -782,6 +658,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
if (!pdev->udev)
|
||||
return -ENODEV;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->v4l2_lock))
|
||||
return -ERESTARTSYS;
|
||||
/* Turn on camera and set LEDS on */
|
||||
pwc_camera_power(pdev, 1);
|
||||
pwc_set_leds(pdev, leds[0], leds[1]);
|
||||
@ -794,6 +672,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||
/* And cleanup any queued bufs!! */
|
||||
pwc_cleanup_queued_bufs(pdev);
|
||||
}
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -802,6 +681,8 @@ static int stop_streaming(struct vb2_queue *vq)
|
||||
{
|
||||
struct pwc_device *pdev = vb2_get_drv_priv(vq);
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->v4l2_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (pdev->udev) {
|
||||
pwc_set_leds(pdev, 0, 0);
|
||||
pwc_camera_power(pdev, 0);
|
||||
@ -809,22 +690,11 @@ static int stop_streaming(struct vb2_queue *vq)
|
||||
}
|
||||
|
||||
pwc_cleanup_queued_bufs(pdev);
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wait_prepare(struct vb2_queue *vq)
|
||||
{
|
||||
struct pwc_device *pdev = vb2_get_drv_priv(vq);
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
}
|
||||
|
||||
static void wait_finish(struct vb2_queue *vq)
|
||||
{
|
||||
struct pwc_device *pdev = vb2_get_drv_priv(vq);
|
||||
mutex_lock(&pdev->vb_queue_lock);
|
||||
}
|
||||
|
||||
static struct vb2_ops pwc_vb_queue_ops = {
|
||||
.queue_setup = queue_setup,
|
||||
.buf_init = buffer_init,
|
||||
@ -834,8 +704,8 @@ static struct vb2_ops pwc_vb_queue_ops = {
|
||||
.buf_queue = buffer_queue,
|
||||
.start_streaming = start_streaming,
|
||||
.stop_streaming = stop_streaming,
|
||||
.wait_prepare = wait_prepare,
|
||||
.wait_finish = wait_finish,
|
||||
.wait_prepare = vb2_ops_wait_prepare,
|
||||
.wait_finish = vb2_ops_wait_finish,
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -1136,6 +1006,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
/* Init video_device structure */
|
||||
memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
|
||||
strcpy(pdev->vdev.name, name);
|
||||
pdev->vdev.queue = &pdev->vb_queue;
|
||||
pdev->vdev.queue->lock = &pdev->vb_queue_lock;
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
|
||||
video_set_drvdata(&pdev->vdev, pdev);
|
||||
|
||||
@ -1190,15 +1062,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
|
||||
pdev->vdev.lock = &pdev->v4l2_lock;
|
||||
|
||||
/*
|
||||
* Don't take v4l2_lock for these ioctls. This improves latency if
|
||||
* v4l2_lock is taken for a long time, e.g. when changing a control
|
||||
* value, and a new frame is ready to be dequeued.
|
||||
*/
|
||||
v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_DQBUF);
|
||||
v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QBUF);
|
||||
v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QUERYBUF);
|
||||
|
||||
rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
|
||||
if (rc < 0) {
|
||||
PWC_ERROR("Failed to register as video device (%d).\n", rc);
|
||||
@ -1253,20 +1116,18 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
|
||||
struct v4l2_device *v = usb_get_intfdata(intf);
|
||||
struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
|
||||
|
||||
mutex_lock(&pdev->v4l2_lock);
|
||||
|
||||
mutex_lock(&pdev->vb_queue_lock);
|
||||
mutex_lock(&pdev->v4l2_lock);
|
||||
/* No need to keep the urbs around after disconnection */
|
||||
if (pdev->vb_queue.streaming)
|
||||
pwc_isoc_cleanup(pdev);
|
||||
pdev->udev = NULL;
|
||||
pwc_cleanup_queued_bufs(pdev);
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
|
||||
v4l2_device_disconnect(&pdev->v4l2_dev);
|
||||
video_unregister_device(&pdev->vdev);
|
||||
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
mutex_unlock(pdev->vb_queue.lock);
|
||||
|
||||
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
|
||||
if (pdev->button_dev)
|
||||
|
@ -468,17 +468,8 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret)
|
||||
goto leave;
|
||||
|
||||
if (pdev->vb_queue.streaming) {
|
||||
ret = -EBUSY;
|
||||
goto leave;
|
||||
}
|
||||
if (vb2_is_busy(&pdev->vb_queue))
|
||||
return -EBUSY;
|
||||
|
||||
pixelformat = f->fmt.pix.pixelformat;
|
||||
|
||||
@ -496,8 +487,6 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
|
||||
PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
|
||||
|
||||
pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
|
||||
leave:
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -933,104 +922,6 @@ static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *
|
||||
return pwc_vidioc_try_fmt(pdev, f);
|
||||
}
|
||||
|
||||
static int pwc_reqbufs(struct file *file, void *fh,
|
||||
struct v4l2_requestbuffers *rb)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_reqbufs(&pdev->vb_queue, rb);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_querybuf(&pdev->vb_queue, buf);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_qbuf(&pdev->vb_queue, buf);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_dqbuf(&pdev->vb_queue, buf,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_streamon(&pdev->vb_queue, i);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_streamoff(&pdev->vb_queue, i);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_enum_framesizes(struct file *file, void *fh,
|
||||
struct v4l2_frmsizeenum *fsize)
|
||||
{
|
||||
@ -1119,25 +1010,14 @@ static int pwc_s_parm(struct file *file, void *fh,
|
||||
fps = parm->parm.capture.timeperframe.denominator /
|
||||
parm->parm.capture.timeperframe.numerator;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret)
|
||||
goto leave;
|
||||
|
||||
if (pdev->vb_queue.streaming) {
|
||||
ret = -EBUSY;
|
||||
goto leave;
|
||||
}
|
||||
if (vb2_is_busy(&pdev->vb_queue))
|
||||
return -EBUSY;
|
||||
|
||||
ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
|
||||
fps, &compression, 0);
|
||||
|
||||
pwc_g_parm(file, fh, parm);
|
||||
|
||||
leave:
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1150,12 +1030,12 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
|
||||
.vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap,
|
||||
.vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap,
|
||||
.vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap,
|
||||
.vidioc_reqbufs = pwc_reqbufs,
|
||||
.vidioc_querybuf = pwc_querybuf,
|
||||
.vidioc_qbuf = pwc_qbuf,
|
||||
.vidioc_dqbuf = pwc_dqbuf,
|
||||
.vidioc_streamon = pwc_streamon,
|
||||
.vidioc_streamoff = pwc_streamoff,
|
||||
.vidioc_reqbufs = vb2_ioctl_reqbufs,
|
||||
.vidioc_querybuf = vb2_ioctl_querybuf,
|
||||
.vidioc_qbuf = vb2_ioctl_qbuf,
|
||||
.vidioc_dqbuf = vb2_ioctl_dqbuf,
|
||||
.vidioc_streamon = vb2_ioctl_streamon,
|
||||
.vidioc_streamoff = vb2_ioctl_streamoff,
|
||||
.vidioc_log_status = v4l2_ctrl_log_status,
|
||||
.vidioc_enum_framesizes = pwc_enum_framesizes,
|
||||
.vidioc_enum_frameintervals = pwc_enum_frameintervals,
|
||||
|
@ -239,7 +239,6 @@ struct pwc_device
|
||||
int features; /* feature bits */
|
||||
|
||||
/*** Video data ***/
|
||||
struct file *capt_file; /* file doing video capture */
|
||||
int vendpoint; /* video isoc endpoint */
|
||||
int vcinterface; /* video control interface */
|
||||
int valternate; /* alternate interface needed */
|
||||
@ -355,8 +354,6 @@ struct pwc_device
|
||||
extern int pwc_trace;
|
||||
#endif
|
||||
|
||||
int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file);
|
||||
|
||||
/** Functions in pwc-misc.c */
|
||||
/* sizes in pixels */
|
||||
extern const int pwc_image_sizes[PSZ_MAX][2];
|
||||
|
Loading…
Reference in New Issue
Block a user