Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96fd3c96 authored by Pavan Kumar Chilamkurthi's avatar Pavan Kumar Chilamkurthi
Browse files

msm: camera: core: Req list handling enhancement



On sync callback while flush add the req back into
free list to avoid leak. Add debug enhancement to
track each request moving among different lists
at different timelines which will help in debugging
how different requests are handled.

Change-Id: I56eb57ac74faf6b2c3d0d52b4437a4a5d34ef054
Signed-off-by: default avatarPavan Kumar Chilamkurthi <pchilamk@codeaurora.org>
parent ba5ee985
Loading
Loading
Loading
Loading
+16 −0
Original line number Original line Diff line number Diff line
@@ -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");
@@ -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;
@@ -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,
@@ -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;
+8 −0
Original line number Original line Diff line number Diff line
@@ -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
@@ -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;
@@ -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
@@ -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,
+146 −30
Original line number Original line Diff line number Diff line
@@ -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()) {
@@ -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;
	}
	}
@@ -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;
	}
	}
@@ -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
@@ -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;
	}
	}
@@ -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;
@@ -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:
@@ -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;
@@ -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);
@@ -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);
@@ -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;
	}
	}


@@ -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;
	}
	}
@@ -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;
	}
	}
@@ -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;
	}
	}
@@ -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;
	}
	}
@@ -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(
@@ -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",
@@ -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;
	}
	}
@@ -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;
	}
	}
@@ -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,
		&param);
		&param);
	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;
	}
	}


@@ -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;
@@ -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
@@ -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,
@@ -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) {
@@ -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(
@@ -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;
}
}
@@ -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;
@@ -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;


@@ -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;
}
}
@@ -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;
	}
	}
@@ -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:
@@ -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;
@@ -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;
		}
		}
	}
	}
@@ -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;
	}
	}
+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
@@ -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;


@@ -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;
+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
@@ -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