Преглед изворни кода

disp: msm: dsi: add check for DSI resources during display probe

The change adds a check for DSI controller and PHY resources during the
DSI display probe. The validation now only checks for the availabilty
of the resources without increasing the refcount of the controller or
PHY till an exact match is found after the device tree is parsed.

Change-Id: I96a5022a8ab5f55271e0df36675037b597e1ec85
Signed-off-by: Satya Rama Aditya Pinapala <[email protected]>
Satya Rama Aditya Pinapala пре 4 година
родитељ
комит
3f8ac6983f
5 измењених фајлова са 99 додато и 37 уклоњено
  1. 31 0
      msm/dsi/dsi_ctrl.c
  2. 10 0
      msm/dsi/dsi_ctrl.h
  3. 16 37
      msm/dsi/dsi_display.c
  4. 32 0
      msm/dsi/dsi_phy.c
  5. 10 0
      msm/dsi/dsi_phy.h

+ 31 - 0
msm/dsi/dsi_ctrl.c

@@ -2204,6 +2204,37 @@ int dsi_ctrl_get_io_resources(struct msm_io_res *io_res)
 	return rc;
 }
 
+/**
+ * dsi_ctrl_check_resource() - check if DSI controller is probed
+ * @of_node:    of_node of the DSI controller.
+ *
+ * Checks if the DSI controller has been probed and is available.
+ *
+ * Return: status of DSI controller
+ */
+bool dsi_ctrl_check_resource(struct device_node *of_node)
+{
+	struct list_head *pos, *tmp;
+	struct dsi_ctrl *ctrl = NULL;
+
+	mutex_lock(&dsi_ctrl_list_lock);
+	list_for_each_safe(pos, tmp, &dsi_ctrl_list) {
+		struct dsi_ctrl_list_item *n;
+
+		n = list_entry(pos, struct dsi_ctrl_list_item, list);
+		if (!n->ctrl || !n->ctrl->pdev)
+			break;
+
+		if (n->ctrl->pdev->dev.of_node == of_node) {
+			ctrl = n->ctrl;
+			break;
+		}
+	}
+	mutex_unlock(&dsi_ctrl_list_lock);
+
+	return ctrl ? true : false;
+}
+
 /**
  * dsi_ctrl_get() - get a dsi_ctrl handle from an of_node
  * @of_node:    of_node of the DSI controller.

+ 10 - 0
msm/dsi/dsi_ctrl.h

@@ -319,6 +319,16 @@ struct dsi_ctrl {
 	u32 cmd_success_frame;
 };
 
+/**
+ * dsi_ctrl_check_resource() - check if DSI controller is probed
+ * @of_node:    of_node of the DSI controller.
+ *
+ * Checks if the DSI controller has been probed and is available.
+ *
+ * Return: status of DSI controller
+ */
+bool dsi_ctrl_check_resource(struct device_node *of_node);
+
 /**
  * dsi_ctrl_get() - get a dsi_ctrl handle from an of_node
  * @of_node:    of_node of the DSI controller.

+ 16 - 37
msm/dsi/dsi_display.c

@@ -4008,35 +4008,27 @@ end:
 	return rc;
 }
 
-static int dsi_display_validate_res(struct dsi_display *display)
+static bool dsi_display_validate_res(struct dsi_display *display)
 {
 	struct device_node *of_node = display->pdev->dev.of_node;
 	struct of_phandle_iterator it;
-	struct dsi_ctrl *dsi_ctrl;
 	bool ctrl_avail = false;
+	bool phy_avail = false;
 
+	/*
+	 * At least if one of the controller or PHY is present or has been probed, the
+	 * dsi_display_dev_probe can pass this check.  Exact ctrl and PHY match will be
+	 * done after the DT is parsed.
+	 */
 	of_phandle_iterator_init(&it, of_node, "qcom,dsi-ctrl", NULL, 0);
-	while (of_phandle_iterator_next(&it) == 0) {
-		dsi_ctrl = dsi_ctrl_get(it.node);
-		if (IS_ERR(dsi_ctrl)) {
-			int rc = PTR_ERR(dsi_ctrl);
+	while (of_phandle_iterator_next(&it) == 0)
+		ctrl_avail |= dsi_ctrl_check_resource(it.node);
 
-			if (rc == -EPROBE_DEFER)
-				return rc;
-			/*
-			 * With dual display mode, the seconday display needs at least
-			 * one ctrl to proceed through the probe. Exact ctrl match
-			 * will be done after parsing the DT or firmware data.
-			 */
-			if (rc == -EBUSY)
-				ctrl_avail |= false;
-		} else {
-			dsi_ctrl_put(dsi_ctrl);
-			ctrl_avail = true;
-		}
-	}
+	of_phandle_iterator_init(&it, of_node, "qcom,dsi-phy", NULL, 0);
+	while (of_phandle_iterator_next(&it) == 0)
+		phy_avail |= dsi_phy_check_resource(it.node);
 
-	return ctrl_avail ? 0 : -EBUSY;
+	return (ctrl_avail & phy_avail);
 }
 
 static int dsi_display_get_phandle_count(struct dsi_display *display,
@@ -5902,22 +5894,9 @@ int dsi_display_dev_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, display);
 
-	rc = dsi_display_validate_res(display);
-	if (rc) {
-		/*
-		 * Display's bailing out without probe deferral must register its
-		 * components to complete MDSS binding. Scheduled to be fixed in the future
-		 * with dynamic component binding.
-		 */
-		if (rc == -EBUSY) {
-			int ret = component_add(&pdev->dev,
-					&dsi_display_comp_ops);
-			if (ret)
-				DSI_ERR(
-					"component add failed for display type: %s, rc=%d\n"
-					, display->type, ret);
-		}
-
+	if (!dsi_display_validate_res(display)) {
+		rc = -EPROBE_DEFER;
+		DSI_ERR("resources required for display probe not present: rc=%d\n", rc);
 		goto end;
 	}
 

+ 32 - 0
msm/dsi/dsi_phy.c

@@ -579,6 +579,38 @@ static void dsi_phy_disable_hw(struct msm_dsi_phy *phy)
 		phy->hw.ops.regulator_disable(&phy->hw);
 }
 
+/**
+ * dsi_phy_check_resource() - check if DSI PHY is probed
+ * @of_node:    of_node of the DSI PHY.
+ *
+ * Checks if the DSI PHY has been probed and is available.
+ *
+ * Return: status of DSI PHY
+ */
+bool dsi_phy_check_resource(struct device_node *of_node)
+{
+	struct list_head *pos, *tmp;
+	struct msm_dsi_phy *phy = NULL;
+
+	mutex_lock(&dsi_phy_list_lock);
+	list_for_each_safe(pos, tmp, &dsi_phy_list) {
+		struct dsi_phy_list_item *n;
+
+		n = list_entry(pos, struct dsi_phy_list_item, list);
+
+		if (!n->phy || !n->phy->pdev)
+			break;
+
+		if (n->phy->pdev->dev.of_node == of_node) {
+			phy = n->phy;
+			break;
+		}
+	}
+	mutex_unlock(&dsi_phy_list_lock);
+
+	return phy ? true : false;
+}
+
 /**
  * dsi_phy_get() - get a dsi phy handle from device node
  * @of_node:           device node for dsi phy controller

+ 10 - 0
msm/dsi/dsi_phy.h

@@ -106,6 +106,16 @@ struct msm_dsi_phy {
 	bool dfps_trigger_mdpintf_flush;
 };
 
+/**
+ * dsi_phy_check_resource() - check if DSI PHY is probed
+ * @of_node:    of_node of the DSI PHY.
+ *
+ * Checks if the DSI PHY has been probed and is available.
+ *
+ * Return: status of DSI PHY
+ */
+bool dsi_phy_check_resource(struct device_node *of_node);
+
 /**
  * dsi_phy_get() - get a dsi phy handle from device node
  * @of_node:           device node for dsi phy controller