[PATCH] drm/bridge: dw-mipi-dsi: Fix bridge leak when host attach fails

From: Osama Abdelkader

Date: Thu Apr 02 2026 - 17:03:35 EST


dw_mipi_dsi_host_attach() and dw_mipi_dsi2_host_attach() call
drm_bridge_add() before pdata->host_ops->attach(). If attach fails,
the bridge stayed registered without drm_bridge_remove(), leaking the
bridge reference and leaving the device on the global bridge list.

On failure, undo in the same order as host_detach(): for dw-mipi-dsi,
drm_of_panel_bridge_remove() then drm_bridge_remove(); for dw-mipi-dsi2,
drm_bridge_remove() then drm_of_panel_bridge_remove().

Fixes: 90910a651123 ("drm/bridge/synopsys: dsi: add ability to have glue-specific attach and detach")
Fixes: 0d6d86253fef ("drm/bridge/synopsys: Add MIPI DSI2 host controller bridge")
Signed-off-by: Osama Abdelkader <osama.abdelkader@xxxxxxxxx>
---
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 7 ++++++-
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c | 7 ++++++-
2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index ca4dea226f4b..ffa169c2de73 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -345,10 +345,15 @@ static int dw_mipi_dsi_host_attach(struct mipi_dsi_host *host,
if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0)
- return ret;
+ goto err_remove_bridge;
}

return 0;
+
+err_remove_bridge:
+ drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
+ drm_bridge_remove(&dsi->bridge);
+ return ret;
}

static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
index e6eaf9fd0251..d7c922d8841c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c
@@ -540,10 +540,15 @@ static int dw_mipi_dsi2_host_attach(struct mipi_dsi_host *host,
if (pdata->host_ops && pdata->host_ops->attach) {
ret = pdata->host_ops->attach(pdata->priv_data, device);
if (ret < 0)
- return ret;
+ goto err_remove_bridge;
}

return 0;
+
+err_remove_bridge:
+ drm_bridge_remove(&dsi2->bridge);
+ drm_of_panel_bridge_remove(host->dev->of_node, 1, 0);
+ return ret;
}

static int dw_mipi_dsi2_host_detach(struct mipi_dsi_host *host,
--
2.43.0