@@ -245,40 +245,6 @@ static int sn65dsi83_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
- struct device *dev = ctx->dev;
- struct mipi_dsi_device *dsi;
- struct mipi_dsi_host *host;
- int ret = 0;
-
- const struct mipi_dsi_device_info info = {
- .type = "sn65dsi83",
- .channel = 0,
- .node = NULL,
- };
-
- host = of_find_mipi_dsi_host_by_node(ctx->host_node);
- if (!host) {
- dev_err(dev, "failed to find dsi host\n");
- return -EPROBE_DEFER;
- }
-
- dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
- if (IS_ERR(dsi)) {
- return dev_err_probe(dev, PTR_ERR(dsi),
- "failed to create dsi device\n");
- }
-
- ctx->dsi = dsi;
-
- dsi->lanes = ctx->dsi_lanes;
- dsi->format = MIPI_DSI_FMT_RGB888;
- dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST;
-
- ret = devm_mipi_dsi_attach(dev, dsi);
- if (ret < 0) {
- dev_err(dev, "failed to attach dsi to host\n");
- return ret;
- }
return drm_bridge_attach(bridge->encoder, ctx->panel_bridge,
&ctx->bridge, flags);
@@ -646,6 +612,44 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, enum sn65dsi83_model model)
return 0;
}
+static int sn65dsi83_host_attach(struct sn65dsi83 *ctx)
+{
+ struct device *dev = ctx->dev;
+ struct mipi_dsi_device *dsi;
+ struct mipi_dsi_host *host;
+ const struct mipi_dsi_device_info info = {
+ .type = "sn65dsi83",
+ .channel = 0,
+ .node = NULL,
+ };
+ int ret;
+
+ host = of_find_mipi_dsi_host_by_node(ctx->host_node);
+ if (!host) {
+ dev_err(dev, "failed to find dsi host\n");
+ return -EPROBE_DEFER;
+ }
+
+ dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
+ if (IS_ERR(dsi))
+ return dev_err_probe(dev, PTR_ERR(dsi),
+ "failed to create dsi device\n");
+
+ ctx->dsi = dsi;
+
+ dsi->lanes = ctx->dsi_lanes;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST;
+
+ ret = devm_mipi_dsi_attach(dev, dsi);
+ if (ret < 0) {
+ dev_err(dev, "failed to attach dsi to host: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
static int sn65dsi83_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -686,7 +690,15 @@ static int sn65dsi83_probe(struct i2c_client *client,
ctx->bridge.of_node = dev->of_node;
drm_bridge_add(&ctx->bridge);
+ ret = sn65dsi83_host_attach(ctx);
+ if (ret)
+ goto err_remove_bridge;
+
return 0;
+
+err_remove_bridge:
+ drm_bridge_remove(&ctx->bridge);
+ return ret;
}
static int sn65dsi83_remove(struct i2c_client *client)
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. Signed-off-by: Maxime Ripard <maxime@cerno.tech> --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 80 +++++++++++++++------------ 1 file changed, 46 insertions(+), 34 deletions(-)