Browse Source

Merge "disp: msm: dp: move fsa init from dp probe to dp hotplug"

qctecmdr 3 years ago
parent
commit
e8a4a92814
1 changed files with 60 additions and 49 deletions
  1. 60 49
      msm/dp/dp_display.c

+ 60 - 49
msm/dp/dp_display.c

@@ -163,6 +163,7 @@ struct dp_display_private {
 
 	struct platform_device *pdev;
 	struct device_node *aux_switch_node;
+	bool aux_switch_ready;
 	struct dp_aux_bridge *aux_bridge;
 	struct dentry *root;
 	struct completion notification_comp;
@@ -1324,6 +1325,55 @@ static int dp_display_process_hpd_low(struct dp_display_private *dp)
 	return rc;
 }
 
+static int dp_display_fsa4480_callback(struct notifier_block *self,
+		unsigned long event, void *data)
+{
+	return 0;
+}
+
+static int dp_display_init_aux_switch(struct dp_display_private *dp)
+{
+	int rc = 0;
+	struct notifier_block nb;
+	const u32 max_retries = 50;
+	u32 retry;
+
+	if (dp->aux_switch_ready)
+	       return rc;
+
+	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY);
+
+	nb.notifier_call = dp_display_fsa4480_callback;
+	nb.priority = 0;
+
+	/*
+	 * Iteratively wait for reg notifier which confirms that fsa driver is probed.
+	 * Bootup DP with cable connected usecase can hit this scenario.
+	 */
+	for (retry = 0; retry < max_retries; retry++) {
+		rc = fsa4480_reg_notifier(&nb, dp->aux_switch_node);
+		if (rc == 0) {
+			DP_DEBUG("registered notifier successfully\n");
+			dp->aux_switch_ready = true;
+			break;
+		} else {
+			DP_DEBUG("failed to register notifier retry=%d rc=%d\n", retry, rc);
+			msleep(100);
+		}
+	}
+
+	if (retry == max_retries) {
+		DP_WARN("Failed to register fsa notifier\n");
+		dp->aux_switch_ready = false;
+		return rc;
+	}
+
+	fsa4480_unreg_notifier(&nb, dp->aux_switch_node);
+
+	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, rc);
+	return rc;
+}
+
 static int dp_display_usbpd_configure_cb(struct device *dev)
 {
 	int rc = 0;
@@ -1341,7 +1391,11 @@ static int dp_display_usbpd_configure_cb(struct device *dev)
 	}
 
 	if (!dp->debug->sim_mode && !dp->parser->no_aux_switch
-	    && !dp->parser->gpio_aux_switch) {
+	    && !dp->parser->gpio_aux_switch && dp->aux_switch_node) {
+		rc = dp_display_init_aux_switch(dp);
+		if (rc)
+			return rc;
+
 		rc = dp->aux->aux_switch(dp->aux, true, dp->hpd->orientation);
 		if (rc)
 			return rc;
@@ -1896,6 +1950,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
 	int rc = 0;
 	u32 dp_core_revision = 0;
 	bool hdcp_disabled;
+	const char *phandle = "qcom,dp-aux-switch";
 	struct device *dev = &dp->pdev->dev;
 	struct dp_hpd_cb *cb = &dp->hpd_cb;
 	struct dp_ctrl_in ctrl_in = {
@@ -1940,6 +1995,10 @@ static int dp_init_sub_modules(struct dp_display_private *dp)
 
 	dp_core_revision = dp_catalog_get_dp_core_version(dp->catalog);
 
+	dp->aux_switch_node = of_parse_phandle(dp->pdev->dev.of_node, phandle, 0);
+	if (!dp->aux_switch_node)
+		DP_DEBUG("cannot parse %s handle\n", phandle);
+
 	dp->aux = dp_aux_get(dev, &dp->catalog->aux, dp->parser,
 			dp->aux_switch_node, dp->aux_bridge);
 	if (IS_ERR(dp->aux)) {
@@ -3047,48 +3106,6 @@ static int dp_display_create_workqueue(struct dp_display_private *dp)
 	return 0;
 }
 
-static int dp_display_fsa4480_callback(struct notifier_block *self,
-		unsigned long event, void *data)
-{
-	return 0;
-}
-
-static int dp_display_init_aux_switch(struct dp_display_private *dp)
-{
-	int rc = 0;
-	const char *phandle = "qcom,dp-aux-switch";
-	struct notifier_block nb;
-
-	if (!dp->pdev->dev.of_node) {
-		DP_ERR("cannot find dev.of_node\n");
-		rc = -ENODEV;
-		goto end;
-	}
-
-	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_ENTRY);
-	dp->aux_switch_node = of_parse_phandle(dp->pdev->dev.of_node,
-			phandle, 0);
-	if (!dp->aux_switch_node) {
-		DP_WARN("cannot parse %s handle\n", phandle);
-		rc = -ENODEV;
-		goto end;
-	}
-
-	nb.notifier_call = dp_display_fsa4480_callback;
-	nb.priority = 0;
-
-	rc = fsa4480_reg_notifier(&nb, dp->aux_switch_node);
-	if (rc) {
-		DP_ERR("failed to register notifier (%d)\n", rc);
-		goto end;
-	}
-
-	fsa4480_unreg_notifier(&nb, dp->aux_switch_node);
-end:
-	SDE_EVT32_EXTERNAL(SDE_EVTLOG_FUNC_EXIT, rc);
-	return rc;
-}
-
 static int dp_display_bridge_internal_hpd(void *dev, bool hpd, bool hpd_irq)
 {
 	struct dp_display_private *dp = dev;
@@ -3502,12 +3519,6 @@ static int dp_display_probe(struct platform_device *pdev)
 
 	memset(&dp->mst, 0, sizeof(dp->mst));
 
-	rc = dp_display_init_aux_switch(dp);
-	if (rc) {
-		rc = -EPROBE_DEFER;
-		goto error;
-	}
-
 	rc = dp_display_init_aux_bridge(dp);
 	if (rc)
 		goto error;