Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 06/12

* commit '6e4bb1a37af305e7d4d1aa4eb124140133cf6fc0':

  msm: camera: sensor: Increase the eeprom map buffer count
  msm: camera: reqmgr: Reset previous skipped slot if valid request
  msm: camera: crm: Increasing the device handles to 128
  msm: camera: Adding device type to track device handles
  msm: camera: isp: Add support for initial frame drop
  msm: camera: cpas: Check the HW state before accessing register
  msm: camera: cci: Add rd_done to handle read done operation
  msm: camera: crm: Increase the device handles to 128
  msm: camera: fd: Remove duplicate "qcom,fd501" property
  msm: camera: reqmgr: Fix CRM shift one req issue
  msm: camera: icp: Mapping fw error numbers with error names
  msm: camera: csiphy: correct DPHY bring up sequence (Merged)
  msm: camera: Fix cpas axi clk rate overflow (Merged)
  msm: camera: reqmgr: Skip reset if no request from UMD
  msm: camera: sync: Dump fence info in case of fence exhaust
  msm: camera: Add uapi changes for axi bw voting v2
  msm: camera: isp: Handle Dual VFE incase of event mismatch
  msm: camera: icp: Get GDSC control prior to IPE/BPS reset

Change-Id: I813060ef4d332f8d782b60b1beac81a638855da3
Signed-off-by: Raja Mallik <rmallik@codeaurora.org>
diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
index 3304912..7600cbb 100644
--- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
@@ -574,7 +574,7 @@
 	req_hdl_param.media_entity_flag = 0;
 	req_hdl_param.priv = ctx;
 	req_hdl_param.ops = ctx->crm_ctx_intf;
-
+	req_hdl_param.dev_id = ctx->dev_id;
 	ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
 	if (ctx->dev_hdl <= 0) {
 		rc = -EFAULT;
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
index a05901a..4276b35 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
@@ -568,7 +568,7 @@
 		struct cam_cpas_axi_port *curr_axi_port = NULL;
 		struct cam_cpas_axi_port *temp_axi_port = NULL;
 		uint64_t required_camnoc_bw = 0;
-		int32_t clk_rate = 0;
+		int64_t clk_rate = 0;
 
 		list_for_each_entry_safe(curr_axi_port, temp_axi_port,
 			&cpas_core->axi_ports_list_head, sibling_port) {
@@ -596,13 +596,13 @@
 
 		clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width;
 
-		CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %d",
+		CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %lld",
 			required_camnoc_bw, clk_rate);
 
 		rc = cam_soc_util_set_src_clk_rate(soc_info, clk_rate);
 		if (rc)
 			CAM_ERR(CAM_CPAS,
-				"Failed in setting camnoc axi clk %llu %d %d",
+				"Failed in setting camnoc axi clk %llu %lld %d",
 				required_camnoc_bw, clk_rate, rc);
 	}
 
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
index 49774f2..719fb12 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
@@ -415,6 +415,12 @@
 		return;
 	}
 
+	mutex_lock(&cpas_hw->hw_mutex);
+	if (cpas_hw->hw_state == CAM_HW_STATE_POWER_DOWN) {
+		CAM_ERR(CAM_CPAS, "CPAS CORE is off");
+		mutex_unlock(&cpas_hw->hw_mutex);
+		return;
+	}
 	for (i = 0; i < camnoc_info->irq_err_size; i++) {
 		if ((payload->irq_status & camnoc_info->irq_err[i].sbm_port) &&
 			(camnoc_info->irq_err[i].enable)) {
@@ -460,6 +466,7 @@
 				~camnoc_info->irq_err[i].sbm_port;
 		}
 	}
+	mutex_unlock(&cpas_hw->hw_mutex);
 	atomic_dec(&cpas_core->irq_count);
 	wake_up(&cpas_core->irq_count_wq);
 	CAM_DBG(CAM_CPAS, "irq_count=%d\n", atomic_read(&cpas_core->irq_count));
diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c
index d4c9326..083041c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c
@@ -206,10 +206,6 @@
 		.compatible = "qcom,fd501",
 		.data = &cam_fd_wrapper200_core501_info,
 	},
-	{
-		.compatible = "qcom,fd501",
-		.data = &cam_fd_wrapper200_core501_info,
-	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, cam_fd_hw_dt_match);
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h b/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h
index 311886f..d60a25e 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  *
  * 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
@@ -215,6 +215,27 @@
 
 #define HFI_DEV_VERSION_MAX      0x5
 
+/* General errors and HFI Specific errors. */
+enum hfi_errors {
+	CAMERAICP_SUCCESS,
+	CAMERAICP_EFAILED,
+	CAMERAICP_ENOMEMORY,
+	CAMERAICP_EBADSTATE,
+	CAMERAICP_EBADPARM,
+	CAMERAICP_EBADITEM,
+	CAMERAICP_EINVALIDFORMAT,
+	CAMERAICP_EUNSUPPORTED,
+	CAMERAICP_EOUTOFBOUND,
+	CAMERAICP_ETIMEDOUT,
+	CAMERAICP_EABORTED,
+	CAMERAICP_EHWVIOLATION,
+	CAMERAICP_ECDMERROR,
+	CAMERAICP_HFI_ERR_COMMAND_SIZE = 1000,
+	CAMERAICP_HFI_ERR_MESSAGE_SIZE,
+	CAMERAICP_HFI_QUEUE_EMPTY,
+	CAMERAICP_HFI_QUEUE_FULL,
+};
+
 /**
  * start of sys command packet types
  * These commands are used to get system level information
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index ca10a3a..2b764d1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -1293,6 +1293,44 @@
 	return rc;
 }
 
+static int cam_icp_mgr_ipe_bps_get_gdsc_control(
+	struct cam_icp_hw_mgr *hw_mgr)
+{
+	int rc = 0;
+	struct cam_hw_intf *ipe0_dev_intf = NULL;
+	struct cam_hw_intf *ipe1_dev_intf = NULL;
+	struct cam_hw_intf *bps_dev_intf = NULL;
+
+	ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
+	ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
+	bps_dev_intf = hw_mgr->bps_dev_intf;
+
+	if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
+		CAM_ERR(CAM_ICP, "dev intfs are wrong");
+		return -EINVAL;
+	}
+
+	if (icp_hw_mgr.ipe_bps_pc_flag) {
+		rc = bps_dev_intf->hw_ops.process_cmd(
+			bps_dev_intf->hw_priv,
+			CAM_ICP_BPS_CMD_POWER_COLLAPSE,
+			NULL, 0);
+
+		rc = ipe0_dev_intf->hw_ops.process_cmd(
+			ipe0_dev_intf->hw_priv,
+			CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0);
+
+		if (ipe1_dev_intf) {
+			rc = ipe1_dev_intf->hw_ops.process_cmd(
+				ipe1_dev_intf->hw_priv,
+				CAM_ICP_IPE_CMD_POWER_COLLAPSE,
+				NULL, 0);
+		}
+	}
+
+	return rc;
+}
+
 static int cam_icp_set_dbg_default_clk(void *data, u64 val)
 {
 	icp_hw_mgr.icp_debug_clk = val;
@@ -1563,7 +1601,69 @@
 
 	return 0;
 }
+static const char *cam_icp_error_handle_id_to_type(
+	uint32_t error_handle)
+{
+	const char *name = NULL;
 
+	switch (error_handle) {
+	case CAMERAICP_SUCCESS:
+		name = "SUCCESS";
+		break;
+	case CAMERAICP_EFAILED:
+		name = "EFAILED";
+		break;
+	case CAMERAICP_ENOMEMORY:
+		name = "ENOMEMORY";
+		break;
+	case CAMERAICP_EBADSTATE:
+		name = "EBADSTATE";
+		break;
+	case CAMERAICP_EBADPARM:
+		name = "EBADPARM";
+		break;
+	case CAMERAICP_EBADITEM:
+		name = "EBADITEM";
+		break;
+	case CAMERAICP_EINVALIDFORMAT:
+		name = "EINVALIDFORMAT";
+		break;
+	case CAMERAICP_EUNSUPPORTED:
+		name = "EUNSUPPORTED";
+		break;
+	case CAMERAICP_EOUTOFBOUND:
+		name = "EOUTOFBOUND";
+		break;
+	case CAMERAICP_ETIMEDOUT:
+		name = "ETIMEDOUT";
+		break;
+	case CAMERAICP_EABORTED:
+		name = "EABORTED";
+		break;
+	case CAMERAICP_EHWVIOLATION:
+		name = "EHWVIOLATION";
+		break;
+	case CAMERAICP_ECDMERROR:
+		name = "ECDMERROR";
+		break;
+	case CAMERAICP_HFI_ERR_COMMAND_SIZE:
+		name = "HFI_ERR_COMMAND_SIZE";
+		break;
+	case CAMERAICP_HFI_ERR_MESSAGE_SIZE:
+		name = "HFI_ERR_MESSAGE_SIZE";
+		break;
+	case CAMERAICP_HFI_QUEUE_EMPTY:
+		name = "HFI_QUEUE_EMPTY";
+		break;
+	case CAMERAICP_HFI_QUEUE_FULL:
+		name = "HFI_QUEUE_FULL";
+		break;
+	default:
+		name = NULL;
+		break;
+	}
+	return name;
+}
 static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr)
 {
 	struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
@@ -1576,8 +1676,11 @@
 
 	ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
 	if (ioconfig_ack->err_type != HFI_ERR_SYS_NONE) {
-		CAM_ERR(CAM_ICP, "failed with error : %u",
-			ioconfig_ack->err_type);
+		CAM_ERR(CAM_ICP,
+			"failed with err_no= [%u] err_type= [%s]",
+			ioconfig_ack->err_type,
+			cam_icp_error_handle_id_to_type(
+			ioconfig_ack->err_type));
 		cam_icp_mgr_handle_frame_process(msg_ptr,
 			ICP_FRAME_PROCESS_FAILURE);
 		return -EIO;
@@ -1617,8 +1720,12 @@
 		ipe_config_ack =
 			(struct hfi_msg_ipe_config *)(ioconfig_ack->msg_data);
 		if (ipe_config_ack->rc) {
-			CAM_ERR(CAM_ICP, "rc = %d err = %u",
-				ipe_config_ack->rc, ioconfig_ack->err_type);
+			CAM_ERR(CAM_ICP, "rc = %d failed with\n"
+				"err_no = [%u] err_type = [%s]",
+				ipe_config_ack->rc,
+				ioconfig_ack->err_type,
+				cam_icp_error_handle_id_to_type(
+				ioconfig_ack->err_type));
 			return -EIO;
 		}
 		ctx_data = (struct cam_icp_hw_ctx_data *)
@@ -1783,9 +1890,13 @@
 			(struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
 		if (ctx_data->state != CAM_ICP_CTX_STATE_FREE)
 			complete(&ctx_data->wait_complete);
-		CAM_DBG(CAM_ICP,
-			"received IPE/BPS MAP ACK:ctx_state =%d err_status =%u",
-			ctx_data->state, ioconfig_ack->err_type);
+			CAM_DBG(CAM_ICP, "received IPE/BPS\n"
+				"MAP ACK:ctx_state =%d\n"
+				"failed with err_no = [%u] err_type = [%s]",
+				ctx_data->state,
+				ioconfig_ack->err_type,
+				cam_icp_error_handle_id_to_type(
+				ioconfig_ack->err_type));
 		break;
 	case HFI_IPEBPS_CMD_OPCODE_MEM_UNMAP:
 		ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
@@ -1793,9 +1904,13 @@
 			(struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
 		if (ctx_data->state != CAM_ICP_CTX_STATE_FREE)
 			complete(&ctx_data->wait_complete);
-		CAM_DBG(CAM_ICP,
-			"received IPE/BPS UNMAP ACK:ctx_state =%d err_status =%u",
-			ctx_data->state, ioconfig_ack->err_type);
+				CAM_DBG(CAM_ICP,
+					"received IPE/BPS UNMAP ACK:ctx_state =%d\n"
+					"failed with err_no = [%u] err_type = [%s]",
+					ctx_data->state,
+					ioconfig_ack->err_type,
+					cam_icp_error_handle_id_to_type(
+					ioconfig_ack->err_type));
 		break;
 	default:
 		CAM_ERR(CAM_ICP, "Invalid opcode : %u",
@@ -1817,27 +1932,31 @@
 	ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
 	bps_dev_intf = hw_mgr->bps_dev_intf;
 
-	rc = bps_dev_intf->hw_ops.process_cmd(
-		bps_dev_intf->hw_priv,
-		CAM_ICP_BPS_CMD_RESET,
-		NULL, 0);
-	if (rc)
-		CAM_ERR(CAM_ICP, "bps reset failed");
+	if (hw_mgr->bps_ctxt_cnt) {
+		rc = bps_dev_intf->hw_ops.process_cmd(
+			bps_dev_intf->hw_priv,
+			CAM_ICP_BPS_CMD_RESET,
+			NULL, 0);
+		if (rc)
+			CAM_ERR(CAM_ICP, "bps reset failed");
+	}
 
-	rc = ipe0_dev_intf->hw_ops.process_cmd(
-		ipe0_dev_intf->hw_priv,
-		CAM_ICP_IPE_CMD_RESET,
-		NULL, 0);
-	if (rc)
-		CAM_ERR(CAM_ICP, "ipe0 reset failed");
-
-	if (ipe1_dev_intf) {
-		rc = ipe1_dev_intf->hw_ops.process_cmd(
-			ipe1_dev_intf->hw_priv,
+	if (hw_mgr->ipe_ctxt_cnt) {
+		rc = ipe0_dev_intf->hw_ops.process_cmd(
+			ipe0_dev_intf->hw_priv,
 			CAM_ICP_IPE_CMD_RESET,
 			NULL, 0);
 		if (rc)
-			CAM_ERR(CAM_ICP, "ipe1 reset failed");
+			CAM_ERR(CAM_ICP, "ipe0 reset failed");
+
+		if (ipe1_dev_intf) {
+			rc = ipe1_dev_intf->hw_ops.process_cmd(
+				ipe1_dev_intf->hw_priv,
+				CAM_ICP_IPE_CMD_RESET,
+				NULL, 0);
+			if (rc)
+				CAM_ERR(CAM_ICP, "ipe1 reset failed");
+		}
 	}
 
 	return 0;
@@ -1858,6 +1977,7 @@
 	sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva;
 	CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg);
 
+	cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr);
 	cam_icp_ipebps_reset(hw_mgr);
 
 	atomic_set(&hw_mgr->recovery, 1);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
index 2982ce0..57375c4 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
@@ -2875,7 +2875,7 @@
 	req_hdl_param.media_entity_flag = 0;
 	req_hdl_param.ops = ctx->crm_ctx_intf;
 	req_hdl_param.priv = ctx;
-
+	req_hdl_param.dev_id = CAM_ISP;
 	CAM_DBG(CAM_ISP, "get device handle form bridge");
 	ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
 	if (ctx->dev_hdl <= 0) {
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 177538a..fe3d2f1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -2984,6 +2984,7 @@
 		}
 	}
 
+	ctx->dual_ife_irq_mismatch_cnt = 0;
 	/* Start IFE root node: do nothing */
 	CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index);
 
@@ -3066,6 +3067,7 @@
 	ctx->is_rdi_only_context = 0;
 	ctx->cdm_handle = 0;
 	ctx->cdm_ops = NULL;
+	ctx->dual_ife_irq_mismatch_cnt = 0;
 	atomic_set(&ctx->overflow_pending, 0);
 	for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
 		ctx->sof_cnt[i] = 0;
@@ -3573,6 +3575,38 @@
 	}
 }
 
+static int cam_isp_blob_init_frame_drop(
+	struct cam_isp_init_frame_drop_config  *frame_drop_cfg,
+	struct cam_hw_prepare_update_args      *prepare)
+{
+	struct cam_ife_hw_mgr_ctx             *ctx = NULL;
+	struct cam_ife_hw_mgr_res             *hw_mgr_res;
+	struct cam_hw_intf                    *hw_intf;
+	uint32_t hw_idx = UINT_MAX;
+	uint32_t  i;
+	int rc = 0;
+
+	ctx = prepare->ctxt_to_hw_map;
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+
+			hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+			if (hw_intf->hw_idx == hw_idx)
+				continue;
+
+			rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+				CAM_IFE_CSID_SET_INIT_FRAME_DROP,
+				frame_drop_cfg,
+				sizeof(
+				struct cam_isp_init_frame_drop_config *));
+			hw_idx = hw_intf->hw_idx;
+		}
+	}
+	return rc;
+}
+
 static int cam_isp_packet_generic_blob_handler(void *user_data,
 	uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
 {
@@ -3818,7 +3852,22 @@
 			CAM_ERR(CAM_ISP, "FS Update Failed rc: %d", rc);
 	}
 		break;
+	case CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP: {
+		struct cam_isp_init_frame_drop_config  *frame_drop_cfg =
+			(struct cam_isp_init_frame_drop_config *)blob_data;
 
+		if (blob_size < sizeof(struct cam_isp_init_frame_drop_config)) {
+			CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+				blob_size,
+				sizeof(struct cam_isp_init_frame_drop_config));
+			return -EINVAL;
+		}
+
+		rc = cam_isp_blob_init_frame_drop(frame_drop_cfg, prepare);
+		if (rc)
+			CAM_ERR(CAM_ISP, "Init Frame drop Update Failed");
+	}
+		break;
 	default:
 		CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
 		break;
@@ -4101,6 +4150,36 @@
 	}
 }
 
+static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx)
+{
+	struct cam_ife_hw_mgr_res        *hw_mgr_res;
+	struct cam_hw_intf               *hw_intf;
+	struct cam_isp_hw_get_cmd_update  cmd_update;
+	int i = 0;
+
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+		if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT)
+			continue;
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+			switch (hw_mgr_res->hw_res[i]->res_id) {
+			case CAM_ISP_HW_VFE_IN_CAMIF:
+				hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+				cmd_update.res = hw_mgr_res->hw_res[i];
+				cmd_update.cmd_type =
+					CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP;
+				hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+					CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
+					&cmd_update, sizeof(cmd_update));
+				break;
+			default:
+				break;
+			}
+		}
+	}
+}
+
 static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 {
 	int rc = 0;
@@ -4771,11 +4850,26 @@
 		(event_cnt[core_idx1] &&
 		(event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) {
 
+		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) {
+			rc = -1;
+			return rc;
+		}
+
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
 			"One of the VFE could not generate hw event %d",
 			hw_event_type);
-		rc = -1;
-		return rc;
+		if (event_cnt[core_idx0] >= 2) {
+			event_cnt[core_idx0]--;
+			ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
+		}
+		if (event_cnt[core_idx1] >= 2) {
+			event_cnt[core_idx1]--;
+			ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
+		}
+
+		if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1)
+			cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx);
+		rc = 0;
 	}
 
 	CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d",
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
index bf5f152..0e6d79b 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
@@ -102,38 +102,42 @@
 /**
  * struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object
  *
- * @list:                   used by the ctx list.
- * @common:                 common acquired context data
- * @ctx_index:              acquired context id.
- * @hw_mgr:                 IFE hw mgr which owns this context
- * @ctx_in_use:             flag to tell whether context is active
- * @res_list_ife_in:        Starting resource(TPG,PHY0, PHY1...) Can only be
- *                          one.
- * @res_list_csid:          CSID resource list
- * @res_list_ife_src:       IFE input resource list
- * @res_list_ife_in_rd      IFE input resource list for read path
- * @res_list_ife_out:       IFE output resoruces array
- * @free_res_list:          Free resources list for the branch node
- * @res_pool:               memory storage for the free resource list
- * @irq_status0_mask:       irq_status0_mask for the context
- * @irq_status1_mask:       irq_status1_mask for the context
- * @base                    device base index array contain the all IFE HW
- *                          instance associated with this context.
- * @num_base                number of valid base data in the base array
- * @cdm_handle              cdm hw acquire handle
- * @cdm_ops                 cdm util operation pointer for building
- *                          cdm commands
- * @cdm_cmd                 cdm base and length request pointer
- * @sof_cnt                 sof count value per core, used for dual VFE
- * @epoch_cnt               epoch count value per core, used for dual VFE
- * @eof_cnt                 eof count value per core, used for dual VFE
- * @overflow_pending        flat to specify the overflow is pending for the
- *                          context
- * @is_rdi_only_context     flag to specify the context has only rdi resource
- * @config_done_complete    indicator for configuration complete
- * @init_done               indicate whether init hw is done
- * @is_fe_enable            indicate whether fetch engine\read path is enabled
- * @res_bitmap              fill resource bitmap for which rup to be set
+ * @list:                       used by the ctx list.
+ * @common:                     common acquired context data
+ * @ctx_index:                  acquired context id.
+ * @hw_mgr:                     IFE hw mgr which owns this context
+ * @ctx_in_use:                 flag to tell whether context is active
+ * @res_list_ife_in:            Starting resource(TPG,PHY0, PHY1...) Can only be
+ *                              one.
+ * @res_list_csid:              CSID resource list
+ * @res_list_ife_src:           IFE input resource list
+ * @res_list_ife_in_rd          IFE input resource list for read path
+ * @res_list_ife_out:           IFE output resoruces array
+ * @free_res_list:              Free resources list for the branch node
+ * @res_pool:                   memory storage for the free resource list
+ * @irq_status0_mask:           irq_status0_mask for the context
+ * @irq_status1_mask:           irq_status1_mask for the context
+ * @base                        device base index array contain the all IFE HW
+ *                              instance associated with this context.
+ * @num_base                    number of valid base data in the base array
+ * @cdm_handle                  cdm hw acquire handle
+ * @cdm_ops                     cdm util operation pointer for building
+ *                              cdm commands
+ * @cdm_cmd                     cdm base and length request pointer
+ * @sof_cnt                     sof count value per core, used for dual VFE
+ * @epoch_cnt                   epoch count value per core, used for dual VFE
+ * @eof_cnt                     eof count value per core, used for dual VFE
+ * @overflow_pending            flat to specify the overflow is pending
+ *                              for the context
+ * @is_rdi_only_context         flag to specify the context has only rdi
+ *                              resource
+ * @config_done_complete        indicator for configuration complete
+ * @init_done                   indicate whether init hw is done
+ * @is_fe_enable                indicate whether fetch engine\read path
+ *                              is enabled
+ * @res_bitmap                  fill resource bitmap for which rup to be set
+ * @dual_ife_irq_mismatch_cnt   irq mismatch count value per core, used for
+ *                              dual VFE
  */
 struct cam_ife_hw_mgr_ctx {
 	struct list_head                list;
@@ -171,6 +175,7 @@
 	bool                            init_done;
 	bool                            is_fe_enable;
 	unsigned long                   res_bitmap;
+	uint32_t                        dual_ife_irq_mismatch_cnt;
 };
 
 /**
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index 8fba017..5610f6d 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -468,6 +468,9 @@
 			csid_hw->hw_intf->hw_idx, val);
 	csid_hw->error_irq_count = 0;
 
+	for (i = 0 ; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
+		csid_hw->res_sof_cnt[i] = 0;
+
 	return rc;
 }
 
@@ -838,7 +841,6 @@
 	return rc;
 }
 
-
 static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
 	struct cam_csid_hw_reserve_resource_args  *reserve)
 {
@@ -953,7 +955,7 @@
 	path_data->height  = reserve->in_port->height;
 	path_data->start_line = reserve->in_port->line_start;
 	path_data->end_line = reserve->in_port->line_stop;
-
+	path_data->usage_type = reserve->in_port->usage_type;
 	/* Enable RDI crop for single ife use case only */
 	switch (reserve->res_id) {
 	case CAM_IFE_PIX_PATH_RES_RDI_0:
@@ -1119,6 +1121,7 @@
 static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
 {
 	int rc = -EINVAL;
+	uint32_t i;
 	struct cam_hw_soc_info                   *soc_info;
 	const struct cam_ife_csid_reg_offset     *csid_reg;
 	unsigned long                             flags;
@@ -1159,12 +1162,95 @@
 	spin_lock_irqsave(&csid_hw->lock_state, flags);
 	csid_hw->device_enabled = 0;
 	spin_unlock_irqrestore(&csid_hw->lock_state, flags);
+	for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
+		csid_hw->res_sof_cnt[i] = 0;
+
 	csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
 	csid_hw->error_irq_count = 0;
 
 	return rc;
 }
 
+static int cam_ife_csid_check_path_active(struct cam_ife_csid_hw   *csid_hw)
+{
+	struct cam_hw_soc_info          *soc_info;
+	const struct cam_ife_csid_reg_offset  *csid_reg;
+	uint32_t i, path_status = 1;
+
+	csid_reg = csid_hw->csid_info->csid_reg;
+	soc_info = &csid_hw->hw_info->soc_info;
+
+	/* check the IPP path status */
+	if (csid_reg->cmn_reg->num_pix) {
+		path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+				csid_reg->ipp_reg->csid_pxl_status_addr);
+		CAM_DBG(CAM_ISP, "CSID:%d IPP path status:%d",
+			csid_hw->hw_intf->hw_idx, path_status);
+		/* if status is 0 then it is active */
+		if (!path_status)
+			goto end;
+	}
+
+	if (csid_reg->cmn_reg->num_ppp) {
+		path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+				csid_reg->ppp_reg->csid_pxl_status_addr);
+		CAM_DBG(CAM_ISP, "CSID:%d PPP path status:%d",
+			csid_hw->hw_intf->hw_idx, path_status);
+		/* if status is 0 then it is active */
+		if (!path_status)
+			goto end;
+	}
+
+	/* Check the RDI path status */
+	for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
+		path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+				csid_reg->rdi_reg[i]->csid_rdi_status_addr);
+		CAM_DBG(CAM_ISP, "CSID:%d RDI:%d path status:%d",
+			csid_hw->hw_intf->hw_idx, i,  path_status);
+		/* if status is 0 then it is active */
+		if (!path_status)
+			goto end;
+	}
+
+end:
+	return path_status;
+}
+
+static void cam_ife_csid_reset_init_frame_drop(
+	struct cam_ife_csid_hw   *csid_hw)
+{
+	const struct cam_ife_csid_reg_offset  *csid_reg;
+	uint32_t i = 0;
+
+	/*
+	 * Reset CSID init frame drop value only if all resources are
+	 * released
+	 */
+	csid_reg = csid_hw->csid_info->csid_reg;
+	if (csid_reg->cmn_reg->num_pix) {
+		if (csid_hw->ipp_res.res_state !=
+			CAM_ISP_RESOURCE_STATE_AVAILABLE)
+			goto end;
+	}
+
+	if (csid_reg->cmn_reg->num_ppp) {
+		if (csid_hw->ppp_res.res_state !=
+			CAM_ISP_RESOURCE_STATE_AVAILABLE)
+			goto end;
+	}
+
+	for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
+		if (csid_hw->rdi_res[i].res_state !=
+			CAM_ISP_RESOURCE_STATE_AVAILABLE)
+			goto end;
+	}
+
+	/* All CSID resources are available reset the init frame drop */
+	csid_hw->init_frame_drop = 0;
+end:
+	return;
+
+}
 
 static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw   *csid_hw,
 	struct cam_isp_resource_node       *res)
@@ -1724,7 +1810,7 @@
 	struct cam_ife_csid_path_cfg             *path_data;
 	const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL;
 	bool                                      is_ipp;
-	uint32_t                                  val = 0;
+	uint32_t                                  val = 0, path_status;
 
 	path_data = (struct cam_ife_csid_path_cfg   *) res->res_priv;
 	csid_reg = csid_hw->csid_info->csid_reg;
@@ -1767,14 +1853,15 @@
 		/* Default is internal halt mode */
 		val = 0;
 
-	/*
-	 * Resume at frame boundary if Master or No Sync.
-	 * Slave will get resume command from Master.
-	 */
-	if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
-		path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
-		val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
-
+	/* Resume at frame boundary */
+	path_status = cam_ife_csid_check_path_active(csid_hw);
+	if (!csid_hw->init_frame_drop ||
+		(csid_hw->init_frame_drop && !path_status)) {
+		CAM_DBG(CAM_ISP, "start pixel path");
+		if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
+			path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
+			val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
+	}
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 		pxl_reg->csid_pxl_ctrl_addr);
 
@@ -1788,8 +1875,10 @@
 	if (pxl_reg->ccif_violation_en)
 		val |= CSID_PATH_ERROR_CCIF_VIOLATION;
 
-	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
+	if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) ||
+		(csid_hw->init_frame_drop && path_status))
 		val |= CSID_PATH_INFO_INPUT_SOF;
+
 	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
 		val |= CSID_PATH_INFO_INPUT_EOF;
 
@@ -2086,8 +2175,10 @@
 {
 	const struct cam_ife_csid_reg_offset      *csid_reg;
 	struct cam_hw_soc_info                    *soc_info;
-	uint32_t id, val;
+	struct cam_ife_csid_path_cfg              *path_data;
+	uint32_t id, val, path_status;
 
+	path_data = (struct cam_ife_csid_path_cfg   *) res->res_priv;
 	csid_reg = csid_hw->csid_info->csid_reg;
 	soc_info = &csid_hw->hw_info->soc_info;
 	id = res->res_id;
@@ -2102,19 +2193,28 @@
 		return -EINVAL;
 	}
 
-	/*resume at frame boundary */
-	cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
-			soc_info->reg_map[0].mem_base +
-			csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
+	if (path_data->usage_type)
+		path_data->init_frame_drop = csid_hw->init_frame_drop + 1;
 
+	/*resume at frame boundary */
+	path_status = cam_ife_csid_check_path_active(csid_hw);
+	if (!path_data->init_frame_drop ||
+		(path_data->init_frame_drop && !path_status)) {
+		CAM_DBG(CAM_ISP, "Start RDI:%d path", id);
+		cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+				soc_info->reg_map[0].mem_base +
+				csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
+	}
 	/* Enable the required RDI interrupts */
 	val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
 
 	if (csid_reg->rdi_reg[id]->ccif_violation_en)
 		val |= CSID_PATH_ERROR_CCIF_VIOLATION;
 
-	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
+	if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) ||
+		(path_data->init_frame_drop && path_status))
 		val |= CSID_PATH_INFO_INPUT_SOF;
+
 	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
 		val |= CSID_PATH_INFO_INPUT_EOF;
 
@@ -2374,6 +2474,19 @@
 	return 0;
 }
 
+static int cam_ife_csid_set_init_frame_drop(struct cam_ife_csid_hw   *csid_hw,
+	void *cmd_args)
+{
+	struct cam_isp_init_frame_drop_config  *frame_drop_cfg;
+
+	frame_drop_cfg = (struct cam_isp_init_frame_drop_config  *) cmd_args;
+	csid_hw->init_frame_drop = frame_drop_cfg->init_frame_drop;
+	CAM_DBG(CAM_ISP, "CSID:%d set init frame drop:%d",
+		csid_hw->hw_intf->hw_idx, csid_hw->init_frame_drop);
+
+	return 0;
+}
+
 static int cam_ife_csid_get_hw_caps(void *hw_priv,
 	void *get_hw_cap_args, uint32_t arg_size)
 {
@@ -2550,6 +2663,7 @@
 		break;
 	case CAM_ISP_RESOURCE_PIX_PATH:
 		res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
+		cam_ife_csid_reset_init_frame_drop(csid_hw);
 		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
@@ -3014,6 +3128,9 @@
 	case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE:
 		rc = cam_ife_csid_set_csid_clock(csid_hw, cmd_args);
 		break;
+	case CAM_IFE_CSID_SET_INIT_FRAME_DROP:
+		rc = cam_ife_csid_set_init_frame_drop(csid_hw, cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);
@@ -3031,6 +3148,9 @@
 	struct cam_hw_soc_info                         *soc_info;
 	const struct cam_ife_csid_reg_offset           *csid_reg;
 	const struct cam_ife_csid_csi2_rx_reg_offset   *csi2_reg;
+	struct cam_ife_csid_path_cfg                   *path_data;
+	const struct cam_ife_csid_pxl_reg_offset       *pxl_reg;
+	const struct cam_ife_csid_rdi_reg_offset       *rdi_reg;
 	uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
 	uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
 	uint32_t val, irq_status_ppp = 0;
@@ -3262,6 +3382,53 @@
 				csid_hw->irq_debug_cnt++;
 		}
 
+		if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) &&
+			(csid_hw->init_frame_drop) &&
+			(csid_hw->ipp_res.res_state ==
+			CAM_ISP_RESOURCE_STATE_STREAMING)) {
+			csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP]++;
+			CAM_DBG(CAM_ISP,
+				"CSID:%d IPP SOF cnt:%d init_frame_drop:%d",
+				csid_hw->hw_intf->hw_idx,
+				csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP],
+				csid_hw->init_frame_drop);
+			if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP] ==
+				csid_hw->init_frame_drop) {
+				pxl_reg = csid_reg->ipp_reg;
+				path_data = csid_hw->ipp_res.res_priv;
+				if (path_data->sync_mode ==
+					CAM_ISP_HW_SYNC_MASTER) {
+					val = cam_io_r_mb(
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+
+					val |=
+					CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
+					cam_io_w_mb(val,
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+
+				} else if (path_data->sync_mode ==
+					CAM_ISP_HW_SYNC_NONE) {
+					cam_io_w_mb(
+					CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+				}
+
+				if (!(csid_hw->csid_debug &
+					CSID_DEBUG_ENABLE_SOF_IRQ)) {
+					val = cam_io_r_mb(
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_irq_mask_addr);
+					val &= ~(CSID_PATH_INFO_INPUT_SOF);
+					cam_io_w_mb(val,
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_irq_mask_addr);
+				}
+			}
+		}
+
 		if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) &&
 			(csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
 			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received",
@@ -3297,6 +3464,52 @@
 				csid_hw->irq_debug_cnt++;
 		}
 
+		if ((irq_status_ppp & CSID_PATH_INFO_INPUT_SOF) &&
+			(csid_hw->init_frame_drop) &&
+			(csid_hw->ppp_res.res_state ==
+			CAM_ISP_RESOURCE_STATE_STREAMING)) {
+			csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP]++;
+			CAM_DBG(CAM_ISP,
+				"CSID:%d PPP SOF cnt:%d init_frame_drop:%d",
+				csid_hw->hw_intf->hw_idx,
+				csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP],
+				csid_hw->init_frame_drop);
+			if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP] ==
+				csid_hw->init_frame_drop) {
+				path_data = csid_hw->ppp_res.res_priv;
+				pxl_reg = csid_reg->ppp_reg;
+				if (path_data->sync_mode ==
+					CAM_ISP_HW_SYNC_MASTER) {
+					val = cam_io_r_mb(
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+
+					val |=
+					CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
+					cam_io_w_mb(val,
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_ctrl_addr);
+				} else if (path_data->sync_mode ==
+					CAM_ISP_HW_SYNC_NONE) {
+					cam_io_w_mb(
+					CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+						soc_info->reg_map[0].mem_base +
+						pxl_reg->csid_pxl_ctrl_addr);
+				}
+
+				if (!(csid_hw->csid_debug &
+					CSID_DEBUG_ENABLE_SOF_IRQ)) {
+					val = cam_io_r_mb(
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_irq_mask_addr);
+					val &= ~(CSID_PATH_INFO_INPUT_SOF);
+					cam_io_w_mb(val,
+					soc_info->reg_map[0].mem_base +
+					pxl_reg->csid_pxl_irq_mask_addr);
+				}
+			}
+		}
+
 		if ((irq_status_ppp & CSID_PATH_INFO_INPUT_EOF) &&
 			(csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
 			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received",
@@ -3317,6 +3530,9 @@
 	}
 
 	for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
+		path_data = (struct cam_ife_csid_path_cfg *)
+			csid_hw->rdi_res[i].res_priv;
+		rdi_reg = csid_reg->rdi_reg[i];
 		if (irq_status_rdi[i] &
 			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
 			complete(&csid_hw->csid_rdin_complete[i]);
@@ -3330,6 +3546,35 @@
 				csid_hw->irq_debug_cnt++;
 		}
 
+		if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) &&
+			(path_data->init_frame_drop) &&
+			(csid_hw->rdi_res[i].res_state ==
+			CAM_ISP_RESOURCE_STATE_STREAMING)) {
+			csid_hw->res_sof_cnt[i]++;
+			CAM_DBG(CAM_ISP,
+				"CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d",
+				csid_hw->hw_intf->hw_idx, i,
+				csid_hw->res_sof_cnt[i],
+				path_data->init_frame_drop);
+			if (csid_hw->res_sof_cnt[i] ==
+				path_data->init_frame_drop) {
+				cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+					soc_info->reg_map[0].mem_base +
+					rdi_reg->csid_rdi_ctrl_addr);
+
+				if (!(csid_hw->csid_debug &
+					CSID_DEBUG_ENABLE_SOF_IRQ)) {
+					val = cam_io_r_mb(
+					soc_info->reg_map[0].mem_base +
+					rdi_reg->csid_rdi_irq_mask_addr);
+					val &= ~(CSID_PATH_INFO_INPUT_SOF);
+					cam_io_w_mb(val,
+					soc_info->reg_map[0].mem_base +
+					rdi_reg->csid_rdi_irq_mask_addr);
+				}
+			}
+		}
+
 		if ((irq_status_rdi[i]  & CSID_PATH_INFO_INPUT_EOF) &&
 			(csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
 			CAM_INFO_RATE_LIMIT(CAM_ISP,
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
index 3a093d2..600deb2 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
@@ -419,6 +419,9 @@
  * @master_idx:     For Slave reservation, Give master IFE instance Index.
  *                  Slave will synchronize with master Start and stop operations
  * @clk_rate        Clock rate
+ * @usage_type      Usage type ie dual or single ife usecase
+ * @init_frame_drop init frame drop value. In dual ife case rdi need to drop one
+ *                  more frame than pix.
  *
  */
 struct cam_ife_csid_path_cfg {
@@ -437,6 +440,8 @@
 	enum cam_isp_hw_sync_mode       sync_mode;
 	uint32_t                        master_idx;
 	uint64_t                        clk_rate;
+	uint32_t                        usage_type;
+	uint32_t                        init_frame_drop;
 };
 
 /**
@@ -468,6 +473,13 @@
  * @irq_debug_cnt:            Counter to track sof irq's when above flag is set.
  * @error_irq_count           Error IRQ count, if continuous error irq comes
  *                            need to stop the CSID and mask interrupts.
+ * @device_enabled            Device enabled will set once CSID powered on and
+ *                            initial configuration are done.
+ * @lock_state                csid spin lock
+ * @dual_usage                usage type, dual ife or single ife
+ * @init_frame_drop           Initial frame drop number
+ * @res_sof_cnt               path resource sof count value. it used for initial
+ *                            frame drop
  *
  */
 struct cam_ife_csid_hw {
@@ -496,6 +508,9 @@
 	uint32_t                         error_irq_count;
 	uint32_t                         device_enabled;
 	spinlock_t                       lock_state;
+	uint32_t                         dual_usage;
+	uint32_t                         init_frame_drop;
+	uint32_t                         res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX];
 };
 
 int cam_ife_csid_hw_probe_init(struct cam_hw_intf  *csid_hw_intf,
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
index 58818fb..0c45bd1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  *
  * 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
@@ -157,6 +157,7 @@
 	CAM_IFE_CSID_CMD_GET_TIME_STAMP,
 	CAM_IFE_CSID_SET_CSID_DEBUG,
 	CAM_IFE_CSID_SOF_IRQ_DEBUG,
+	CAM_IFE_CSID_SET_INIT_FRAME_DROP,
 	CAM_IFE_CSID_CMD_MAX,
 };
 
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index 6154256..b230147 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -104,6 +104,7 @@
 	CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE,
 	CAM_ISP_HW_CMD_FE_UPDATE_IN_RD,
 	CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD,
+	CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
 	CAM_ISP_HW_CMD_MAX,
 };
 
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 2bd6db9..a26c112 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -760,6 +760,7 @@
 	case CAM_ISP_HW_CMD_CLOCK_UPDATE:
 	case CAM_ISP_HW_CMD_BW_UPDATE:
 	case CAM_ISP_HW_CMD_BW_CONTROL:
+	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
 		rc = core_info->vfe_top->hw_ops.process_cmd(
 			core_info->vfe_top->top_priv, cmd_type, cmd_args,
 			arg_size);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index c409365..4e9a975 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -421,6 +421,40 @@
 	return 0;
 }
 
+static int cam_vfe_camif_irq_reg_dump(
+	struct cam_isp_resource_node *camif_res)
+{
+	struct cam_vfe_mux_camif_data *camif_priv;
+	struct cam_vfe_soc_private *soc_private;
+	int rc = 0;
+
+	if (!camif_res) {
+		CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n");
+		return -EINVAL;
+	}
+
+	if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) ||
+		(camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
+		CAM_ERR(CAM_ISP, "Error! Invalid state\n");
+		return 0;
+	}
+
+	camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv;
+	soc_private = camif_priv->soc_info->soc_private;
+
+	CAM_INFO(CAM_ISP,
+		"Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
+		camif_priv->hw_intf->hw_idx,
+		0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c),
+		0x60, cam_io_r_mb(camif_priv->mem_base + 0x60));
+	CAM_INFO(CAM_ISP,
+		"Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
+		camif_priv->hw_intf->hw_idx,
+		0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c),
+		0x70, cam_io_r_mb(camif_priv->mem_base + 0x70));
+	return rc;
+}
+
 static int cam_vfe_camif_resource_stop(
 	struct cam_isp_resource_node        *camif_res)
 {
@@ -508,6 +542,9 @@
 			(struct cam_vfe_mux_camif_data *)rsrc_node->res_priv;
 		camif_priv->camif_debug = *((uint32_t *)cmd_args);
 		break;
+	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+		rc = cam_vfe_camif_irq_reg_dump(rsrc_node);
+		break;
 	default:
 		CAM_ERR(CAM_ISP,
 			"unsupported process command:%d", cmd_type);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index c5acbe5..b0ac94b 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -438,6 +438,19 @@
 	return -EINVAL;
 }
 
+static int cam_vfe_get_irq_register_dump(
+	struct cam_vfe_top_ver2_priv *top_priv,
+	void *cmd_args, uint32_t arg_size)
+{
+	struct cam_isp_hw_get_cmd_update  *cmd_update = cmd_args;
+
+	if (cmd_update->res->process_cmd)
+		cmd_update->res->process_cmd(cmd_update->res,
+		CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, cmd_args, arg_size);
+
+	return 0;
+}
+
 int cam_vfe_top_get_hw_caps(void *device_priv,
 	void *get_hw_cap_args, uint32_t arg_size)
 {
@@ -723,6 +736,10 @@
 	case CAM_ISP_HW_CMD_BW_CONTROL:
 		rc = cam_vfe_top_bw_control(top_priv, cmd_args, arg_size);
 		break;
+	case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+		rc = cam_vfe_get_irq_register_dump(top_priv,
+				cmd_args, arg_size);
+		break;
 	default:
 		rc = -EINVAL;
 		CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type);
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
index f1b3cce..c8e2a02 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
@@ -348,10 +348,12 @@
 	struct cam_req_mgr_req_queue *in_q = link->req.in_q;
 
 	slot = &in_q->slot[idx];
-	CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status);
+	CAM_DBG(CAM_CRM, "RESET: last applied idx %d: idx %d: slot->status %d",
+			in_q->last_applied_idx, idx, slot->status);
 
 	/* Check if CSL has already pushed new request*/
-	if (slot->status == CRM_SLOT_STATUS_REQ_ADDED)
+	if (slot->status == CRM_SLOT_STATUS_REQ_ADDED ||
+		in_q->last_applied_idx == idx)
 		return;
 
 	/* Reset input queue slot */
@@ -512,9 +514,11 @@
 			}
 			if (link->req.apply_data[pd].skip_idx ||
 				link->req.apply_data[pd].req_id < 0) {
-				CAM_DBG(CAM_CRM, "skip %d req_id %lld",
+				CAM_DBG(CAM_CRM,
+					"skip %d req_id %lld pd %d dev_name %s",
 					link->req.apply_data[pd].skip_idx,
-					link->req.apply_data[pd].req_id);
+					link->req.apply_data[pd].req_id,
+					pd, dev->dev_info.name);
 				continue;
 			}
 			if (!(dev->dev_info.trigger & trigger))
@@ -893,6 +897,7 @@
 	int64_t req_id = 0;
 	int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
 	int32_t sync_num_slots = 0;
+	bool ready = true, sync_ready = true;
 
 	if (!link->sync_link) {
 		CAM_ERR(CAM_CRM, "Sync link null");
@@ -921,17 +926,7 @@
 		CAM_DBG(CAM_CRM,
 			"Skip Process Req: %lld on link: %x",
 			req_id, link->link_hdl);
-		link->sync_link_sof_skip = true;
-		return rc;
-	}
-
-	rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true);
-	if (rc) {
-		CAM_DBG(CAM_CRM,
-			"Req: %lld [My link] not ready on link: %x, rc=%d",
-			req_id, link->link_hdl, rc);
-		link->sync_link_sof_skip = true;
-		return rc;
+		ready = false;
 	}
 
 	sync_slot_idx = __cam_req_mgr_find_slot_for_req(
@@ -939,8 +934,7 @@
 	if (sync_slot_idx == -1) {
 		CAM_DBG(CAM_CRM, "Req: %lld not found on link: %x [other link]",
 			req_id, sync_link->link_hdl);
-		link->sync_link_sof_skip = true;
-		return -EINVAL;
+		sync_ready = false;
 	}
 
 	sync_rd_idx = sync_link->req.in_q->rd_idx;
@@ -956,14 +950,38 @@
 		return -EAGAIN;
 	}
 
+	rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true);
+	if (rc) {
+		CAM_DBG(CAM_CRM,
+			"Req: %lld [My link] not ready on link: %x, rc=%d",
+			req_id, link->link_hdl, rc);
+		ready = false;
+	}
+
 	rc = __cam_req_mgr_check_link_is_ready(sync_link, sync_slot_idx, true);
 	if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status !=
 		CRM_SLOT_STATUS_REQ_APPLIED)) {
 		CAM_DBG(CAM_CRM,
 			"Req: %lld not ready on [other link] link: %x, rc=%d",
 			req_id, sync_link->link_hdl, rc);
+		sync_ready = false;
+	}
+
+	/*
+	 * If both of them are ready or not ready, then just
+	 * skip this sof and don't skip sync link next SOF.
+	 */
+	if (sync_ready != ready) {
+		CAM_DBG(CAM_CRM,
+			"Req: %lld ready %d sync_ready %d, ignore sync link next SOF",
+			req_id, ready, sync_ready);
 		link->sync_link_sof_skip = true;
-		return rc;
+		return -EINVAL;
+	} else if (ready == false) {
+		CAM_DBG(CAM_CRM,
+			"Req: %lld not ready on link: %x",
+			req_id, link->link_hdl);
+		return -EINVAL;
 	}
 
 	CAM_DBG(CAM_REQ,
@@ -995,7 +1013,7 @@
 static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
 	uint32_t trigger)
 {
-	int                                  rc = 0, idx;
+	int                                  rc = 0, idx, last_app_idx;
 	int                                  reset_step = 0;
 	struct cam_req_mgr_slot             *slot = NULL;
 	struct cam_req_mgr_req_queue        *in_q;
@@ -1129,6 +1147,7 @@
 				slot->req_id,
 				link->link_hdl);
 			idx = in_q->rd_idx;
+
 			reset_step = link->max_delay;
 			if (link->sync_link) {
 				if ((link->in_msync_mode) &&
@@ -1136,6 +1155,25 @@
 					reset_step =
 						link->sync_link->max_delay;
 			}
+
+			/* This is to handle a rare scenario of scheduling
+			 * issue. If ISP sends multiple sofs due to scheduling
+			 * issue, it is required to retain last applied index
+			 * to help recover.
+			 * In this case, ISP goes into Bubble, asking to reapply
+			 * the bubbled request which has already been reset by
+			 * CRM. Below code retains the last applied request.
+			 */
+
+			if (slot->req_id > 0) {
+				last_app_idx = in_q->last_applied_idx;
+				in_q->last_applied_idx = idx;
+				if (abs(last_app_idx - idx) >=
+					reset_step + 1)
+					__cam_req_mgr_reset_req_slot(link,
+						last_app_idx);
+			}
+
 			__cam_req_mgr_dec_idx(
 				&idx, reset_step + 1,
 				in_q->num_slots);
@@ -2359,18 +2397,24 @@
  *
  */
 static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
-	struct cam_req_mgr_link_info *link_info)
+	struct cam_req_mgr_ver_info *link_info)
 {
-	int                                     rc = 0, i = 0;
+	int                                     rc = 0, i = 0, num_devices = 0;
 	struct cam_req_mgr_core_dev_link_setup  link_data;
 	struct cam_req_mgr_connected_device    *dev;
 	struct cam_req_mgr_req_tbl             *pd_tbl;
 	enum cam_pipeline_delay                 max_delay;
 	uint32_t                                subscribe_event = 0;
-
-	if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES)
-		return -EPERM;
-
+	if (link_info->version == VERSION_1) {
+		if (link_info->u.link_info_v1.num_devices >
+			CAM_REQ_MGR_MAX_HANDLES)
+			return -EPERM;
+		}
+	else if (link_info->version == VERSION_2) {
+		if (link_info->u.link_info_v2.num_devices >
+			CAM_REQ_MGR_MAX_HANDLES_V2)
+			return -EPERM;
+		}
 	mutex_init(&link->req.lock);
 	CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock);
 	link->req.num_tbl = 0;
@@ -2380,11 +2424,21 @@
 		return rc;
 
 	max_delay = CAM_PIPELINE_DELAY_0;
-	for (i = 0; i < link_info->num_devices; i++) {
+	if (link_info->version == VERSION_1)
+		num_devices = link_info->u.link_info_v1.num_devices;
+	else if (link_info->version == VERSION_2)
+		num_devices = link_info->u.link_info_v2.num_devices;
+	for (i = 0; i < num_devices; i++) {
 		dev = &link->l_dev[i];
 		/* Using dev hdl, get ops ptr to communicate with device */
-		dev->ops = (struct cam_req_mgr_kmd_ops *)
-			cam_get_device_ops(link_info->dev_hdls[i]);
+		if (link_info->version == VERSION_1)
+			dev->ops = (struct cam_req_mgr_kmd_ops *)
+					cam_get_device_ops(
+					link_info->u.link_info_v1.dev_hdls[i]);
+		else if (link_info->version == VERSION_2)
+			dev->ops = (struct cam_req_mgr_kmd_ops *)
+					cam_get_device_ops(
+					link_info->u.link_info_v2.dev_hdls[i]);
 		if (!dev->ops ||
 			!dev->ops->get_dev_info ||
 			!dev->ops->link_setup) {
@@ -2392,18 +2446,29 @@
 			rc = -ENXIO;
 			goto error;
 		}
-		dev->dev_hdl = link_info->dev_hdls[i];
+		if (link_info->version == VERSION_1)
+			dev->dev_hdl = link_info->u.link_info_v1.dev_hdls[i];
+		else if (link_info->version == VERSION_2)
+			dev->dev_hdl = link_info->u.link_info_v2.dev_hdls[i];
 		dev->parent = (void *)link;
 		dev->dev_info.dev_hdl = dev->dev_hdl;
 		rc = dev->ops->get_dev_info(&dev->dev_info);
 
 		trace_cam_req_mgr_connect_device(link, &dev->dev_info);
-
-		CAM_DBG(CAM_CRM,
-			"%x: connected: %s, id %d, delay %d, trigger %x",
-			link_info->session_hdl, dev->dev_info.name,
-			dev->dev_info.dev_id, dev->dev_info.p_delay,
-			dev->dev_info.trigger);
+		if (link_info->version == VERSION_1)
+			CAM_DBG(CAM_CRM,
+				"%x: connected: %s, id %d, delay %d, trigger %x",
+				link_info->u.link_info_v1.session_hdl,
+				dev->dev_info.name,
+				dev->dev_info.dev_id, dev->dev_info.p_delay,
+				dev->dev_info.trigger);
+		else if (link_info->version == VERSION_2)
+			CAM_DBG(CAM_CRM,
+				"%x: connected: %s, id %d, delay %d, trigger %x",
+				link_info->u.link_info_v2.session_hdl,
+				dev->dev_info.name,
+				dev->dev_info.dev_id, dev->dev_info.p_delay,
+				dev->dev_info.trigger);
 		if (rc < 0 ||
 			dev->dev_info.p_delay >=
 			CAM_PIPELINE_DELAY_MAX ||
@@ -2412,10 +2477,18 @@
 			CAM_ERR(CAM_CRM, "get device info failed");
 			goto error;
 		} else {
-			CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
-				link_info->session_hdl,
-				dev->dev_info.name,
-				dev->dev_info.p_delay);
+			if (link_info->version == VERSION_1) {
+				CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
+					link_info->u.link_info_v1.session_hdl,
+					dev->dev_info.name,
+					dev->dev_info.p_delay);
+				}
+			else if (link_info->version == VERSION_2) {
+				CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
+					link_info->u.link_info_v2.session_hdl,
+					dev->dev_info.name,
+					dev->dev_info.p_delay);
+				}
 			if (dev->dev_info.p_delay > max_delay)
 				max_delay = dev->dev_info.p_delay;
 
@@ -2430,7 +2503,7 @@
 	link_data.max_delay = max_delay;
 	link_data.subscribe_event = subscribe_event;
 
-	for (i = 0; i < link_info->num_devices; i++) {
+	for (i = 0; i < num_devices; i++) {
 		dev = &link->l_dev[i];
 
 		link_data.dev_hdl = dev->dev_hdl;
@@ -2473,7 +2546,7 @@
 		if (link->max_delay < dev->dev_info.p_delay)
 			link->max_delay = dev->dev_info.p_delay;
 	}
-	link->num_devs = link_info->num_devices;
+	link->num_devs = num_devices;
 
 	/* Assign id for pd tables */
 	__cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req);
@@ -2631,7 +2704,7 @@
 	return rc;
 }
 
-int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
+int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
 {
 	int                                     rc = 0;
 	int                                     wq_flag = 0;
@@ -2644,9 +2717,9 @@
 		CAM_DBG(CAM_CRM, "NULL pointer");
 		return -EINVAL;
 	}
-	if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) {
+	if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) {
 		CAM_ERR(CAM_CRM, "Invalid num devices %d",
-			link_info->num_devices);
+			link_info->u.link_info_v1.num_devices);
 		return -EINVAL;
 	}
 
@@ -2654,7 +2727,7 @@
 
 	/* session hdl's priv data is cam session struct */
 	cam_session = (struct cam_req_mgr_core_session *)
-		cam_get_device_priv(link_info->session_hdl);
+		cam_get_device_priv(link_info->u.link_info_v1.session_hdl);
 	if (!cam_session) {
 		CAM_DBG(CAM_CRM, "NULL pointer");
 		mutex_unlock(&g_crm_core_dev->crm_lock);
@@ -2671,9 +2744,9 @@
 	CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);
 
 	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
-	root_dev.session_hdl = link_info->session_hdl;
+	root_dev.session_hdl = link_info->u.link_info_v1.session_hdl;
 	root_dev.priv = (void *)link;
-
+	root_dev.dev_id = CAM_CRM;
 	mutex_lock(&link->lock);
 	/* Create unique dev handle for link */
 	link->link_hdl = cam_create_device_hdl(&root_dev);
@@ -2683,12 +2756,12 @@
 		rc = link->link_hdl;
 		goto link_hdl_fail;
 	}
-	link_info->link_hdl = link->link_hdl;
+	link_info->u.link_info_v1.link_hdl = link->link_hdl;
 	link->last_flush_id = 0;
 
 	/* Allocate memory to hold data of all linked devs */
 	rc = __cam_req_mgr_create_subdevs(&link->l_dev,
-		link_info->num_devices);
+		link_info->u.link_info_v1.num_devices);
 	if (rc < 0) {
 		CAM_ERR(CAM_CRM,
 			"Insufficient memory to create new crm subdevs");
@@ -2706,7 +2779,7 @@
 
 	/* Create worker for current link */
 	snprintf(buf, sizeof(buf), "%x-%x",
-		link_info->session_hdl, link->link_hdl);
+		link_info->u.link_info_v1.session_hdl, link->link_hdl);
 	wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL;
 	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
 		&link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
@@ -2731,7 +2804,7 @@
 	__cam_req_mgr_destroy_subdev(link->l_dev);
 create_subdev_failed:
 	cam_destroy_device_hdl(link->link_hdl);
-	link_info->link_hdl = -1;
+	link_info->u.link_info_v1.link_hdl = -1;
 link_hdl_fail:
 	mutex_unlock(&link->lock);
 	__cam_req_mgr_unreserve_link(cam_session, link);
@@ -2739,6 +2812,116 @@
 	return rc;
 }
 
+int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
+{
+	int                                     rc = 0;
+	int                                     wq_flag = 0;
+	char                                    buf[128];
+	struct cam_create_dev_hdl               root_dev;
+	struct cam_req_mgr_core_session        *cam_session;
+	struct cam_req_mgr_core_link           *link;
+
+	if (!link_info) {
+		CAM_DBG(CAM_CRM, "NULL pointer");
+		return -EINVAL;
+	}
+	if (link_info->u.link_info_v2.num_devices >
+		CAM_REQ_MGR_MAX_HANDLES_V2) {
+		CAM_ERR(CAM_CRM, "Invalid num devices %d",
+			link_info->u.link_info_v2.num_devices);
+		return -EINVAL;
+	}
+
+	mutex_lock(&g_crm_core_dev->crm_lock);
+
+	/* session hdl's priv data is cam session struct */
+	cam_session = (struct cam_req_mgr_core_session *)
+		cam_get_device_priv(link_info->u.link_info_v2.session_hdl);
+	if (!cam_session) {
+		CAM_DBG(CAM_CRM, "NULL pointer");
+		mutex_unlock(&g_crm_core_dev->crm_lock);
+		return -EINVAL;
+	}
+
+	/* Allocate link struct and map it with session's request queue */
+	link = __cam_req_mgr_reserve_link(cam_session);
+	if (!link) {
+		CAM_ERR(CAM_CRM, "failed to reserve new link");
+		mutex_unlock(&g_crm_core_dev->crm_lock);
+		return -EINVAL;
+	}
+	CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);
+
+	memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
+	root_dev.session_hdl = link_info->u.link_info_v2.session_hdl;
+	root_dev.priv = (void *)link;
+
+	mutex_lock(&link->lock);
+	/* Create unique dev handle for link */
+	link->link_hdl = cam_create_device_hdl(&root_dev);
+	if (link->link_hdl < 0) {
+		CAM_ERR(CAM_CRM,
+			"Insufficient memory to create new device handle");
+		rc = link->link_hdl;
+		goto link_hdl_fail;
+	}
+	link_info->u.link_info_v2.link_hdl = link->link_hdl;
+	link->last_flush_id = 0;
+
+	/* Allocate memory to hold data of all linked devs */
+	rc = __cam_req_mgr_create_subdevs(&link->l_dev,
+		link_info->u.link_info_v2.num_devices);
+	if (rc < 0) {
+		CAM_ERR(CAM_CRM,
+			"Insufficient memory to create new crm subdevs");
+		goto create_subdev_failed;
+	}
+
+	/* Using device ops query connected devs, prepare request tables */
+	rc = __cam_req_mgr_setup_link_info(link, link_info);
+	if (rc < 0)
+		goto setup_failed;
+
+	spin_lock_bh(&link->link_state_spin_lock);
+	link->state = CAM_CRM_LINK_STATE_READY;
+	spin_unlock_bh(&link->link_state_spin_lock);
+
+	/* Create worker for current link */
+	snprintf(buf, sizeof(buf), "%x-%x",
+		link_info->u.link_info_v2.session_hdl, link->link_hdl);
+	wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL;
+	rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
+		&link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
+	if (rc < 0) {
+		CAM_ERR(CAM_CRM, "FATAL: unable to create worker");
+		__cam_req_mgr_destroy_link_info(link);
+		goto setup_failed;
+	}
+
+	/* Assign payload to workqueue tasks */
+	rc = __cam_req_mgr_setup_payload(link->workq);
+	if (rc < 0) {
+		__cam_req_mgr_destroy_link_info(link);
+		cam_req_mgr_workq_destroy(&link->workq);
+		goto setup_failed;
+	}
+
+	mutex_unlock(&link->lock);
+	mutex_unlock(&g_crm_core_dev->crm_lock);
+	return rc;
+setup_failed:
+	__cam_req_mgr_destroy_subdev(link->l_dev);
+create_subdev_failed:
+	cam_destroy_device_hdl(link->link_hdl);
+	link_info->u.link_info_v2.link_hdl = -1;
+link_hdl_fail:
+	mutex_unlock(&link->lock);
+	__cam_req_mgr_unreserve_link(cam_session, link);
+	mutex_unlock(&g_crm_core_dev->crm_lock);
+	return rc;
+}
+
+
 int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
 {
 	int                              rc = 0;
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
index 9bff66b..05fe086 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
@@ -36,6 +36,9 @@
 
 #define MAXIMUM_LINKS_PER_SESSION  4
 
+#define VERSION_1  1
+#define VERSION_2  2
+
 /**
  * enum crm_workq_task_type
  * @codes: to identify which type of task is present
@@ -233,12 +236,14 @@
  * @slot        : request slot holding incoming request id and bubble info.
  * @rd_idx      : indicates slot index currently in process.
  * @wr_idx      : indicates slot index to hold new upcoming req.
+ * @last_applied_idx : indicates slot index last applied successfully.
  */
 struct cam_req_mgr_req_queue {
 	int32_t                     num_slots;
 	struct cam_req_mgr_slot     slot[MAX_REQ_SLOTS];
 	int32_t                     rd_idx;
 	int32_t                     wr_idx;
+	int32_t                     last_applied_idx;
 };
 
 /**
@@ -411,7 +416,9 @@
  * a unique link handle for the link and is specific to a
  * session. Returns link handle
  */
-int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info);
+int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info);
+int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info);
+
 
 /**
  * cam_req_mgr_unlink()
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c
index 5cf1d84..31607ac 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  *
  * 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
@@ -268,27 +268,50 @@
 		break;
 
 	case CAM_REQ_MGR_LINK: {
-		struct cam_req_mgr_link_info link_info;
+		struct cam_req_mgr_ver_info ver_info;
 
-		if (k_ioctl->size != sizeof(link_info))
+		if (k_ioctl->size != sizeof(ver_info.u.link_info_v1))
 			return -EINVAL;
 
-		if (copy_from_user(&link_info,
+		if (copy_from_user(&ver_info.u.link_info_v1,
 			u64_to_user_ptr(k_ioctl->handle),
 			sizeof(struct cam_req_mgr_link_info))) {
 			return -EFAULT;
 		}
-
-		rc = cam_req_mgr_link(&link_info);
+		ver_info.version = VERSION_1;
+		rc = cam_req_mgr_link(&ver_info);
 		if (!rc)
 			if (copy_to_user(
 				u64_to_user_ptr(k_ioctl->handle),
-				&link_info,
+				&ver_info.u.link_info_v1,
 				sizeof(struct cam_req_mgr_link_info)))
 				rc = -EFAULT;
 		}
 		break;
 
+	case CAM_REQ_MGR_LINK_V2: {
+			struct cam_req_mgr_ver_info ver_info;
+
+			if (k_ioctl->size != sizeof(ver_info.u.link_info_v2))
+				return -EINVAL;
+
+			if (copy_from_user(&ver_info.u.link_info_v2,
+				u64_to_user_ptr(k_ioctl->handle),
+				sizeof(struct cam_req_mgr_link_info_v2))) {
+				return -EFAULT;
+			}
+			ver_info.version = VERSION_2;
+			rc = cam_req_mgr_link_v2(&ver_info);
+			if (!rc)
+				if (copy_to_user(
+					u64_to_user_ptr(k_ioctl->handle),
+					&ver_info.u.link_info_v2,
+					sizeof(struct
+						cam_req_mgr_link_info_v2)))
+					rc = -EFAULT;
+			}
+			break;
+
 	case CAM_REQ_MGR_UNLINK: {
 		struct cam_req_mgr_unlink_info unlink_info;
 
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c
index dda04f8..d531fdc 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  *
  * 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
@@ -128,6 +128,21 @@
 	return idx;
 }
 
+void cam_dump_tbl_info(void)
+{
+	int i;
+
+	for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES; i++)
+		CAM_INFO(CAM_CRM, "session_hdl=%x hdl_value=%x\n"
+			"type=%d state=%d dev_id=%lld",
+			hdl_tbl->hdl[i].session_hdl,
+			hdl_tbl->hdl[i].hdl_value,
+			hdl_tbl->hdl[i].type,
+			hdl_tbl->hdl[i].state,
+			hdl_tbl->hdl[i].dev_id);
+
+}
+
 int32_t cam_create_session_hdl(void *priv)
 {
 	int idx;
@@ -144,6 +159,7 @@
 	idx = cam_get_free_handle_index();
 	if (idx < 0) {
 		CAM_ERR(CAM_CRM, "Unable to create session handle");
+		cam_dump_tbl_info();
 		spin_unlock_bh(&hdl_tbl_lock);
 		return idx;
 	}
@@ -177,6 +193,7 @@
 	idx = cam_get_free_handle_index();
 	if (idx < 0) {
 		CAM_ERR(CAM_CRM, "Unable to create device handle");
+		cam_dump_tbl_info();
 		spin_unlock_bh(&hdl_tbl_lock);
 		return idx;
 	}
@@ -189,6 +206,7 @@
 	hdl_tbl->hdl[idx].state = HDL_ACTIVE;
 	hdl_tbl->hdl[idx].priv = hdl_data->priv;
 	hdl_tbl->hdl[idx].ops = hdl_data->ops;
+	hdl_tbl->hdl[idx].dev_id = hdl_data->dev_id;
 	spin_unlock_bh(&hdl_tbl_lock);
 
 	pr_debug("%s: handle = %x", __func__, handle);
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h
index 7b8e3e6..50d6f30 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  *
  * 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
@@ -50,6 +50,7 @@
 	uint32_t hdl_value;
 	enum hdl_type type;
 	enum hdl_state state;
+	uint64_t dev_id;
 	void *ops;
 	void *priv;
 };
@@ -80,6 +81,7 @@
 	int32_t v4l2_sub_dev_flag;
 	int32_t media_entity_flag;
 	int32_t reserved;
+	uint64_t dev_id;
 	void *ops;
 	void *priv;
 };
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c
index 1262db7..3837aac 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c
@@ -786,7 +786,7 @@
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = a_ctrl;
-
+		bridge_params.dev_id = CAM_ACTUATOR;
 		actuator_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);
 		a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c
index f41cb475..a06a4c6 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c
@@ -1094,7 +1094,7 @@
 		    * RD_DONE exclusively.
 		    */
 			rem_jiffies = wait_for_completion_timeout(
-			&cci_dev->cci_master_info[master].reset_complete,
+			&cci_dev->cci_master_info[master].rd_done,
 			CCI_TIMEOUT);
 			if (!rem_jiffies) {
 				rc = -ETIMEDOUT;
@@ -1275,10 +1275,11 @@
 	val = 1 << ((master * 2) + queue);
 	cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR);
 	CAM_DBG(CAM_CCI,
-		"waiting_for_rd_done [exp_words: %d]", exp_words);
+		"waiting_for_rd_done [exp_words: %d]",
+		((read_cfg->num_byte / 4) + 1));
 
 	rc = wait_for_completion_timeout(
-		&cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
+		&cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT);
 	if (rc <= 0) {
 #ifdef DUMP_CCI_REGISTERS
 		cam_cci_dump_registers(cci_dev, master, queue);
@@ -1692,14 +1693,19 @@
 	struct cam_cci_ctrl *cci_ctrl)
 {
 	int32_t rc = 0;
-
+	struct cci_device *cci_dev = v4l2_get_subdevdata(sd);
 	CAM_DBG(CAM_CCI, "cmd %d", cci_ctrl->cmd);
+
 	switch (cci_ctrl->cmd) {
 	case MSM_CCI_INIT:
+		mutex_lock(&cci_dev->init_mutex);
 		rc = cam_cci_init(sd, cci_ctrl);
+		mutex_unlock(&cci_dev->init_mutex);
 		break;
 	case MSM_CCI_RELEASE:
+		mutex_lock(&cci_dev->init_mutex);
 		rc = cam_cci_release(sd);
+		mutex_unlock(&cci_dev->init_mutex);
 		break;
 	case MSM_CCI_I2C_READ:
 		rc = cam_cci_read_bytes(sd, cci_ctrl);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c
index 7934aa5..69b5af0 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c
@@ -71,20 +71,26 @@
 
 	irq_status0 = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR);
 	irq_status1 = cam_io_r_mb(base + CCI_IRQ_STATUS_1_ADDR);
+	CAM_DBG(CAM_CCI, "BASE: %pK", base);
 	CAM_DBG(CAM_CCI, "irq0:%x irq1:%x", irq_status0, irq_status1);
 
 	if (irq_status0 & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) {
+		struct cam_cci_master_info *cci_master_info;
 		if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) {
+			cci_master_info = &cci_dev->cci_master_info[MASTER_0];
 			cci_dev->cci_master_info[MASTER_0].reset_pending =
 				FALSE;
-			complete(
-			&cci_dev->cci_master_info[MASTER_0].reset_complete);
+			if (!cci_master_info->status)
+				complete(&cci_master_info->reset_complete);
+			cci_master_info->status = 0;
 		}
 		if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) {
+			cci_master_info = &cci_dev->cci_master_info[MASTER_1];
 			cci_dev->cci_master_info[MASTER_1].reset_pending =
 				FALSE;
-			complete(
-			&cci_dev->cci_master_info[MASTER_1].reset_complete);
+			if (!cci_master_info->status)
+				complete(&cci_master_info->reset_complete);
+			cci_master_info->status = 0;
 		}
 	}
 
@@ -93,7 +99,7 @@
 		cci_dev->cci_master_info[MASTER_0].status = 0;
 		rd_done_th_assert = true;
 		complete(&cci_dev->cci_master_info[MASTER_0].th_complete);
-		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+		complete(&cci_dev->cci_master_info[MASTER_0].rd_done);
 	}
 	if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) &&
 		(!rd_done_th_assert)) {
@@ -102,7 +108,7 @@
 		if (cci_dev->is_burst_read)
 			complete(
 			&cci_dev->cci_master_info[MASTER_0].th_complete);
-		complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+		complete(&cci_dev->cci_master_info[MASTER_0].rd_done);
 	}
 	if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) &&
 		(!rd_done_th_assert)) {
@@ -149,7 +155,7 @@
 		cci_dev->cci_master_info[MASTER_1].status = 0;
 		rd_done_th_assert = true;
 		complete(&cci_dev->cci_master_info[MASTER_1].th_complete);
-		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+		complete(&cci_dev->cci_master_info[MASTER_1].rd_done);
 	}
 	if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) &&
 		(!rd_done_th_assert)) {
@@ -158,7 +164,7 @@
 		if (cci_dev->is_burst_read)
 			complete(
 			&cci_dev->cci_master_info[MASTER_1].th_complete);
-		complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+		complete(&cci_dev->cci_master_info[MASTER_1].rd_done);
 	}
 	if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) &&
 		(!rd_done_th_assert)) {
@@ -217,16 +223,33 @@
 	}
 	if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) {
 		cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
-		cam_io_w_mb(CCI_M0_HALT_REQ_RMSK,
-			base + CCI_HALT_REQ_ADDR);
-		CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq_status0);
+		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK)
+			CAM_ERR(CAM_CCI, "Base:%pK, M0 NACK ERROR: 0x%x",
+				base, irq_status0);
+		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK)
+			CAM_ERR(CAM_CCI,
+			"Base:%pK, M0 QUEUE_OVER/UNDER_FLOW OR CMD ERR: 0x%x",
+				base, irq_status0);
+		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK)
+			CAM_ERR(CAM_CCI,
+				"Base: %pK, M0 RD_OVER/UNDER_FLOW ERROR: 0x%x",
+				base, irq_status0);
+		cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR);
 	}
 	if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) {
 		cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
-		cam_io_w_mb(CCI_M1_HALT_REQ_RMSK,
-			base + CCI_HALT_REQ_ADDR);
-		CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0);
-
+		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK)
+			CAM_ERR(CAM_CCI, "Base:%pK, M1 NACK ERROR: 0x%x",
+				base, irq_status0);
+		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK)
+			CAM_ERR(CAM_CCI,
+			"Base:%pK, M1 QUEUE_OVER_UNDER_FLOW OR CMD ERROR:0x%x",
+				base, irq_status0);
+		if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK)
+			CAM_ERR(CAM_CCI,
+				"Base:%pK, M1 RD_OVER/UNDER_FLOW ERROR: 0x%x",
+				base, irq_status0);
+		cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR);
 	}
 
 	cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR);
@@ -402,7 +425,8 @@
 	}
 
 	g_cci_subdev[soc_info->index] = &new_cci_dev->v4l2_dev_str.sd;
-	CAM_ERR(CAM_CCI, "Device Type :%d", soc_info->index);
+	mutex_init(&(new_cci_dev->init_mutex));
+	CAM_INFO(CAM_CCI, "Device Type :%d", soc_info->index);
 
 	cam_register_subdev_fops(&cci_v4l2_subdev_fops);
 	cci_v4l2_subdev_fops.unlocked_ioctl = cam_cci_subdev_fops_ioctl;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h
index 349effc..54eed83 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h
@@ -140,6 +140,7 @@
 	uint8_t reset_pending;
 	struct mutex mutex;
 	struct completion reset_complete;
+	struct completion rd_done;
 	struct completion th_complete;
 	struct mutex mutex_q[NUM_QUEUES];
 	struct completion report_q[NUM_QUEUES];
@@ -171,41 +172,41 @@
 };
 
 /**
- * struct cci_device
- * @pdev: Platform device
- * @subdev: V4L2 sub device
- * @base: Base address of CCI device
- * @hw_version: Hardware version
- * @ref_count: Reference Count
- * @cci_state: CCI state machine
- * @num_clk: Number of CCI clock
- * @cci_clk: CCI clock structure
- * @cci_clk_info: CCI clock information
- * @cam_cci_i2c_queue_info: CCI queue information
- * @i2c_freq_mode: I2C frequency of operations
- * @cci_clk_params: CCI hw clk params
- * @cci_gpio_tbl: CCI GPIO table
- * @cci_gpio_tbl_size: GPIO table size
- * @cci_pinctrl: Pinctrl structure
- * @cci_pinctrl_status: CCI pinctrl status
- * @cci_clk_src: CCI clk src rate
- * @cci_vreg: CCI regulator structure
- * @cci_reg_ptr: CCI individual regulator structure
- * @regulator_count: Regulator count
- * @support_seq_write:
- *     Set this flag when sequential write is enabled
- * @write_wq: Work queue structure
- * @valid_sync: Is it a valid sync with CSID
- * @v4l2_dev_str: V4L2 device structure
- * @cci_wait_sync_cfg: CCI sync config
- * @cycles_per_us: Cycles per micro sec
- * @payload_size: CCI packet payload size
- * @irq_status1: Store irq_status1 to be cleared after
- *               draining FIFO buffer for burst read
- * @lock_status: to protect changes to irq_status1
- * @is_burst_read: Flag to determine if we are performing
- *                 a burst read operation or not
- * @irqs_disabled: Mask for IRQs that are disabled
+ * @pdev:                       Platform device
+ * @subdev:                     V4L2 sub device
+ * @base:                       Base address of CCI device
+ * @hw_version:                 Hardware version
+ * @ref_count:                  Reference Count
+ * @cci_state:                  CCI state machine
+ * @num_clk:                    Number of CCI clock
+ * @cci_clk:                    CCI clock structure
+ * @cci_clk_info:               CCI clock information
+ * @cam_cci_i2c_queue_info:     CCI queue information
+ * @i2c_freq_mode:              I2C frequency of operations
+ * @cci_clk_params:             CCI hw clk params
+ * @cci_gpio_tbl:               CCI GPIO table
+ * @cci_gpio_tbl_size:          GPIO table size
+ * @cci_pinctrl:                Pinctrl structure
+ * @cci_pinctrl_status:         CCI pinctrl status
+ * @cci_clk_src:                CCI clk src rate
+ * @cci_vreg:                   CCI regulator structure
+ * @cci_reg_ptr:                CCI individual regulator structure
+ * @regulator_count:            Regulator count
+ * @support_seq_write:          Set this flag when sequential write is enabled
+ * @write_wq:                   Work queue structure
+ * @valid_sync:                 Is it a valid sync with CSID
+ * @v4l2_dev_str:               V4L2 device structure
+ * @cci_wait_sync_cfg:          CCI sync config
+ * @cycles_per_us:              Cycles per micro sec
+ * @payload_size:               CCI packet payload size
+ * @irq_status1:                Store irq_status1 to be cleared after
+ *                              draining FIFO buffer for burst read
+ * @lock_status:                to protect changes to irq_status1
+ * @is_burst_read:              Flag to determine if we are performing
+ *                              a burst read operation or not
+ * @irqs_disabled:              Mask for IRQs that are disabled
+ * @init_mutex:                 Mutex for maintaining refcount for attached
+ *                              devices to cci during init/deinit.
  */
 struct cci_device {
 	struct v4l2_subdev subdev;
@@ -234,6 +235,7 @@
 	spinlock_t lock_status;
 	bool is_burst_read;
 	uint32_t irqs_disabled;
+	struct mutex init_mutex;
 };
 
 enum cam_cci_i2c_cmd_type {
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h
index 027a050..ead18af 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 2017-2019, The Linux Foundation. All rights reserved.
  *
  * 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
@@ -61,6 +61,12 @@
 #define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK                            0x10
 #define CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK                          0x18000EE6
 #define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK                          0x60EE6000
+#define CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK                     0x18000000
+#define CCI_IRQ_STATUS_0_I2C_M1_NACK_ERROR_BMSK                     0x60000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK                          0xEE0
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_ERROR_BMSK                       0xEE0000
+#define CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK                              0x6
+#define CCI_IRQ_STATUS_0_I2C_M1_RD_ERROR_BMSK                           0x6000
 #define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK                               0x1
 #define CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD                           0x10000
 #define CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE                               0x20000
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
index fa290c0..0181a4d 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
@@ -19,7 +19,7 @@
 	uint8_t i = 0, j = 0;
 	int32_t rc = 0;
 	struct cci_device *cci_dev;
-	enum cci_i2c_master_t master = MASTER_0;
+	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
 	struct cam_ahb_vote ahb_vote;
 	struct cam_axi_vote axi_vote;
 	struct cam_hw_soc_info *soc_info = NULL;
@@ -47,7 +47,6 @@
 
 	if (cci_dev->ref_count++) {
 		CAM_DBG(CAM_CCI, "ref_count %d", cci_dev->ref_count);
-		master = c_ctrl->cci_info->cci_i2c_master;
 		CAM_DBG(CAM_CCI, "master %d", master);
 		if (master < MASTER_MAX && master >= 0) {
 			mutex_lock(&cci_dev->cci_master_info[master].mutex);
@@ -55,6 +54,8 @@
 			/* Re-initialize the completion */
 			reinit_completion(
 			&cci_dev->cci_master_info[master].reset_complete);
+			reinit_completion(
+			&cci_dev->cci_master_info[master].rd_done);
 			for (i = 0; i < NUM_QUEUES; i++)
 				reinit_completion(
 				&cci_dev->cci_master_info[master].report_q[i]);
@@ -93,6 +94,7 @@
 
 	/* Re-initialize the completion */
 	reinit_completion(&cci_dev->cci_master_info[master].reset_complete);
+	reinit_completion(&cci_dev->cci_master_info[master].rd_done);
 	for (i = 0; i < NUM_QUEUES; i++)
 		reinit_completion(
 			&cci_dev->cci_master_info[master].report_q[i]);
@@ -128,12 +130,12 @@
 		}
 	}
 
-	cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
+	cci_dev->cci_master_info[master].reset_pending = TRUE;
 	cam_io_w_mb(CCI_RESET_CMD_RMSK, base +
 			CCI_RESET_CMD_ADDR);
 	cam_io_w_mb(0x1, base + CCI_RESET_CMD_ADDR);
 	rc = wait_for_completion_timeout(
-		&cci_dev->cci_master_info[MASTER_0].reset_complete,
+		&cci_dev->cci_master_info[master].reset_complete,
 		CCI_TIMEOUT);
 	if (rc <= 0) {
 		CAM_ERR(CAM_CCI, "wait_for_completion_timeout");
@@ -205,6 +207,8 @@
 			&new_cci_dev->cci_master_info[i].reset_complete);
 		init_completion(
 			&new_cci_dev->cci_master_info[i].th_complete);
+		init_completion(
+			&new_cci_dev->cci_master_info[i].rd_done);
 
 		for (j = 0; j < NUM_QUEUES; j++) {
 			mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 318ea55..8074ecd 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -725,7 +725,7 @@
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = csiphy_dev;
-
+		bridge_params.dev_id = CAM_CSIPHY;
 		if (csiphy_acq_params.combo_mode >= 2) {
 			CAM_ERR(CAM_CSIPHY, "Invalid combo_mode %d",
 				csiphy_acq_params.combo_mode);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
index 67653e8..edde070 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
@@ -21,7 +21,7 @@
 	.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
 	.csiphy_common_array_size = 6,
 	.csiphy_reset_array_size = 5,
-	.csiphy_2ph_config_array_size = 21,
+	.csiphy_2ph_config_array_size = 22,
 	.csiphy_3ph_config_array_size = 38,
 	.csiphy_2ph_clock_lane = 0x1,
 	.csiphy_2ph_combo_ck_ln = 0x10,
@@ -78,10 +78,11 @@
 		{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
 		{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -105,6 +106,7 @@
 		{0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
 		{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -128,6 +130,7 @@
 		{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
 		{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -151,6 +154,7 @@
 		{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 	{
 		{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -174,6 +178,7 @@
 		{0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
 	},
 };
 
@@ -197,10 +202,11 @@
 		{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
-		{0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
 		{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 	},
 	{
 		{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -224,6 +230,7 @@
 		{0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 	},
 	{
 		{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -247,6 +254,7 @@
 		{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 	},
 	{
 		{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -270,6 +278,7 @@
 		{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 		{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 	},
 	{
 		{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -293,6 +302,7 @@
 		{0x060c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
 		{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
 	},
 };
 
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
index a04d971..8f59ca3 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
@@ -357,7 +357,7 @@
 	bridge_params.v4l2_sub_dev_flag = 0;
 	bridge_params.media_entity_flag = 0;
 	bridge_params.priv = e_ctrl;
-
+	bridge_params.dev_id = CAM_EEPROM;
 	eeprom_acq_dev.device_handle =
 		cam_create_device_hdl(&bridge_params);
 	e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h
index 7ffafc3..9c36134 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h
@@ -35,7 +35,7 @@
 #define PROPERTY_MAXSIZE 32
 
 #define MSM_EEPROM_MEMORY_MAP_MAX_SIZE         80
-#define MSM_EEPROM_MAX_MEM_MAP_CNT             8
+#define MSM_EEPROM_MAX_MEM_MAP_CNT             16
 #define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT      8
 
 enum cam_eeprom_state {
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c
index 1a0edb8..f4c9d25 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c
@@ -71,7 +71,7 @@
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = fctrl;
-
+		bridge_params.dev_id = CAM_FLASH;
 		flash_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);
 		fctrl->bridge_intf.device_hdl =
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c
index a5c7039..711077c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c
@@ -90,7 +90,7 @@
 	bridge_params.v4l2_sub_dev_flag = 0;
 	bridge_params.media_entity_flag = 0;
 	bridge_params.priv = o_ctrl;
-
+	bridge_params.dev_id = CAM_OIS;
 	ois_acq_dev.device_handle =
 		cam_create_device_hdl(&bridge_params);
 	o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 111f121..a2a738d 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -776,7 +776,7 @@
 		bridge_params.v4l2_sub_dev_flag = 0;
 		bridge_params.media_entity_flag = 0;
 		bridge_params.priv = s_ctrl;
-
+		bridge_params.dev_id = CAM_SENSOR;
 		sensor_acq_dev.device_handle =
 			cam_create_device_hdl(&bridge_params);
 		s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
index d3f62d6..d4487ef 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
@@ -29,6 +29,20 @@
  */
 static bool trigger_cb_without_switch;
 
+void cam_sync_print_fence_table(void)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < CAM_SYNC_MAX_OBJS; cnt++) {
+		CAM_INFO(CAM_SYNC, "%d, %s, %d, %d, %d",
+			sync_dev->sync_table[cnt].sync_id,
+			sync_dev->sync_table[cnt].name,
+			sync_dev->sync_table[cnt].type,
+			sync_dev->sync_table[cnt].state,
+			atomic_read(&sync_dev->sync_table[cnt].ref_cnt));
+	}
+}
+
 int cam_sync_create(int32_t *sync_obj, const char *name)
 {
 	int rc;
@@ -37,8 +51,15 @@
 
 	do {
 		idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
-		if (idx >= CAM_SYNC_MAX_OBJS)
+		if (idx >= CAM_SYNC_MAX_OBJS) {
+			CAM_ERR(CAM_SYNC,
+				"Error: Unable to Create Sync Idx = %ld Reached Max!!",
+				idx);
+			sync_dev->err_cnt++;
+			if (sync_dev->err_cnt == 1)
+				cam_sync_print_fence_table();
 			return -ENOMEM;
+		}
 		CAM_DBG(CAM_SYNC, "Index location available at idx: %ld", idx);
 		bit = test_and_set_bit(idx, sync_dev->bitmap);
 	} while (bit);
@@ -765,6 +786,7 @@
 		CAM_ERR(CAM_SYNC, "Sync device NULL");
 		return -ENODEV;
 	}
+	sync_dev->err_cnt = 0;
 
 	mutex_lock(&sync_dev->table_lock);
 	if (sync_dev->open_cnt >= 1) {
@@ -797,6 +819,7 @@
 		rc = -ENODEV;
 		return rc;
 	}
+	sync_dev->err_cnt = 0;
 	mutex_lock(&sync_dev->table_lock);
 	sync_dev->open_cnt--;
 	if (!sync_dev->open_cnt) {
@@ -972,6 +995,7 @@
 	if (!sync_dev)
 		return -ENOMEM;
 
+	sync_dev->err_cnt = 0;
 	mutex_init(&sync_dev->table_lock);
 	spin_lock_init(&sync_dev->cam_sync_eventq_lock);
 
diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h
index eb2fb34..c3cb345 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  *
  * 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
@@ -184,6 +184,7 @@
  * @work_queue      : Work queue used for dispatching kernel callbacks
  * @cam_sync_eventq : Event queue used to dispatch user payloads to user space
  * @bitmap          : Bitmap representation of all sync objects
+ * @err_cnt         : Error counter to dump fence table
  */
 struct sync_device {
 	struct video_device *vdev;
@@ -197,6 +198,7 @@
 	struct v4l2_fh *cam_sync_eventq;
 	spinlock_t cam_sync_eventq_lock;
 	DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS);
+	int err_cnt;
 };
 
 
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
index f3af619..36e6e1c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
@@ -77,7 +77,7 @@
 static char debugfs_dir_name[64];
 
 static int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info,
-	int32_t src_clk_idx, int32_t clk_rate)
+	int32_t src_clk_idx, int64_t clk_rate)
 {
 	int i;
 	long clk_rate_round;
@@ -92,7 +92,7 @@
 	for (i = 0; i < CAM_MAX_VOTE; i++) {
 		if (soc_info->clk_rate[i][src_clk_idx] >= clk_rate_round) {
 			CAM_DBG(CAM_UTIL,
-				"soc = %d round rate = %ld actual = %d",
+				"soc = %d round rate = %ld actual = %lld",
 				soc_info->clk_rate[i][src_clk_idx],
 				clk_rate_round,	clk_rate);
 			return i;
@@ -441,7 +441,7 @@
  * @return:         Success or failure
  */
 static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name,
-	int32_t clk_rate)
+	int64_t clk_rate)
 {
 	int rc = 0;
 	long clk_rate_round;
@@ -449,7 +449,7 @@
 	if (!clk || !clk_name)
 		return -EINVAL;
 
-	CAM_DBG(CAM_UTIL, "set %s, rate %d", clk_name, clk_rate);
+	CAM_DBG(CAM_UTIL, "set %s, rate %lld", clk_name, clk_rate);
 	if (clk_rate > 0) {
 		clk_rate_round = clk_round_rate(clk, clk_rate);
 		CAM_DBG(CAM_UTIL, "new_rate %ld", clk_rate_round);
@@ -485,7 +485,7 @@
 }
 
 int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info,
-	int32_t clk_rate)
+	int64_t clk_rate)
 {
 	int32_t src_clk_idx;
 	struct clk *clk = NULL;
@@ -506,7 +506,7 @@
 	if (soc_info->cam_cx_ipeak_enable && clk_rate >= 0) {
 		apply_level = cam_soc_util_get_clk_level(soc_info, src_clk_idx,
 				clk_rate);
-		CAM_DBG(CAM_UTIL, "set %s, rate %d dev_name = %s\n"
+		CAM_DBG(CAM_UTIL, "set %s, rate %lld dev_name = %s\n"
 			"apply level = %d",
 			soc_info->clk_name[src_clk_idx], clk_rate,
 			soc_info->dev_name, apply_level);
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h
index ee07f0e..859fee7 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h
@@ -397,7 +397,7 @@
  * @return:             success or failure
  */
 int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info,
-	int32_t clk_rate);
+	int64_t clk_rate);
 
 /**
  * cam_soc_util_get_option_clk_by_name()
diff --git a/include/uapi/media/cam_cpas.h b/include/uapi/media/cam_cpas.h
index c5cbac8..371b74c 100644
--- a/include/uapi/media/cam_cpas.h
+++ b/include/uapi/media/cam_cpas.h
@@ -6,6 +6,40 @@
 #define CAM_FAMILY_CAMERA_SS     1
 #define CAM_FAMILY_CPAS_SS       2
 
+/* AXI BW Voting Version */
+#define CAM_AXI_BW_VOTING_V2                2
+
+/* AXI BW Voting Transaction Type */
+#define CAM_AXI_TRANSACTION_READ            0
+#define CAM_AXI_TRANSACTION_WRITE           1
+
+/* AXI BW Voting Path Data Type */
+#define CAM_AXI_PATH_DATA_IFE_START_OFFSET 0
+#define CAM_AXI_PATH_DATA_IFE_LINEAR    (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 0)
+#define CAM_AXI_PATH_DATA_IFE_VID       (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 1)
+#define CAM_AXI_PATH_DATA_IFE_DISP      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 2)
+#define CAM_AXI_PATH_DATA_IFE_STATS     (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 3)
+#define CAM_AXI_PATH_DATA_IFE_RDI0      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 4)
+#define CAM_AXI_PATH_DATA_IFE_RDI1      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 5)
+#define CAM_AXI_PATH_DATA_IFE_RDI2      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 6)
+#define CAM_AXI_PATH_DATA_IFE_RDI3      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 7)
+#define CAM_AXI_PATH_DATA_IFE_PDAF      (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 8)
+#define CAM_AXI_PATH_DATA_IFE_PIXEL_RAW \
+	(CAM_AXI_PATH_DATA_IFE_START_OFFSET + 9)
+#define CAM_AXI_PATH_DATA_IFE_MAX_OFFSET \
+	(CAM_AXI_PATH_DATA_IFE_START_OFFSET + 31)
+
+#define CAM_AXI_PATH_DATA_IPE_START_OFFSET 32
+#define CAM_AXI_PATH_DATA_IPE_RD_IN     (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 0)
+#define CAM_AXI_PATH_DATA_IPE_RD_REF    (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 1)
+#define CAM_AXI_PATH_DATA_IPE_WR_VID    (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 2)
+#define CAM_AXI_PATH_DATA_IPE_WR_DISP   (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 3)
+#define CAM_AXI_PATH_DATA_IPE_WR_REF    (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 4)
+#define CAM_AXI_PATH_DATA_IPE_MAX_OFFSET \
+	(CAM_AXI_PATH_DATA_IPE_START_OFFSET + 31)
+
+#define CAM_AXI_PATH_DATA_ALL              256
+
 /**
  * struct cam_cpas_query_cap - CPAS query device capability payload
  *
@@ -22,4 +56,29 @@
 	struct cam_hw_version    cpas_version;
 };
 
+/**
+ * struct cam_axi_per_path_bw_vote - Per path bandwidth vote information
+ *
+ * @usage_data               client usage data (left/right/rdi)
+ * @transac_type             Transaction type on the path (read/write)
+ * @path_data_type           Path for which vote is given (video, display, rdi)
+ * @reserved                 Reserved for alignment
+ * @camnoc_bw                CAMNOC bw for this path
+ * @mnoc_ab_bw               MNOC AB bw for this path
+ * @mnoc_ib_bw               MNOC IB bw for this path
+ * @ddr_ab_bw                DDR AB bw for this path
+ * @ddr_ib_bw                DDR IB bw for this path
+ */
+struct cam_axi_per_path_bw_vote {
+	uint32_t                      usage_data;
+	uint32_t                      transac_type;
+	uint32_t                      path_data_type;
+	uint32_t                      reserved;
+	uint64_t                      camnoc_bw;
+	uint64_t                      mnoc_ab_bw;
+	uint64_t                      mnoc_ib_bw;
+	uint64_t                      ddr_ab_bw;
+	uint64_t                      ddr_ib_bw;
+};
+
 #endif /* __UAPI_CAM_CPAS_H__ */
diff --git a/include/uapi/media/cam_icp.h b/include/uapi/media/cam_icp.h
index f2c1c91..5b4a604 100644
--- a/include/uapi/media/cam_icp.h
+++ b/include/uapi/media/cam_icp.h
@@ -2,6 +2,7 @@
 #define __UAPI_CAM_ICP_H__
 
 #include "cam_defs.h"
+#include "cam_cpas.h"
 
 /* icp, ipe, bps, cdm(ipe/bps) are used in querycap */
 #define CAM_ICP_DEV_TYPE_A5      1
@@ -66,6 +67,26 @@
 #define CAM_ICP_CMD_GENERIC_BLOB_CFG_IO         0x2
 #define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_MAP     0x3
 #define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_UNMAP   0x4
+#define CAM_ICP_CMD_GENERIC_BLOB_CLK_V2         0x5
+
+/**
+ * struct cam_icp_clk_bw_request_v2
+ *
+ * @budget_ns: Time required to process frame
+ * @frame_cycles: Frame cycles needed to process the frame
+ * @rt_flag: Flag to indicate real time stream
+ * @reserved: For memory alignment
+ * @num_paths: Number of axi paths in bw request
+ * @axi_path: Per path vote info for IPE/BPS
+ */
+struct cam_icp_clk_bw_request_v2 {
+	uint64_t                          budget_ns;
+	uint32_t                          frame_cycles;
+	uint32_t                          rt_flag;
+	uint32_t                          reserved;
+	uint32_t                          num_paths;
+	struct cam_axi_per_path_bw_vote   axi_path[1];
+};
 
 /**
  * struct cam_icp_clk_bw_request
diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h
index 995d6ec..7489b72 100644
--- a/include/uapi/media/cam_isp.h
+++ b/include/uapi/media/cam_isp.h
@@ -4,7 +4,7 @@
 #include "cam_defs.h"
 #include "cam_isp_vfe.h"
 #include "cam_isp_ife.h"
-
+#include "cam_cpas.h"
 
 /* ISP driver name */
 #define CAM_ISP_DEV_NAME                        "cam-isp"
@@ -91,6 +91,13 @@
 #define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG   4
 #define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG           5
 #define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2        6
+#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP     10
+
+/* Per Path Usage Data */
+#define CAM_ISP_USAGE_INVALID     0
+#define CAM_ISP_USAGE_LEFT_PX     1
+#define CAM_ISP_USAGE_RIGHT_PX    2
+#define CAM_ISP_USAGE_RDI         3
 
 /* Query devices */
 /**
@@ -362,7 +369,6 @@
  * @cam_bw_bps:                 Bandwidth vote for CAMNOC
  * @ext_bw_bps:                 Bandwidth vote for path-to-DDR after CAMNOC
  */
-
 struct cam_isp_bw_vote {
 	uint32_t                       resource_id;
 	uint32_t                       reserved;
@@ -379,7 +385,6 @@
  * @right_pix_vote:             Bandwidth vote for right ISP
  * @rdi_vote:                   RDI bandwidth requirements
  */
-
 struct cam_isp_bw_config {
 	uint32_t                       usage_type;
 	uint32_t                       num_rdi;
@@ -408,6 +413,19 @@
 } __attribute__((packed));
 
 /**
+ * struct cam_isp_bw_config_v2 - Bandwidth configuration
+ *
+ * @usage_type:                 Usage type (Single/Dual)
+ * @num_paths:                  Number of axi data paths
+ * @axi_path                    Per path vote info
+ */
+struct cam_isp_bw_config_v2 {
+	uint32_t                             usage_type;
+	uint32_t                             num_paths;
+	struct cam_axi_per_path_bw_vote      axi_path[1];
+} __attribute__((packed));
+
+/**
  * struct cam_fe_config - Fetch Engine configuration
  *
  * @version:                    fetch engine veriosn
@@ -479,4 +497,14 @@
 
 #define CAM_ISP_ACQUIRE_OUT_VER0            0x3000
 
+/**
+ * struct cam_isp_init_frame_drop_config - init frame drop configuration
+ *
+ * @init_frame_drop:            Initial number of frames needs to drop
+ */
+
+struct cam_isp_init_frame_drop_config {
+	uint32_t                       init_frame_drop;
+} __attribute__((packed));
+
 #endif /* __UAPI_CAM_ISP_H__ */
diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h
index 5341d62..defed87 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -36,6 +36,7 @@
  * It includes both session and device handles
  */
 #define CAM_REQ_MGR_MAX_HANDLES           64
+#define CAM_REQ_MGR_MAX_HANDLES_V2        128
 #define MAX_LINKS_PER_SESSION             2
 
 /* V4L event type which user space will subscribe to */
@@ -122,6 +123,20 @@
 	int32_t link_hdl;
 };
 
+struct cam_req_mgr_link_info_v2 {
+	int32_t session_hdl;
+	uint32_t num_devices;
+	int32_t dev_hdls[CAM_REQ_MGR_MAX_HANDLES_V2];
+	int32_t link_hdl;
+};
+
+struct cam_req_mgr_ver_info {
+	uint32_t version;
+	union {
+		struct cam_req_mgr_link_info link_info_v1;
+		struct cam_req_mgr_link_info_v2 link_info_v2;
+	} u;
+};
 /**
  * struct cam_req_mgr_unlink_info
  * @session_hdl: input param - session handle
@@ -231,6 +246,7 @@
 #define CAM_REQ_MGR_RELEASE_BUF                 (CAM_COMMON_OPCODE_MAX + 11)
 #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)
 /* end of cam_req_mgr opcodes */
 
 #define CAM_MEM_FLAG_HW_READ_WRITE              (1<<0)