return 0;
}
-static int go7007_open(struct file *file)
-{
- struct go7007 *go = video_get_drvdata(video_devdata(file));
- struct go7007_file *gofh;
-
- if (go->status != STATUS_ONLINE)
- return -EBUSY;
- gofh = kzalloc(sizeof(struct go7007_file), GFP_KERNEL);
- if (gofh == NULL)
- return -ENOMEM;
- gofh->go = go;
- mutex_init(&gofh->lock);
- gofh->buf_count = 0;
- file->private_data = gofh;
- v4l2_fh_init(&gofh->fh, video_devdata(file));
- v4l2_fh_add(&gofh->fh);
- return 0;
-}
-
static int go7007_release(struct file *file)
{
- struct go7007_file *gofh = file->private_data;
- struct go7007 *go = gofh->go;
+ struct go7007 *go = video_drvdata(file);
- if (gofh->buf_count > 0) {
+ if (file->private_data == go->bufs_owner && go->buf_count > 0) {
go7007_streamoff(go);
go->in_use = 0;
- kfree(gofh->bufs);
- gofh->buf_count = 0;
+ kfree(go->bufs);
+ go->bufs = NULL;
+ go->buf_count = 0;
+ go->bufs_owner = NULL;
}
- v4l2_fh_del(&gofh->fh);
- v4l2_fh_exit(&gofh->fh);
- kfree(gofh);
- file->private_data = NULL;
- return 0;
+ return v4l2_fh_release(file);
}
static bool valid_pixelformat(u32 pixelformat)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
strlcpy(cap->driver, "go7007", sizeof(cap->driver));
strlcpy(cap->card, go->name, sizeof(cap->card));
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *fmt)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt->fmt.pix.width = go->width;
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *fmt)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
return set_capture_size(go, fmt, 1);
}
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *fmt)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (go->streaming)
return -EBUSY;
static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *req)
{
- struct go7007_file *gofh = priv;
- struct go7007 *go = gofh->go;
+ struct go7007 *go = video_drvdata(file);
int retval = -EBUSY;
unsigned int count, i;
req->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
- mutex_lock(&gofh->lock);
- for (i = 0; i < gofh->buf_count; ++i)
- if (gofh->bufs[i].mapped > 0)
+ for (i = 0; i < go->buf_count; ++i)
+ if (go->bufs[i].mapped > 0)
goto unlock_and_return;
set_formatting(go);
mutex_lock(&go->hw_lock);
- if (go->in_use > 0 && gofh->buf_count == 0) {
+ if (go->in_use > 0 && go->buf_count == 0) {
mutex_unlock(&go->hw_lock);
goto unlock_and_return;
}
- if (gofh->buf_count > 0)
- kfree(gofh->bufs);
+ if (go->buf_count > 0)
+ kfree(go->bufs);
retval = -ENOMEM;
count = req->count;
if (count > 32)
count = 32;
- gofh->bufs = kcalloc(count, sizeof(struct go7007_buffer),
+ go->bufs = kcalloc(count, sizeof(struct go7007_buffer),
GFP_KERNEL);
- if (!gofh->bufs) {
+ if (!go->bufs) {
mutex_unlock(&go->hw_lock);
goto unlock_and_return;
}
for (i = 0; i < count; ++i) {
- gofh->bufs[i].go = go;
- gofh->bufs[i].index = i;
- gofh->bufs[i].state = BUF_STATE_IDLE;
- gofh->bufs[i].mapped = 0;
+ go->bufs[i].go = go;
+ go->bufs[i].index = i;
+ go->bufs[i].state = BUF_STATE_IDLE;
+ go->bufs[i].mapped = 0;
}
go->in_use = 1;
+ go->bufs_owner = file->private_data;
} else {
go->in_use = 0;
+ go->bufs_owner = NULL;
}
- gofh->buf_count = count;
+ go->buf_count = count;
mutex_unlock(&go->hw_lock);
- mutex_unlock(&gofh->lock);
memset(req, 0, sizeof(*req));
return 0;
unlock_and_return:
- mutex_unlock(&gofh->lock);
return retval;
}
static int vidioc_querybuf(struct file *file, void *priv,
struct v4l2_buffer *buf)
{
- struct go7007_file *gofh = priv;
+ struct go7007 *go = video_drvdata(file);
int retval = -EINVAL;
unsigned int index;
index = buf->index;
- mutex_lock(&gofh->lock);
- if (index >= gofh->buf_count)
+ if (index >= go->buf_count)
goto unlock_and_return;
memset(buf, 0, sizeof(*buf));
buf->index = index;
buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- switch (gofh->bufs[index].state) {
+ switch (go->bufs[index].state) {
case BUF_STATE_QUEUED:
buf->flags = V4L2_BUF_FLAG_QUEUED;
break;
buf->flags = 0;
}
- if (gofh->bufs[index].mapped)
+ if (go->bufs[index].mapped)
buf->flags |= V4L2_BUF_FLAG_MAPPED;
buf->memory = V4L2_MEMORY_MMAP;
buf->m.offset = index * GO7007_BUF_SIZE;
buf->length = GO7007_BUF_SIZE;
- mutex_unlock(&gofh->lock);
return 0;
unlock_and_return:
- mutex_unlock(&gofh->lock);
return retval;
}
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
- struct go7007_file *gofh = priv;
- struct go7007 *go = gofh->go;
+ struct go7007 *go = video_drvdata(file);
struct go7007_buffer *gobuf;
unsigned long flags;
int retval = -EINVAL;
buf->memory != V4L2_MEMORY_MMAP)
return retval;
- mutex_lock(&gofh->lock);
- if (buf->index >= gofh->buf_count)
+ if (buf->index >= go->buf_count)
goto unlock_and_return;
- gobuf = &gofh->bufs[buf->index];
+ gobuf = &go->bufs[buf->index];
if (!gobuf->mapped)
goto unlock_and_return;
spin_lock_irqsave(&go->spinlock, flags);
list_add_tail(&gobuf->stream, &go->stream);
spin_unlock_irqrestore(&go->spinlock, flags);
- mutex_unlock(&gofh->lock);
return 0;
unlock_and_return:
- mutex_unlock(&gofh->lock);
return retval;
}
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
{
- struct go7007_file *gofh = priv;
- struct go7007 *go = gofh->go;
+ struct go7007 *go = video_drvdata(file);
struct go7007_buffer *gobuf;
int retval = -EINVAL;
unsigned long flags;
if (buf->memory != V4L2_MEMORY_MMAP)
return retval;
- mutex_lock(&gofh->lock);
if (list_empty(&go->stream))
goto unlock_and_return;
gobuf = list_entry(go->stream.next,
buf->length = GO7007_BUF_SIZE;
buf->reserved = gobuf->modet_active;
- mutex_unlock(&gofh->lock);
return 0;
unlock_and_return:
- mutex_unlock(&gofh->lock);
return retval;
}
static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct go7007_file *gofh = priv;
- struct go7007 *go = gofh->go;
+ struct go7007 *go = video_drvdata(file);
int retval = 0;
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- mutex_lock(&gofh->lock);
mutex_lock(&go->hw_lock);
if (!go->streaming) {
retval = 0;
}
mutex_unlock(&go->hw_lock);
- mutex_unlock(&gofh->lock);
call_all(&go->v4l2_dev, video, s_stream, 1);
v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct go7007_file *gofh = priv;
- struct go7007 *go = gofh->go;
+ struct go7007 *go = video_drvdata(file);
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- mutex_lock(&gofh->lock);
go7007_streamoff(go);
- mutex_unlock(&gofh->lock);
call_all(&go->v4l2_dev, video, s_stream, 0);
return 0;
static int vidioc_g_parm(struct file *filp, void *priv,
struct v4l2_streamparm *parm)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(filp);
struct v4l2_fract timeperframe = {
.numerator = 1001 * go->fps_scale,
.denominator = go->sensor_framerate,
static int vidioc_s_parm(struct file *filp, void *priv,
struct v4l2_streamparm *parm)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(filp);
unsigned int n, d;
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
static int vidioc_enum_framesizes(struct file *filp, void *priv,
struct v4l2_frmsizeenum *fsize)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(filp);
int width, height;
if (fsize->index > 2)
static int vidioc_enum_frameintervals(struct file *filp, void *priv,
struct v4l2_frmivalenum *fival)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(filp);
int width, height;
int i;
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
*std = go->std;
return 0;
static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
return call_all(&go->v4l2_dev, video, querystd, std);
}
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (inp->index >= go->board_info->num_inputs)
return -EINVAL;
static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
*input = go->input;
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *t)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (t->index != 0)
return -EINVAL;
static int vidioc_s_tuner(struct file *file, void *priv,
const struct v4l2_tuner *t)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (t->index != 0)
return -EINVAL;
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (f->tuner)
return -EINVAL;
static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (f->tuner)
return -EINVAL;
static int vidioc_log_status(struct file *file, void *priv)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
v4l2_ctrl_log_status(file, priv);
return call_all(&go->v4l2_dev, core, log_status);
static int vidioc_cropcap(struct file *file, void *priv,
struct v4l2_cropcap *cropcap)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
{
- struct go7007 *go = ((struct go7007_file *) priv)->go;
+ struct go7007 *go = video_drvdata(file);
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
{
- struct go7007_file *gofh = file->private_data;
+ struct go7007 *go = video_drvdata(file);
unsigned int index;
- if (gofh->go->status != STATUS_ONLINE)
+ if (go->status != STATUS_ONLINE)
return -EIO;
if (!(vma->vm_flags & VM_SHARED))
return -EINVAL; /* only support VM_SHARED mapping */
if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
return -EINVAL; /* must map exactly one full buffer */
- mutex_lock(&gofh->lock);
index = vma->vm_pgoff / GO7007_BUF_PAGES;
- if (index >= gofh->buf_count) {
- mutex_unlock(&gofh->lock);
+ if (index >= go->buf_count)
return -EINVAL; /* trying to map beyond requested buffers */
- }
- if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
- mutex_unlock(&gofh->lock);
+ if (index * GO7007_BUF_PAGES != vma->vm_pgoff)
return -EINVAL; /* offset is not aligned on buffer boundary */
- }
- if (gofh->bufs[index].mapped > 0) {
- mutex_unlock(&gofh->lock);
+ if (go->bufs[index].mapped > 0)
return -EBUSY;
- }
- gofh->bufs[index].mapped = 1;
- gofh->bufs[index].user_addr = vma->vm_start;
+ go->bufs[index].mapped = 1;
+ go->bufs[index].user_addr = vma->vm_start;
vma->vm_ops = &go7007_vm_ops;
vma->vm_flags |= VM_DONTEXPAND;
vma->vm_flags &= ~VM_IO;
- vma->vm_private_data = &gofh->bufs[index];
- mutex_unlock(&gofh->lock);
+ vma->vm_private_data = &go->bufs[index];
return 0;
}
static unsigned int go7007_poll(struct file *file, poll_table *wait)
{
unsigned long req_events = poll_requested_events(wait);
- struct go7007_file *gofh = file->private_data;
+ struct go7007 *go = video_drvdata(file);
struct go7007_buffer *gobuf;
unsigned int res = v4l2_ctrl_poll(file, wait);
if (!(req_events & (POLLIN | POLLRDNORM)))
return res;
- if (list_empty(&gofh->go->stream))
+ if (list_empty(&go->stream))
return POLLERR;
- gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
- poll_wait(file, &gofh->go->frame_waitq, wait);
+ gobuf = list_entry(go->stream.next, struct go7007_buffer, stream);
+ poll_wait(file, &go->frame_waitq, wait);
if (gobuf->state == BUF_STATE_DONE)
return res | POLLIN | POLLRDNORM;
return res;
static struct v4l2_file_operations go7007_fops = {
.owner = THIS_MODULE,
- .open = go7007_open,
+ .open = v4l2_fh_open,
.release = go7007_release,
.ioctl = video_ioctl2,
.read = go7007_read,