drm/bridge: ps8640: Register and attach our DSI device at probe
authorMaxime Ripard <maxime@cerno.tech>
Mon, 25 Oct 2021 15:15:27 +0000 (17:15 +0200)
committerMaxime Ripard <maxime@cerno.tech>
Wed, 27 Oct 2021 20:07:57 +0000 (22:07 +0200)
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 <sam@ravnborg.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20211025151536.1048186-13-maxime@cerno.tech
drivers/gpu/drm/bridge/parade-ps8640.c

index 5ae15fc407c544910d9587e0869592fe1e5b12bc..4b36e4dc78f1117f8aaedc77bae7cb92f914f209 100644 (file)
@@ -401,54 +401,11 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge,
 {
        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 +464,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 +588,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)