msm: camera: Handling Buffer Error notified by reg_mgr

This change provides provision to allow devices connected
to the req_mgr to receive error notifications on the given link.
ISP on receiving such notification will flag a sync failure on the
buffer corresponding to the req_id flagged by req_mgr as a
failure to userspace

Change-Id: I12d3d718595660cb3a655114112f26e64fc60046
Signed-off-by: vhajeri <vhajeri@codeaurora.org>
This commit is contained in:
vhajeri 2017-11-10 18:43:08 -08:00
commit 0554525646
4 changed files with 99 additions and 9 deletions

View file

@ -196,6 +196,30 @@ int cam_context_handle_crm_flush_req(struct cam_context *ctx,
return rc;
}
int cam_context_handle_crm_process_evt(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *process_evt)
{
int rc;
if (!ctx->state_machine) {
CAM_ERR(CAM_CORE, "Context is not ready");
return -EINVAL;
}
mutex_lock(&ctx->ctx_mutex);
if (ctx->state_machine[ctx->state].crm_ops.process_evt) {
rc = ctx->state_machine[ctx->state].crm_ops.process_evt(ctx,
process_evt);
} else {
CAM_ERR(CAM_CORE, "No crm process evt in dev %d, state %d",
ctx->dev_hdl, ctx->state);
rc = -EPROTO;
}
mutex_unlock(&ctx->ctx_mutex);
return rc;
}
int cam_context_handle_acquire_dev(struct cam_context *ctx,
struct cam_acquire_dev_cmd *cmd)
{

View file

@ -56,6 +56,7 @@ enum cam_context_state {
* @num_in_acked: Number of in fence acked
* @num_out_acked: Number of out fence acked
* @flushed: Request is flushed
* @error_flag: Flag an error
* @ctx: The context to which this request belongs
*
*/
@ -73,6 +74,7 @@ struct cam_ctx_request {
uint32_t num_in_acked;
uint32_t num_out_acked;
int flushed;
bool error_flag;
struct cam_context *ctx;
};
@ -120,6 +122,8 @@ struct cam_ctx_crm_ops {
struct cam_req_mgr_apply_request *apply);
int (*flush_req)(struct cam_context *ctx,
struct cam_req_mgr_flush_request *flush);
int (*process_evt)(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *evt_data);
};
@ -269,6 +273,18 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
int cam_context_handle_crm_flush_req(struct cam_context *ctx,
struct cam_req_mgr_flush_request *apply);
/**
* cam_context_handle_crm_process_evt()
*
* @brief: Handle process event command
*
* @ctx: Object pointer for cam_context
* @process_evt: process event command payload
*
*/
int cam_context_handle_crm_process_evt(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *process_evt);
/**
* cam_context_handle_acquire_dev()
*

View file

@ -309,6 +309,26 @@ static int __cam_node_crm_flush_req(struct cam_req_mgr_flush_request *flush)
return cam_context_handle_crm_flush_req(ctx, flush);
}
static int __cam_node_crm_process_evt(
struct cam_req_mgr_link_evt_data *evt_data)
{
struct cam_context *ctx = NULL;
if (!evt_data) {
CAM_ERR(CAM_CORE, "Invalid process event request payload");
return -EINVAL;
}
ctx = (struct cam_context *) cam_get_device_priv(evt_data->dev_hdl);
if (!ctx) {
CAM_ERR(CAM_CORE, "Can not get context for handle %d",
evt_data->dev_hdl);
return -EINVAL;
}
return cam_context_handle_crm_process_evt(ctx, evt_data);
}
int cam_node_deinit(struct cam_node *node)
{
if (node)
@ -361,6 +381,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
node->crm_node_intf.get_dev_info = __cam_node_crm_get_dev_info;
node->crm_node_intf.link_setup = __cam_node_crm_link_setup;
node->crm_node_intf.flush_req = __cam_node_crm_flush_req;
node->crm_node_intf.process_evt = __cam_node_crm_process_evt;
mutex_init(&node->list_mutex);
INIT_LIST_HEAD(&node->free_ctx_list);

View file

@ -216,19 +216,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
continue;
}
if (!bubble_state) {
CAM_DBG(CAM_ISP,
"Sync with success: req %lld res 0x%x fd 0x%x",
req->request_id,
req_isp->fence_map_out[j].resource_handle,
req_isp->fence_map_out[j].sync_id);
rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
CAM_SYNC_STATE_SIGNALED_SUCCESS);
if (rc)
CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
rc);
} else if (!req_isp->bubble_report) {
if (req->error_flag || !req_isp->bubble_report) {
CAM_DBG(CAM_ISP,
"Sync with failure: req %lld res 0x%x fd 0x%x",
req->request_id,
@ -240,6 +228,18 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
if (rc)
CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
rc);
} else if (!bubble_state) {
CAM_DBG(CAM_ISP,
"Sync with success: req %lld res 0x%x fd 0x%x",
req->request_id,
req_isp->fence_map_out[j].resource_handle,
req_isp->fence_map_out[j].sync_id);
rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
CAM_SYNC_STATE_SIGNALED_SUCCESS);
if (rc)
CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
rc);
} else {
/*
* Ignore the buffer done if bubble detect is on
@ -2005,6 +2005,34 @@ static int __cam_isp_ctx_release_dev_in_activated(struct cam_context *ctx,
return rc;
}
static int __cam_isp_ctx_process_evt(struct cam_context *ctx,
struct cam_req_mgr_link_evt_data *link_evt_data)
{
int rc = 0;
struct cam_ctx_request *req_current;
struct cam_ctx_request *req_prev;
bool req_id_found = false;
list_for_each_entry_safe(req_current, req_prev,
&ctx->pending_req_list, list) {
if (link_evt_data->req_id == req_current->request_id) {
req_current->error_flag = true;
req_id_found = true;
CAM_DBG(CAM_ISP,
"flagging req_id=%lld as error on link_hdl: %d for dev_hdl: %d",
link_evt_data->req_id, link_evt_data->link_hdl,
link_evt_data->dev_hdl);
}
}
if (!req_id_found) {
CAM_ERR(CAM_ISP,
"req_id=%lld not found in the pending list ",
link_evt_data->req_id);
rc = -EINVAL;
}
return rc;
}
static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
struct cam_req_mgr_core_dev_link_setup *unlink)
{
@ -2137,6 +2165,7 @@ static struct cam_ctx_ops
.unlink = __cam_isp_ctx_unlink_in_activated,
.apply_req = __cam_isp_ctx_apply_req,
.flush_req = __cam_isp_ctx_flush_req_in_top_state,
.process_evt = __cam_isp_ctx_process_evt,
},
.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
},