When connecting the sn65dsi83 device to the Samsung MIPI DSI host
controller found in i.MX8M Mini, probing the host and device
infinitely defers, waiting for each other to appear. on probe of the
host, it tries to attach to the device, which has not been probed yet.
It therefore does not register the host, and defers. When the sn65dsi83
probes, it tries to attach to the host, which is not registered as it is
deferred, and thereofore it defers as well, without registering. This
means the two drivers are infinetely waiting for each other to appear.
This is the case on the Samsung MIPI DSI host controller, but might be
the case with other host controllers as well.

Only register the sn65dsi83 on probe, and attach to the host later. This
means the host has a bridge to attache to in probe. When the host
attaches to the bridge, the bridge can attach to the host, breaking the
infinite defer.

Signed-off-by: Paul Geurts <[email protected]>
Fixes: 6ef7ee48765f ("drm/bridge: sn65dsi83: Register and attach our DSI device 
at probe")
---
 drivers/gpu/drm/bridge/ti-sn65dsi83.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c 
b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 2d0e767a23b6..d114db8f5307 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -288,6 +288,8 @@ static const int lvds_vod_swing_clock_table[2][4][2] = {
        },
 };
 
+static int sn65dsi83_host_attach(struct sn65dsi83 *ctx);
+
 static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge)
 {
        return container_of(bridge, struct sn65dsi83, bridge);
@@ -298,6 +300,13 @@ static int sn65dsi83_attach(struct drm_bridge *bridge,
                            enum drm_bridge_attach_flags flags)
 {
        struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
+       int ret = 0;
+
+       ret = sn65dsi83_host_attach(ctx);
+       if (ret) {
+               dev_err(ctx->dev, "Failed to attach DSI host %d\n", ret);
+               return ret;
+       }
 
        return drm_bridge_attach(encoder, ctx->panel_bridge,
                                 &ctx->bridge, flags);
@@ -1051,17 +1060,7 @@ static int sn65dsi83_probe(struct i2c_client *client)
        ctx->bridge.type = DRM_MODE_CONNECTOR_LVDS;
        drm_bridge_add(&ctx->bridge);
 
-       ret = sn65dsi83_host_attach(ctx);
-       if (ret) {
-               dev_err_probe(dev, ret, "failed to attach DSI host\n");
-               goto err_remove_bridge;
-       }
-
        return 0;
-
-err_remove_bridge:
-       drm_bridge_remove(&ctx->bridge);
-       return ret;
 }
 
 static void sn65dsi83_remove(struct i2c_client *client)
-- 
2.39.2

Reply via email to