tegra_dsi_driver leaks a device reference, which is obtained by of_find_device_by_node() in tegra_dsi_ganged_probe(). Add a function tegra_dsi_ganged_put() and call it in the error path of .probe() and in .remove(). This bug was found by an experimental verification tool that I am developing. Fixes: e94236cde4d5 ("drm/tegra: dsi: Add ganged mode support") Signed-off-by: Joe Hattori <joe@xxxxxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/tegra/dsi.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 4a8cd9ed0a94..4225b1979f64 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -1561,6 +1561,12 @@ static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi) return 0; } +static void tegra_dsi_ganged_put(struct tegra_dsi *dsi) +{ + if (dsi->slave) + put_device(dsi->slave->dev); +} + static int tegra_dsi_probe(struct platform_device *pdev) { struct tegra_dsi *dsi; @@ -1581,7 +1587,7 @@ static int tegra_dsi_probe(struct platform_device *pdev) err = tegra_output_probe(&dsi->output); if (err < 0) - return err; + goto put_ganged; dsi->output.connector.polled = DRM_CONNECTOR_POLL_HPD; @@ -1681,6 +1687,8 @@ static int tegra_dsi_probe(struct platform_device *pdev) tegra_mipi_free(dsi->mipi); remove: tegra_output_remove(&dsi->output); +put_ganged: + tegra_dsi_ganged_put(dsi); return err; } @@ -1694,6 +1702,8 @@ static void tegra_dsi_remove(struct platform_device *pdev) tegra_output_remove(&dsi->output); + tegra_dsi_ganged_put(dsi); + mipi_dsi_host_unregister(&dsi->host); tegra_mipi_free(dsi->mipi); } -- 2.34.1