diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-01-30 07:54:06 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-02-05 14:52:41 -0500 |
commit | 81619ce1931a1d96e53b455ca2f35757f0c457a5 (patch) | |
tree | 2ec70dacd59aa087d9d8c13b2c22f8919959eb67 /drivers/media/platform | |
parent | 031f515b3d303eca80518ed9a71c79ed420b352a (diff) |
[media] s5p-fimc: Set default image format at device open()
Make sure a valid image format is initially set on both the CAPTURE
and the OUTPUT buffer queue.
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/platform')
-rw-r--r-- | drivers/media/platform/s5p-fimc/fimc-core.c | 20 | ||||
-rw-r--r-- | drivers/media/platform/s5p-fimc/fimc-core.h | 5 | ||||
-rw-r--r-- | drivers/media/platform/s5p-fimc/fimc-m2m.c | 131 |
3 files changed, 75 insertions, 81 deletions
diff --git a/drivers/media/platform/s5p-fimc/fimc-core.c b/drivers/media/platform/s5p-fimc/fimc-core.c index a9625414ea95..29f7bb71c7e1 100644 --- a/drivers/media/platform/s5p-fimc/fimc-core.c +++ b/drivers/media/platform/s5p-fimc/fimc-core.c | |||
@@ -525,7 +525,6 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) | |||
525 | { | 525 | { |
526 | struct fimc_dev *fimc = ctx->fimc_dev; | 526 | struct fimc_dev *fimc = ctx->fimc_dev; |
527 | const struct fimc_variant *variant = fimc->variant; | 527 | const struct fimc_variant *variant = fimc->variant; |
528 | unsigned int flags = FIMC_DST_FMT | FIMC_SRC_FMT; | ||
529 | int ret = 0; | 528 | int ret = 0; |
530 | 529 | ||
531 | if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) | 530 | if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) |
@@ -541,8 +540,7 @@ static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl) | |||
541 | break; | 540 | break; |
542 | 541 | ||
543 | case V4L2_CID_ROTATE: | 542 | case V4L2_CID_ROTATE: |
544 | if (fimc_capture_pending(fimc) || | 543 | if (fimc_capture_pending(fimc)) { |
545 | (ctx->state & flags) == flags) { | ||
546 | ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, | 544 | ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, |
547 | ctx->s_frame.height, ctx->d_frame.width, | 545 | ctx->s_frame.height, ctx->d_frame.width, |
548 | ctx->d_frame.height, ctrl->val); | 546 | ctx->d_frame.height, ctrl->val); |
@@ -709,22 +707,6 @@ void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f) | |||
709 | } | 707 | } |
710 | } | 708 | } |
711 | 709 | ||
712 | void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f) | ||
713 | { | ||
714 | struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp; | ||
715 | |||
716 | frame->f_width = pixm->plane_fmt[0].bytesperline; | ||
717 | if (frame->fmt->colplanes == 1) | ||
718 | frame->f_width = (frame->f_width * 8) / frame->fmt->depth[0]; | ||
719 | frame->f_height = pixm->height; | ||
720 | frame->width = pixm->width; | ||
721 | frame->height = pixm->height; | ||
722 | frame->o_width = pixm->width; | ||
723 | frame->o_height = pixm->height; | ||
724 | frame->offs_h = 0; | ||
725 | frame->offs_v = 0; | ||
726 | } | ||
727 | |||
728 | /** | 710 | /** |
729 | * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane | 711 | * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane |
730 | * @fmt: fimc pixel format description (input) | 712 | * @fmt: fimc pixel format description (input) |
diff --git a/drivers/media/platform/s5p-fimc/fimc-core.h b/drivers/media/platform/s5p-fimc/fimc-core.h index cf760c364099..412d50708f75 100644 --- a/drivers/media/platform/s5p-fimc/fimc-core.h +++ b/drivers/media/platform/s5p-fimc/fimc-core.h | |||
@@ -112,9 +112,7 @@ enum fimc_color_fmt { | |||
112 | 112 | ||
113 | /* The hardware context state. */ | 113 | /* The hardware context state. */ |
114 | #define FIMC_PARAMS (1 << 0) | 114 | #define FIMC_PARAMS (1 << 0) |
115 | #define FIMC_SRC_FMT (1 << 3) | 115 | #define FIMC_COMPOSE (1 << 1) |
116 | #define FIMC_DST_FMT (1 << 4) | ||
117 | #define FIMC_COMPOSE (1 << 5) | ||
118 | #define FIMC_CTX_M2M (1 << 16) | 116 | #define FIMC_CTX_M2M (1 << 16) |
119 | #define FIMC_CTX_CAP (1 << 17) | 117 | #define FIMC_CTX_CAP (1 << 17) |
120 | #define FIMC_CTX_SHUT (1 << 18) | 118 | #define FIMC_CTX_SHUT (1 << 18) |
@@ -654,7 +652,6 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, | |||
654 | struct fimc_frame *frame, struct fimc_addr *paddr); | 652 | struct fimc_frame *frame, struct fimc_addr *paddr); |
655 | void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f); | 653 | void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f); |
656 | void fimc_set_yuv_order(struct fimc_ctx *ctx); | 654 | void fimc_set_yuv_order(struct fimc_ctx *ctx); |
657 | void fimc_fill_frame(struct fimc_frame *frame, struct v4l2_format *f); | ||
658 | void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf); | 655 | void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf); |
659 | 656 | ||
660 | int fimc_register_m2m_device(struct fimc_dev *fimc, | 657 | int fimc_register_m2m_device(struct fimc_dev *fimc, |
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c b/drivers/media/platform/s5p-fimc/fimc-m2m.c index 1eabd7e74849..f3d535cdd87f 100644 --- a/drivers/media/platform/s5p-fimc/fimc-m2m.c +++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver | 2 | * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver |
3 | * | 3 | * |
4 | * Copyright (C) 2012 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd. |
5 | * Sylwester Nawrocki, <s.nawrocki@samsung.com> | 5 | * Sylwester Nawrocki <s.nawrocki@samsung.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published | 8 | * it under the terms of the GNU General Public License as published |
@@ -160,8 +160,7 @@ static void fimc_device_run(void *priv) | |||
160 | fimc_hw_set_output_addr(fimc, &df->paddr, -1); | 160 | fimc_hw_set_output_addr(fimc, &df->paddr, -1); |
161 | 161 | ||
162 | fimc_activate_capture(ctx); | 162 | fimc_activate_capture(ctx); |
163 | ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP | | 163 | ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP); |
164 | FIMC_SRC_FMT | FIMC_DST_FMT); | ||
165 | fimc_hw_activate_input_dma(fimc, true); | 164 | fimc_hw_activate_input_dma(fimc, true); |
166 | 165 | ||
167 | dma_unlock: | 166 | dma_unlock: |
@@ -309,8 +308,6 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f) | |||
309 | if (!IS_M2M(f->type)) | 308 | if (!IS_M2M(f->type)) |
310 | return -EINVAL; | 309 | return -EINVAL; |
311 | 310 | ||
312 | dbg("w: %d, h: %d", pix->width, pix->height); | ||
313 | |||
314 | fmt = fimc_find_format(&pix->pixelformat, NULL, | 311 | fmt = fimc_find_format(&pix->pixelformat, NULL, |
315 | get_m2m_fmt_flags(f->type), 0); | 312 | get_m2m_fmt_flags(f->type), 0); |
316 | if (WARN(fmt == NULL, "Pixel format lookup failed")) | 313 | if (WARN(fmt == NULL, "Pixel format lookup failed")) |
@@ -350,19 +347,39 @@ static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh, | |||
350 | struct v4l2_format *f) | 347 | struct v4l2_format *f) |
351 | { | 348 | { |
352 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 349 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
353 | |||
354 | return fimc_try_fmt_mplane(ctx, f); | 350 | return fimc_try_fmt_mplane(ctx, f); |
355 | } | 351 | } |
356 | 352 | ||
353 | static void __set_frame_format(struct fimc_frame *frame, struct fimc_fmt *fmt, | ||
354 | struct v4l2_pix_format_mplane *pixm) | ||
355 | { | ||
356 | int i; | ||
357 | |||
358 | for (i = 0; i < fmt->colplanes; i++) { | ||
359 | frame->bytesperline[i] = pixm->plane_fmt[i].bytesperline; | ||
360 | frame->payload[i] = pixm->plane_fmt[i].sizeimage; | ||
361 | } | ||
362 | |||
363 | frame->f_width = pixm->width; | ||
364 | frame->f_height = pixm->height; | ||
365 | frame->o_width = pixm->width; | ||
366 | frame->o_height = pixm->height; | ||
367 | frame->width = pixm->width; | ||
368 | frame->height = pixm->height; | ||
369 | frame->offs_h = 0; | ||
370 | frame->offs_v = 0; | ||
371 | frame->fmt = fmt; | ||
372 | } | ||
373 | |||
357 | static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, | 374 | static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, |
358 | struct v4l2_format *f) | 375 | struct v4l2_format *f) |
359 | { | 376 | { |
360 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 377 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
361 | struct fimc_dev *fimc = ctx->fimc_dev; | 378 | struct fimc_dev *fimc = ctx->fimc_dev; |
379 | struct fimc_fmt *fmt; | ||
362 | struct vb2_queue *vq; | 380 | struct vb2_queue *vq; |
363 | struct fimc_frame *frame; | 381 | struct fimc_frame *frame; |
364 | struct v4l2_pix_format_mplane *pix; | 382 | int ret; |
365 | int i, ret = 0; | ||
366 | 383 | ||
367 | ret = fimc_try_fmt_mplane(ctx, f); | 384 | ret = fimc_try_fmt_mplane(ctx, f); |
368 | if (ret) | 385 | if (ret) |
@@ -380,31 +397,16 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, | |||
380 | else | 397 | else |
381 | frame = &ctx->d_frame; | 398 | frame = &ctx->d_frame; |
382 | 399 | ||
383 | pix = &f->fmt.pix_mp; | 400 | fmt = fimc_find_format(&f->fmt.pix_mp.pixelformat, NULL, |
384 | frame->fmt = fimc_find_format(&pix->pixelformat, NULL, | 401 | get_m2m_fmt_flags(f->type), 0); |
385 | get_m2m_fmt_flags(f->type), 0); | 402 | if (!fmt) |
386 | if (!frame->fmt) | ||
387 | return -EINVAL; | 403 | return -EINVAL; |
388 | 404 | ||
405 | __set_frame_format(frame, fmt, &f->fmt.pix_mp); | ||
406 | |||
389 | /* Update RGB Alpha control state and value range */ | 407 | /* Update RGB Alpha control state and value range */ |
390 | fimc_alpha_ctrl_update(ctx); | 408 | fimc_alpha_ctrl_update(ctx); |
391 | 409 | ||
392 | for (i = 0; i < frame->fmt->colplanes; i++) { | ||
393 | frame->bytesperline[i] = pix->plane_fmt[i].bytesperline; | ||
394 | frame->payload[i] = pix->plane_fmt[i].sizeimage; | ||
395 | } | ||
396 | |||
397 | fimc_fill_frame(frame, f); | ||
398 | |||
399 | ctx->scaler.enabled = 1; | ||
400 | |||
401 | if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
402 | fimc_ctx_state_set(FIMC_PARAMS | FIMC_DST_FMT, ctx); | ||
403 | else | ||
404 | fimc_ctx_state_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx); | ||
405 | |||
406 | dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height); | ||
407 | |||
408 | return 0; | 410 | return 0; |
409 | } | 411 | } |
410 | 412 | ||
@@ -412,7 +414,6 @@ static int fimc_m2m_reqbufs(struct file *file, void *fh, | |||
412 | struct v4l2_requestbuffers *reqbufs) | 414 | struct v4l2_requestbuffers *reqbufs) |
413 | { | 415 | { |
414 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 416 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
415 | |||
416 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); | 417 | return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); |
417 | } | 418 | } |
418 | 419 | ||
@@ -420,7 +421,6 @@ static int fimc_m2m_querybuf(struct file *file, void *fh, | |||
420 | struct v4l2_buffer *buf) | 421 | struct v4l2_buffer *buf) |
421 | { | 422 | { |
422 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 423 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
423 | |||
424 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); | 424 | return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); |
425 | } | 425 | } |
426 | 426 | ||
@@ -428,7 +428,6 @@ static int fimc_m2m_qbuf(struct file *file, void *fh, | |||
428 | struct v4l2_buffer *buf) | 428 | struct v4l2_buffer *buf) |
429 | { | 429 | { |
430 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 430 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
431 | |||
432 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); | 431 | return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); |
433 | } | 432 | } |
434 | 433 | ||
@@ -436,7 +435,6 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh, | |||
436 | struct v4l2_buffer *buf) | 435 | struct v4l2_buffer *buf) |
437 | { | 436 | { |
438 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 437 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
439 | |||
440 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); | 438 | return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); |
441 | } | 439 | } |
442 | 440 | ||
@@ -444,7 +442,6 @@ static int fimc_m2m_expbuf(struct file *file, void *fh, | |||
444 | struct v4l2_exportbuffer *eb) | 442 | struct v4l2_exportbuffer *eb) |
445 | { | 443 | { |
446 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 444 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
447 | |||
448 | return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb); | 445 | return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb); |
449 | } | 446 | } |
450 | 447 | ||
@@ -453,15 +450,6 @@ static int fimc_m2m_streamon(struct file *file, void *fh, | |||
453 | enum v4l2_buf_type type) | 450 | enum v4l2_buf_type type) |
454 | { | 451 | { |
455 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 452 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
456 | |||
457 | /* The source and target color format need to be set */ | ||
458 | if (V4L2_TYPE_IS_OUTPUT(type)) { | ||
459 | if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx)) | ||
460 | return -EINVAL; | ||
461 | } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) { | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | |||
465 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); | 453 | return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); |
466 | } | 454 | } |
467 | 455 | ||
@@ -469,7 +457,6 @@ static int fimc_m2m_streamoff(struct file *file, void *fh, | |||
469 | enum v4l2_buf_type type) | 457 | enum v4l2_buf_type type) |
470 | { | 458 | { |
471 | struct fimc_ctx *ctx = fh_to_ctx(fh); | 459 | struct fimc_ctx *ctx = fh_to_ctx(fh); |
472 | |||
473 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); | 460 | return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); |
474 | } | 461 | } |
475 | 462 | ||
@@ -577,20 +564,18 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop * | |||
577 | &ctx->s_frame : &ctx->d_frame; | 564 | &ctx->s_frame : &ctx->d_frame; |
578 | 565 | ||
579 | /* Check to see if scaling ratio is within supported range */ | 566 | /* Check to see if scaling ratio is within supported range */ |
580 | if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) { | 567 | if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
581 | if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { | 568 | ret = fimc_check_scaler_ratio(ctx, cr.c.width, |
582 | ret = fimc_check_scaler_ratio(ctx, cr.c.width, | 569 | cr.c.height, ctx->d_frame.width, |
583 | cr.c.height, ctx->d_frame.width, | 570 | ctx->d_frame.height, ctx->rotation); |
584 | ctx->d_frame.height, ctx->rotation); | 571 | } else { |
585 | } else { | 572 | ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, |
586 | ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, | 573 | ctx->s_frame.height, cr.c.width, |
587 | ctx->s_frame.height, cr.c.width, | 574 | cr.c.height, ctx->rotation); |
588 | cr.c.height, ctx->rotation); | 575 | } |
589 | } | 576 | if (ret) { |
590 | if (ret) { | 577 | v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n"); |
591 | v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n"); | 578 | return -EINVAL; |
592 | return -EINVAL; | ||
593 | } | ||
594 | } | 579 | } |
595 | 580 | ||
596 | f->offs_h = cr.c.left; | 581 | f->offs_h = cr.c.left; |
@@ -653,6 +638,29 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, | |||
653 | return vb2_queue_init(dst_vq); | 638 | return vb2_queue_init(dst_vq); |
654 | } | 639 | } |
655 | 640 | ||
641 | static int fimc_m2m_set_default_format(struct fimc_ctx *ctx) | ||
642 | { | ||
643 | struct v4l2_pix_format_mplane pixm = { | ||
644 | .pixelformat = V4L2_PIX_FMT_RGB32, | ||
645 | .width = 800, | ||
646 | .height = 600, | ||
647 | .plane_fmt[0] = { | ||
648 | .bytesperline = 800 * 4, | ||
649 | .sizeimage = 800 * 4 * 600, | ||
650 | }, | ||
651 | }; | ||
652 | struct fimc_fmt *fmt; | ||
653 | |||
654 | fmt = fimc_find_format(&pixm.pixelformat, NULL, FMT_FLAGS_M2M, 0); | ||
655 | if (!fmt) | ||
656 | return -EINVAL; | ||
657 | |||
658 | __set_frame_format(&ctx->s_frame, fmt, &pixm); | ||
659 | __set_frame_format(&ctx->d_frame, fmt, &pixm); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
656 | static int fimc_m2m_open(struct file *file) | 664 | static int fimc_m2m_open(struct file *file) |
657 | { | 665 | { |
658 | struct fimc_dev *fimc = video_drvdata(file); | 666 | struct fimc_dev *fimc = video_drvdata(file); |
@@ -697,6 +705,7 @@ static int fimc_m2m_open(struct file *file) | |||
697 | ctx->flags = 0; | 705 | ctx->flags = 0; |
698 | ctx->in_path = FIMC_IO_DMA; | 706 | ctx->in_path = FIMC_IO_DMA; |
699 | ctx->out_path = FIMC_IO_DMA; | 707 | ctx->out_path = FIMC_IO_DMA; |
708 | ctx->scaler.enabled = 1; | ||
700 | 709 | ||
701 | ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); | 710 | ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init); |
702 | if (IS_ERR(ctx->m2m_ctx)) { | 711 | if (IS_ERR(ctx->m2m_ctx)) { |
@@ -707,9 +716,15 @@ static int fimc_m2m_open(struct file *file) | |||
707 | if (fimc->m2m.refcnt++ == 0) | 716 | if (fimc->m2m.refcnt++ == 0) |
708 | set_bit(ST_M2M_RUN, &fimc->state); | 717 | set_bit(ST_M2M_RUN, &fimc->state); |
709 | 718 | ||
719 | ret = fimc_m2m_set_default_format(ctx); | ||
720 | if (ret < 0) | ||
721 | goto error_m2m_ctx; | ||
722 | |||
710 | mutex_unlock(&fimc->lock); | 723 | mutex_unlock(&fimc->lock); |
711 | return 0; | 724 | return 0; |
712 | 725 | ||
726 | error_m2m_ctx: | ||
727 | v4l2_m2m_ctx_release(ctx->m2m_ctx); | ||
713 | error_c: | 728 | error_c: |
714 | fimc_ctrls_delete(ctx); | 729 | fimc_ctrls_delete(ctx); |
715 | error_fh: | 730 | error_fh: |