瀏覽代碼

disp: msm: dp: clear connected state if switch config fails

During HPD High, the driver sets the CONNECTED state and then performs
a sequence of initialization operations. If any of them fails, it should
properly unwind the executed operations to restore the driver to its
initial state. This change adds error handling paths in the hpd high
handler to do just that.

Change-Id: I66a77ff73b7c11d0a59d80b8df3c4ea49a4ed3a6
Signed-off-by: Rajkumar Subbiah <[email protected]>
Rajkumar Subbiah 2 年之前
父節點
當前提交
2d4c6cf994
共有 1 個文件被更改,包括 23 次插入19 次删除
  1. 23 19
      msm/dp/dp_display.c

+ 23 - 19
msm/dp/dp_display.c

@@ -1204,7 +1204,7 @@ static void dp_display_host_deinit(struct dp_display_private *dp)
 static int dp_display_process_hpd_high(struct dp_display_private *dp)
 {
 	int rc = -EINVAL;
-	unsigned long wait_timeout_ms;
+	unsigned long wait_timeout_ms = 0;
 	unsigned long t;
 
 	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY, dp->state);
@@ -1224,10 +1224,8 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
 	if (!dp->debug->sim_mode && !dp->no_aux_switch && !dp->parser->gpio_aux_switch
 			&& dp->aux_switch_node && dp->aux->switch_configure) {
 		rc = dp->aux->switch_configure(dp->aux, true, dp->hpd->orientation);
-		if (rc) {
-			mutex_unlock(&dp->session_lock);
-			return rc;
-		}
+		if (rc)
+			goto err_state;
 	}
 
 	/*
@@ -1255,7 +1253,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
 				 */
 				dp_display_state_remove(DP_STATE_CONNECTED);
 			}
-			goto end;
+			goto err_unlock;
 		}
 
 		/*
@@ -1269,14 +1267,14 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
 	rc = dp_display_host_ready(dp);
 	if (rc) {
 		dp_display_state_show("[ready failed]");
-		goto end;
+		goto err_state;
 	}
 
 	dp->link->psm_config(dp->link, &dp->panel->link_info, false);
 	dp->debug->psm_enabled = false;
 
 	if (!dp->dp_display.base_connector)
-		goto end;
+		goto err_unready;
 
 	rc = dp->panel->read_sink_caps(dp->panel,
 			dp->dp_display.base_connector, dp->hpd->multi_func);
@@ -1284,10 +1282,8 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
 	 * ETIMEDOUT --> cable may have been removed
 	 * ENOTCONN --> no downstream device connected
 	 */
-	if (rc == -ETIMEDOUT || rc == -ENOTCONN) {
-		dp_display_state_remove(DP_STATE_CONNECTED);
-		goto end;
-	}
+	if (rc == -ETIMEDOUT || rc == -ENOTCONN)
+		goto err_unready;
 
 	dp->link->process_request(dp->link);
 	dp->panel->handle_sink_request(dp->panel);
@@ -1296,15 +1292,13 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp)
 
 	rc = dp->ctrl->on(dp->ctrl, dp->mst.mst_active,
 			dp->panel->fec_en, dp->panel->dsc_en, false);
-	if (rc) {
-		dp_display_state_remove(DP_STATE_CONNECTED);
-		goto end;
-	}
+	if (rc)
+		goto err_mst;
 
 	dp->process_hpd_connect = false;
 
 	dp_display_set_mst_mgr_state(dp, true);
-end:
+
 	mutex_unlock(&dp->session_lock);
 
 	/*
@@ -1337,13 +1331,23 @@ end:
 		(work_busy(&dp->attention_work) == WORK_BUSY_PENDING)) {
 		SDE_EVT32_EXTERNAL(dp->state, 99, jiffies_to_msecs(t));
 		DP_DEBUG("Attention pending, skip HPD notification\n");
-		goto skip_notify;
+		goto end;
 	}
 
 	if (!rc && !dp_display_state_is(DP_STATE_ABORTED))
 		dp_display_send_hpd_notification(dp, false);
 
-skip_notify:
+	goto end;
+
+err_mst:
+	dp_display_update_mst_state(dp, false);
+err_unready:
+	dp_display_host_unready(dp);
+err_state:
+	dp_display_state_remove(DP_STATE_CONNECTED);
+err_unlock:
+	mutex_unlock(&dp->session_lock);
+end:
 	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, dp->state,
 		wait_timeout_ms, rc);
 	return rc;