[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260107-drm-bridge-alloc-getput-drm_of_find_bridge-2-v1-12-283d7bba061a@bootlin.com>
Date: Wed, 07 Jan 2026 14:13:03 +0100
From: Luca Ceresoli <luca.ceresoli@...tlin.com>
To: Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
Maxime Ripard <mripard@...nel.org>, Thomas Zimmermann <tzimmermann@...e.de>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
Philippe Cornu <philippe.cornu@...com>, benjamin.gaignard@...aro.org,
Andrzej Hajda <andrzej.hajda@...el.com>,
Neil Armstrong <neil.armstrong@...aro.org>, Robert Foss <rfoss@...nel.org>,
Laurent Pinchart <Laurent.pinchart@...asonboard.com>,
Jonas Karlman <jonas@...boo.se>, Jernej Skrabec <jernej.skrabec@...il.com>,
Adrien Grassein <adrien.grassein@...il.com>, Liu Ying <victor.liu@....com>,
Shawn Guo <shawnguo@...nel.org>, Sascha Hauer <s.hauer@...gutronix.de>,
Pengutronix Kernel Team <kernel@...gutronix.de>,
Fabio Estevam <festevam@...il.com>, Inki Dae <inki.dae@...sung.com>,
Jagan Teki <jagan@...rulasolutions.com>,
Marek Szyprowski <m.szyprowski@...sung.com>
Cc: Hui Pu <Hui.Pu@...ealthcare.com>,
Thomas Petazzoni <thomas.petazzoni@...tlin.com>,
dri-devel@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
imx@...ts.linux.dev, linux-arm-kernel@...ts.infradead.org,
Luca Ceresoli <luca.ceresoli@...tlin.com>
Subject: [PATCH 12/12] drm/bridge: samsung-dsim: samsung_dsim_host_attach:
convert to of_drm_find_and_get_bridge()
of_drm_find_bridge() is deprecated. Move to its replacement
of_drm_find_and_get_bridge() which gets a bridge reference, and ensure it
is put when done. Also switch to the drm_bridge::next_bridge pointer.
This needs to handle both cases: when of_drm_find_panel() succeeds and when
it fails.
In the 'else' case (i.e. when of_drm_find_panel() fails), just switch to
of_drm_find_and_get_bridge() to ensure the bridge is not freed while in use
in the function tail, when it is stored in dsi->bridge.next_bridge.
In the 'then' case (i.e. when of_drm_find_panel() succeeds),
devm_drm_panel_bridge_add() already increments the refcount using devres
which ties the bridge allocation lifetime to the device lifetime, so we
would not need to do anything. However to have the same behaviour in both
branches take an additional reference here, so that the bridge needs to be
put whichever branch is taken without more complicated logic. Ensure to
clear the bridge pointer however, to avoid calling drm_bridge_put() on an
ERR_PTR.
Signed-off-by: Luca Ceresoli <luca.ceresoli@...tlin.com>
---
drivers/gpu/drm/bridge/samsung-dsim.c | 19 ++++++++++++-------
include/drm/bridge/samsung-dsim.h | 1 -
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index d6ef64e68623..e10c01672efd 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1828,7 +1828,7 @@ static int samsung_dsim_attach(struct drm_bridge *bridge,
{
struct samsung_dsim *dsi = bridge_to_dsi(bridge);
- return drm_bridge_attach(encoder, dsi->out_bridge, bridge,
+ return drm_bridge_attach(encoder, dsi->bridge.next_bridge, bridge,
flags);
}
@@ -1886,7 +1886,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
{
struct samsung_dsim *dsi = host_to_dsi(host);
const struct samsung_dsim_plat_data *pdata = dsi->plat_data;
- struct drm_bridge *next_bridge;
+ struct drm_bridge *next_bridge __free(drm_bridge_put) = NULL;
struct device *dev = dsi->dev;
struct device_node *np = dev->of_node;
struct device_node *remote;
@@ -1926,10 +1926,14 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
panel = of_drm_find_panel(remote);
if (!IS_ERR(panel)) {
next_bridge = devm_drm_panel_bridge_add(dev, panel);
- if (IS_ERR(next_bridge))
+ if (IS_ERR(next_bridge)) {
ret = PTR_ERR(next_bridge);
+ next_bridge = NULL; // Inhibit the cleanup action on an ERR_PTR
+ } else {
+ drm_bridge_get(next_bridge);
+ }
} else {
- next_bridge = of_drm_find_bridge(remote);
+ next_bridge = of_drm_find_and_get_bridge(remote);
if (!next_bridge)
ret = -EINVAL;
}
@@ -1969,7 +1973,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,
dsi->lanes = device->lanes;
dsi->format = device->format;
dsi->mode_flags = device->mode_flags;
- dsi->out_bridge = next_bridge;
+ dsi->bridge.next_bridge = drm_bridge_get(next_bridge);
return 0;
}
@@ -1988,8 +1992,6 @@ static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
struct samsung_dsim *dsi = host_to_dsi(host);
const struct samsung_dsim_plat_data *pdata = dsi->plat_data;
- dsi->out_bridge = NULL;
-
if (pdata->host_ops && pdata->host_ops->detach)
pdata->host_ops->detach(dsi, device);
@@ -1997,6 +1999,9 @@ static int samsung_dsim_host_detach(struct mipi_dsi_host *host,
drm_bridge_remove(&dsi->bridge);
+ drm_bridge_put(dsi->bridge.next_bridge);
+ dsi->bridge.next_bridge = NULL;
+
return 0;
}
diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h
index 31d7ed589233..03005e474704 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -100,7 +100,6 @@ struct samsung_dsim_plat_data {
struct samsung_dsim {
struct mipi_dsi_host dsi_host;
struct drm_bridge bridge;
- struct drm_bridge *out_bridge;
struct device *dev;
struct drm_display_mode mode;
--
2.52.0
Powered by blists - more mailing lists