Allow this bridge to be removable without dangling pointers and use-after-free, together with proper use of drm_bridge_get() and _put() by consumers. Signed-off-by: Luca Ceresoli <luca.ceresoli@xxxxxxxxxxx> --- Changed in v6: - Update to use devm_drm_bridge_alloc(), remove .destroy - Update the *_of_get_bridge() functions to put instead of kfree on devm/drmm events This patch was added in v5. --- drivers/gpu/drm/bridge/panel.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c index 3c0e22e61c1092de1571d800ac440aad7b5c86bc..5950c752ff2469f7e5c28f9d5833141551b98227 100644 --- a/drivers/gpu/drm/bridge/panel.c +++ b/drivers/gpu/drm/bridge/panel.c @@ -912,15 +912,14 @@ struct drm_bridge *drm_panel_bridge_add_typed(struct drm_panel *panel, if (!panel) return ERR_PTR(-EINVAL); - panel_bridge = devm_kzalloc(panel->dev, sizeof(*panel_bridge), - GFP_KERNEL); - if (!panel_bridge) - return ERR_PTR(-ENOMEM); + panel_bridge = devm_drm_bridge_alloc(panel->dev, struct panel_bridge, bridge, + &panel_bridge_bridge_funcs); + if (IS_ERR(panel_bridge)) + return (void *)panel_bridge; panel_bridge->connector_type = connector_type; panel_bridge->panel = panel; - panel_bridge->bridge.funcs = &panel_bridge_bridge_funcs; panel_bridge->bridge.of_node = panel->dev->of_node; panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES; panel_bridge->bridge.type = connector_type; @@ -939,8 +938,6 @@ EXPORT_SYMBOL(drm_panel_bridge_add_typed); */ void drm_panel_bridge_remove(struct drm_bridge *bridge) { - struct panel_bridge *panel_bridge; - if (!bridge) return; @@ -949,10 +946,7 @@ void drm_panel_bridge_remove(struct drm_bridge *bridge) return; } - panel_bridge = drm_bridge_to_panel_bridge(bridge); - drm_bridge_remove(bridge); - devm_kfree(panel_bridge->panel->dev, bridge); } EXPORT_SYMBOL(drm_panel_bridge_remove); -- 2.34.1