Skip to content

Commit

Permalink
drm/bridge: sn65dsi86: Register and attach our DSI device at probe
Browse files Browse the repository at this point in the history
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-18-maxime@cerno.tech
  • Loading branch information
Maxime Ripard committed Oct 27, 2021
1 parent 77d2a71 commit c3b75d4
Showing 1 changed file with 40 additions and 37 deletions.
77 changes: 40 additions & 37 deletions drivers/gpu/drm/bridge/ti-sn65dsi86.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,58 +702,27 @@ static struct ti_sn65dsi86 *bridge_to_ti_sn65dsi86(struct drm_bridge *bridge)
return container_of(bridge, struct ti_sn65dsi86, bridge);
}

static int ti_sn_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
static int ti_sn_attach_host(struct ti_sn65dsi86 *pdata)
{
int ret, val;
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
struct mipi_dsi_host *host;
struct mipi_dsi_device *dsi;
struct device *dev = pdata->dev;
const struct mipi_dsi_device_info info = { .type = "ti_sn_bridge",
.channel = 0,
.node = NULL,
};

if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
DRM_ERROR("Fix bridge driver to make connector optional!");
return -EINVAL;
}

pdata->aux.drm_dev = bridge->dev;
ret = drm_dp_aux_register(&pdata->aux);
if (ret < 0) {
drm_err(bridge->dev, "Failed to register DP AUX channel: %d\n", ret);
return ret;
}

ret = ti_sn_bridge_connector_init(pdata);
if (ret < 0)
goto err_conn_init;
};

/*
* TODO: ideally finding host resource and dsi dev registration needs
* to be done in bridge probe. But some existing DSI host drivers will
* wait for any of the drm_bridge/drm_panel to get added to the global
* bridge/panel list, before completing their probe. So if we do the
* dsi dev registration part in bridge probe, before populating in
* the global bridge list, then it will cause deadlock as dsi host probe
* will never complete, neither our bridge probe. So keeping it here
* will satisfy most of the existing host drivers. Once the host driver
* is fixed we can move the below code to bridge probe safely.
*/
host = of_find_mipi_dsi_host_by_node(pdata->host_node);
if (!host) {
DRM_ERROR("failed to find dsi host\n");
ret = -ENODEV;
goto err_dsi_host;
return -ENODEV;
}

dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
if (IS_ERR(dsi)) {
DRM_ERROR("failed to create dsi device\n");
ret = PTR_ERR(dsi);
goto err_dsi_host;
return PTR_ERR(dsi);
}

/* TODO: setting to 4 MIPI lanes always for now */
Expand All @@ -768,12 +737,38 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge,
if (!(val & DPPLL_CLK_SRC_DSICLK))
dsi->mode_flags |= MIPI_DSI_CLOCK_NON_CONTINUOUS;

pdata->dsi = dsi;

ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
DRM_ERROR("failed to attach dsi to host\n");
goto err_dsi_host;
return ret;
}
pdata->dsi = dsi;

return 0;
}

static int ti_sn_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
{
struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
int ret;

if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
DRM_ERROR("Fix bridge driver to make connector optional!");
return -EINVAL;
}

pdata->aux.drm_dev = bridge->dev;
ret = drm_dp_aux_register(&pdata->aux);
if (ret < 0) {
drm_err(bridge->dev, "Failed to register DP AUX channel: %d\n", ret);
return ret;
}

ret = ti_sn_bridge_connector_init(pdata);
if (ret < 0)
goto err_conn_init;

/* We never want the next bridge to *also* create a connector: */
flags |= DRM_BRIDGE_ATTACH_NO_CONNECTOR;
Expand Down Expand Up @@ -1271,7 +1266,15 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev,

drm_bridge_add(&pdata->bridge);

ret = ti_sn_attach_host(pdata);
if (ret)
goto err_remove_bridge;

return 0;

err_remove_bridge:
drm_bridge_remove(&pdata->bridge);
return ret;
}

static void ti_sn_bridge_remove(struct auxiliary_device *adev)
Expand Down

0 comments on commit c3b75d4

Please sign in to comment.