[Linux-stm32] [PATCH 1/1] drm/bridge/synopsys/dsi: fix activation sequence

Antonio Borneo antonio.borneo at st.com
Mon Jun 22 12:36:42 UTC 2020


The current driver relies on the probing of panel or bridge
sub-nodes to trigger the execution of dsi host attach() in order
to add the dsi bridge to the global bridge list through
drm_bridge_add().
This causes an incomplete driver initialization if the panel or
the next bridge is not present as sub-node, e.g. because it is an
i2c device, thus sub-node of the respective i2c controller.

Move the relevant code from host attach() to probe(), and the
corresponding code from detach() to remove().

Signed-off-by: Antonio Borneo <antonio.borneo at st.com>
Change-Id: I29df3ddbfc43272d56bef95f32686b2055778571
---
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 72 ++++++++++---------
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index bd5d63032a75..02aadfc7042d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -310,16 +310,8 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
 {
 	struct dw_mipi_dsi *dsi = host_to_dsi(host);
 	const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data;
-	struct drm_bridge *bridge;
-	struct drm_panel *panel;
-	int i, nb_endpoints;
 	int ret = -ENODEV;
 
-	/* Get number of endpoints */
-	nb_endpoints = of_graph_get_endpoint_count(host->dev->of_node);
-	if (!nb_endpoints)
-		return -ENODEV;
-
 	if (device->lanes > dsi->plat_data->max_data_lanes) {
 		dev_err(dsi->dev, "the number of data lanes(%u) is too many\n",
 			device->lanes);
@@ -331,29 +323,6 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
 
-	for (i = 1; i < nb_endpoints; i++) {
-		ret = drm_of_find_panel_or_bridge(host->dev->of_node, i, 0,
-						  &panel, &bridge);
-		if (!ret)
-			break;
-		else if (ret == -EPROBE_DEFER)
-			return ret;
-	}
-
-	/* check if an error is returned >> no panel or bridge detected */
-	if (ret)
-		return ret;
-
-	if (panel) {
-		bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
-		if (IS_ERR(bridge))
-			return PTR_ERR(bridge);
-	}
-
-	dsi->panel_bridge = bridge;
-
-	drm_bridge_add(&dsi->bridge);
-
 	if (pdata->host_ops && pdata->host_ops->attach) {
 		ret = pdata->host_ops->attach(pdata->priv_data, device);
 		if (ret < 0)
@@ -376,10 +345,6 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
 			return ret;
 	}
 
-	drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
-
-	drm_bridge_remove(&dsi->bridge);
-
 	return 0;
 }
 
@@ -1091,6 +1056,9 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
 	struct reset_control *apb_rst;
 	struct dw_mipi_dsi *dsi;
 	struct resource *res;
+	struct drm_bridge *bridge;
+	struct drm_panel *panel;
+	int i, nb_endpoints;
 	int ret;
 
 	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
@@ -1171,11 +1139,45 @@ __dw_mipi_dsi_probe(struct platform_device *pdev,
 	dsi->bridge.of_node = pdev->dev.of_node;
 #endif
 
+	nb_endpoints = of_graph_get_endpoint_count(pdev->dev.of_node);
+	if (!nb_endpoints)
+		return ERR_PTR(-ENODEV);
+
+	for (i = 1; i < nb_endpoints; i++) {
+		ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, i, 0,
+				&panel, &bridge);
+		if (!ret)
+			break;
+		else if (ret == -EPROBE_DEFER)
+			return ERR_PTR(ret);
+	}
+
+	/* check if an error is returned >> no panel or bridge detected */
+	if (ret) {
+		dev_info(dsi->dev, "no panel or bridge detected");
+		return ERR_PTR(ret);
+	}
+	dev_info(dsi->dev, "panel or bridge detected");
+
+	if (panel) {
+		bridge = drm_panel_bridge_add(panel, DRM_MODE_CONNECTOR_DSI);
+		if (IS_ERR(bridge))
+			return ERR_PTR(PTR_ERR(bridge));
+	}
+
+	dsi->panel_bridge = bridge;
+
+	drm_bridge_add(&dsi->bridge);
+
 	return dsi;
 }
 
 static void __dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi)
 {
+	/* FIXME: it is not anymore port 1 */
+	drm_of_panel_bridge_remove(dsi->bridge.of_node, 1, 0);
+	drm_bridge_remove(&dsi->bridge);
+
 	mipi_dsi_host_unregister(&dsi->dsi_host);
 
 	pm_runtime_disable(dsi->dev);
-- 
2.17.1




More information about the Linux-stm32 mailing list