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:
parent
6e4bc9378d
commit
0554525646
4 changed files with 99 additions and 9 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue