In order to avoid any probe ordering issue, the best practice is to move
the secondary MIPI-DSI device registration and attachment to the
MIPI-DSI host at probe time. Let's do this.

Acked-by: Sam Ravnborg <s...@ravnborg.org>
Signed-off-by: Maxime Ripard <max...@cerno.tech>
---
 drivers/gpu/drm/bridge/parade-ps8640.c | 100 ++++++++++++++-----------
 1 file changed, 55 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/bridge/parade-ps8640.c 
b/drivers/gpu/drm/bridge/parade-ps8640.c
index 5ae15fc407c5..5f70eaca175b 100644
--- a/drivers/gpu/drm/bridge/parade-ps8640.c
+++ b/drivers/gpu/drm/bridge/parade-ps8640.c
@@ -400,55 +400,10 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge,
                                enum drm_bridge_attach_flags flags)
 {
        struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
-       struct device *dev = &ps_bridge->page[0]->dev;
-       struct device_node *in_ep, *dsi_node;
-       struct mipi_dsi_device *dsi;
-       struct mipi_dsi_host *host;
-       int ret;
-       const struct mipi_dsi_device_info info = { .type = "ps8640",
-                                                  .channel = 0,
-                                                  .node = NULL,
-                                                };
 
        if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
                return -EINVAL;
 
-       /* port@0 is ps8640 dsi input port */
-       in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
-       if (!in_ep)
-               return -ENODEV;
-
-       dsi_node = of_graph_get_remote_port_parent(in_ep);
-       of_node_put(in_ep);
-       if (!dsi_node)
-               return -ENODEV;
-
-       host = of_find_mipi_dsi_host_by_node(dsi_node);
-       of_node_put(dsi_node);
-       if (!host)
-               return -ENODEV;
-
-       dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
-       if (IS_ERR(dsi)) {
-               dev_err(dev, "failed to create dsi device\n");
-               ret = PTR_ERR(dsi);
-               return ret;
-       }
-
-       ps_bridge->dsi = dsi;
-
-       dsi->host = host;
-       dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
-                         MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
-       dsi->format = MIPI_DSI_FMT_RGB888;
-       dsi->lanes = NUM_MIPI_LANES;
-
-       ret = devm_mipi_dsi_attach(dev, dsi);
-       if (ret) {
-               dev_err(dev, "failed to attach dsi device: %d\n", ret);
-               return ret;
-       }
-
        ret = drm_dp_aux_register(&ps_bridge->aux);
        if (ret) {
                dev_err(dev, "failed to register DP AUX channel: %d\n", ret);
@@ -507,6 +462,53 @@ static const struct drm_bridge_funcs ps8640_bridge_funcs = 
{
        .pre_enable = ps8640_pre_enable,
 };
 
+static int ps8640_bridge_host_attach(struct device *dev, struct ps8640 
*ps_bridge)
+{
+       struct device_node *in_ep, *dsi_node;
+       struct mipi_dsi_device *dsi;
+       struct mipi_dsi_host *host;
+       int ret;
+       const struct mipi_dsi_device_info info = { .type = "ps8640",
+                                                  .channel = 0,
+                                                  .node = NULL,
+                                                };
+
+       /* port@0 is ps8640 dsi input port */
+       in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
+       if (!in_ep)
+               return -ENODEV;
+
+       dsi_node = of_graph_get_remote_port_parent(in_ep);
+       of_node_put(in_ep);
+       if (!dsi_node)
+               return -ENODEV;
+
+       host = of_find_mipi_dsi_host_by_node(dsi_node);
+       of_node_put(dsi_node);
+       if (!host)
+               return -EPROBE_DEFER;
+
+       dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
+       if (IS_ERR(dsi)) {
+               dev_err(dev, "failed to create dsi device\n");
+               return PTR_ERR(dsi);
+       }
+
+       ps_bridge->dsi = dsi;
+
+       dsi->host = host;
+       dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
+                         MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+       dsi->format = MIPI_DSI_FMT_RGB888;
+       dsi->lanes = NUM_MIPI_LANES;
+
+       ret = devm_mipi_dsi_attach(dev, dsi);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 static int ps8640_probe(struct i2c_client *client)
 {
        struct device *dev = &client->dev;
@@ -584,7 +586,15 @@ static int ps8640_probe(struct i2c_client *client)
 
        drm_bridge_add(&ps_bridge->bridge);
 
+       ret = ps8640_bridge_host_attach(dev, ps_bridge);
+       if (ret)
+               goto err_bridge_remove;
+
        return 0;
+
+err_bridge_remove:
+       drm_bridge_remove(&ps_bridge->bridge);
+       return ret;
 }
 
 static int ps8640_remove(struct i2c_client *client)
-- 
2.31.1

Reply via email to