From 5925180360bca209c21e9271e277caaca68bcad5 Mon Sep 17 00:00:00 2001 From: annamraj Date: Fri, 6 Apr 2018 19:39:07 +0530 Subject: [PATCH] msm: camera: Framedrop notification Notify the frame drop using ioctl VIDIOC_MSM_BUF_MNGR_BUF_ERROR Change-Id: Ide54d98fd05e19f5e2d7e88b6b65e151aa257334 Signed-off-by: annamraj --- .../platform/msm/camera_v2/isp/msm_buf_mgr.c | 3 +- .../msm_buf_mgr/msm_generic_buf_mgr.c | 37 ++++++++++- drivers/media/platform/msm/camera_v2/msm_sd.h | 5 +- .../platform/msm/camera_v2/msm_vb2/msm_vb2.c | 64 ++++++++++++++++++- .../msm/camera_v2/pproc/cpp/msm_cpp.c | 5 +- include/media/msmb_generic_buf_mgr.h | 4 +- include/uapi/media/msmb_generic_buf_mgr.h | 2 + 7 files changed, 113 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index eab56b70e646..20a38925aa10 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -26,6 +26,7 @@ #include #include #include +#include #include "msm.h" #include "msm_buf_mgr.h" diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c index f732f5180e81..58bfdb77a492 100644 --- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -166,6 +166,33 @@ static int32_t msm_buf_mngr_buf_done(struct msm_buf_mngr_device *buf_mngr_dev, return ret; } +static int32_t msm_buf_mngr_buf_error(struct msm_buf_mngr_device *buf_mngr_dev, + struct msm_buf_mngr_info *buf_info) +{ + unsigned long flags; + struct msm_get_bufs *bufs, *save; + int32_t ret = -EINVAL; + + spin_lock_irqsave(&buf_mngr_dev->buf_q_spinlock, flags); + list_for_each_entry_safe(bufs, save, &buf_mngr_dev->buf_qhead, entry) { + if ((bufs->session_id == buf_info->session_id) && + (bufs->stream_id == buf_info->stream_id) && + (bufs->index == buf_info->index)) { + ret = buf_mngr_dev->vb2_ops.buf_error + (bufs->vb2_v4l2_buf, + buf_info->session_id, + buf_info->stream_id, + buf_info->frame_id, + &buf_info->timestamp, + buf_info->reserved); + list_del_init(&bufs->entry); + kfree(bufs); + break; + } + } + spin_unlock_irqrestore(&buf_mngr_dev->buf_q_spinlock, flags); + return ret; +} static int32_t msm_buf_mngr_put_buf(struct msm_buf_mngr_device *buf_mngr_dev, struct msm_buf_mngr_info *buf_info) @@ -473,6 +500,9 @@ int msm_cam_buf_mgr_ops(unsigned int cmd, void *argp) case VIDIOC_MSM_BUF_MNGR_BUF_DONE: rc = msm_buf_mngr_buf_done(msm_buf_mngr_dev, argp); break; + case VIDIOC_MSM_BUF_MNGR_BUF_ERROR: + rc = msm_buf_mngr_buf_error(msm_buf_mngr_dev, argp); + break; case VIDIOC_MSM_BUF_MNGR_PUT_BUF: rc = msm_buf_mngr_put_buf(msm_buf_mngr_dev, argp); break; @@ -571,6 +601,7 @@ static long msm_buf_mngr_subdev_ioctl(struct v4l2_subdev *sd, case VIDIOC_MSM_BUF_MNGR_GET_BUF: case VIDIOC_MSM_BUF_MNGR_BUF_DONE: case VIDIOC_MSM_BUF_MNGR_PUT_BUF: + case VIDIOC_MSM_BUF_MNGR_BUF_ERROR: rc = msm_cam_buf_mgr_ops(cmd, argp); break; case VIDIOC_MSM_BUF_MNGR_INIT: @@ -719,6 +750,9 @@ static long msm_bmgr_subdev_fops_compat_ioctl(struct file *file, case VIDIOC_MSM_BUF_MNGR_BUF_DONE32: cmd = VIDIOC_MSM_BUF_MNGR_BUF_DONE; break; + case VIDIOC_MSM_BUF_MNGR_BUF_ERROR32: + cmd = VIDIOC_MSM_BUF_MNGR_BUF_ERROR; + break; case VIDIOC_MSM_BUF_MNGR_PUT_BUF32: cmd = VIDIOC_MSM_BUF_MNGR_PUT_BUF; break; @@ -737,6 +771,7 @@ static long msm_bmgr_subdev_fops_compat_ioctl(struct file *file, switch (cmd) { case VIDIOC_MSM_BUF_MNGR_GET_BUF: case VIDIOC_MSM_BUF_MNGR_BUF_DONE: + case VIDIOC_MSM_BUF_MNGR_BUF_ERROR: case VIDIOC_MSM_BUF_MNGR_FLUSH: case VIDIOC_MSM_BUF_MNGR_PUT_BUF: { struct msm_buf_mngr_info32_t buf_info32; diff --git a/drivers/media/platform/msm/camera_v2/msm_sd.h b/drivers/media/platform/msm/camera_v2/msm_sd.h index d893d9fc07e3..3d5d3e03632e 100644 --- a/drivers/media/platform/msm/camera_v2/msm_sd.h +++ b/drivers/media/platform/msm/camera_v2/msm_sd.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -81,6 +81,9 @@ struct msm_sd_req_vb2_q { unsigned int stream_id, uint32_t sequence, struct timeval *ts, uint32_t reserved); int (*flush_buf)(int session_id, unsigned int stream_id); + int (*buf_error)(struct vb2_v4l2_buffer *vb2_v4l2_buf, int session_id, + unsigned int stream_id, uint32_t sequence, struct timeval *ts, + uint32_t reserved); }; #define MSM_SD_NOTIFY_GET_SD 0x00000001 diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c index e271c7fcd1b6..f2b048e37319 100644 --- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -457,6 +457,67 @@ static int msm_vb2_buf_done(struct vb2_v4l2_buffer *vb, int session_id, return rc; } +static int msm_vb2_buf_error(struct vb2_v4l2_buffer *vb, int session_id, + unsigned int stream_id, uint32_t sequence, + struct timeval *ts, uint32_t buf_type) +{ + unsigned long flags, rl_flags; + struct msm_vb2_buffer *msm_vb2; + struct msm_stream *stream; + struct msm_session *session; + struct vb2_v4l2_buffer *vb2_v4l2_buf = NULL; + int rc = 0; + + session = msm_get_session(session_id); + if (IS_ERR_OR_NULL(session)) + return -EINVAL; + + read_lock_irqsave(&session->stream_rwlock, rl_flags); + + stream = msm_get_stream(session, stream_id); + if (IS_ERR_OR_NULL(stream)) { + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return -EINVAL; + } + + spin_lock_irqsave(&stream->stream_lock, flags); + if (vb) { + list_for_each_entry(msm_vb2, &(stream->queued_list), list) { + vb2_v4l2_buf = &(msm_vb2->vb2_v4l2_buf); + if (vb2_v4l2_buf == vb) + break; + } + if (vb2_v4l2_buf != vb) { + pr_err("VB buffer is INVALID ses_id=%d, str_id=%d, vb=%pK\n", + session_id, stream_id, vb); + spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, + rl_flags); + return -EINVAL; + } + msm_vb2 = + container_of(vb2_v4l2_buf, struct msm_vb2_buffer, + vb2_v4l2_buf); + /* put buf before buf done */ + if (msm_vb2->in_freeq) { + vb2_v4l2_buf->sequence = sequence; + vb2_v4l2_buf->timestamp = *ts; + vb2_buffer_done(&vb2_v4l2_buf->vb2_buf, + VB2_BUF_STATE_ERROR); + msm_vb2->in_freeq = 0; + rc = 0; + } else + rc = -EINVAL; + } else { + pr_err(" VB buffer is NULL for ses_id=%d, str_id=%d\n", + session_id, stream_id); + rc = -EINVAL; + } + spin_unlock_irqrestore(&stream->stream_lock, flags); + read_unlock_irqrestore(&session->stream_rwlock, rl_flags); + return rc; +} + long msm_vb2_return_buf_by_idx(int session_id, unsigned int stream_id, uint32_t index) { @@ -555,6 +616,7 @@ int msm_vb2_request_cb(struct msm_sd_req_vb2_q *req) req->put_buf = msm_vb2_put_buf; req->buf_done = msm_vb2_buf_done; req->flush_buf = msm_vb2_flush_buf; + req->buf_error = msm_vb2_buf_error; return 0; } diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 25fc34b26bc1..53a01aff4bdd 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1624,6 +1624,7 @@ static int msm_cpp_buffer_ops(struct cpp_device *cpp_dev, case VIDIOC_MSM_BUF_MNGR_PUT_BUF: case VIDIOC_MSM_BUF_MNGR_BUF_DONE: case VIDIOC_MSM_BUF_MNGR_GET_BUF: + case VIDIOC_MSM_BUF_MNGR_BUF_ERROR: default: { struct msm_buf_mngr_info *buff_mgr_info = (struct msm_buf_mngr_info *)arg; @@ -3617,7 +3618,7 @@ STREAM_BUFF_END: break; } buff_mgr_info.frame_id = frame_info.frame_id; - rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_DONE, + rc = msm_cpp_buffer_ops(cpp_dev, VIDIOC_MSM_BUF_MNGR_BUF_ERROR, 0x0, &buff_mgr_info); if (rc < 0) { pr_err("error in buf done\n"); diff --git a/include/media/msmb_generic_buf_mgr.h b/include/media/msmb_generic_buf_mgr.h index 6588420fd6fd..3cb82668acde 100644 --- a/include/media/msmb_generic_buf_mgr.h +++ b/include/media/msmb_generic_buf_mgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,6 +43,8 @@ struct msm_buf_mngr_info32_t { #define VIDIOC_MSM_BUF_MNGR_FLUSH32 \ _IOWR('V', BASE_VIDIOC_PRIVATE + 39, struct msm_buf_mngr_info32_t) +#define VIDIOC_MSM_BUF_MNGR_BUF_ERROR32 \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 41, struct msm_buf_mngr_info32_t) #endif #endif diff --git a/include/uapi/media/msmb_generic_buf_mgr.h b/include/uapi/media/msmb_generic_buf_mgr.h index 2961cae1e7c1..8dad9ae92cf8 100644 --- a/include/uapi/media/msmb_generic_buf_mgr.h +++ b/include/uapi/media/msmb_generic_buf_mgr.h @@ -62,5 +62,7 @@ struct msm_buf_mngr_main_cont_info { _IOWR('V', BASE_VIDIOC_PRIVATE + 40, \ struct msm_camera_private_ioctl_arg) +#define VIDIOC_MSM_BUF_MNGR_BUF_ERROR \ + _IOWR('V', BASE_VIDIOC_PRIVATE + 41, struct msm_buf_mngr_info) #endif