diff options
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 | } |