linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Jagan Teki <jagan@amarulasolutions.com>
To: Maxime Ripard <mripard@kernel.org>, Chen-Yu Tsai <wens@csie.org>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	Neil Armstrong <narmstrong@baylibre.com>,
	Robert Foss <robert.foss@linaro.org>,
	Sam Ravnborg <sam@ravnborg.org>
Cc: dri-devel@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	linux-sunxi@googlegroups.com, linux-amarula@amarulasolutions.com,
	Jagan Teki <jagan@amarulasolutions.com>
Subject: [PATCH v5 2/7] drm: sun4i: dsi: Add component only once DSI device attached
Date: Mon, 22 Nov 2021 12:22:18 +0530	[thread overview]
Message-ID: <20211122065223.88059-3-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20211122065223.88059-1-jagan@amarulasolutions.com>

Having component_add for running all drm bind callbacks returns
error or unbound due to chain of DSI devices connected across
bridge topology on a display pipeline.

In a typical bridge oriented display pipeline where the host is
connected to the bridge converter and that indeed connected to
a panel.

DRM => SUN6I DSI Host => Chipone ICN6211 => BananaPi Panel

The bridge converter is looking for a panel to probe first and
then attach the host. The host attach is looking for a bridge
converter to probe and preserve bridge pointer, at this movement
the host is trying to bind the all callbacks and one of the bind
callback in the DSI host is trying to find the bridge using the
bridge pointer in sun6i_dsi_attach call.

chipone_probe().start
    drm_of_find_panel_or_bridge
        mipi_dsi_attach
             sun6i_dsi_attach
                 drm_of_find_panel_or_bridge
chipone_probe().done

sun6i_dsi_probe().start
    mipi_dsi_host_register
        component_add
sun6i_dsi_probe().done

However, the movement when panel defers the probe, will make the
bridge converter defer the host attach call which eventually found
a NULL bridge pointer during DSI component bind callback.

So, in order to prevent this scenario of binding invalid bridge,
wait for DSI devices on the pipeline to probe first and start the
binding process by moving component_add in host probe to attach call.

chipone_probe().start
    drm_of_find_panel_or_bridge
        mipi_dsi_attach
             sun6i_dsi_attach
                 drm_of_find_panel_or_bridge
      		      component_add
chipone_probe().done

sun6i_dsi_probe().start
    mipi_dsi_host_register
sun6i_dsi_probe().done

Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
---
Changes for v5:
- new patch

 drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 119 +++++++++++++------------
 1 file changed, 60 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 4bdcce8f1d84..43d9c9e5198d 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -959,11 +959,62 @@ static int sun6i_dsi_dcs_read(struct sun6i_dsi *dsi,
 	return 1;
 }
 
+static int sun6i_dsi_bind(struct device *dev, struct device *master,
+			 void *data)
+{
+	struct drm_device *drm = data;
+	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
+	int ret;
+
+	drm_encoder_helper_add(&dsi->encoder,
+			       &sun6i_dsi_enc_helper_funcs);
+	ret = drm_simple_encoder_init(drm, &dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		dev_err(dsi->dev, "Couldn't initialise the DSI encoder\n");
+		return ret;
+	}
+	dsi->encoder.possible_crtcs = BIT(0);
+
+	drm_connector_helper_add(&dsi->connector,
+				 &sun6i_dsi_connector_helper_funcs);
+	ret = drm_connector_init(drm, &dsi->connector,
+				 &sun6i_dsi_connector_funcs,
+				 DRM_MODE_CONNECTOR_DSI);
+	if (ret) {
+		dev_err(dsi->dev,
+			"Couldn't initialise the DSI connector\n");
+		goto err_cleanup_connector;
+	}
+
+	drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
+
+	return 0;
+
+err_cleanup_connector:
+	drm_encoder_cleanup(&dsi->encoder);
+	return ret;
+}
+
+static void sun6i_dsi_unbind(struct device *dev, struct device *master,
+			    void *data)
+{
+	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
+
+	drm_encoder_cleanup(&dsi->encoder);
+}
+
+static const struct component_ops sun6i_dsi_ops = {
+	.bind	= sun6i_dsi_bind,
+	.unbind	= sun6i_dsi_unbind,
+};
+
 static int sun6i_dsi_attach(struct mipi_dsi_host *host,
 			    struct mipi_dsi_device *device)
 {
 	struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
 	struct drm_panel *panel = of_drm_find_panel(device->dev.of_node);
+	int ret;
 
 	if (IS_ERR(panel))
 		return PTR_ERR(panel);
@@ -973,6 +1024,13 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host,
 
 	dev_info(host->dev, "Attached device %s\n", device->name);
 
+	ret = component_add(dsi->dev, &sun6i_dsi_ops);
+	if (ret) {
+		dev_err(dsi->dev, "Couldn't register our component\n");
+		mipi_dsi_host_unregister(&dsi->host);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -984,6 +1042,8 @@ static int sun6i_dsi_detach(struct mipi_dsi_host *host,
 	dsi->panel = NULL;
 	dsi->device = NULL;
 
+	component_del(dsi->dev, &sun6i_dsi_ops);
+
 	return 0;
 }
 
@@ -1041,56 +1101,6 @@ static const struct regmap_config sun6i_dsi_regmap_config = {
 	.name		= "mipi-dsi",
 };
 
-static int sun6i_dsi_bind(struct device *dev, struct device *master,
-			 void *data)
-{
-	struct drm_device *drm = data;
-	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
-	int ret;
-
-	drm_encoder_helper_add(&dsi->encoder,
-			       &sun6i_dsi_enc_helper_funcs);
-	ret = drm_simple_encoder_init(drm, &dsi->encoder,
-				      DRM_MODE_ENCODER_DSI);
-	if (ret) {
-		dev_err(dsi->dev, "Couldn't initialise the DSI encoder\n");
-		return ret;
-	}
-	dsi->encoder.possible_crtcs = BIT(0);
-
-	drm_connector_helper_add(&dsi->connector,
-				 &sun6i_dsi_connector_helper_funcs);
-	ret = drm_connector_init(drm, &dsi->connector,
-				 &sun6i_dsi_connector_funcs,
-				 DRM_MODE_CONNECTOR_DSI);
-	if (ret) {
-		dev_err(dsi->dev,
-			"Couldn't initialise the DSI connector\n");
-		goto err_cleanup_connector;
-	}
-
-	drm_connector_attach_encoder(&dsi->connector, &dsi->encoder);
-
-	return 0;
-
-err_cleanup_connector:
-	drm_encoder_cleanup(&dsi->encoder);
-	return ret;
-}
-
-static void sun6i_dsi_unbind(struct device *dev, struct device *master,
-			    void *data)
-{
-	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
-
-	drm_encoder_cleanup(&dsi->encoder);
-}
-
-static const struct component_ops sun6i_dsi_ops = {
-	.bind	= sun6i_dsi_bind,
-	.unbind	= sun6i_dsi_unbind,
-};
-
 static int sun6i_dsi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -1172,16 +1182,8 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
 		goto err_unprotect_clk;
 	}
 
-	ret = component_add(&pdev->dev, &sun6i_dsi_ops);
-	if (ret) {
-		dev_err(dev, "Couldn't register our component\n");
-		goto err_remove_dsi_host;
-	}
-
 	return 0;
 
-err_remove_dsi_host:
-	mipi_dsi_host_unregister(&dsi->host);
 err_unprotect_clk:
 	clk_rate_exclusive_put(dsi->mod_clk);
 err_attach_clk:
@@ -1195,7 +1197,6 @@ static int sun6i_dsi_remove(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct sun6i_dsi *dsi = dev_get_drvdata(dev);
 
-	component_del(&pdev->dev, &sun6i_dsi_ops);
 	mipi_dsi_host_unregister(&dsi->host);
 	clk_rate_exclusive_put(dsi->mod_clk);
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2021-11-22  6:55 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-22  6:52 [PATCH v5 0/7] drm: sun4i: dsi: Convert drm bridge Jagan Teki
2021-11-22  6:52 ` [PATCH v5 1/7] drm: sun4i: dsi: Drop DRM bind race with bridge attach Jagan Teki
2021-11-22  6:52 ` Jagan Teki [this message]
2021-11-22  6:52 ` [PATCH v5 3/7] drm: sun4i: dsi: Convert to bridge driver Jagan Teki
2021-11-22 10:07   ` Maxime Ripard
2021-11-22 12:45     ` Laurent Pinchart
2021-11-22 13:48     ` Jagan Teki
2021-11-22 14:04       ` Maxime Ripard
2021-11-22 14:19         ` Jagan Teki
2021-11-22 15:04           ` Maxime Ripard
2021-11-25 16:17             ` Jagan Teki
2021-11-23 18:32           ` Jagan Teki
2021-11-25 14:15             ` Maxime Ripard
2021-11-25 14:25               ` Jagan Teki
2021-11-25 16:10                 ` Maxime Ripard
2021-11-25 16:14                   ` Jagan Teki
2021-11-26 16:04                     ` Maxime Ripard
2021-11-30  7:39                       ` Jagan Teki
2021-12-05 17:39                         ` Michael Nazzareno Trimarchi
2021-11-22 12:52   ` Neil Armstrong
2021-11-22 13:16     ` Jagan Teki
2021-11-22 15:35       ` Neil Armstrong
2021-11-22 17:19         ` Dave Stevenson
2021-11-23  8:19           ` Neil Armstrong
2021-11-22  6:52 ` [PATCH v5 4/7] drm: sun4i: dsi: Add mode_set function Jagan Teki
2021-11-22 10:07   ` Maxime Ripard
2021-11-22 13:05     ` Jagan Teki
2021-11-22 13:28       ` Maxime Ripard
2021-11-22 13:51         ` Jagan Teki
2021-11-22 14:09           ` Maxime Ripard
2021-11-22 14:31             ` Jagan Teki
2021-11-22 15:06               ` Maxime Ripard
2021-11-22 15:17                 ` Jagan Teki
2021-11-22  6:52 ` [DO NOT MERGE] [PATCH v5 5/7] ARM: dts: sun8i: bananapi-m2m: Enable S070WV20-CT16 Panel Jagan Teki
2021-11-22  6:52 ` [DO NOT MERGE] [PATCH v5 6/7] ARM: dts: sun8i: bananapi-m2m: Enable ICN6211 DSI Bridge Jagan Teki
2021-11-22  6:52 ` [DO NOT MERGE] [PATCH v5 7/7] ARM: dts: sun8i: Enable DLPC3433 Bridge (I2C) Jagan Teki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211122065223.88059-3-jagan@amarulasolutions.com \
    --to=jagan@amarulasolutions.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-amarula@amarulasolutions.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=mripard@kernel.org \
    --cc=narmstrong@baylibre.com \
    --cc=robert.foss@linaro.org \
    --cc=sam@ravnborg.org \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).