diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2011-06-10 14:36:50 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-09-06 16:37:18 -0400 |
commit | e578588eb01d9493513ca1527f464715cfd3f47f (patch) | |
tree | 8073e81fb2d3463117c9c2db1defec6990bfcbd3 /drivers/media/video/s5p-fimc/fimc-core.c | |
parent | d3953223b0905437fef7ce60506b5fdfaf98dda6 (diff) |
[media] s5p-fimc: Conversion to use struct v4l2_fh
This is a prerequisite for the patch converting the driver to use
the control framework. As the capture driver does not use per file
handle contexts, two separate ioctl handlers are created for it
(vidioc_try_fmt_mplane, and vidioc_g_fmt_mplane) so there is no
handlers shared between the memory-to-memory and capture video node.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-core.c')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 179 |
1 files changed, 96 insertions, 83 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 16314c94cc12..3dab803e8054 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -777,10 +777,10 @@ static struct vb2_ops fimc_qops = { | |||
777 | .start_streaming = start_streaming, | 777 | .start_streaming = start_streaming, |
778 | }; | 778 | }; |
779 | 779 | ||
780 | static int fimc_m2m_querycap(struct file *file, void *priv, | 780 | static int fimc_m2m_querycap(struct file *file, void *fh, |
781 | struct v4l2_capability *cap) | 781 | struct v4l2_capability *cap) |
782 | { | 782 | { |
783 | struct fimc_ctx *ctx = file->private_data; | 783 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
784 | struct fimc_dev *fimc = ctx->fimc_dev; | 784 | struct fimc_dev *fimc = ctx->fimc_dev; |
785 | 785 | ||
786 | strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1); | 786 | strncpy(cap->driver, fimc->pdev->name, sizeof(cap->driver) - 1); |
@@ -808,42 +808,41 @@ int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv, | |||
808 | return 0; | 808 | return 0; |
809 | } | 809 | } |
810 | 810 | ||
811 | int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv, | 811 | int fimc_fill_format(struct fimc_frame *frame, struct v4l2_format *f) |
812 | struct v4l2_format *f) | ||
813 | { | 812 | { |
814 | struct fimc_ctx *ctx = priv; | 813 | struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; |
815 | struct fimc_frame *frame; | ||
816 | struct v4l2_pix_format_mplane *pixm; | ||
817 | int i; | 814 | int i; |
818 | 815 | ||
819 | frame = ctx_get_frame(ctx, f->type); | 816 | pixm->width = frame->o_width; |
820 | if (IS_ERR(frame)) | 817 | pixm->height = frame->o_height; |
821 | return PTR_ERR(frame); | 818 | pixm->field = V4L2_FIELD_NONE; |
822 | 819 | pixm->pixelformat = frame->fmt->fourcc; | |
823 | pixm = &f->fmt.pix_mp; | 820 | pixm->colorspace = V4L2_COLORSPACE_JPEG; |
824 | 821 | pixm->num_planes = frame->fmt->memplanes; | |
825 | pixm->width = frame->width; | ||
826 | pixm->height = frame->height; | ||
827 | pixm->field = V4L2_FIELD_NONE; | ||
828 | pixm->pixelformat = frame->fmt->fourcc; | ||
829 | pixm->colorspace = V4L2_COLORSPACE_JPEG; | ||
830 | pixm->num_planes = frame->fmt->memplanes; | ||
831 | 822 | ||
832 | for (i = 0; i < pixm->num_planes; ++i) { | 823 | for (i = 0; i < pixm->num_planes; ++i) { |
833 | int bpl = frame->o_width; | 824 | int bpl = frame->f_width; |
834 | |||
835 | if (frame->fmt->colplanes == 1) /* packed formats */ | 825 | if (frame->fmt->colplanes == 1) /* packed formats */ |
836 | bpl = (bpl * frame->fmt->depth[0]) / 8; | 826 | bpl = (bpl * frame->fmt->depth[0]) / 8; |
837 | |||
838 | pixm->plane_fmt[i].bytesperline = bpl; | 827 | pixm->plane_fmt[i].bytesperline = bpl; |
839 | |||
840 | pixm->plane_fmt[i].sizeimage = (frame->o_width * | 828 | pixm->plane_fmt[i].sizeimage = (frame->o_width * |
841 | frame->o_height * frame->fmt->depth[i]) / 8; | 829 | frame->o_height * frame->fmt->depth[i]) / 8; |
842 | } | 830 | } |
843 | |||
844 | return 0; | 831 | return 0; |
845 | } | 832 | } |
846 | 833 | ||
834 | static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh, | ||
835 | struct v4l2_format *f) | ||
836 | { | ||
837 | struct fimc_ctx *ctx = fh_to_ctx(fh); | ||
838 | struct fimc_frame *frame = ctx_get_frame(ctx, f->type); | ||
839 | |||
840 | if (IS_ERR(frame)) | ||
841 | return PTR_ERR(frame); | ||
842 | |||
843 | return fimc_fill_format(frame, f); | ||
844 | } | ||
845 | |||
847 | struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask) | 846 | struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask) |
848 | { | 847 | { |
849 | struct fimc_fmt *fmt; | 848 | struct fimc_fmt *fmt; |
@@ -874,11 +873,8 @@ struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, | |||
874 | return (i == ARRAY_SIZE(fimc_formats)) ? NULL : fmt; | 873 | return (i == ARRAY_SIZE(fimc_formats)) ? NULL : fmt; |
875 | } | 874 | } |
876 | 875 | ||
877 | 876 | int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f) | |
878 | int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv, | ||
879 | struct v4l2_format *f) | ||
880 | { | 877 | { |
881 | struct fimc_ctx *ctx = priv; | ||
882 | struct fimc_dev *fimc = ctx->fimc_dev; | 878 | struct fimc_dev *fimc = ctx->fimc_dev; |
883 | struct samsung_fimc_variant *variant = fimc->variant; | 879 | struct samsung_fimc_variant *variant = fimc->variant; |
884 | struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; | 880 | struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp; |
@@ -957,17 +953,25 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv, | |||
957 | return 0; | 953 | return 0; |
958 | } | 954 | } |
959 | 955 | ||
960 | static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, | 956 | static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh, |
957 | struct v4l2_format *f) | ||
958 | { | ||
959 | struct fimc_ctx *ctx = fh_to_ctx(fh); | ||
960 | |||
961 | return fimc_try_fmt_mplane(ctx, f); | ||
962 | } | ||
963 | |||
964 | static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, | ||
961 | struct v4l2_format *f) | 965 | struct v4l2_format *f) |
962 | { | 966 | { |
963 | struct fimc_ctx *ctx = priv; | 967 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
964 | struct fimc_dev *fimc = ctx->fimc_dev; | 968 | struct fimc_dev *fimc = ctx->fimc_dev; |
965 | struct vb2_queue *vq; | 969 | struct vb2_queue *vq; |
966 | struct fimc_frame *frame; | 970 | struct fimc_frame *frame; |
967 | struct v4l2_pix_format_mplane *pix; | 971 | struct v4l2_pix_format_mplane *pix; |
968 | int i, ret = 0; | 972 | int i, ret = 0; |
969 | 973 | ||
970 | ret = fimc_vidioc_try_fmt_mplane(file, priv, f); | 974 | ret = fimc_try_fmt_mplane(ctx, f); |
971 | if (ret) | 975 | if (ret) |
972 | return ret; | 976 | return ret; |
973 | 977 | ||
@@ -978,15 +982,10 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, | |||
978 | return -EBUSY; | 982 | return -EBUSY; |
979 | } | 983 | } |
980 | 984 | ||
981 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 985 | if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
982 | frame = &ctx->s_frame; | 986 | frame = &ctx->s_frame; |
983 | } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { | 987 | else |
984 | frame = &ctx->d_frame; | 988 | frame = &ctx->d_frame; |
985 | } else { | ||
986 | v4l2_err(fimc->m2m.vfd, | ||
987 | "Wrong buffer/video queue type (%d)\n", f->type); | ||
988 | return -EINVAL; | ||
989 | } | ||
990 | 989 | ||
991 | pix = &f->fmt.pix_mp; | 990 | pix = &f->fmt.pix_mp; |
992 | frame->fmt = find_format(f, FMT_FLAGS_M2M); | 991 | frame->fmt = find_format(f, FMT_FLAGS_M2M); |
@@ -1018,39 +1017,42 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, | |||
1018 | return 0; | 1017 | return 0; |
1019 | } | 1018 | } |
1020 | 1019 | ||
1021 | static int fimc_m2m_reqbufs(struct file *file, void *priv, | 1020 | static int fimc_m2m_reqbufs(struct file *file, void *fh, |
1022 | struct v4l2_requestbuffers *reqbufs) | 1021 | struct v4l2_requestbuffers *reqbufs) |
1023 | { | 1022 | { |
1024 | struct fimc_ctx *ctx = priv; | 1023 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1024 | |||
1025 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); | 1025 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | static int fimc_m2m_querybuf(struct file *file, void *priv, | 1028 | static int fimc_m2m_querybuf(struct file *file, void *fh, |
1029 | struct v4l2_buffer *buf) | 1029 | struct v4l2_buffer *buf) |
1030 | { | 1030 | { |
1031 | struct fimc_ctx *ctx = priv; | 1031 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1032 | |||
1032 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); | 1033 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); |
1033 | } | 1034 | } |
1034 | 1035 | ||
1035 | static int fimc_m2m_qbuf(struct file *file, void *priv, | 1036 | static int fimc_m2m_qbuf(struct file *file, void *fh, |
1036 | struct v4l2_buffer *buf) | 1037 | struct v4l2_buffer *buf) |
1037 | { | 1038 | { |
1038 | struct fimc_ctx *ctx = priv; | 1039 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1039 | 1040 | ||
1040 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); | 1041 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); |
1041 | } | 1042 | } |
1042 | 1043 | ||
1043 | static int fimc_m2m_dqbuf(struct file *file, void *priv, | 1044 | static int fimc_m2m_dqbuf(struct file *file, void *fh, |
1044 | struct v4l2_buffer *buf) | 1045 | struct v4l2_buffer *buf) |
1045 | { | 1046 | { |
1046 | struct fimc_ctx *ctx = priv; | 1047 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1048 | |||
1047 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); | 1049 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); |
1048 | } | 1050 | } |
1049 | 1051 | ||
1050 | static int fimc_m2m_streamon(struct file *file, void *priv, | 1052 | static int fimc_m2m_streamon(struct file *file, void *fh, |
1051 | enum v4l2_buf_type type) | 1053 | enum v4l2_buf_type type) |
1052 | { | 1054 | { |
1053 | struct fimc_ctx *ctx = priv; | 1055 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1054 | 1056 | ||
1055 | /* The source and target color format need to be set */ | 1057 | /* The source and target color format need to be set */ |
1056 | if (V4L2_TYPE_IS_OUTPUT(type)) { | 1058 | if (V4L2_TYPE_IS_OUTPUT(type)) { |
@@ -1063,17 +1065,19 @@ static int fimc_m2m_streamon(struct file *file, void *priv, | |||
1063 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); | 1065 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); |
1064 | } | 1066 | } |
1065 | 1067 | ||
1066 | static int fimc_m2m_streamoff(struct file *file, void *priv, | 1068 | static int fimc_m2m_streamoff(struct file *file, void *fh, |
1067 | enum v4l2_buf_type type) | 1069 | enum v4l2_buf_type type) |
1068 | { | 1070 | { |
1069 | struct fimc_ctx *ctx = priv; | 1071 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1072 | |||
1070 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); | 1073 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); |
1071 | } | 1074 | } |
1072 | 1075 | ||
1073 | int fimc_vidioc_queryctrl(struct file *file, void *priv, | 1076 | int fimc_vidioc_queryctrl(struct file *file, void *fh, |
1074 | struct v4l2_queryctrl *qc) | 1077 | struct v4l2_queryctrl *qc) |
1075 | { | 1078 | { |
1076 | struct fimc_ctx *ctx = priv; | 1079 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1080 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
1077 | struct v4l2_queryctrl *c; | 1081 | struct v4l2_queryctrl *c; |
1078 | int ret = -EINVAL; | 1082 | int ret = -EINVAL; |
1079 | 1083 | ||
@@ -1090,10 +1094,9 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv, | |||
1090 | return ret; | 1094 | return ret; |
1091 | } | 1095 | } |
1092 | 1096 | ||
1093 | int fimc_vidioc_g_ctrl(struct file *file, void *priv, | 1097 | int fimc_vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *ctrl) |
1094 | struct v4l2_control *ctrl) | ||
1095 | { | 1098 | { |
1096 | struct fimc_ctx *ctx = priv; | 1099 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1097 | struct fimc_dev *fimc = ctx->fimc_dev; | 1100 | struct fimc_dev *fimc = ctx->fimc_dev; |
1098 | 1101 | ||
1099 | switch (ctrl->id) { | 1102 | switch (ctrl->id) { |
@@ -1186,10 +1189,10 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl) | |||
1186 | return 0; | 1189 | return 0; |
1187 | } | 1190 | } |
1188 | 1191 | ||
1189 | static int fimc_m2m_s_ctrl(struct file *file, void *priv, | 1192 | static int fimc_m2m_s_ctrl(struct file *file, void *fh, |
1190 | struct v4l2_control *ctrl) | 1193 | struct v4l2_control *ctrl) |
1191 | { | 1194 | { |
1192 | struct fimc_ctx *ctx = priv; | 1195 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1193 | int ret = 0; | 1196 | int ret = 0; |
1194 | 1197 | ||
1195 | ret = check_ctrl_val(ctx, ctrl); | 1198 | ret = check_ctrl_val(ctx, ctrl); |
@@ -1201,10 +1204,10 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv, | |||
1201 | } | 1204 | } |
1202 | 1205 | ||
1203 | static int fimc_m2m_cropcap(struct file *file, void *fh, | 1206 | static int fimc_m2m_cropcap(struct file *file, void *fh, |
1204 | struct v4l2_cropcap *cr) | 1207 | struct v4l2_cropcap *cr) |
1205 | { | 1208 | { |
1209 | struct fimc_ctx *ctx = fh_to_ctx(fh); | ||
1206 | struct fimc_frame *frame; | 1210 | struct fimc_frame *frame; |
1207 | struct fimc_ctx *ctx = fh; | ||
1208 | 1211 | ||
1209 | frame = ctx_get_frame(ctx, cr->type); | 1212 | frame = ctx_get_frame(ctx, cr->type); |
1210 | if (IS_ERR(frame)) | 1213 | if (IS_ERR(frame)) |
@@ -1221,8 +1224,8 @@ static int fimc_m2m_cropcap(struct file *file, void *fh, | |||
1221 | 1224 | ||
1222 | static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) | 1225 | static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) |
1223 | { | 1226 | { |
1227 | struct fimc_ctx *ctx = fh_to_ctx(fh); | ||
1224 | struct fimc_frame *frame; | 1228 | struct fimc_frame *frame; |
1225 | struct fimc_ctx *ctx = file->private_data; | ||
1226 | 1229 | ||
1227 | frame = ctx_get_frame(ctx, cr->type); | 1230 | frame = ctx_get_frame(ctx, cr->type); |
1228 | if (IS_ERR(frame)) | 1231 | if (IS_ERR(frame)) |
@@ -1300,7 +1303,7 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) | |||
1300 | 1303 | ||
1301 | static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | 1304 | static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) |
1302 | { | 1305 | { |
1303 | struct fimc_ctx *ctx = file->private_data; | 1306 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
1304 | struct fimc_dev *fimc = ctx->fimc_dev; | 1307 | struct fimc_dev *fimc = ctx->fimc_dev; |
1305 | struct fimc_frame *f; | 1308 | struct fimc_frame *f; |
1306 | int ret; | 1309 | int ret; |
@@ -1347,11 +1350,11 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { | |||
1347 | .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane, | 1350 | .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane, |
1348 | .vidioc_enum_fmt_vid_out_mplane = fimc_vidioc_enum_fmt_mplane, | 1351 | .vidioc_enum_fmt_vid_out_mplane = fimc_vidioc_enum_fmt_mplane, |
1349 | 1352 | ||
1350 | .vidioc_g_fmt_vid_cap_mplane = fimc_vidioc_g_fmt_mplane, | 1353 | .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane, |
1351 | .vidioc_g_fmt_vid_out_mplane = fimc_vidioc_g_fmt_mplane, | 1354 | .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane, |
1352 | 1355 | ||
1353 | .vidioc_try_fmt_vid_cap_mplane = fimc_vidioc_try_fmt_mplane, | 1356 | .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane, |
1354 | .vidioc_try_fmt_vid_out_mplane = fimc_vidioc_try_fmt_mplane, | 1357 | .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane, |
1355 | 1358 | ||
1356 | .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane, | 1359 | .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane, |
1357 | .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane, | 1360 | .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane, |
@@ -1407,7 +1410,8 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, | |||
1407 | static int fimc_m2m_open(struct file *file) | 1410 | static int fimc_m2m_open(struct file *file) |
1408 | { | 1411 | { |
1409 | struct fimc_dev *fimc = video_drvdata(file); | 1412 | struct fimc_dev *fimc = video_drvdata(file); |
1410 | struct fimc_ctx *ctx = NULL; | 1413 | struct fimc_ctx *ctx; |
1414 | int ret; | ||
1411 | 1415 | ||
1412 | dbg("pid: %d, state: 0x%lx, refcnt: %d", | 1416 | dbg("pid: %d, state: 0x%lx, refcnt: %d", |
1413 | task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); | 1417 | task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); |
@@ -1422,13 +1426,16 @@ static int fimc_m2m_open(struct file *file) | |||
1422 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); | 1426 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
1423 | if (!ctx) | 1427 | if (!ctx) |
1424 | return -ENOMEM; | 1428 | return -ENOMEM; |
1429 | v4l2_fh_init(&ctx->fh, fimc->m2m.vfd); | ||
1430 | |||
1431 | file->private_data = &ctx->fh; | ||
1432 | v4l2_fh_add(&ctx->fh); | ||
1425 | 1433 | ||
1426 | file->private_data = ctx; | ||
1427 | ctx->fimc_dev = fimc; | 1434 | ctx->fimc_dev = fimc; |
1428 | /* Default color format */ | 1435 | /* Default color format */ |
1429 | ctx->s_frame.fmt = &fimc_formats[0]; | 1436 | ctx->s_frame.fmt = &fimc_formats[0]; |
1430 | ctx->d_frame.fmt = &fimc_formats[0]; | 1437 | ctx->d_frame.fmt = &fimc_formats[0]; |
1431 | /* Setup the device context for mem2mem mode. */ | 1438 | /* Setup the device context for memory-to-memory mode */ |
1432 | ctx->state = FIMC_CTX_M2M; | 1439 | ctx->state = FIMC_CTX_M2M; |
1433 | ctx->flags = 0; | 1440 | ctx->flags = 0; |
1434 | ctx->in_path = FIMC_DMA; | 1441 | ctx->in_path = FIMC_DMA; |
@@ -1437,26 +1444,32 @@ static int fimc_m2m_open(struct file *file) | |||
1437 | 1444 | ||
1438 | ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); | 1445 | ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); |
1439 | if (IS_ERR(ctx->m2m_ctx)) { | 1446 | if (IS_ERR(ctx->m2m_ctx)) { |
1440 | int err = PTR_ERR(ctx->m2m_ctx); | 1447 | ret = PTR_ERR(ctx->m2m_ctx); |
1441 | kfree(ctx); | 1448 | goto error_fh; |
1442 | return err; | ||
1443 | } | 1449 | } |
1444 | 1450 | ||
1445 | if (fimc->m2m.refcnt++ == 0) | 1451 | if (fimc->m2m.refcnt++ == 0) |
1446 | set_bit(ST_M2M_RUN, &fimc->state); | 1452 | set_bit(ST_M2M_RUN, &fimc->state); |
1447 | |||
1448 | return 0; | 1453 | return 0; |
1454 | |||
1455 | error_fh: | ||
1456 | v4l2_fh_del(&ctx->fh); | ||
1457 | v4l2_fh_exit(&ctx->fh); | ||
1458 | kfree(ctx); | ||
1459 | return ret; | ||
1449 | } | 1460 | } |
1450 | 1461 | ||
1451 | static int fimc_m2m_release(struct file *file) | 1462 | static int fimc_m2m_release(struct file *file) |
1452 | { | 1463 | { |
1453 | struct fimc_ctx *ctx = file->private_data; | 1464 | struct fimc_ctx *ctx = fh_to_ctx(file->private_data); |
1454 | struct fimc_dev *fimc = ctx->fimc_dev; | 1465 | struct fimc_dev *fimc = ctx->fimc_dev; |
1455 | 1466 | ||
1456 | dbg("pid: %d, state: 0x%lx, refcnt= %d", | 1467 | dbg("pid: %d, state: 0x%lx, refcnt= %d", |
1457 | task_pid_nr(current), fimc->state, fimc->m2m.refcnt); | 1468 | task_pid_nr(current), fimc->state, fimc->m2m.refcnt); |
1458 | 1469 | ||
1459 | v4l2_m2m_ctx_release(ctx->m2m_ctx); | 1470 | v4l2_m2m_ctx_release(ctx->m2m_ctx); |
1471 | v4l2_fh_del(&ctx->fh); | ||
1472 | v4l2_fh_exit(&ctx->fh); | ||
1460 | 1473 | ||
1461 | if (--fimc->m2m.refcnt <= 0) | 1474 | if (--fimc->m2m.refcnt <= 0) |
1462 | clear_bit(ST_M2M_RUN, &fimc->state); | 1475 | clear_bit(ST_M2M_RUN, &fimc->state); |
@@ -1465,9 +1478,9 @@ static int fimc_m2m_release(struct file *file) | |||
1465 | } | 1478 | } |
1466 | 1479 | ||
1467 | static unsigned int fimc_m2m_poll(struct file *file, | 1480 | static unsigned int fimc_m2m_poll(struct file *file, |
1468 | struct poll_table_struct *wait) | 1481 | struct poll_table_struct *wait) |
1469 | { | 1482 | { |
1470 | struct fimc_ctx *ctx = file->private_data; | 1483 | struct fimc_ctx *ctx = fh_to_ctx(file->private_data); |
1471 | 1484 | ||
1472 | return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); | 1485 | return v4l2_m2m_poll(file, ctx->m2m_ctx, wait); |
1473 | } | 1486 | } |
@@ -1475,7 +1488,7 @@ static unsigned int fimc_m2m_poll(struct file *file, | |||
1475 | 1488 | ||
1476 | static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma) | 1489 | static int fimc_m2m_mmap(struct file *file, struct vm_area_struct *vma) |
1477 | { | 1490 | { |
1478 | struct fimc_ctx *ctx = file->private_data; | 1491 | struct fimc_ctx *ctx = fh_to_ctx(file->private_data); |
1479 | 1492 | ||
1480 | return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); | 1493 | return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); |
1481 | } | 1494 | } |