Merge "msm: camera: Deregister sync callbacks at context flush" into dev/msm-4.9-camx
This commit is contained in:
commit
0bb037141d
3 changed files with 57 additions and 8 deletions
|
|
@ -70,7 +70,7 @@ struct cam_ctx_request {
|
|||
uint32_t num_in_map_entries;
|
||||
struct cam_hw_fence_map_entry out_map_entries[CAM_CTX_CFG_MAX];
|
||||
uint32_t num_out_map_entries;
|
||||
uint32_t num_in_acked;
|
||||
atomic_t num_in_acked;
|
||||
uint32_t num_out_acked;
|
||||
int flushed;
|
||||
struct cam_context *ctx;
|
||||
|
|
|
|||
|
|
@ -189,8 +189,7 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data)
|
|||
return;
|
||||
}
|
||||
|
||||
req->num_in_acked++;
|
||||
if (req->num_in_acked == req->num_in_map_entries) {
|
||||
if (atomic_inc_return(&req->num_in_acked) == req->num_in_map_entries) {
|
||||
apply.request_id = req->request_id;
|
||||
/*
|
||||
* take mutex to ensure that another thread does
|
||||
|
|
@ -342,6 +341,7 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
|
|||
req->num_hw_update_entries = cfg.num_hw_update_entries;
|
||||
req->num_out_map_entries = cfg.num_out_map_entries;
|
||||
req->num_in_map_entries = cfg.num_in_map_entries;
|
||||
atomic_set(&req->num_in_acked, 0);
|
||||
req->request_id = packet->header.request_id;
|
||||
req->status = 1;
|
||||
req->req_priv = cfg.priv;
|
||||
|
|
@ -492,6 +492,7 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
|
|||
struct cam_ctx_request *req;
|
||||
uint32_t i;
|
||||
int rc = 0;
|
||||
bool free_req;
|
||||
|
||||
CAM_DBG(CAM_CTXT, "[%s] E: NRT flush ctx", ctx->dev_name);
|
||||
|
||||
|
|
@ -528,6 +529,21 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
|
|||
|
||||
flush_args.flush_req_pending[flush_args.num_req_pending++] =
|
||||
req->req_priv;
|
||||
|
||||
free_req = false;
|
||||
for (i = 0; i < req->num_in_map_entries; i++) {
|
||||
rc = cam_sync_deregister_callback(
|
||||
cam_context_sync_callback,
|
||||
(void *)req,
|
||||
req->in_map_entries[i].sync_id);
|
||||
if (!rc) {
|
||||
cam_context_putref(ctx);
|
||||
if (atomic_inc_return(&req->num_in_acked) ==
|
||||
req->num_in_map_entries)
|
||||
free_req = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < req->num_out_map_entries; i++) {
|
||||
if (req->out_map_entries[i].sync_id != -1) {
|
||||
rc = cam_sync_signal(
|
||||
|
|
@ -543,6 +559,17 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have deregistered the last sync callback, req will
|
||||
* not be put on the free list. So put it on the free list here
|
||||
*/
|
||||
if (free_req) {
|
||||
req->ctx = NULL;
|
||||
spin_lock(&ctx->lock);
|
||||
list_add_tail(&req->list, &ctx->free_req_list);
|
||||
spin_unlock(&ctx->lock);
|
||||
}
|
||||
|
||||
if (cam_debug_ctx_req_list & ctx->dev_id)
|
||||
CAM_INFO(CAM_CTXT,
|
||||
"[%s][%d] : Deleting req[%llu] from temp_list",
|
||||
|
|
@ -630,6 +657,7 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
|
|||
uint32_t i;
|
||||
int32_t sync_id = 0;
|
||||
int rc = 0;
|
||||
bool free_req = false;
|
||||
|
||||
CAM_DBG(CAM_CTXT, "[%s] E: NRT flush req", ctx->dev_name);
|
||||
|
||||
|
|
@ -682,6 +710,22 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
|
|||
}
|
||||
|
||||
if (req) {
|
||||
if (flush_args.num_req_pending) {
|
||||
for (i = 0; i < req->num_in_map_entries; i++) {
|
||||
rc = cam_sync_deregister_callback(
|
||||
cam_context_sync_callback,
|
||||
(void *)req,
|
||||
req->in_map_entries[i].sync_id);
|
||||
if (rc)
|
||||
continue;
|
||||
|
||||
cam_context_putref(ctx);
|
||||
if (atomic_inc_return(&req->num_in_acked) ==
|
||||
req->num_in_map_entries)
|
||||
free_req = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (flush_args.num_req_pending || flush_args.num_req_active) {
|
||||
for (i = 0; i < req->num_out_map_entries; i++) {
|
||||
sync_id =
|
||||
|
|
@ -697,17 +741,20 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (flush_args.num_req_active) {
|
||||
if (flush_args.num_req_active || free_req) {
|
||||
req->ctx = NULL;
|
||||
spin_lock(&ctx->lock);
|
||||
list_add_tail(&req->list, &ctx->free_req_list);
|
||||
spin_unlock(&ctx->lock);
|
||||
req->ctx = NULL;
|
||||
|
||||
if (cam_debug_ctx_req_list & ctx->dev_id)
|
||||
CAM_INFO(CAM_CTXT,
|
||||
"[%s][%d] : Moving req[%llu] from active_list to free_list",
|
||||
"[%s][%d] : Moving req[%llu] from %s to free_list",
|
||||
ctx->dev_name, ctx->ctx_id,
|
||||
req->request_id);
|
||||
req->request_id,
|
||||
flush_args.num_req_active ?
|
||||
"active_list" :
|
||||
"pending_list");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ int cam_sync_deregister_callback(sync_callback cb_func,
|
|||
{
|
||||
struct sync_table_row *row = NULL;
|
||||
struct sync_callback_info *sync_cb, *temp;
|
||||
bool found = false;
|
||||
|
||||
if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0)
|
||||
return -EINVAL;
|
||||
|
|
@ -145,11 +146,12 @@ int cam_sync_deregister_callback(sync_callback cb_func,
|
|||
sync_cb->cb_data == userdata) {
|
||||
list_del_init(&sync_cb->list);
|
||||
kfree(sync_cb);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
|
||||
return 0;
|
||||
return found ? 0 : -ENOENT;
|
||||
}
|
||||
|
||||
int cam_sync_signal(int32_t sync_obj, uint32_t status)
|
||||
|
|
|
|||
Loading…
Reference in a new issue