With proper use of drm_bridge_get() and _put(), this allows the bridge to be removable without dangling pointers and use-after-free. Signed-off-by: Luca Ceresoli <luca.ceresoli@xxxxxxxxxxx> --- This patch was added in v5. --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index 246fece303bc0ae9fb2eaa9c6218ce2ecd550f3b..df3ec39817f32879f9aab65812b6e7f4723f72fb 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -267,6 +267,11 @@ static void sn65dsi83_detach(struct drm_bridge *bridge) ctx->dsi = NULL; } +static void sn65dsi83_destroy(struct drm_bridge *bridge) +{ + kfree(bridge_to_sn65dsi83(bridge)); +} + static u8 sn65dsi83_get_lvds_range(struct sn65dsi83 *ctx, const struct drm_display_mode *mode) { @@ -695,6 +700,7 @@ sn65dsi83_atomic_get_input_bus_fmts(struct drm_bridge *bridge, static const struct drm_bridge_funcs sn65dsi83_funcs = { .attach = sn65dsi83_attach, .detach = sn65dsi83_detach, + .destroy = sn65dsi83_destroy, .atomic_enable = sn65dsi83_atomic_enable, .atomic_pre_enable = sn65dsi83_atomic_pre_enable, .atomic_disable = sn65dsi83_atomic_disable, @@ -813,10 +819,14 @@ static int sn65dsi83_probe(struct i2c_client *client) struct sn65dsi83 *ctx; int ret; - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + ret = drm_bridge_init(dev, &ctx->bridge, &sn65dsi83_funcs); + if (ret) + return ret; + ctx->dev = dev; INIT_WORK(&ctx->reset_work, sn65dsi83_reset_work); INIT_DELAYED_WORK(&ctx->monitor_work, sn65dsi83_monitor_work); @@ -855,7 +865,6 @@ static int sn65dsi83_probe(struct i2c_client *client) dev_set_drvdata(dev, ctx); i2c_set_clientdata(client, ctx); - ctx->bridge.funcs = &sn65dsi83_funcs; ctx->bridge.of_node = dev->of_node; ctx->bridge.pre_enable_prev_first = true; drm_bridge_add(&ctx->bridge); -- 2.34.1