Skip to content

Commit 803ec1f

Browse files
osamakaderlucaceresoli
authored andcommitted
drm/bridge: samsung-dsim: Fix memory leak in error path
In samsung_dsim_host_attach(), drm_bridge_add() is called to add the bridge. However, if samsung_dsim_register_te_irq() or pdata->host_ops->attach() fails afterwards, the function returns without removing the bridge, causing a memory leak. Fix this by adding proper error handling with goto labels to ensure drm_bridge_remove() is called in all error paths. Also ensure that samsung_dsim_unregister_te_irq() is called if the attach operation fails after the TE IRQ has been registered. samsung_dsim_unregister_te_irq() function is moved without changes to be before samsung_dsim_host_attach() to avoid forward declaration. Fixes: e744712 ("drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge") Cc: stable@vger.kernel.org Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com> Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> Link: https://patch.msgid.link/20260209184115.10937-1-osama.abdelkader@gmail.com Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
1 parent 496daa2 commit 803ec1f

1 file changed

Lines changed: 16 additions & 9 deletions

File tree

drivers/gpu/drm/bridge/samsung-dsim.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,6 +1881,14 @@ static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device
18811881
return 0;
18821882
}
18831883

1884+
static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)
1885+
{
1886+
if (dsi->te_gpio) {
1887+
free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
1888+
gpiod_put(dsi->te_gpio);
1889+
}
1890+
}
1891+
18841892
static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
18851893
struct mipi_dsi_device *device)
18861894
{
@@ -1955,28 +1963,27 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
19551963
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {
19561964
ret = samsung_dsim_register_te_irq(dsi, &device->dev);
19571965
if (ret)
1958-
return ret;
1966+
goto err_remove_bridge;
19591967
}
19601968

19611969
if (pdata->host_ops && pdata->host_ops->attach) {
19621970
ret = pdata->host_ops->attach(dsi, device);
19631971
if (ret)
1964-
return ret;
1972+
goto err_unregister_te_irq;
19651973
}
19661974

19671975
dsi->lanes = device->lanes;
19681976
dsi->format = device->format;
19691977
dsi->mode_flags = device->mode_flags;
19701978

19711979
return 0;
1972-
}
19731980

1974-
static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)
1975-
{
1976-
if (dsi->te_gpio) {
1977-
free_irq(gpiod_to_irq(dsi->te_gpio), dsi);
1978-
gpiod_put(dsi->te_gpio);
1979-
}
1981+
err_unregister_te_irq:
1982+
if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO))
1983+
samsung_dsim_unregister_te_irq(dsi);
1984+
err_remove_bridge:
1985+
drm_bridge_remove(&dsi->bridge);
1986+
return ret;
19801987
}
19811988

19821989
static int samsung_dsim_host_detach(struct mipi_dsi_host *host,

0 commit comments

Comments
 (0)