From 445ecaae40ccbe51cbfa0e38650dbddbd081b66e Mon Sep 17 00:00:00 2001
From: Stefan Eichenberger <stefan.eichenberger@toradex.com>
Date: Fri, 9 Feb 2024 10:10:02 +0100
Subject: [PATCH] drm/imx: imx8mp-ldb: return EPROBE_DEFER in probe

Return EPROBE_DEFER in the probe function if the LDB bridge is missing
some of its child bridges. The current implementation returns
EPROBE_DEFER in the bind function, which is incorrect because the kernel
assumes the driver is fully functional when bind is called. This results
in a deferal loop if native HDMI and the ldb bridge are enabled that
looks as follows:

dwhdmi-imx 32fd8000.hdmi: Detected HDMI TX controller v2.13a with HDCP (samsung_dw_hdmi_phy2)
dwhdmi-imx 32fd8000.hdmi: registered DesignWare HDMI I2C bus driver
imx-drm display-subsystem: bound imx-lcdifv3-crtc.0 (ops lcdifv3_crtc_ops)
imx-drm display-subsystem: bound imx-lcdifv3-crtc.1 (ops lcdifv3_crtc_ops)
dwhdmi-imx 32fd8000.hdmi: Detected HDMI TX controller v2.13a with HDCP (samsung_dw_hdmi_phy2)
dwhdmi-imx 32fd8000.hdmi: registered DesignWare HDMI I2C bus driver
...

The upstream imx8mp-ldb driver is a complete rewrite of the downstream
one and is most likely not affected because there is no bind:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/bridge/fsl-ldb.c

Upstream-Status: Inappropriate [Other]
Signed-off-by: Stefan Eichenberger <stefan.eichenberger@toradex.com>
---
 drivers/gpu/drm/imx/imx8mp-ldb.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/gpu/drm/imx/imx8mp-ldb.c b/drivers/gpu/drm/imx/imx8mp-ldb.c
index e3f5c5e6e842e..e01331b638479 100644
--- a/drivers/gpu/drm/imx/imx8mp-ldb.c
+++ b/drivers/gpu/drm/imx/imx8mp-ldb.c
@@ -14,6 +14,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_of.h>
 
 #include "imx-drm.h"
 
@@ -390,6 +391,28 @@ static int imx8mp_ldb_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct imx8mp_ldb *imx8mp_ldb;
+	struct device_node *np = dev->of_node;
+	struct device_node *child;
+	int ret;
+
+	/*
+	 * Make sure we can defer already in the probe function else we will
+	 * have an issue in the bind function. It is expected that in the bind
+	 * function the driver is functional.
+	 */
+	for_each_child_of_node(np, child) {
+		struct drm_panel *panel;
+		struct drm_bridge *next_bridge;
+
+		ret = drm_of_find_panel_or_bridge(child, 1, 0,
+						  &panel, &next_bridge);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+		/*
+		 * We can continue even if there is an error, this is most
+		 * likely because this driver has not loaded yet
+		 */
+	}
 
 	imx8mp_ldb = devm_kzalloc(dev, sizeof(*imx8mp_ldb), GFP_KERNEL);
 	if (!imx8mp_ldb)
-- 
GitLab