This bridge driver calls drm_bridge_add() in the DSI host .attach callback
instead of in the probe function.

This works for current use cases but is problematic for supporting hotplug
of DRM bridges. The problematic case is when this DSI host is always
present while its DSI device is hot-pluggable. In such case with the
current code the DRM card will not be populated until after the DSI device
attaches to the host, which could happen a very long time after booting, or
even not happen at all.

The reason is that the previous pipeline component (the encoder in this
case) when probing cannot find the samsung-dsim bridge. What happens is:

 [1 and 2 can happen in any order, same result]
 1) samsung-dsim probes (does not drm_bridge_add() itself)
 2) The lcdif starts probing multiple times, but
    lcdif_probe
    -> lcdif_load
       -> lcdif_attach_bridge
          -> devm_drm_of_get_bridge() returns -EPROBE_DEFER because
             the samsung-dsim is not in the global bridge_list
             (deferred probe pending: imx-lcdif: Cannot connect bridge)

The samsung-dsim will not drm_bridge_add() itself until a DSI device will
try to mipi_dsi_attach() to the DSI Host, which can happen arbitratily late
on hot-pluggable hardware.

As a preliminary step to supporting hotplug move drm_bridge_add() at probe
time, so that the samsung-dsim DSI host bridge is available during boot,
even without a connected DSI device. This results in:

 1) samsung-dsim probes (and adds to drm_bridge_add() itself)
 2) The lcdif starts probing multiple times, but
    lcdif_probe
    -> lcdif_load
       -> lcdif_attach_bridge
          -> devm_drm_of_get_bridge() --> OK, returns samsung-dsim ptr

Signed-off-by: Luca Ceresoli <[email protected]>
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 2af287221e22..cefb20ec68ad 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1980,8 +1980,6 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host 
*host,
                     mipi_dsi_pixel_format_to_bpp(device->format),
                     device->mode_flags);
 
-       drm_bridge_add(&dsi->bridge);
-
        /*
         * This is a temporary solution and should be made by more generic way.
         *
@@ -2014,7 +2012,6 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host 
*host,
        if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO))
                samsung_dsim_unregister_te_irq(dsi);
 err_remove_panel_bridge:
-       drm_bridge_remove(&dsi->bridge);
        if (dsi->panel_bridge_added) {
                drm_panel_bridge_remove(next_bridge);
                dsi->panel_bridge_added = false;
@@ -2040,8 +2037,6 @@ static int samsung_dsim_host_detach(struct mipi_dsi_host 
*host,
 
        samsung_dsim_unregister_te_irq(dsi);
 
-       drm_bridge_remove(&dsi->bridge);
-
        return 0;
 }
 
@@ -2242,6 +2237,8 @@ int samsung_dsim_probe(struct platform_device *pdev)
                        goto err_disable_runtime;
        }
 
+       drm_bridge_add(&dsi->bridge);
+
        return 0;
 
 err_disable_runtime:
@@ -2255,6 +2252,8 @@ void samsung_dsim_remove(struct platform_device *pdev)
 {
        struct samsung_dsim *dsi = platform_get_drvdata(pdev);
 
+       drm_bridge_remove(&dsi->bridge);
+
        pm_runtime_disable(&pdev->dev);
 
        if (dsi->plat_data->host_ops && 
dsi->plat_data->host_ops->unregister_host)

-- 
2.54.0

Reply via email to