Selaa lähdekoodia

Merge "msm: camera: req_mgr: LDAR Debug framework implementation" into camera-kernel.lnx.4.0

Camera Software Integration 5 vuotta sitten
vanhempi
sitoutus
18c0155b3f

+ 65 - 0
drivers/cam_core/cam_context.c

@@ -230,6 +230,34 @@ int cam_context_handle_crm_process_evt(struct cam_context *ctx,
 	return rc;
 }
 
+int cam_context_handle_crm_dump_req(struct cam_context *ctx,
+	struct cam_req_mgr_dump_info *dump)
+{
+	int rc = 0;
+
+	if (!ctx) {
+		CAM_ERR(CAM_CORE, "Invalid Context");
+		return -EINVAL;
+	}
+	if (!ctx->state_machine) {
+		CAM_ERR(CAM_CORE, "Context %s ctx_id %d is not ready",
+			ctx->dev_name, ctx->ctx_id);
+		return -EINVAL;
+	}
+	mutex_lock(&ctx->ctx_mutex);
+
+	if (ctx->state_machine[ctx->state].crm_ops.dump_req)
+		rc = ctx->state_machine[ctx->state].crm_ops.dump_req(ctx,
+			dump);
+	else
+		CAM_ERR(CAM_CORE, "No crm dump req for %s dev %d, state %d",
+			ctx->dev_name, ctx->dev_hdl, ctx->state);
+
+	mutex_unlock(&ctx->ctx_mutex);
+
+	return rc;
+}
+
 int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
 	uint32_t buf_info)
 {
@@ -524,6 +552,43 @@ int cam_context_handle_info_dump(void *context,
 	return rc;
 }
 
+int cam_context_handle_dump_dev(struct cam_context *ctx,
+	struct cam_dump_req_cmd *cmd)
+{
+	int rc = 0;
+
+	if (!ctx) {
+		CAM_ERR(CAM_CORE, "Invalid Context");
+		return -EINVAL;
+	}
+
+	if (!ctx->state_machine) {
+		CAM_ERR(CAM_CORE, "Context %s ctx_id %d is not ready",
+			ctx->dev_name, ctx->ctx_id);
+		return -EINVAL;
+	}
+
+	if (!cmd) {
+		CAM_ERR(CAM_CORE,
+			"Context %s ctx_id %d Invalid dump command payload",
+			ctx->dev_name, ctx->ctx_id);
+		return -EINVAL;
+	}
+
+	mutex_lock(&ctx->ctx_mutex);
+	CAM_DBG(CAM_CORE, "dump device in dev %d, name %s state %d",
+		ctx->dev_hdl, ctx->dev_name, ctx->state);
+	if (ctx->state_machine[ctx->state].ioctl_ops.dump_dev)
+		rc = ctx->state_machine[ctx->state].ioctl_ops.dump_dev(
+			ctx, cmd);
+	else
+		CAM_WARN(CAM_CORE, "No dump device in dev %d, name %s state %d",
+			ctx->dev_hdl, ctx->dev_name, ctx->state);
+	mutex_unlock(&ctx->ctx_mutex);
+
+	return rc;
+}
+
 int cam_context_init(struct cam_context *ctx,
 	const char *dev_name,
 	uint64_t dev_id,

+ 49 - 0
drivers/cam_core/cam_context.h

@@ -23,6 +23,12 @@ struct cam_context;
 #define CAM_CTX_CFG_MAX              20
 #define CAM_CTX_RES_MAX              20
 
+/* max tag  dump header string length*/
+#define CAM_CTXT_DUMP_TAG_MAX_LEN 32
+
+/* Number of words to be dumped for context*/
+#define CAM_CTXT_DUMP_NUM_WORDS 10
+
 /**
  * enum cam_ctx_state -  context top level states
  *
@@ -86,6 +92,7 @@ struct cam_ctx_request {
  * @flush_dev:             Function pointer for flush device
  * @acquire_hw:            Function pointer for acquire hw
  * @release_hw:            Function pointer for release hw
+ * @dump_dev:              Function pointer for dump dev
  *
  */
 struct cam_ctx_ioctl_ops {
@@ -103,6 +110,8 @@ struct cam_ctx_ioctl_ops {
 			struct cam_flush_dev_cmd *cmd);
 	int (*acquire_hw)(struct cam_context *ctx, void *args);
 	int (*release_hw)(struct cam_context *ctx, void *args);
+	int (*dump_dev)(struct cam_context *ctx,
+			struct cam_dump_req_cmd *cmd);
 };
 
 /**
@@ -114,6 +123,7 @@ struct cam_ctx_ioctl_ops {
  * @apply_req:             Apply setting for the context
  * @flush_req:             Flush request to remove request ids
  * @process_evt:           Handle event notification from CRM.(optional)
+ * @dump_req:              Dump information for the issue request
  *
  */
 struct cam_ctx_crm_ops {
@@ -129,6 +139,8 @@ struct cam_ctx_crm_ops {
 			struct cam_req_mgr_flush_request *flush);
 	int (*process_evt)(struct cam_context *ctx,
 			struct cam_req_mgr_link_evt_data *evt_data);
+	int (*dump_req)(struct cam_context *ctx,
+			struct cam_req_mgr_dump_info *dump);
 };
 
 
@@ -219,6 +231,19 @@ struct cam_context {
 	uint32_t                     last_flush_req;
 };
 
+/**
+ * struct cam_context_dump_header -  Function for context dump header
+ *
+ * @tag         :    Tag for context dump header
+ * @size        :    Size of data
+ * @word_size   :    Word size of data
+ */
+struct cam_context_dump_header {
+	uint8_t   tag[CAM_CTXT_DUMP_TAG_MAX_LEN];
+	uint64_t  size;
+	uint32_t  word_size;
+};
+
 /**
  * cam_context_shutdown()
  *
@@ -301,6 +326,18 @@ int cam_context_handle_crm_flush_req(struct cam_context *ctx,
 int cam_context_handle_crm_process_evt(struct cam_context *ctx,
 	struct cam_req_mgr_link_evt_data *process_evt);
 
+/**
+ * cam_context_handle_crm_dump_req()
+ *
+ * @brief:        Handle CRM dump request
+ *
+ * @ctx:          Object pointer for cam_context
+ * @dump:         Dump request command payload
+ *
+ */
+int cam_context_handle_crm_dump_req(struct cam_context *ctx,
+	struct cam_req_mgr_dump_info *dump);
+
 /**
  * cam_context_dump_pf_info()
  *
@@ -410,6 +447,18 @@ int cam_context_handle_start_dev(struct cam_context *ctx,
 int cam_context_handle_stop_dev(struct cam_context *ctx,
 		struct cam_start_stop_dev_cmd *cmd);
 
+/**
+ * cam_context_handle_dump_dev()
+ *
+ * @brief:        Handle dump device command
+ *
+ * @ctx:          Object pointer for cam_context
+ * @cmd:          Dump device command payload
+ *
+ */
+int cam_context_handle_dump_dev(struct cam_context *ctx,
+	struct cam_dump_req_cmd *cmd);
+
 /**
  * cam_context_handle_info_dump()
  *

+ 127 - 0
drivers/cam_core/cam_context_utils.c

@@ -1046,3 +1046,130 @@ int32_t cam_context_dump_hw_acq_info(struct cam_context *ctx)
 end:
 	return rc;
 }
+
+static int cam_context_dump_context(struct cam_context *ctx,
+	struct cam_hw_dump_args *dump_args)
+{
+	int                             rc;
+	int                             i;
+	size_t                          buf_len;
+	size_t                          remain_len;
+	uint8_t                        *dst;
+	uint64_t                       *addr, *start;
+	uint32_t                        min_len;
+	uintptr_t                       cpu_addr;
+	struct cam_ctx_request         *req;
+	struct cam_context_dump_header *hdr;
+
+	if (!ctx || !dump_args) {
+		CAM_ERR(CAM_CORE, "Invalid parameters %pK %pK",
+			ctx, dump_args);
+		return -EINVAL;
+	}
+
+	spin_lock_bh(&ctx->lock);
+	if (list_empty(&ctx->active_req_list)) {
+		CAM_ERR(CAM_CTXT, "[%s][%d] no active request",
+			ctx->dev_name, ctx->ctx_id);
+		spin_unlock_bh(&ctx->lock);
+		return -EIO;
+	}
+	req = list_first_entry(&ctx->active_req_list,
+		struct cam_ctx_request, list);
+	spin_unlock_bh(&ctx->lock);
+	rc  = cam_mem_get_cpu_buf(dump_args->buf_handle,
+		&cpu_addr, &buf_len);
+	if (rc) {
+		CAM_ERR(CAM_CTXT, "Invalid hdl %u rc %d",
+			dump_args->buf_handle, rc);
+		return rc;
+	}
+	if (dump_args->offset >= buf_len) {
+		CAM_WARN(CAM_CTXT, "dump buffer overshoot offset %zu len %zu",
+			dump_args->offset, buf_len);
+		return -ENOSPC;
+	}
+
+	remain_len = buf_len - dump_args->offset;
+	min_len =  sizeof(struct cam_context_dump_header) +
+		    (CAM_CTXT_DUMP_NUM_WORDS + req->num_in_map_entries +
+		    (req->num_out_map_entries * 2)) * sizeof(uint64_t);
+
+	if (remain_len < min_len) {
+		CAM_WARN(CAM_CTXT, "dump buffer exhaust remain %zu min %u",
+			remain_len, min_len);
+		return -ENOSPC;
+	}
+	dst = (uint8_t *)cpu_addr + dump_args->offset;
+	hdr = (struct cam_context_dump_header *)dst;
+	scnprintf(hdr->tag, CAM_CTXT_DUMP_TAG_MAX_LEN,
+		"%s_CTXT_DUMP:", ctx->dev_name);
+	hdr->word_size = sizeof(uint64_t);
+	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
+	start = addr;
+	*addr++ = ctx->ctx_id;
+	*addr++ = refcount_read(&(ctx->refcount.refcount));
+	*addr++ = ctx->last_flush_req;
+	*addr++ = ctx->state;
+	*addr++ = req->num_out_map_entries;
+	for (i = 0; i < req->num_out_map_entries; i++) {
+		*addr++ = req->out_map_entries[i].resource_handle;
+		*addr++ = req->out_map_entries[i].sync_id;
+	}
+	*addr++ = req->num_in_map_entries;
+	for (i = 0; i < req->num_in_map_entries; i++)
+		*addr++ = req->in_map_entries[i].sync_id;
+	hdr->size = hdr->word_size * (addr - start);
+	dump_args->offset += hdr->size +
+		sizeof(struct cam_context_dump_header);
+	return rc;
+}
+
+int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
+	struct cam_dump_req_cmd *cmd)
+{
+	int                     rc = 0;
+	struct cam_hw_dump_args dump_args;
+
+	if (!ctx || !cmd) {
+		CAM_ERR(CAM_CTXT, "Invalid input params %pK %pK", ctx, cmd);
+		return -EINVAL;
+	}
+	if (!ctx->hw_mgr_intf) {
+		CAM_ERR(CAM_CTXT, "[%s][%d] HW interface is not ready",
+			ctx->dev_name, ctx->ctx_id);
+		return -EFAULT;
+	}
+	memset(&dump_args, 0, sizeof(dump_args));
+	if (ctx->hw_mgr_intf->hw_dump) {
+		dump_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
+		dump_args.buf_handle = cmd->buf_handle;
+		dump_args.offset = cmd->offset;
+		dump_args.request_id = cmd->issue_req_id;
+		dump_args.error_type = cmd->error_type;
+		rc  = ctx->hw_mgr_intf->hw_dump(
+			ctx->hw_mgr_intf->hw_mgr_priv,
+			&dump_args);
+		if (rc) {
+			CAM_ERR(CAM_CTXT, "[%s][%d] handle[%u] failed",
+			    ctx->dev_name, ctx->ctx_id, dump_args.buf_handle);
+			return rc;
+		}
+		/* Offset will change if the issue request id is found with
+		 * the hw and has been lying with it beyond threshold time.
+		 * If offset does not change, do not dump the context
+		 * information as the current context has no problem with
+		 * the provided request id.
+		 */
+		if (dump_args.offset > cmd->offset) {
+			cam_context_dump_context(ctx, &dump_args);
+			CAM_INFO(CAM_CTXT, "[%s] ctx: %d Filled Length %u",
+				 ctx->dev_name, ctx->ctx_id,
+				 dump_args.offset - cmd->offset);
+			cmd->offset  = dump_args.offset;
+		}
+	} else {
+		CAM_DBG(CAM_CTXT, "%s hw dump not registered", ctx->dev_name);
+	}
+	return rc;
+}

+ 2 - 1
drivers/cam_core/cam_context_utils.h

@@ -30,5 +30,6 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
 	struct cam_packet *packet, unsigned long iova, uint32_t buf_info,
 	bool *mem_found);
 int32_t cam_context_dump_hw_acq_info(struct cam_context *ctx);
-
+int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
+	struct cam_dump_req_cmd *cmd);
 #endif /* _CAM_CONTEXT_UTILS_H_ */

+ 19 - 0
drivers/cam_core/cam_hw_mgr_intf.h

@@ -300,6 +300,23 @@ struct cam_hw_reset_args {
 	void                           *ctxt_to_hw_map;
 };
 
+/**
+ * struct cam_hw_dump_args - Dump arguments
+ *
+ * @request_id:            request_id
+ * @offset:                Buffer offset. This is updated by the drivers.
+ * @buf_handle:            Buffer handle
+ * @error_type:            Error type, to be used to extend dump information
+ * @ctxt_to_hw_map:        HW context from the acquire
+ */
+struct cam_hw_dump_args {
+	uint64_t          request_id;
+	size_t            offset;
+	uint32_t          buf_handle;
+	uint32_t          error_type;
+	void             *ctxt_to_hw_map;
+};
+
 /* enum cam_hw_mgr_command - Hardware manager command type */
 enum cam_hw_mgr_command {
 	CAM_HW_MGR_CMD_INTERNAL,
@@ -355,6 +372,7 @@ struct cam_hw_cmd_args {
  * @hw_close:                  Function pointer for HW deinit
  * @hw_flush:                  Function pointer for HW flush
  * @hw_reset:                  Function pointer for HW reset
+ * @hw_dump:                   Function pointer for HW dump
  *
  */
 struct cam_hw_mgr_intf {
@@ -376,6 +394,7 @@ struct cam_hw_mgr_intf {
 	int (*hw_close)(void *hw_priv, void *hw_close_args);
 	int (*hw_flush)(void *hw_priv, void *hw_flush_args);
 	int (*hw_reset)(void *hw_priv, void *hw_reset_args);
+	int (*hw_dump)(void *hw_priv, void *hw_dump_args);
 };
 
 #endif /* _CAM_HW_MGR_INTF_H_ */

+ 77 - 0
drivers/cam_core/cam_node.c

@@ -435,6 +435,39 @@ destroy_dev_hdl:
 	return rc;
 }
 
+static int __cam_node_handle_dump_dev(struct cam_node *node,
+	struct cam_dump_req_cmd *dump)
+{
+	int                 rc;
+	struct cam_context *ctx = NULL;
+
+	if (!dump)
+		return -EINVAL;
+
+	if (dump->dev_handle <= 0) {
+		CAM_ERR(CAM_CORE, "Invalid device handle for context");
+		return -EINVAL;
+	}
+
+	if (dump->session_handle <= 0) {
+		CAM_ERR(CAM_CORE, "Invalid session handle for context");
+		return -EINVAL;
+	}
+
+	ctx = (struct cam_context *)cam_get_device_priv(dump->dev_handle);
+	if (!ctx) {
+		CAM_ERR(CAM_CORE, "Can not get context for handle %d",
+			dump->dev_handle);
+		return -EINVAL;
+	}
+
+	rc = cam_context_handle_dump_dev(ctx, dump);
+	if (rc)
+		CAM_ERR(CAM_CORE, "Dump failure for node %s", node->name);
+
+	return rc;
+}
+
 static int __cam_node_handle_release_hw_v1(struct cam_node *node,
 	struct cam_release_hw_cmd_v1 *release)
 {
@@ -575,6 +608,25 @@ static int __cam_node_crm_process_evt(
 	return cam_context_handle_crm_process_evt(ctx, evt_data);
 }
 
+static int __cam_node_crm_dump_req(struct cam_req_mgr_dump_info *dump)
+{
+	struct cam_context *ctx = NULL;
+
+	if (!dump) {
+		CAM_ERR(CAM_CORE, "Invalid dump request payload");
+		return -EINVAL;
+	}
+
+	ctx = (struct cam_context *) cam_get_device_priv(dump->dev_hdl);
+	if (!ctx) {
+		CAM_ERR(CAM_CORE, "Can not get context for handle %d",
+			dump->dev_hdl);
+		return -EINVAL;
+	}
+
+	return cam_context_handle_crm_dump_req(ctx, dump);
+}
+
 int cam_node_deinit(struct cam_node *node)
 {
 	if (node)
@@ -630,6 +682,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
 	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;
+	node->crm_node_intf.dump_req = __cam_node_crm_dump_req;
 
 	mutex_init(&node->list_mutex);
 	INIT_LIST_HEAD(&node->free_ctx_list);
@@ -877,6 +930,30 @@ release_kfree:
 		}
 		break;
 	}
+	case CAM_DUMP_REQ: {
+		struct cam_dump_req_cmd dump;
+
+		if (copy_from_user(&dump, u64_to_user_ptr(cmd->handle),
+			sizeof(dump))) {
+			rc = -EFAULT;
+			break;
+		}
+		rc = __cam_node_handle_dump_dev(node, &dump);
+		if (rc) {
+			CAM_ERR(CAM_CORE,
+			    "Dump device %s failed(rc = %d) ",
+			    node->name, rc);
+			break;
+		}
+		if (copy_to_user(u64_to_user_ptr(cmd->handle),
+			&dump, sizeof(dump))) {
+			CAM_ERR(CAM_CORE,
+			    "Dump device %s copy_to_user fail",
+			    node->name);
+			rc = -EFAULT;
+		}
+		break;
+	}
 	default:
 		CAM_ERR(CAM_CORE, "Unknown op code %d", cmd->op_code);
 		rc = -EINVAL;

+ 60 - 0
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -3863,6 +3863,66 @@ end:
 	return rc;
 }
 
+int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req)
+{
+	int                                  rc = 0;
+	int                                  i;
+	struct cam_req_mgr_dump_info         info;
+	struct cam_req_mgr_core_link        *link = NULL;
+	struct cam_req_mgr_core_session     *session = NULL;
+	struct cam_req_mgr_connected_device *device = NULL;
+
+	if (!dump_req) {
+		CAM_ERR(CAM_CRM, "dump req is NULL");
+		return -EFAULT;
+	}
+
+	mutex_lock(&g_crm_core_dev->crm_lock);
+	/* session hdl's priv data is cam session struct */
+	session = (struct cam_req_mgr_core_session *)
+	    cam_get_device_priv(dump_req->session_handle);
+	if (!session) {
+		CAM_ERR(CAM_CRM, "Invalid session %x",
+			dump_req->session_handle);
+		rc = -EINVAL;
+		goto end;
+	}
+	if (session->num_links <= 0) {
+		CAM_WARN(CAM_CRM, "No active links in session %x",
+			dump_req->session_handle);
+		goto end;
+	}
+
+	link = (struct cam_req_mgr_core_link *)
+		cam_get_device_priv(dump_req->link_hdl);
+	if (!link) {
+		CAM_DBG(CAM_CRM, "link ptr NULL %x", dump_req->link_hdl);
+		rc = -EINVAL;
+		goto end;
+	}
+	info.offset = dump_req->offset;
+	for (i = 0; i < link->num_devs; i++) {
+		device = &link->l_dev[i];
+		info.link_hdl = dump_req->link_hdl;
+		info.dev_hdl = device->dev_hdl;
+		info.req_id = dump_req->issue_req_id;
+		info.buf_handle = dump_req->buf_handle;
+		info.error_type = dump_req->error_type;
+		if (device->ops && device->ops->dump_req) {
+			rc = device->ops->dump_req(&info);
+			if (rc)
+				CAM_ERR(CAM_REQ,
+					"Fail dump req %llu dev %d rc %d",
+					info.req_id, device->dev_hdl, rc);
+		}
+	}
+	dump_req->offset = info.offset;
+	CAM_INFO(CAM_REQ, "req %llu, offset %zu",
+		dump_req->issue_req_id, dump_req->offset);
+end:
+	mutex_unlock(&g_crm_core_dev->crm_lock);
+	return 0;
+}
 
 int cam_req_mgr_core_device_init(void)
 {

+ 6 - 0
drivers/cam_req_mgr/cam_req_mgr_core.h

@@ -501,4 +501,10 @@ void cam_req_mgr_handle_core_shutdown(void);
  */
 int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control);
 
+/**
+ * cam_req_mgr_dump_request()
+ * @brief:   Dumps the request information
+ * @dump_req: Dump request
+ */
+int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req);
 #endif

+ 24 - 0
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -523,6 +523,30 @@ static long cam_private_ioctl(struct file *file, void *fh,
 			rc = -EINVAL;
 		}
 		break;
+	case CAM_REQ_MGR_REQUEST_DUMP: {
+		struct cam_dump_req_cmd cmd;
+
+		if (k_ioctl->size != sizeof(cmd))
+			return -EINVAL;
+
+		if (copy_from_user(&cmd,
+			u64_to_user_ptr(k_ioctl->handle),
+			sizeof(struct cam_dump_req_cmd))) {
+			rc = -EFAULT;
+			break;
+		}
+		rc = cam_req_mgr_dump_request(&cmd);
+		if (rc) {
+			CAM_ERR(CAM_CORE, "dump fail for dev %d req %llu rc %d",
+				cmd.dev_handle, cmd.issue_req_id, rc);
+			break;
+		}
+		if (copy_to_user(
+			u64_to_user_ptr(k_ioctl->handle),
+			&cmd, sizeof(struct cam_dump_req_cmd)))
+			rc = -EFAULT;
+		}
+		break;
 	default:
 		return -ENOIOCTLCMD;
 	}

+ 24 - 0
drivers/cam_req_mgr/cam_req_mgr_interface.h

@@ -21,6 +21,7 @@ struct cam_req_mgr_core_dev_link_setup;
 struct cam_req_mgr_apply_request;
 struct cam_req_mgr_flush_request;
 struct cam_req_mgr_link_evt_data;
+struct cam_req_mgr_dump_info;
 
 #define SKIP_NEXT_FRAME 0x100
 
@@ -48,12 +49,14 @@ typedef int (*cam_req_mgr_notify_stop)(struct cam_req_mgr_notify_stop *);
  * @cam_req_mgr_apply_req   : CRM asks device to apply certain request id
  * @cam_req_mgr_flush_req   : Flush or cancel request
  * cam_req_mgr_process_evt  : generic events
+ * @cam_req_mgr_dump_req    : dump request
  */
 typedef int (*cam_req_mgr_get_dev_info) (struct cam_req_mgr_device_info *);
 typedef int (*cam_req_mgr_link_setup)(struct cam_req_mgr_core_dev_link_setup *);
 typedef int (*cam_req_mgr_apply_req)(struct cam_req_mgr_apply_request *);
 typedef int (*cam_req_mgr_flush_req)(struct cam_req_mgr_flush_request *);
 typedef int (*cam_req_mgr_process_evt)(struct cam_req_mgr_link_evt_data *);
+typedef int (*cam_req_mgr_dump_req)(struct cam_req_mgr_dump_info *);
 
 /**
  * @brief          : cam_req_mgr_crm_cb - func table
@@ -80,6 +83,7 @@ struct cam_req_mgr_crm_cb {
  * @apply_req    : payload to apply request id on a device linked
  * @flush_req    : payload to flush request
  * @process_evt  : payload to generic event
+ * @dump_req     : payload to dump request
  */
 struct cam_req_mgr_kmd_ops {
 	cam_req_mgr_get_dev_info     get_dev_info;
@@ -87,6 +91,7 @@ struct cam_req_mgr_kmd_ops {
 	cam_req_mgr_apply_req        apply_req;
 	cam_req_mgr_flush_req        flush_req;
 	cam_req_mgr_process_evt      process_evt;
+	cam_req_mgr_dump_req         dump_req;
 };
 
 /**
@@ -366,4 +371,23 @@ struct cam_req_mgr_send_request {
 	int32_t    link_hdl;
 	struct cam_req_mgr_req_queue *in_q;
 };
+
+/**
+ * struct cam_req_mgr_dump_info
+ * @req_id      : request id to dump
+ * @offset      : offset of buffer
+ * @error_type  : error type
+ * @buf_handle  : buf handle
+ * @link_hdl    : link identifier
+ * @dev_hdl     : device handle for cross check
+ *
+ */
+struct cam_req_mgr_dump_info {
+	uint64_t    req_id;
+	size_t      offset;
+	uint32_t    error_type;
+	uint32_t    buf_handle;
+	int32_t     link_hdl;
+	int32_t     dev_hdl;
+};
 #endif

+ 22 - 0
include/uapi/camera/media/cam_defs.h

@@ -26,6 +26,7 @@
 #define CAM_COMMON_OPCODE_BASE_v2           0x150
 #define CAM_ACQUIRE_HW                      (CAM_COMMON_OPCODE_BASE_v2 + 0x1)
 #define CAM_RELEASE_HW                      (CAM_COMMON_OPCODE_BASE_v2 + 0x2)
+#define CAM_DUMP_REQ                        (CAM_COMMON_OPCODE_BASE_v2 + 0x3)
 
 #define CAM_EXT_OPCODE_BASE                     0x200
 #define CAM_CONFIG_DEV_EXTERNAL                 (CAM_EXT_OPCODE_BASE + 0x1)
@@ -868,5 +869,26 @@ struct cam_reg_dump_input_info {
 	uint32_t                   dump_set_offsets[1];
 };
 
+/**
+ * struct cam_dump_req_cmd -
+ *        Dump the information of issue req id
+ *
+ * @issue_req_id   : Issue Request Id
+ * @offset         : Offset for the buffer
+ * @buf_handle     : Buffer Handle
+ * @error_type     : Error type, using it, dumping information can be extended
+ * @session_handle : Session Handle
+ * @link_hdl       : link handle
+ * @dev_handle     : Device Handle
+ */
+struct cam_dump_req_cmd {
+	uint64_t       issue_req_id;
+	size_t         offset;
+	uint32_t       buf_handle;
+	uint32_t       error_type;
+	int32_t        session_handle;
+	int32_t        link_hdl;
+	int32_t        dev_handle;
+};
 
 #endif /* __UAPI_CAM_DEFS_H__ */

+ 2 - 0
include/uapi/camera/media/cam_req_mgr.h

@@ -262,6 +262,8 @@ struct cam_req_mgr_link_control {
 #define CAM_REQ_MGR_CACHE_OPS                   (CAM_COMMON_OPCODE_MAX + 12)
 #define CAM_REQ_MGR_LINK_CONTROL                (CAM_COMMON_OPCODE_MAX + 13)
 #define CAM_REQ_MGR_LINK_V2                     (CAM_COMMON_OPCODE_MAX + 14)
+#define CAM_REQ_MGR_REQUEST_DUMP                (CAM_COMMON_OPCODE_MAX + 15)
+
 /* end of cam_req_mgr opcodes */
 
 #define CAM_MEM_FLAG_HW_READ_WRITE              (1<<0)