@@ -221,9 +221,12 @@ struct emmaprp_ctx {
/* Abort requested by m2m */
int aborting;
struct emmaprp_q_data q_data[2];
+ struct v4l2_fh fh;
struct v4l2_m2m_ctx *m2m_ctx;
};
+#define fh_to_ctx(__fh) container_of(__fh, struct emmaprp_ctx, fh)
+
static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx,
enum v4l2_buf_type type)
{
@@ -478,13 +481,15 @@ static int vidioc_g_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
- return vidioc_g_fmt(priv, f);
+ struct emmaprp_ctx *ctx = fh_to_ctx(priv);
+ return vidioc_g_fmt(ctx, f);
}
static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
- return vidioc_g_fmt(priv, f);
+ struct emmaprp_ctx *ctx = fh_to_ctx(priv);
+ return vidioc_g_fmt(ctx, f);
}
static int vidioc_try_fmt(struct v4l2_format *f)
@@ -524,8 +529,8 @@ static int vidioc_try_fmt(struct v4l2_format *f)
static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct emmaprp_ctx *ctx = fh_to_ctx(priv);
struct emmaprp_fmt *fmt;
- struct emmaprp_ctx *ctx = priv;
fmt = find_format(f);
if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
@@ -541,8 +546,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct emmaprp_ctx *ctx = fh_to_ctx(priv);
struct emmaprp_fmt *fmt;
- struct emmaprp_ctx *ctx = priv;
fmt = find_format(f);
if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
@@ -561,7 +566,7 @@ static int vidioc_s_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
struct vb2_queue *vq;
int ret;
- vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
+ vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
if (!vq)
return -EINVAL;
@@ -596,25 +601,27 @@ static int vidioc_s_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f)
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct emmaprp_ctx *ctx = fh_to_ctx(priv);
int ret;
ret = vidioc_try_fmt_vid_cap(file, priv, f);
if (ret)
return ret;
- return vidioc_s_fmt(priv, f);
+ return vidioc_s_fmt(ctx, f);
}
static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
+ struct emmaprp_ctx *ctx = fh_to_ctx(priv);
int ret;
ret = vidioc_try_fmt_vid_out(file, priv, f);
if (ret)
return ret;
- return vidioc_s_fmt(priv, f);
+ return vidioc_s_fmt(ctx, f);
}
static int vidioc_reqbufs(struct file *file, void *priv,
@@ -790,27 +797,28 @@ static int emmaprp_open(struct file *file)
{
struct emmaprp_dev *pcdev = video_drvdata(file);
struct emmaprp_ctx *ctx;
+ int ret;
ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
if (!ctx)
return -ENOMEM;
- file->private_data = ctx;
- ctx->dev = pcdev;
-
if (mutex_lock_interruptible(&pcdev->dev_mutex)) {
- kfree(ctx);
- return -ERESTARTSYS;
+ ret = -ERESTARTSYS;
+ goto err_free;
}
+ v4l2_fh_init(&ctx->fh, pcdev->vfd);
+ file->private_data = &ctx->fh;
+ v4l2_fh_add(&ctx->fh);
+
+ ctx->dev = pcdev;
+
ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init);
if (IS_ERR(ctx->m2m_ctx)) {
- int ret = PTR_ERR(ctx->m2m_ctx);
-
- mutex_unlock(&pcdev->dev_mutex);
- kfree(ctx);
- return ret;
+ ret = PTR_ERR(ctx->m2m_ctx);
+ goto err_fh;
}
clk_prepare_enable(pcdev->clk_emma_ipg);
@@ -822,12 +830,20 @@ static int emmaprp_open(struct file *file)
dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx);
return 0;
+
+err_fh:
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
+err_free:
+ kfree(ctx);
+ mutex_unlock(&pcdev->dev_mutex);
+ return ret;
}
static int emmaprp_release(struct file *file)
{
+ struct emmaprp_ctx *ctx = fh_to_ctx(file->private_data);
struct emmaprp_dev *pcdev = video_drvdata(file);
- struct emmaprp_ctx *ctx = file->private_data;
dprintk(pcdev, "Releasing instance %p\n", ctx);
@@ -835,6 +851,8 @@ static int emmaprp_release(struct file *file)
clk_disable_unprepare(pcdev->clk_emma_ahb);
clk_disable_unprepare(pcdev->clk_emma_ipg);
v4l2_m2m_ctx_release(ctx->m2m_ctx);
+ v4l2_fh_del(&ctx->fh);
+ v4l2_fh_exit(&ctx->fh);
mutex_unlock(&pcdev->dev_mutex);
kfree(ctx);