浏览代码

Merge "msm: camera: cpas: Remove votes on enable_soc failure" into camera-kernel.lnx.4.0

Camera Software Integration 5 年之前
父节点
当前提交
8c135cd610
共有 1 个文件被更改,包括 36 次插入8 次删除
  1. 36 8
      drivers/cam_cpas/cam_cpas_hw.c

+ 36 - 8
drivers/cam_cpas/cam_cpas_hw.c

@@ -1132,6 +1132,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 	struct cam_cpas_hw_cmd_start *cmd_hw_start;
 	struct cam_cpas_client *cpas_client;
 	struct cam_ahb_vote *ahb_vote;
+	struct cam_ahb_vote remove_ahb;
 	struct cam_axi_vote axi_vote = {0};
 	enum cam_vote_level applied_level = CAM_SVS_VOTE;
 	int rc, i = 0;
@@ -1193,7 +1194,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 		CAM_ERR(CAM_CPAS, "client=[%d] is not registered",
 			client_indx);
 		rc = -EPERM;
-		goto done;
+		goto error;
 	}
 
 	if (CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
@@ -1201,7 +1202,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 			client_indx, cpas_client->data.identifier,
 			cpas_client->data.cell_index);
 		rc = -EPERM;
-		goto done;
+		goto error;
 	}
 
 	CAM_DBG(CAM_CPAS,
@@ -1212,7 +1213,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 	rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client,
 		ahb_vote, &applied_level);
 	if (rc)
-		goto done;
+		goto error;
 
 	cam_cpas_dump_axi_vote_info(cpas_client, "CPAS Start Vote",
 		&axi_vote);
@@ -1233,7 +1234,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 	if (rc) {
 		CAM_ERR(CAM_CPAS, "Unable to create or translate paths rc: %d",
 			rc);
-		goto done;
+		goto remove_ahb_vote;
 	}
 
 	cam_cpas_dump_axi_vote_info(cpas_client, "CPAS Start Translated Vote",
@@ -1242,7 +1243,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
 		cpas_client, &axi_vote);
 	if (rc)
-		goto done;
+		goto remove_ahb_vote;
 
 	if (cpas_core->streamon_clients == 0) {
 		atomic_set(&cpas_core->irq_count, 1);
@@ -1251,7 +1252,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 		if (rc) {
 			atomic_set(&cpas_core->irq_count, 0);
 			CAM_ERR(CAM_CPAS, "enable_resorce failed, rc=%d", rc);
-			goto done;
+			goto remove_axi_vote;
 		}
 
 		if (cpas_core->internal_ops.power_on) {
@@ -1263,7 +1264,7 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 				CAM_ERR(CAM_CPAS,
 					"failed in power_on settings rc=%d",
 					rc);
-				goto done;
+				goto remove_axi_vote;
 			}
 		}
 		CAM_DBG(CAM_CPAS, "irq_count=%d\n",
@@ -1277,7 +1278,34 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
 	CAM_DBG(CAM_CPAS, "client=[%d][%s][%d] streamon_clients=%d",
 		client_indx, cpas_client->data.identifier,
 		cpas_client->data.cell_index, cpas_core->streamon_clients);
-done:
+
+	mutex_unlock(&cpas_core->client_mutex[client_indx]);
+	mutex_unlock(&cpas_hw->hw_mutex);
+	return rc;
+
+remove_axi_vote:
+	memset(&axi_vote, 0x0, sizeof(struct cam_axi_vote));
+	rc = cam_cpas_util_create_vote_all_paths(cpas_client, &axi_vote);
+	if (rc)
+		CAM_ERR(CAM_CPAS, "Unable to create per path votes rc: %d", rc);
+
+	cam_cpas_dump_axi_vote_info(cpas_client, "CPAS Start fail Vote",
+		&axi_vote);
+
+	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
+		cpas_client, &axi_vote);
+	if (rc)
+		CAM_ERR(CAM_CPAS, "Unable remove votes rc: %d", rc);
+
+remove_ahb_vote:
+	remove_ahb.type = CAM_VOTE_ABSOLUTE;
+	remove_ahb.vote.level = CAM_SUSPEND_VOTE;
+	rc = cam_cpas_util_apply_client_ahb_vote(cpas_hw, cpas_client,
+		&remove_ahb, NULL);
+	if (rc)
+		CAM_ERR(CAM_CPAS, "Removing AHB vote failed, rc=%d", rc);
+
+error:
 	mutex_unlock(&cpas_core->client_mutex[client_indx]);
 	mutex_unlock(&cpas_hw->hw_mutex);
 	return rc;