Loading drivers/media/platform/msm/camera/cam_core/cam_context.c +16 −0 Original line number Original line Diff line number Diff line Loading @@ -224,6 +224,7 @@ int cam_context_handle_acquire_dev(struct cam_context *ctx, struct cam_acquire_dev_cmd *cmd) struct cam_acquire_dev_cmd *cmd) { { int rc; int rc; int i; if (!ctx->state_machine) { if (!ctx->state_machine) { CAM_ERR(CAM_CORE, "Context is not ready"); CAM_ERR(CAM_CORE, "Context is not ready"); Loading @@ -244,6 +245,17 @@ int cam_context_handle_acquire_dev(struct cam_context *ctx, cmd->dev_handle, ctx->state); cmd->dev_handle, ctx->state); rc = -EPROTO; rc = -EPROTO; } } INIT_LIST_HEAD(&ctx->active_req_list); INIT_LIST_HEAD(&ctx->wait_req_list); INIT_LIST_HEAD(&ctx->pending_req_list); INIT_LIST_HEAD(&ctx->free_req_list); for (i = 0; i < ctx->req_size; i++) { INIT_LIST_HEAD(&ctx->req_list[i].list); list_add_tail(&ctx->req_list[i].list, &ctx->free_req_list); } mutex_unlock(&ctx->ctx_mutex); mutex_unlock(&ctx->ctx_mutex); return rc; return rc; Loading Loading @@ -394,6 +406,8 @@ int cam_context_handle_stop_dev(struct cam_context *ctx, int cam_context_init(struct cam_context *ctx, int cam_context_init(struct cam_context *ctx, const char *dev_name, const char *dev_name, uint64_t dev_id, uint32_t ctx_id, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_ctx_request *req_list, struct cam_ctx_request *req_list, Loading @@ -417,6 +431,8 @@ int cam_context_init(struct cam_context *ctx, spin_lock_init(&ctx->lock); spin_lock_init(&ctx->lock); ctx->dev_name = dev_name; ctx->dev_name = dev_name; ctx->dev_id = dev_id; ctx->ctx_id = ctx_id; ctx->ctx_crm_intf = NULL; ctx->ctx_crm_intf = NULL; ctx->crm_ctx_intf = crm_node_intf; ctx->crm_ctx_intf = crm_node_intf; ctx->hw_mgr_intf = hw_mgr_intf; ctx->hw_mgr_intf = hw_mgr_intf; Loading drivers/media/platform/msm/camera/cam_core/cam_context.h +8 −0 Original line number Original line Diff line number Diff line Loading @@ -147,6 +147,8 @@ struct cam_ctx_ops { * struct cam_context - camera context object for the subdevice node * struct cam_context - camera context object for the subdevice node * * * @dev_name: String giving name of device associated * @dev_name: String giving name of device associated * @dev_id: ID of device associated * @ctx_id: ID for this context * @list: Link list entry * @list: Link list entry * @sessoin_hdl: Session handle * @sessoin_hdl: Session handle * @dev_hdl: Device handle * @dev_hdl: Device handle Loading Loading @@ -174,6 +176,8 @@ struct cam_ctx_ops { */ */ struct cam_context { struct cam_context { const char *dev_name; const char *dev_name; uint64_t dev_id; uint32_t ctx_id; struct list_head list; struct list_head list; int32_t session_hdl; int32_t session_hdl; int32_t dev_hdl; int32_t dev_hdl; Loading Loading @@ -376,6 +380,8 @@ int cam_context_deinit(struct cam_context *ctx); * * * @ctx: Object pointer for cam_context * @ctx: Object pointer for cam_context * @dev_name: String giving name of device associated * @dev_name: String giving name of device associated * @dev_id: ID of the device associated * @ctx_id: ID for this context * @crm_node_intf: Function table for crm to context interface * @crm_node_intf: Function table for crm to context interface * @hw_mgr_intf: Function table for context to hw interface * @hw_mgr_intf: Function table for context to hw interface * @req_list: Requests storage * @req_list: Requests storage Loading @@ -384,6 +390,8 @@ int cam_context_deinit(struct cam_context *ctx); */ */ int cam_context_init(struct cam_context *ctx, int cam_context_init(struct cam_context *ctx, const char *dev_name, const char *dev_name, uint64_t dev_id, uint32_t ctx_id, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_ctx_request *req_list, struct cam_ctx_request *req_list, Loading drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +146 −30 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,9 @@ #include "cam_trace.h" #include "cam_trace.h" #include "cam_debug_util.h" #include "cam_debug_util.h" static uint cam_debug_ctx_req_list; module_param(cam_debug_ctx_req_list, uint, 0644); static inline int cam_context_validate_thread(void) static inline int cam_context_validate_thread(void) { { if (in_interrupt()) { if (in_interrupt()) { Loading Loading @@ -56,7 +59,8 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx, spin_lock(&ctx->lock); spin_lock(&ctx->lock); if (list_empty(&ctx->active_req_list)) { if (list_empty(&ctx->active_req_list)) { CAM_ERR(CAM_CTXT, "no active request"); CAM_ERR(CAM_CTXT, "[%s][%d] no active request", ctx->dev_name, ctx->ctx_id); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); return -EIO; return -EIO; } } Loading @@ -66,14 +70,17 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx, trace_cam_buf_done("UTILS", ctx, req); trace_cam_buf_done("UTILS", ctx, req); if (done->request_id != req->request_id) { if (done->request_id != req->request_id) { CAM_ERR(CAM_CTXT, "mismatch: done req[%lld], active req[%lld]", CAM_ERR(CAM_CTXT, "[%s][%d] mismatch: done req[%lld], active req[%lld]", ctx->dev_name, ctx->ctx_id, done->request_id, req->request_id); done->request_id, req->request_id); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); return -EIO; return -EIO; } } if (!req->num_out_map_entries) { if (!req->num_out_map_entries) { CAM_ERR(CAM_CTXT, "no output fence to signal"); CAM_ERR(CAM_CTXT, "[%s][%d] no output fence to signal", ctx->dev_name, ctx->ctx_id); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); return -EIO; return -EIO; } } Loading @@ -94,6 +101,11 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx, req->out_map_entries[j].sync_id = -1; req->out_map_entries[j].sync_id = -1; } } if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from active_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); /* /* * another thread may be adding/removing from free list, * another thread may be adding/removing from free list, * so hold the lock * so hold the lock Loading @@ -114,7 +126,8 @@ static int cam_context_apply_req_to_hw(struct cam_ctx_request *req, struct cam_hw_config_args cfg; struct cam_hw_config_args cfg; if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -124,6 +137,11 @@ static int cam_context_apply_req_to_hw(struct cam_ctx_request *req, list_add_tail(&req->list, &ctx->active_req_list); list_add_tail(&req->list, &ctx->active_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from pending_list to active_list", ctx->dev_name, ctx->ctx_id, req->request_id); cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map; cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map; cfg.hw_update_entries = req->hw_update_entries; cfg.hw_update_entries = req->hw_update_entries; cfg.num_hw_update_entries = req->num_hw_update_entries; cfg.num_hw_update_entries = req->num_hw_update_entries; Loading @@ -135,7 +153,13 @@ static int cam_context_apply_req_to_hw(struct cam_ctx_request *req, if (rc) { if (rc) { spin_lock(&ctx->lock); spin_lock(&ctx->lock); list_del_init(&req->list); list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from active_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); } } end: end: Loading @@ -159,6 +183,11 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data) return; return; ctx = req->ctx; ctx = req->ctx; if (!ctx) { CAM_ERR(CAM_CTXT, "Invalid ctx for req %llu", req->request_id); return; } req->num_in_acked++; req->num_in_acked++; if (req->num_in_acked == req->num_in_map_entries) { if (req->num_in_acked == req->num_in_map_entries) { apply.request_id = req->request_id; apply.request_id = req->request_id; Loading @@ -174,8 +203,6 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data) CAM_DBG(CAM_CTXT, "fence error: %d", sync_obj); CAM_DBG(CAM_CTXT, "fence error: %d", sync_obj); flush_cmd.req_id = req->request_id; flush_cmd.req_id = req->request_id; cam_context_flush_req_to_hw(ctx, &flush_cmd); cam_context_flush_req_to_hw(ctx, &flush_cmd); cam_context_putref(ctx); return; } } mutex_lock(&ctx->sync_mutex); mutex_lock(&ctx->sync_mutex); Loading @@ -190,6 +217,12 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data) list_del_init(&req->list); list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from pending_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); } } } } cam_context_putref(ctx); cam_context_putref(ctx); Loading @@ -206,7 +239,8 @@ int32_t cam_context_release_dev_to_hw(struct cam_context *ctx, } } if ((!ctx->hw_mgr_intf) || (!ctx->hw_mgr_intf->hw_release)) { if ((!ctx->hw_mgr_intf) || (!ctx->hw_mgr_intf->hw_release)) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); return -EINVAL; return -EINVAL; } } Loading Loading @@ -241,7 +275,8 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -258,7 +293,8 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (!req) { if (!req) { CAM_ERR(CAM_CTXT, "No more request obj free"); CAM_ERR(CAM_CTXT, "[%s][%d] No more request obj free", ctx->dev_name, ctx->ctx_id); rc = -ENOMEM; rc = -ENOMEM; goto end; goto end; } } Loading @@ -273,7 +309,8 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, (uint64_t *) &packet_addr, (uint64_t *) &packet_addr, &len); &len); if (rc != 0) { if (rc != 0) { CAM_ERR(CAM_CTXT, "Can not get packet address"); CAM_ERR(CAM_CTXT, "[%s][%d] Can not get packet address", ctx->dev_name, ctx->ctx_id); rc = -EINVAL; rc = -EINVAL; goto free_req; goto free_req; } } Loading @@ -295,7 +332,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, rc = ctx->hw_mgr_intf->hw_prepare_update( rc = ctx->hw_mgr_intf->hw_prepare_update( ctx->hw_mgr_intf->hw_mgr_priv, &cfg); ctx->hw_mgr_intf->hw_mgr_priv, &cfg); if (rc != 0) { if (rc != 0) { CAM_ERR(CAM_CTXT, "Prepare config packet failed in HW layer"); CAM_ERR(CAM_CTXT, "[%s][%d] Prepare config packet failed in HW layer", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto free_req; goto free_req; } } Loading @@ -310,6 +349,12 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, spin_lock(&ctx->lock); spin_lock(&ctx->lock); list_add_tail(&req->list, &ctx->pending_req_list); list_add_tail(&req->list, &ctx->pending_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from free_list to pending_list", ctx->dev_name, ctx->ctx_id, req->request_id); for (i = 0; i < req->num_in_map_entries; i++) { for (i = 0; i < req->num_in_map_entries; i++) { cam_context_getref(ctx); cam_context_getref(ctx); rc = cam_sync_register_callback( rc = cam_sync_register_callback( Loading @@ -318,9 +363,21 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, req->in_map_entries[i].sync_id); req->in_map_entries[i].sync_id); if (rc) { if (rc) { CAM_ERR(CAM_CTXT, CAM_ERR(CAM_CTXT, "Failed register fence cb: %d ret = %d", "[%s][%d] Failed register fence cb: %d ret = %d", ctx->dev_name, ctx->ctx_id, req->in_map_entries[i].sync_id, rc); req->in_map_entries[i].sync_id, rc); spin_lock(&ctx->lock); list_del_init(&req->list); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from pending_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); cam_context_putref(ctx); cam_context_putref(ctx); goto free_req; goto free_req; } } CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d", CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d", Loading Loading @@ -355,7 +412,8 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -365,14 +423,16 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, cmd->resource_hdl); cmd->resource_hdl); if (cmd->num_resources > CAM_CTX_RES_MAX) { if (cmd->num_resources > CAM_CTX_RES_MAX) { CAM_ERR(CAM_CTXT, "resource limit exceeded"); CAM_ERR(CAM_CTXT, "[%s][%d] resource limit exceeded", ctx->dev_name, ctx->ctx_id); rc = -ENOMEM; rc = -ENOMEM; goto end; goto end; } } /* for now we only support user pointer */ /* for now we only support user pointer */ if (cmd->handle_type != 1) { if (cmd->handle_type != 1) { CAM_ERR(CAM_CTXT, "Only user pointer is supported"); CAM_ERR(CAM_CTXT, "[%s][%d] Only user pointer is supported", ctx->dev_name, ctx->ctx_id); rc = -EINVAL; rc = -EINVAL; goto end; goto end; } } Loading @@ -387,7 +447,8 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv, rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv, ¶m); ¶m); if (rc != 0) { if (rc != 0) { CAM_ERR(CAM_CTXT, "Acquire device failed"); CAM_ERR(CAM_CTXT, "[%s][%d] Acquire device failed", ctx->dev_name, ctx->ctx_id); goto end; goto end; } } Loading @@ -404,7 +465,8 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); if (ctx->dev_hdl <= 0) { if (ctx->dev_hdl <= 0) { rc = -EFAULT; rc = -EFAULT; CAM_ERR(CAM_CTXT, "Can not create device handle"); CAM_ERR(CAM_CTXT, "[%s][%d] Can not create device handle", ctx->dev_name, ctx->ctx_id); goto free_hw; goto free_hw; } } cmd->dev_handle = ctx->dev_hdl; cmd->dev_handle = ctx->dev_hdl; Loading @@ -430,7 +492,7 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) uint32_t i; uint32_t i; int rc = 0; int rc = 0; CAM_DBG(CAM_CTXT, "E: NRT flush ctx"); CAM_DBG(CAM_CTXT, "[%s] E: NRT flush ctx", ctx->dev_name); /* /* * flush pending requests, take the sync lock to synchronize with the * flush pending requests, take the sync lock to synchronize with the Loading @@ -442,17 +504,30 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) spin_lock(&ctx->lock); spin_lock(&ctx->lock); list_splice_init(&ctx->pending_req_list, &temp_list); list_splice_init(&ctx->pending_req_list, &temp_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving all pending requests from pending_list to temp_list", ctx->dev_name, ctx->ctx_id); flush_args.num_req_pending = 0; flush_args.num_req_pending = 0; while (!list_empty(&temp_list)) { while (true) { spin_lock(&ctx->lock); if (list_empty(&temp_list)) { spin_unlock(&ctx->lock); break; } req = list_first_entry(&temp_list, req = list_first_entry(&temp_list, struct cam_ctx_request, list); struct cam_ctx_request, list); list_del_init(&req->list); list_del_init(&req->list); spin_unlock(&ctx->lock); req->flushed = 1; req->flushed = 1; flush_args.flush_req_pending[flush_args.num_req_pending++] = flush_args.flush_req_pending[flush_args.num_req_pending++] = req->req_priv; req->req_priv; for (i = 0; i < req->num_out_map_entries; i++) for (i = 0; i < req->num_out_map_entries; i++) { if (req->out_map_entries[i].sync_id != -1) { if (req->out_map_entries[i].sync_id != -1) { rc = cam_sync_signal( rc = cam_sync_signal( req->out_map_entries[i].sync_id, req->out_map_entries[i].sync_id, Loading @@ -467,6 +542,12 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) } } } } } } if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Deleting req[%llu] from temp_list", ctx->dev_name, ctx->ctx_id, req->request_id); } mutex_unlock(&ctx->sync_mutex); mutex_unlock(&ctx->sync_mutex); if (ctx->hw_mgr_intf->hw_flush) { if (ctx->hw_mgr_intf->hw_flush) { Loading @@ -492,10 +573,22 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) INIT_LIST_HEAD(&ctx->active_req_list); INIT_LIST_HEAD(&ctx->active_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); while (!list_empty(&temp_list)) { if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving all requests from active_list to temp_list", ctx->dev_name, ctx->ctx_id); while (true) { spin_lock(&ctx->lock); if (list_empty(&temp_list)) { spin_unlock(&ctx->lock); break; } req = list_first_entry(&temp_list, req = list_first_entry(&temp_list, struct cam_ctx_request, list); struct cam_ctx_request, list); list_del_init(&req->list); list_del_init(&req->list); spin_unlock(&ctx->lock); for (i = 0; i < req->num_out_map_entries; i++) { for (i = 0; i < req->num_out_map_entries; i++) { if (req->out_map_entries[i].sync_id != -1) { if (req->out_map_entries[i].sync_id != -1) { rc = cam_sync_signal( rc = cam_sync_signal( Loading @@ -517,9 +610,14 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); req->ctx = NULL; req->ctx = NULL; if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from temp_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); } } CAM_DBG(CAM_CTXT, "X: NRT flush ctx"); CAM_DBG(CAM_CTXT, "[%s] X: NRT flush ctx", ctx->dev_name); return 0; return 0; } } Loading @@ -532,7 +630,7 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, uint32_t i; uint32_t i; int rc = 0; int rc = 0; CAM_DBG(CAM_CTXT, "E: NRT flush req"); CAM_DBG(CAM_CTXT, "[%s] E: NRT flush req", ctx->dev_name); flush_args.num_req_pending = 0; flush_args.num_req_pending = 0; flush_args.num_req_active = 0; flush_args.num_req_active = 0; Loading @@ -542,6 +640,11 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, if (req->request_id != cmd->req_id) if (req->request_id != cmd->req_id) continue; continue; if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Deleting req[%llu] from pending_list", ctx->dev_name, ctx->ctx_id, req->request_id); list_del_init(&req->list); list_del_init(&req->list); req->flushed = 1; req->flushed = 1; Loading Loading @@ -598,10 +701,16 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); req->ctx = NULL; 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", ctx->dev_name, ctx->ctx_id, req->request_id); } } } } } } CAM_DBG(CAM_CTXT, "X: NRT flush req"); CAM_DBG(CAM_CTXT, "[%s] X: NRT flush req", ctx->dev_name); return 0; return 0; } } Loading @@ -619,7 +728,8 @@ int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -630,7 +740,8 @@ int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx, rc = cam_context_flush_req_to_hw(ctx, cmd); rc = cam_context_flush_req_to_hw(ctx, cmd); else { else { rc = -EINVAL; rc = -EINVAL; CAM_ERR(CAM_CORE, "Invalid flush type %d", cmd->flush_type); CAM_ERR(CAM_CORE, "[%s][%d] Invalid flush type %d", ctx->dev_name, ctx->ctx_id, cmd->flush_type); } } end: end: Loading @@ -650,14 +761,17 @@ int32_t cam_context_start_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } if ((cmd->session_handle != ctx->session_hdl) || if ((cmd->session_handle != ctx->session_hdl) || (cmd->dev_handle != ctx->dev_hdl)) { (cmd->dev_handle != ctx->dev_hdl)) { CAM_ERR(CAM_CTXT, "Invalid session hdl[%d], dev_handle[%d]", CAM_ERR(CAM_CTXT, "[%s][%d] Invalid session hdl[%d], dev_handle[%d]", ctx->dev_name, ctx->ctx_id, cmd->session_handle, cmd->dev_handle); cmd->session_handle, cmd->dev_handle); rc = -EPERM; rc = -EPERM; goto end; goto end; Loading @@ -669,7 +783,8 @@ int32_t cam_context_start_dev_to_hw(struct cam_context *ctx, &arg); &arg); if (rc) { if (rc) { /* HW failure. user need to clean up the resource */ /* HW failure. user need to clean up the resource */ CAM_ERR(CAM_CTXT, "Start HW failed"); CAM_ERR(CAM_CTXT, "[%s][%d] Start HW failed", ctx->dev_name, ctx->ctx_id); goto end; goto end; } } } } Loading @@ -690,7 +805,8 @@ int32_t cam_context_stop_dev_to_hw(struct cam_context *ctx) } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c +5 −4 Original line number Original line Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -211,7 +211,8 @@ static struct cam_ctx_ops int cam_fd_context_init(struct cam_fd_context *fd_ctx, int cam_fd_context_init(struct cam_fd_context *fd_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf) struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id) { { int rc; int rc; Loading @@ -222,8 +223,8 @@ int cam_fd_context_init(struct cam_fd_context *fd_ctx, memset(fd_ctx, 0, sizeof(*fd_ctx)); memset(fd_ctx, 0, sizeof(*fd_ctx)); rc = cam_context_init(base_ctx, fd_dev_name, NULL, hw_intf, rc = cam_context_init(base_ctx, fd_dev_name, CAM_FD, ctx_id, fd_ctx->req_base, CAM_CTX_REQ_MAX); NULL, hw_intf, fd_ctx->req_base, CAM_CTX_REQ_MAX); if (rc) { if (rc) { CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc); CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc); return rc; return rc; Loading drivers/media/platform/msm/camera/cam_fd/cam_fd_context.h +3 −2 Original line number Original line Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -30,7 +30,8 @@ struct cam_fd_context { }; }; int cam_fd_context_init(struct cam_fd_context *fd_ctx, int cam_fd_context_init(struct cam_fd_context *fd_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf); struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id); int cam_fd_context_deinit(struct cam_fd_context *ctx); int cam_fd_context_deinit(struct cam_fd_context *ctx); #endif /* _CAM_FD_CONTEXT_H_ */ #endif /* _CAM_FD_CONTEXT_H_ */ Loading
drivers/media/platform/msm/camera/cam_core/cam_context.c +16 −0 Original line number Original line Diff line number Diff line Loading @@ -224,6 +224,7 @@ int cam_context_handle_acquire_dev(struct cam_context *ctx, struct cam_acquire_dev_cmd *cmd) struct cam_acquire_dev_cmd *cmd) { { int rc; int rc; int i; if (!ctx->state_machine) { if (!ctx->state_machine) { CAM_ERR(CAM_CORE, "Context is not ready"); CAM_ERR(CAM_CORE, "Context is not ready"); Loading @@ -244,6 +245,17 @@ int cam_context_handle_acquire_dev(struct cam_context *ctx, cmd->dev_handle, ctx->state); cmd->dev_handle, ctx->state); rc = -EPROTO; rc = -EPROTO; } } INIT_LIST_HEAD(&ctx->active_req_list); INIT_LIST_HEAD(&ctx->wait_req_list); INIT_LIST_HEAD(&ctx->pending_req_list); INIT_LIST_HEAD(&ctx->free_req_list); for (i = 0; i < ctx->req_size; i++) { INIT_LIST_HEAD(&ctx->req_list[i].list); list_add_tail(&ctx->req_list[i].list, &ctx->free_req_list); } mutex_unlock(&ctx->ctx_mutex); mutex_unlock(&ctx->ctx_mutex); return rc; return rc; Loading Loading @@ -394,6 +406,8 @@ int cam_context_handle_stop_dev(struct cam_context *ctx, int cam_context_init(struct cam_context *ctx, int cam_context_init(struct cam_context *ctx, const char *dev_name, const char *dev_name, uint64_t dev_id, uint32_t ctx_id, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_ctx_request *req_list, struct cam_ctx_request *req_list, Loading @@ -417,6 +431,8 @@ int cam_context_init(struct cam_context *ctx, spin_lock_init(&ctx->lock); spin_lock_init(&ctx->lock); ctx->dev_name = dev_name; ctx->dev_name = dev_name; ctx->dev_id = dev_id; ctx->ctx_id = ctx_id; ctx->ctx_crm_intf = NULL; ctx->ctx_crm_intf = NULL; ctx->crm_ctx_intf = crm_node_intf; ctx->crm_ctx_intf = crm_node_intf; ctx->hw_mgr_intf = hw_mgr_intf; ctx->hw_mgr_intf = hw_mgr_intf; Loading
drivers/media/platform/msm/camera/cam_core/cam_context.h +8 −0 Original line number Original line Diff line number Diff line Loading @@ -147,6 +147,8 @@ struct cam_ctx_ops { * struct cam_context - camera context object for the subdevice node * struct cam_context - camera context object for the subdevice node * * * @dev_name: String giving name of device associated * @dev_name: String giving name of device associated * @dev_id: ID of device associated * @ctx_id: ID for this context * @list: Link list entry * @list: Link list entry * @sessoin_hdl: Session handle * @sessoin_hdl: Session handle * @dev_hdl: Device handle * @dev_hdl: Device handle Loading Loading @@ -174,6 +176,8 @@ struct cam_ctx_ops { */ */ struct cam_context { struct cam_context { const char *dev_name; const char *dev_name; uint64_t dev_id; uint32_t ctx_id; struct list_head list; struct list_head list; int32_t session_hdl; int32_t session_hdl; int32_t dev_hdl; int32_t dev_hdl; Loading Loading @@ -376,6 +380,8 @@ int cam_context_deinit(struct cam_context *ctx); * * * @ctx: Object pointer for cam_context * @ctx: Object pointer for cam_context * @dev_name: String giving name of device associated * @dev_name: String giving name of device associated * @dev_id: ID of the device associated * @ctx_id: ID for this context * @crm_node_intf: Function table for crm to context interface * @crm_node_intf: Function table for crm to context interface * @hw_mgr_intf: Function table for context to hw interface * @hw_mgr_intf: Function table for context to hw interface * @req_list: Requests storage * @req_list: Requests storage Loading @@ -384,6 +390,8 @@ int cam_context_deinit(struct cam_context *ctx); */ */ int cam_context_init(struct cam_context *ctx, int cam_context_init(struct cam_context *ctx, const char *dev_name, const char *dev_name, uint64_t dev_id, uint32_t ctx_id, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_req_mgr_kmd_ops *crm_node_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_hw_mgr_intf *hw_mgr_intf, struct cam_ctx_request *req_list, struct cam_ctx_request *req_list, Loading
drivers/media/platform/msm/camera/cam_core/cam_context_utils.c +146 −30 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,9 @@ #include "cam_trace.h" #include "cam_trace.h" #include "cam_debug_util.h" #include "cam_debug_util.h" static uint cam_debug_ctx_req_list; module_param(cam_debug_ctx_req_list, uint, 0644); static inline int cam_context_validate_thread(void) static inline int cam_context_validate_thread(void) { { if (in_interrupt()) { if (in_interrupt()) { Loading Loading @@ -56,7 +59,8 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx, spin_lock(&ctx->lock); spin_lock(&ctx->lock); if (list_empty(&ctx->active_req_list)) { if (list_empty(&ctx->active_req_list)) { CAM_ERR(CAM_CTXT, "no active request"); CAM_ERR(CAM_CTXT, "[%s][%d] no active request", ctx->dev_name, ctx->ctx_id); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); return -EIO; return -EIO; } } Loading @@ -66,14 +70,17 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx, trace_cam_buf_done("UTILS", ctx, req); trace_cam_buf_done("UTILS", ctx, req); if (done->request_id != req->request_id) { if (done->request_id != req->request_id) { CAM_ERR(CAM_CTXT, "mismatch: done req[%lld], active req[%lld]", CAM_ERR(CAM_CTXT, "[%s][%d] mismatch: done req[%lld], active req[%lld]", ctx->dev_name, ctx->ctx_id, done->request_id, req->request_id); done->request_id, req->request_id); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); return -EIO; return -EIO; } } if (!req->num_out_map_entries) { if (!req->num_out_map_entries) { CAM_ERR(CAM_CTXT, "no output fence to signal"); CAM_ERR(CAM_CTXT, "[%s][%d] no output fence to signal", ctx->dev_name, ctx->ctx_id); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); return -EIO; return -EIO; } } Loading @@ -94,6 +101,11 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx, req->out_map_entries[j].sync_id = -1; req->out_map_entries[j].sync_id = -1; } } if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from active_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); /* /* * another thread may be adding/removing from free list, * another thread may be adding/removing from free list, * so hold the lock * so hold the lock Loading @@ -114,7 +126,8 @@ static int cam_context_apply_req_to_hw(struct cam_ctx_request *req, struct cam_hw_config_args cfg; struct cam_hw_config_args cfg; if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -124,6 +137,11 @@ static int cam_context_apply_req_to_hw(struct cam_ctx_request *req, list_add_tail(&req->list, &ctx->active_req_list); list_add_tail(&req->list, &ctx->active_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from pending_list to active_list", ctx->dev_name, ctx->ctx_id, req->request_id); cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map; cfg.ctxt_to_hw_map = ctx->ctxt_to_hw_map; cfg.hw_update_entries = req->hw_update_entries; cfg.hw_update_entries = req->hw_update_entries; cfg.num_hw_update_entries = req->num_hw_update_entries; cfg.num_hw_update_entries = req->num_hw_update_entries; Loading @@ -135,7 +153,13 @@ static int cam_context_apply_req_to_hw(struct cam_ctx_request *req, if (rc) { if (rc) { spin_lock(&ctx->lock); spin_lock(&ctx->lock); list_del_init(&req->list); list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from active_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); } } end: end: Loading @@ -159,6 +183,11 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data) return; return; ctx = req->ctx; ctx = req->ctx; if (!ctx) { CAM_ERR(CAM_CTXT, "Invalid ctx for req %llu", req->request_id); return; } req->num_in_acked++; req->num_in_acked++; if (req->num_in_acked == req->num_in_map_entries) { if (req->num_in_acked == req->num_in_map_entries) { apply.request_id = req->request_id; apply.request_id = req->request_id; Loading @@ -174,8 +203,6 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data) CAM_DBG(CAM_CTXT, "fence error: %d", sync_obj); CAM_DBG(CAM_CTXT, "fence error: %d", sync_obj); flush_cmd.req_id = req->request_id; flush_cmd.req_id = req->request_id; cam_context_flush_req_to_hw(ctx, &flush_cmd); cam_context_flush_req_to_hw(ctx, &flush_cmd); cam_context_putref(ctx); return; } } mutex_lock(&ctx->sync_mutex); mutex_lock(&ctx->sync_mutex); Loading @@ -190,6 +217,12 @@ static void cam_context_sync_callback(int32_t sync_obj, int status, void *data) list_del_init(&req->list); list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from pending_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); } } } } cam_context_putref(ctx); cam_context_putref(ctx); Loading @@ -206,7 +239,8 @@ int32_t cam_context_release_dev_to_hw(struct cam_context *ctx, } } if ((!ctx->hw_mgr_intf) || (!ctx->hw_mgr_intf->hw_release)) { if ((!ctx->hw_mgr_intf) || (!ctx->hw_mgr_intf->hw_release)) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); return -EINVAL; return -EINVAL; } } Loading Loading @@ -241,7 +275,8 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -258,7 +293,8 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (!req) { if (!req) { CAM_ERR(CAM_CTXT, "No more request obj free"); CAM_ERR(CAM_CTXT, "[%s][%d] No more request obj free", ctx->dev_name, ctx->ctx_id); rc = -ENOMEM; rc = -ENOMEM; goto end; goto end; } } Loading @@ -273,7 +309,8 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, (uint64_t *) &packet_addr, (uint64_t *) &packet_addr, &len); &len); if (rc != 0) { if (rc != 0) { CAM_ERR(CAM_CTXT, "Can not get packet address"); CAM_ERR(CAM_CTXT, "[%s][%d] Can not get packet address", ctx->dev_name, ctx->ctx_id); rc = -EINVAL; rc = -EINVAL; goto free_req; goto free_req; } } Loading @@ -295,7 +332,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, rc = ctx->hw_mgr_intf->hw_prepare_update( rc = ctx->hw_mgr_intf->hw_prepare_update( ctx->hw_mgr_intf->hw_mgr_priv, &cfg); ctx->hw_mgr_intf->hw_mgr_priv, &cfg); if (rc != 0) { if (rc != 0) { CAM_ERR(CAM_CTXT, "Prepare config packet failed in HW layer"); CAM_ERR(CAM_CTXT, "[%s][%d] Prepare config packet failed in HW layer", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto free_req; goto free_req; } } Loading @@ -310,6 +349,12 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, spin_lock(&ctx->lock); spin_lock(&ctx->lock); list_add_tail(&req->list, &ctx->pending_req_list); list_add_tail(&req->list, &ctx->pending_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from free_list to pending_list", ctx->dev_name, ctx->ctx_id, req->request_id); for (i = 0; i < req->num_in_map_entries; i++) { for (i = 0; i < req->num_in_map_entries; i++) { cam_context_getref(ctx); cam_context_getref(ctx); rc = cam_sync_register_callback( rc = cam_sync_register_callback( Loading @@ -318,9 +363,21 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, req->in_map_entries[i].sync_id); req->in_map_entries[i].sync_id); if (rc) { if (rc) { CAM_ERR(CAM_CTXT, CAM_ERR(CAM_CTXT, "Failed register fence cb: %d ret = %d", "[%s][%d] Failed register fence cb: %d ret = %d", ctx->dev_name, ctx->ctx_id, req->in_map_entries[i].sync_id, rc); req->in_map_entries[i].sync_id, rc); spin_lock(&ctx->lock); list_del_init(&req->list); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from pending_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); cam_context_putref(ctx); cam_context_putref(ctx); goto free_req; goto free_req; } } CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d", CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d", Loading Loading @@ -355,7 +412,8 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -365,14 +423,16 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, cmd->resource_hdl); cmd->resource_hdl); if (cmd->num_resources > CAM_CTX_RES_MAX) { if (cmd->num_resources > CAM_CTX_RES_MAX) { CAM_ERR(CAM_CTXT, "resource limit exceeded"); CAM_ERR(CAM_CTXT, "[%s][%d] resource limit exceeded", ctx->dev_name, ctx->ctx_id); rc = -ENOMEM; rc = -ENOMEM; goto end; goto end; } } /* for now we only support user pointer */ /* for now we only support user pointer */ if (cmd->handle_type != 1) { if (cmd->handle_type != 1) { CAM_ERR(CAM_CTXT, "Only user pointer is supported"); CAM_ERR(CAM_CTXT, "[%s][%d] Only user pointer is supported", ctx->dev_name, ctx->ctx_id); rc = -EINVAL; rc = -EINVAL; goto end; goto end; } } Loading @@ -387,7 +447,8 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv, rc = ctx->hw_mgr_intf->hw_acquire(ctx->hw_mgr_intf->hw_mgr_priv, ¶m); ¶m); if (rc != 0) { if (rc != 0) { CAM_ERR(CAM_CTXT, "Acquire device failed"); CAM_ERR(CAM_CTXT, "[%s][%d] Acquire device failed", ctx->dev_name, ctx->ctx_id); goto end; goto end; } } Loading @@ -404,7 +465,8 @@ int32_t cam_context_acquire_dev_to_hw(struct cam_context *ctx, ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param); if (ctx->dev_hdl <= 0) { if (ctx->dev_hdl <= 0) { rc = -EFAULT; rc = -EFAULT; CAM_ERR(CAM_CTXT, "Can not create device handle"); CAM_ERR(CAM_CTXT, "[%s][%d] Can not create device handle", ctx->dev_name, ctx->ctx_id); goto free_hw; goto free_hw; } } cmd->dev_handle = ctx->dev_hdl; cmd->dev_handle = ctx->dev_hdl; Loading @@ -430,7 +492,7 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) uint32_t i; uint32_t i; int rc = 0; int rc = 0; CAM_DBG(CAM_CTXT, "E: NRT flush ctx"); CAM_DBG(CAM_CTXT, "[%s] E: NRT flush ctx", ctx->dev_name); /* /* * flush pending requests, take the sync lock to synchronize with the * flush pending requests, take the sync lock to synchronize with the Loading @@ -442,17 +504,30 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) spin_lock(&ctx->lock); spin_lock(&ctx->lock); list_splice_init(&ctx->pending_req_list, &temp_list); list_splice_init(&ctx->pending_req_list, &temp_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving all pending requests from pending_list to temp_list", ctx->dev_name, ctx->ctx_id); flush_args.num_req_pending = 0; flush_args.num_req_pending = 0; while (!list_empty(&temp_list)) { while (true) { spin_lock(&ctx->lock); if (list_empty(&temp_list)) { spin_unlock(&ctx->lock); break; } req = list_first_entry(&temp_list, req = list_first_entry(&temp_list, struct cam_ctx_request, list); struct cam_ctx_request, list); list_del_init(&req->list); list_del_init(&req->list); spin_unlock(&ctx->lock); req->flushed = 1; req->flushed = 1; flush_args.flush_req_pending[flush_args.num_req_pending++] = flush_args.flush_req_pending[flush_args.num_req_pending++] = req->req_priv; req->req_priv; for (i = 0; i < req->num_out_map_entries; i++) for (i = 0; i < req->num_out_map_entries; i++) { if (req->out_map_entries[i].sync_id != -1) { if (req->out_map_entries[i].sync_id != -1) { rc = cam_sync_signal( rc = cam_sync_signal( req->out_map_entries[i].sync_id, req->out_map_entries[i].sync_id, Loading @@ -467,6 +542,12 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) } } } } } } if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Deleting req[%llu] from temp_list", ctx->dev_name, ctx->ctx_id, req->request_id); } mutex_unlock(&ctx->sync_mutex); mutex_unlock(&ctx->sync_mutex); if (ctx->hw_mgr_intf->hw_flush) { if (ctx->hw_mgr_intf->hw_flush) { Loading @@ -492,10 +573,22 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) INIT_LIST_HEAD(&ctx->active_req_list); INIT_LIST_HEAD(&ctx->active_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); while (!list_empty(&temp_list)) { if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving all requests from active_list to temp_list", ctx->dev_name, ctx->ctx_id); while (true) { spin_lock(&ctx->lock); if (list_empty(&temp_list)) { spin_unlock(&ctx->lock); break; } req = list_first_entry(&temp_list, req = list_first_entry(&temp_list, struct cam_ctx_request, list); struct cam_ctx_request, list); list_del_init(&req->list); list_del_init(&req->list); spin_unlock(&ctx->lock); for (i = 0; i < req->num_out_map_entries; i++) { for (i = 0; i < req->num_out_map_entries; i++) { if (req->out_map_entries[i].sync_id != -1) { if (req->out_map_entries[i].sync_id != -1) { rc = cam_sync_signal( rc = cam_sync_signal( Loading @@ -517,9 +610,14 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx) list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); req->ctx = NULL; req->ctx = NULL; if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Moving req[%llu] from temp_list to free_list", ctx->dev_name, ctx->ctx_id, req->request_id); } } CAM_DBG(CAM_CTXT, "X: NRT flush ctx"); CAM_DBG(CAM_CTXT, "[%s] X: NRT flush ctx", ctx->dev_name); return 0; return 0; } } Loading @@ -532,7 +630,7 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, uint32_t i; uint32_t i; int rc = 0; int rc = 0; CAM_DBG(CAM_CTXT, "E: NRT flush req"); CAM_DBG(CAM_CTXT, "[%s] E: NRT flush req", ctx->dev_name); flush_args.num_req_pending = 0; flush_args.num_req_pending = 0; flush_args.num_req_active = 0; flush_args.num_req_active = 0; Loading @@ -542,6 +640,11 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, if (req->request_id != cmd->req_id) if (req->request_id != cmd->req_id) continue; continue; if (cam_debug_ctx_req_list & ctx->dev_id) CAM_INFO(CAM_CTXT, "[%s][%d] : Deleting req[%llu] from pending_list", ctx->dev_name, ctx->ctx_id, req->request_id); list_del_init(&req->list); list_del_init(&req->list); req->flushed = 1; req->flushed = 1; Loading Loading @@ -598,10 +701,16 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx, list_add_tail(&req->list, &ctx->free_req_list); list_add_tail(&req->list, &ctx->free_req_list); spin_unlock(&ctx->lock); spin_unlock(&ctx->lock); req->ctx = NULL; 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", ctx->dev_name, ctx->ctx_id, req->request_id); } } } } } } CAM_DBG(CAM_CTXT, "X: NRT flush req"); CAM_DBG(CAM_CTXT, "[%s] X: NRT flush req", ctx->dev_name); return 0; return 0; } } Loading @@ -619,7 +728,8 @@ int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading @@ -630,7 +740,8 @@ int32_t cam_context_flush_dev_to_hw(struct cam_context *ctx, rc = cam_context_flush_req_to_hw(ctx, cmd); rc = cam_context_flush_req_to_hw(ctx, cmd); else { else { rc = -EINVAL; rc = -EINVAL; CAM_ERR(CAM_CORE, "Invalid flush type %d", cmd->flush_type); CAM_ERR(CAM_CORE, "[%s][%d] Invalid flush type %d", ctx->dev_name, ctx->ctx_id, cmd->flush_type); } } end: end: Loading @@ -650,14 +761,17 @@ int32_t cam_context_start_dev_to_hw(struct cam_context *ctx, } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } if ((cmd->session_handle != ctx->session_hdl) || if ((cmd->session_handle != ctx->session_hdl) || (cmd->dev_handle != ctx->dev_hdl)) { (cmd->dev_handle != ctx->dev_hdl)) { CAM_ERR(CAM_CTXT, "Invalid session hdl[%d], dev_handle[%d]", CAM_ERR(CAM_CTXT, "[%s][%d] Invalid session hdl[%d], dev_handle[%d]", ctx->dev_name, ctx->ctx_id, cmd->session_handle, cmd->dev_handle); cmd->session_handle, cmd->dev_handle); rc = -EPERM; rc = -EPERM; goto end; goto end; Loading @@ -669,7 +783,8 @@ int32_t cam_context_start_dev_to_hw(struct cam_context *ctx, &arg); &arg); if (rc) { if (rc) { /* HW failure. user need to clean up the resource */ /* HW failure. user need to clean up the resource */ CAM_ERR(CAM_CTXT, "Start HW failed"); CAM_ERR(CAM_CTXT, "[%s][%d] Start HW failed", ctx->dev_name, ctx->ctx_id); goto end; goto end; } } } } Loading @@ -690,7 +805,8 @@ int32_t cam_context_stop_dev_to_hw(struct cam_context *ctx) } } if (!ctx->hw_mgr_intf) { if (!ctx->hw_mgr_intf) { CAM_ERR(CAM_CTXT, "HW interface is not ready"); CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready", ctx->dev_name, ctx->ctx_id); rc = -EFAULT; rc = -EFAULT; goto end; goto end; } } Loading
drivers/media/platform/msm/camera/cam_fd/cam_fd_context.c +5 −4 Original line number Original line Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -211,7 +211,8 @@ static struct cam_ctx_ops int cam_fd_context_init(struct cam_fd_context *fd_ctx, int cam_fd_context_init(struct cam_fd_context *fd_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf) struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id) { { int rc; int rc; Loading @@ -222,8 +223,8 @@ int cam_fd_context_init(struct cam_fd_context *fd_ctx, memset(fd_ctx, 0, sizeof(*fd_ctx)); memset(fd_ctx, 0, sizeof(*fd_ctx)); rc = cam_context_init(base_ctx, fd_dev_name, NULL, hw_intf, rc = cam_context_init(base_ctx, fd_dev_name, CAM_FD, ctx_id, fd_ctx->req_base, CAM_CTX_REQ_MAX); NULL, hw_intf, fd_ctx->req_base, CAM_CTX_REQ_MAX); if (rc) { if (rc) { CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc); CAM_ERR(CAM_FD, "Camera Context Base init failed, rc=%d", rc); return rc; return rc; Loading
drivers/media/platform/msm/camera/cam_fd/cam_fd_context.h +3 −2 Original line number Original line Diff line number Diff line /* Copyright (c) 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -30,7 +30,8 @@ struct cam_fd_context { }; }; int cam_fd_context_init(struct cam_fd_context *fd_ctx, int cam_fd_context_init(struct cam_fd_context *fd_ctx, struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf); struct cam_context *base_ctx, struct cam_hw_mgr_intf *hw_intf, uint32_t ctx_id); int cam_fd_context_deinit(struct cam_fd_context *ctx); int cam_fd_context_deinit(struct cam_fd_context *ctx); #endif /* _CAM_FD_CONTEXT_H_ */ #endif /* _CAM_FD_CONTEXT_H_ */