Skip to content

Commit

Permalink
drm/meson: fix unbind path if HDMI fails to bind
Browse files Browse the repository at this point in the history
If the case the HDMI controller fails to bind, we try to unbind
all components before calling drm_dev_put() which makes drm_bridge_detach()
crash because unbinding the HDMI controller frees the bridge memory.

The solution is the unbind all components at the end like in the remove
path.

Reviewed-by: Nicolas Belin <nbelin@baylibre.com>
Tested-by: Nicolas Belin <nbelin@baylibre.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-v5-8-56eb7a4d5b8e@linaro.org
  • Loading branch information
superna9999 committed Jun 1, 2023
1 parent 25b3b35 commit 6a04464
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions drivers/gpu/drm/meson/meson_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,32 +316,34 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
goto exit_afbcd;

if (has_components) {
ret = component_bind_all(drm->dev, drm);
ret = component_bind_all(dev, drm);
if (ret) {
dev_err(drm->dev, "Couldn't bind all components\n");
/* Do not try to unbind */
has_components = false;
goto exit_afbcd;
}
}

ret = meson_encoder_hdmi_init(priv);
if (ret)
goto unbind_all;
goto exit_afbcd;

ret = meson_plane_create(priv);
if (ret)
goto unbind_all;
goto exit_afbcd;

ret = meson_overlay_create(priv);
if (ret)
goto unbind_all;
goto exit_afbcd;

ret = meson_crtc_create(priv);
if (ret)
goto unbind_all;
goto exit_afbcd;

ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm);
if (ret)
goto unbind_all;
goto exit_afbcd;

drm_mode_config_reset(drm);

Expand All @@ -359,15 +361,18 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)

uninstall_irq:
free_irq(priv->vsync_irq, drm);
unbind_all:
if (has_components)
component_unbind_all(drm->dev, drm);
exit_afbcd:
if (priv->afbcd.ops)
priv->afbcd.ops->exit(priv);
free_drm:
drm_dev_put(drm);

meson_encoder_hdmi_remove(priv);
meson_encoder_cvbs_remove(priv);

if (has_components)
component_unbind_all(dev, drm);

return ret;
}

Expand Down

0 comments on commit 6a04464

Please sign in to comment.