* [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4
@ 2026-01-16 17:32 Luca Ceresoli
2026-01-16 17:32 ` [PATCH 1/6] drm: renesas: rz-du: rzg2l_du_encoder: convert to of_drm_find_and_get_bridge() Luca Ceresoli
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-16 17:32 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Linus Walleij, Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-renesas-soc,
linux-kernel, Luca Ceresoli
This series converts many DRM drivers from the now deprecated
of_drm_find_bridge() to its replacement of_drm_find_and_get_bridge() which
allows correct bridge refcounting. Where applicable it also converts
per-driver "next_bridge" pointers to the unified drm_bridge::next_bridge
which puts the reference automatically on bridge deallocation.
This is part of the work to support hotplug of DRM bridges. The grand plan
was discussed in [0].
Here's the work breakdown (➜ marks the current series):
1. ➜ add refcounting to DRM bridges struct drm_bridge,
based on devm_drm_bridge_alloc()
A. ✔ add new alloc API and refcounting (v6.16)
B. ✔ convert all bridge drivers to new API (v6.17)
C. ✔ kunit tests (v6.17)
D. ✔ add get/put to drm_bridge_add/remove() + attach/detach()
and warn on old allocation pattern (v6.17)
E. ➜ add get/put on drm_bridge accessors
1. ✔ drm_bridge_chain_get_first_bridge(), add cleanup action (v6.18)
2. ✔ drm_bridge_get_prev_bridge() (v6.18)
3. ✔ drm_bridge_get_next_bridge() (v6.19)
4. ✔ drm_for_each_bridge_in_chain() (v6.19)
5. ✔ drm_bridge_connector_init (v6.19)
6. … protect encoder bridge chain with a mutex
7. ➜ of_drm_find_bridge
a. ✔… add of_drm_get_bridge(), convert basic direct users
(v6.20?, one driver still pending)
b. … convert direct of_drm_get_bridge() users, part 2
c. … convert direct of_drm_get_bridge() users, part 3
d. ➜ convert direct of_drm_get_bridge() users, part 4
e. convert bridge-only drm_of_find_panel_or_bridge() users
8. drm_of_find_panel_or_bridge, *_of_get_bridge
9. ✔ enforce drm_bridge_add before drm_bridge_attach (v6.19)
F. ✔ debugfs improvements
1. ✔ add top-level 'bridges' file (v6.16)
2. ✔ show refcount and list lingering bridges (v6.19)
2. … handle gracefully atomic updates during bridge removal
A. ✔ Add drm_dev_enter/exit() to protect device resources (v6.20?)
B. … protect private_obj removal from list
3. … DSI host-device driver interaction
4. ✔ removing the need for the "always-disconnected" connector
5. finish the hotplug bridge work, moving code to the core and potentially
removing the hotplug-bridge itself (this needs to be clarified as
points 1-3 are developed)
[0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-0-9d6f2c9c3058@bootlin.com/#t
This work is a continuation of the work to correctly handle bridge
refcounting for existing of_drm_find_bridge(). The ground work is in:
- commit 293a8fd7721a ("drm/bridge: add of_drm_find_and_get_bridge()")
- commit 9da0e06abda8 ("drm/bridge: deprecate of_drm_find_bridge()")
- commit 3fdeae134ba9 ("drm/bridge: add next_bridge pointer to struct drm_bridge")
The whole conversion is split in multiple series to make the review process
a bit smoother:
- Part 2: mostly drivers in drivers/gpu/drm/bridge [2]
- Part 3: other drivers, low-medium complexity [3]
- Part 4: other drivers, converting the most complex cases [this series]
[2] https://lore.kernel.org/lkml/20260109-drm-bridge-alloc-getput-drm_of_find_bridge-2-v2-0-8bad3ef90b9f@bootlin.com/
[3] https://lore.kernel.org/lkml/20260109-drm-bridge-alloc-getput-drm_of_find_bridge-3-v2-0-8d7a3dbacdf4@bootlin.com/
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Luca Ceresoli (6):
drm: renesas: rz-du: rzg2l_du_encoder: convert to of_drm_find_and_get_bridge()
drm/kmb/dsi: convert to of_drm_find_and_get_bridge()
drm/mcde: dsi: warn in case of multiple subnodes
drm/mcde: dsi: convert to of_drm_find_and_get_bridge()
drm: rcar-du: encoder: convert to of_drm_find_and_get_bridge()
drm/omap: dss: convert to of_drm_find_and_get_bridge()
drivers/gpu/drm/kmb/kmb_dsi.c | 2 +-
drivers/gpu/drm/mcde/mcde_dsi.c | 16 ++++++++-----
drivers/gpu/drm/omapdrm/dss/output.c | 11 ++++++---
drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.c | 28 ++++++++++++++++++-----
drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.h | 1 +
drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 2 ++
drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c | 14 ++++++++----
7 files changed, 54 insertions(+), 20 deletions(-)
---
base-commit: 6821fd5cf409d7147441abedf31ec3e4daeb7b55
change-id: 20260107-drm-bridge-alloc-getput-drm_of_find_bridge-4-0a92b361fe9d
Best regards,
--
Luca Ceresoli <luca.ceresoli@bootlin.com>
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/6] drm: renesas: rz-du: rzg2l_du_encoder: convert to of_drm_find_and_get_bridge()
2026-01-16 17:32 [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4 Luca Ceresoli
@ 2026-01-16 17:32 ` Luca Ceresoli
2026-01-16 17:32 ` [PATCH 2/6] drm/kmb/dsi: " Luca Ceresoli
` (4 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-16 17:32 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Linus Walleij, Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-renesas-soc,
linux-kernel, Luca Ceresoli
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.
This is made somewhat simpler by the fact that 'bridge' is a local
variable.
However we need to handle both branches of the main if().
In the 'else' case, just switch to of_drm_find_and_get_bridge() to ensure
the bridge is not freed while in use in the function tail
(drm_bridge_attach() mainly).
In the 'then' case, devm_drm_panel_bridge_add_typed() 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@bootlin.com>
---
drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c
index 5e6dd16705e6..9b65bcefdb86 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_encoder.c
@@ -67,7 +67,7 @@ int rzg2l_du_encoder_init(struct rzg2l_du_device *rcdu,
{
struct rzg2l_du_encoder *renc;
struct drm_connector *connector;
- struct drm_bridge *bridge;
+ struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
int ret;
/*
@@ -83,10 +83,16 @@ int rzg2l_du_encoder_init(struct rzg2l_du_device *rcdu,
bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel,
DRM_MODE_CONNECTOR_DPI);
- if (IS_ERR(bridge))
- return PTR_ERR(bridge);
+ if (IS_ERR(bridge)) {
+ // Inhibit the cleanup action on an ERR_PTR
+ ret = PTR_ERR(bridge);
+ bridge = NULL;
+ return ret;
+ }
+
+ drm_bridge_get(bridge);
} else {
- bridge = of_drm_find_bridge(enc_node);
+ bridge = of_drm_find_and_get_bridge(enc_node);
if (!bridge)
return -EPROBE_DEFER;
}
--
2.52.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/6] drm/kmb/dsi: convert to of_drm_find_and_get_bridge()
2026-01-16 17:32 [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4 Luca Ceresoli
2026-01-16 17:32 ` [PATCH 1/6] drm: renesas: rz-du: rzg2l_du_encoder: convert to of_drm_find_and_get_bridge() Luca Ceresoli
@ 2026-01-16 17:32 ` Luca Ceresoli
2026-01-16 17:32 ` [PATCH 3/6] drm/mcde: dsi: warn in case of multiple subnodes Luca Ceresoli
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-16 17:32 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Linus Walleij, Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-renesas-soc,
linux-kernel, Luca Ceresoli
of_drm_find_bridge() is deprecated. Move to its replacement
of_drm_find_and_get_bridge() which gets a bridge reference.
This driver has global variables for the DSI host and DSI device, and code
to allocate them on probe but no code to free them when on remove. So it
does not at all support removal, and not even multiple instances. For this
reason putting the reference would be pointless here.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
drivers/gpu/drm/kmb/kmb_dsi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
index faf38ca9e44c..8c8908c3bf32 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.c
+++ b/drivers/gpu/drm/kmb/kmb_dsi.c
@@ -251,7 +251,7 @@ int kmb_dsi_host_bridge_init(struct device *dev)
return -EINVAL;
}
/* Locate drm bridge from the hdmi encoder DT node */
- adv_bridge = of_drm_find_bridge(encoder_node);
+ adv_bridge = of_drm_find_and_get_bridge(encoder_node);
of_node_put(dsi_out);
of_node_put(encoder_node);
if (!adv_bridge) {
--
2.52.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/6] drm/mcde: dsi: warn in case of multiple subnodes
2026-01-16 17:32 [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4 Luca Ceresoli
2026-01-16 17:32 ` [PATCH 1/6] drm: renesas: rz-du: rzg2l_du_encoder: convert to of_drm_find_and_get_bridge() Luca Ceresoli
2026-01-16 17:32 ` [PATCH 2/6] drm/kmb/dsi: " Luca Ceresoli
@ 2026-01-16 17:32 ` Luca Ceresoli
2026-01-19 8:54 ` Linus Walleij
2026-01-16 17:32 ` [PATCH 4/6] drm/mcde: dsi: convert to of_drm_find_and_get_bridge() Luca Ceresoli
` (2 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-16 17:32 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Linus Walleij, Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-renesas-soc,
linux-kernel, Luca Ceresoli
mcde_dsi_bind() has a loop over all subnodes looking for a panel, but does
not exit when a match is found and only stores the last match. However this
will be problematic when introducing refcounting on the struct drm_device
pointer in a following commit, because of_drm_find_and_get_bridge() would
get a reference to multiple bridges.
Assuming there is no real reason for looking for multiple panels, add a
warning so it gets noticed in case the assumption is wrong.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
I think the correct thing to do would be adding a break statement when
there is a match. However I don't have knowledge of this driver and the
hardware, thus this patch is a prudential alternative, not changing the
behaviour.
---
drivers/gpu/drm/mcde/mcde_dsi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
index a3423459dd7a..3faebe571fc2 100644
--- a/drivers/gpu/drm/mcde/mcde_dsi.c
+++ b/drivers/gpu/drm/mcde/mcde_dsi.c
@@ -1103,6 +1103,9 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
/* Look for a panel as a child to this node */
for_each_available_child_of_node(dev->of_node, child) {
+ /* There should be only one panel subnode */
+ WARN_ON(panel || bridge);
+
panel = of_drm_find_panel(child);
if (IS_ERR(panel)) {
dev_err(dev, "failed to find panel try bridge (%ld)\n",
--
2.52.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/6] drm/mcde: dsi: convert to of_drm_find_and_get_bridge()
2026-01-16 17:32 [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4 Luca Ceresoli
` (2 preceding siblings ...)
2026-01-16 17:32 ` [PATCH 3/6] drm/mcde: dsi: warn in case of multiple subnodes Luca Ceresoli
@ 2026-01-16 17:32 ` Luca Ceresoli
2026-01-19 8:57 ` Linus Walleij
2026-01-16 17:32 ` [PATCH 5/6] drm: rcar-du: encoder: " Luca Ceresoli
2026-01-16 17:32 ` [PATCH 6/6] drm/omap: dss: " Luca Ceresoli
5 siblings, 1 reply; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-16 17:32 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Linus Walleij, Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-renesas-soc,
linux-kernel, Luca Ceresoli
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.
We need to handle the two cases: when a panel is found and when it isn't,
even though the latter is not supported. So:
* in case a panel is not found and bridge is, get a reference to the
found bridge
* in case a panel is found, get a reference to the panel_bridge when it
is added, so the following code always get exactly one reference that
it needs to put
Finally, use the next_bridge pointer in struct drm_bridge in order to
simplify putting the reference.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
drivers/gpu/drm/mcde/mcde_dsi.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
index 3faebe571fc2..bd2135fd4293 100644
--- a/drivers/gpu/drm/mcde/mcde_dsi.c
+++ b/drivers/gpu/drm/mcde/mcde_dsi.c
@@ -40,7 +40,6 @@ struct mcde_dsi {
struct mcde *mcde;
struct drm_bridge bridge;
struct drm_panel *panel;
- struct drm_bridge *bridge_out;
struct mipi_dsi_host dsi_host;
struct mipi_dsi_device *mdsi;
const struct drm_display_mode *mode;
@@ -1060,7 +1059,7 @@ static int mcde_dsi_bridge_attach(struct drm_bridge *bridge,
}
/* Attach the DSI bridge to the output (panel etc) bridge */
- return drm_bridge_attach(encoder, d->bridge_out, bridge, flags);
+ return drm_bridge_attach(encoder, d->bridge.next_bridge, bridge, flags);
}
static const struct drm_bridge_funcs mcde_dsi_bridge_funcs = {
@@ -1076,7 +1075,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
struct mcde_dsi *d = dev_get_drvdata(dev);
struct device_node *child;
struct drm_panel *panel = NULL;
- struct drm_bridge *bridge = NULL;
+ struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
if (!of_get_available_child_count(dev->of_node)) {
dev_info(dev, "unused DSI interface\n");
@@ -1112,7 +1111,8 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
PTR_ERR(panel));
panel = NULL;
- bridge = of_drm_find_bridge(child);
+ drm_bridge_put(bridge); // In case of multiple matching loops
+ bridge = of_drm_find_and_get_bridge(child);
if (!bridge) {
dev_err(dev, "failed to find bridge\n");
of_node_put(child);
@@ -1127,6 +1127,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
dev_err(dev, "error adding panel bridge\n");
return PTR_ERR(bridge);
}
+ drm_bridge_get(bridge);
dev_info(dev, "connected to panel\n");
d->panel = panel;
} else if (bridge) {
@@ -1138,7 +1139,7 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,
return -ENODEV;
}
- d->bridge_out = bridge;
+ d->bridge.next_bridge = drm_bridge_get(bridge);
/* Create a bridge for this DSI channel */
d->bridge.of_node = dev->of_node;
@@ -1158,7 +1159,7 @@ static void mcde_dsi_unbind(struct device *dev, struct device *master,
struct mcde_dsi *d = dev_get_drvdata(dev);
if (d->panel)
- drm_panel_bridge_remove(d->bridge_out);
+ drm_panel_bridge_remove(d->bridge.next_bridge);
regmap_update_bits(d->prcmu, PRCM_DSI_SW_RESET,
PRCM_DSI_SW_RESET_DSI0_SW_RESETN, 0);
}
--
2.52.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 5/6] drm: rcar-du: encoder: convert to of_drm_find_and_get_bridge()
2026-01-16 17:32 [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4 Luca Ceresoli
` (3 preceding siblings ...)
2026-01-16 17:32 ` [PATCH 4/6] drm/mcde: dsi: convert to of_drm_find_and_get_bridge() Luca Ceresoli
@ 2026-01-16 17:32 ` Luca Ceresoli
2026-01-16 17:32 ` [PATCH 6/6] drm/omap: dss: " Luca Ceresoli
5 siblings, 0 replies; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-16 17:32 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Linus Walleij, Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-renesas-soc,
linux-kernel, Luca Ceresoli
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.
We need to handle the two cases: when a panel_bridge is added and when it
isn't. So:
* in the 'else' case a panel_bridge is not added and bridge is found: use
of_drm_find_and_get_bridge() to get a reference to the found bridge
* in the 'then' case a panel_bridge is found using a devm function which
already takes a refcount and will put it on removal, but we need to take
another so the following code in this function always get exactly one
reference that it needs to put
In order to put the reference, add the needed drm_bridge_put() calls in the
existing cleanup function.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.c | 28 ++++++++++++++++++-----
drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.h | 1 +
drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c | 2 ++
3 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.c
index 7ecec7b04a8d..5789fc75092f 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.c
@@ -51,7 +51,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
{
struct rcar_du_encoder *renc;
struct drm_connector *connector;
- struct drm_bridge *bridge;
+ struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
int ret;
/*
@@ -69,20 +69,26 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel,
DRM_MODE_CONNECTOR_DPI);
- if (IS_ERR(bridge))
- return PTR_ERR(bridge);
+ if (IS_ERR(bridge)) {
+ // Inhibit the cleanup action on an ERR_PTR
+ ret = PTR_ERR(bridge);
+ bridge = NULL;
+ return ret;
+ }
+
+ drm_bridge_get(bridge);
} else {
- bridge = of_drm_find_bridge(enc_node);
+ bridge = of_drm_find_and_get_bridge(enc_node);
if (!bridge)
return -EPROBE_DEFER;
if (output == RCAR_DU_OUTPUT_LVDS0 ||
output == RCAR_DU_OUTPUT_LVDS1)
- rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] = bridge;
+ rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] = drm_bridge_get(bridge);
if (output == RCAR_DU_OUTPUT_DSI0 ||
output == RCAR_DU_OUTPUT_DSI1)
- rcdu->dsi[output - RCAR_DU_OUTPUT_DSI0] = bridge;
+ rcdu->dsi[output - RCAR_DU_OUTPUT_DSI0] = drm_bridge_get(bridge);
}
/*
@@ -135,3 +141,13 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
return drm_connector_attach_encoder(connector, &renc->base);
}
+
+void rcar_du_encoder_cleanup(struct rcar_du_device *rcdu)
+{
+ int i;
+
+ for (i = 0; i < RCAR_DU_MAX_LVDS; i++)
+ drm_bridge_put(rcdu->lvds[i]);
+ for (i = 0; i < RCAR_DU_MAX_DSI; i++)
+ drm_bridge_put(rcdu->dsi[i]);
+}
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.h
index e5ec8fbb3979..b2b5e93f30f8 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.h
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.h
@@ -25,5 +25,6 @@ struct rcar_du_encoder {
int rcar_du_encoder_init(struct rcar_du_device *rcdu,
enum rcar_du_output output,
struct device_node *enc_node);
+void rcar_du_encoder_cleanup(struct rcar_du_device *rcdu);
#endif /* __RCAR_DU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
index 6294443f6068..15d301ab5eef 100644
--- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c
@@ -836,6 +836,8 @@ static void rcar_du_modeset_cleanup(struct drm_device *dev, void *res)
for (i = 0; i < ARRAY_SIZE(rcdu->cmms); ++i)
platform_device_put(rcdu->cmms[i]);
+
+ rcar_du_encoder_cleanup(rcdu);
}
int rcar_du_modeset_init(struct rcar_du_device *rcdu)
--
2.52.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 6/6] drm/omap: dss: convert to of_drm_find_and_get_bridge()
2026-01-16 17:32 [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4 Luca Ceresoli
` (4 preceding siblings ...)
2026-01-16 17:32 ` [PATCH 5/6] drm: rcar-du: encoder: " Luca Ceresoli
@ 2026-01-16 17:32 ` Luca Ceresoli
5 siblings, 0 replies; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-16 17:32 UTC (permalink / raw)
To: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Linus Walleij, Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen
Cc: Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-renesas-soc,
linux-kernel, Luca Ceresoli
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.
omapdss_device_init_output() can take one bridge pointer in out->bridge or
two pointers in out->bridge and out->next_bridge. Ensure each has a
corresponding drm_bridge_get() and add drm_bridge_put() calls in the
cleanup code.
Also slightly change the initial code assigning out->panel and out->bridge
to ensure and clarify that either out->panel or out->bridge is set in the
function prologue, not both. If both were set, the 'if (out->panel){...}'
code that follows would overwrite out->bridge without having put the
reference.
Finally, take a reference in case a panel_bridge is added using
drm_panel_bridge_add(). This ensures we always need to put a reference,
which came either from of_drm_find_and_get_bridge() or by the
drm_panel_bridge_add+drm_bridge_get() branch.
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
drivers/gpu/drm/omapdrm/dss/output.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c b/drivers/gpu/drm/omapdrm/dss/output.c
index 7378e855c278..ca891aba3820 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -30,11 +30,13 @@ int omapdss_device_init_output(struct omap_dss_device *out,
return 0;
}
- out->bridge = of_drm_find_bridge(remote_node);
out->panel = of_drm_find_panel(remote_node);
if (IS_ERR(out->panel))
out->panel = NULL;
+ if (!out->panel)
+ out->bridge = of_drm_find_and_get_bridge(remote_node);
+
of_node_put(remote_node);
if (out->panel) {
@@ -49,7 +51,7 @@ int omapdss_device_init_output(struct omap_dss_device *out,
goto error;
}
- out->bridge = bridge;
+ out->bridge = drm_bridge_get(bridge);
}
if (local_bridge) {
@@ -59,7 +61,7 @@ int omapdss_device_init_output(struct omap_dss_device *out,
}
out->next_bridge = out->bridge;
- out->bridge = local_bridge;
+ out->bridge = drm_bridge_get(local_bridge);
}
if (!out->bridge) {
@@ -79,6 +81,9 @@ void omapdss_device_cleanup_output(struct omap_dss_device *out)
if (out->bridge && out->panel)
drm_panel_bridge_remove(out->next_bridge ?
out->next_bridge : out->bridge);
+
+ drm_bridge_put(out->next_bridge);
+ drm_bridge_put(out->bridge);
}
void dss_mgr_set_timings(struct omap_dss_device *dssdev,
--
2.52.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/6] drm/mcde: dsi: warn in case of multiple subnodes
2026-01-16 17:32 ` [PATCH 3/6] drm/mcde: dsi: warn in case of multiple subnodes Luca Ceresoli
@ 2026-01-19 8:54 ` Linus Walleij
2026-01-31 15:26 ` Luca Ceresoli
0 siblings, 1 reply; 11+ messages in thread
From: Linus Walleij @ 2026-01-19 8:54 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen, Hui Pu, Ian Ray,
Thomas Petazzoni, dri-devel, linux-renesas-soc, linux-kernel
On Fri, Jan 16, 2026 at 6:33 PM Luca Ceresoli <luca.ceresoli@bootlin.com> wrote:
> mcde_dsi_bind() has a loop over all subnodes looking for a panel, but does
> not exit when a match is found and only stores the last match. However this
> will be problematic when introducing refcounting on the struct drm_device
> pointer in a following commit, because of_drm_find_and_get_bridge() would
> get a reference to multiple bridges.
>
> Assuming there is no real reason for looking for multiple panels, add a
> warning so it gets noticed in case the assumption is wrong.
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>
> ---
>
> I think the correct thing to do would be adding a break statement when
> there is a match. However I don't have knowledge of this driver and the
> hardware, thus this patch is a prudential alternative, not changing the
> behaviour.
Go ahead and insert a break when the panel is found, there is
no MCDE-attached device with more than one panel.
There *exist* the Samsung Gavini device which has a
LED panel, *and* the same lines attached to a mini-projector
so these two can be used at the same time. I have no idea
how to actually deal with that if someone one day want to
support it. Probably by putting the projector as a side thing
and not deal with the video stream in the device tree.
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/6] drm/mcde: dsi: convert to of_drm_find_and_get_bridge()
2026-01-16 17:32 ` [PATCH 4/6] drm/mcde: dsi: convert to of_drm_find_and_get_bridge() Luca Ceresoli
@ 2026-01-19 8:57 ` Linus Walleij
2026-01-31 15:27 ` Luca Ceresoli
0 siblings, 1 reply; 11+ messages in thread
From: Linus Walleij @ 2026-01-19 8:57 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen, Hui Pu, Ian Ray,
Thomas Petazzoni, dri-devel, linux-renesas-soc, linux-kernel
On Fri, Jan 16, 2026 at 6:33 PM Luca Ceresoli <luca.ceresoli@bootlin.com> wrote:
> 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.
>
> We need to handle the two cases: when a panel is found and when it isn't,
> even though the latter is not supported. So:
>
> * in case a panel is not found and bridge is, get a reference to the
> found bridge
> * in case a panel is found, get a reference to the panel_bridge when it
> is added, so the following code always get exactly one reference that
> it needs to put
>
> Finally, use the next_bridge pointer in struct drm_bridge in order to
> simplify putting the reference.
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
I do not understand the change as a whole but the approach
looks sane so:
Acked-by: Linus Walleij <linusw@kernel.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/6] drm/mcde: dsi: warn in case of multiple subnodes
2026-01-19 8:54 ` Linus Walleij
@ 2026-01-31 15:26 ` Luca Ceresoli
0 siblings, 0 replies; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-31 15:26 UTC (permalink / raw)
To: Linus Walleij
Cc: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen, Hui Pu, Ian Ray,
Thomas Petazzoni, dri-devel, linux-renesas-soc, linux-kernel
Hello Linus,
On Mon Jan 19, 2026 at 9:54 AM CET, Linus Walleij wrote:
> On Fri, Jan 16, 2026 at 6:33 PM Luca Ceresoli <luca.ceresoli@bootlin.com> wrote:
>
>> mcde_dsi_bind() has a loop over all subnodes looking for a panel, but does
>> not exit when a match is found and only stores the last match. However this
>> will be problematic when introducing refcounting on the struct drm_device
>> pointer in a following commit, because of_drm_find_and_get_bridge() would
>> get a reference to multiple bridges.
>>
>> Assuming there is no real reason for looking for multiple panels, add a
>> warning so it gets noticed in case the assumption is wrong.
>>
>> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>>
>> ---
>>
>> I think the correct thing to do would be adding a break statement when
>> there is a match. However I don't have knowledge of this driver and the
>> hardware, thus this patch is a prudential alternative, not changing the
>> behaviour.
>
> Go ahead and insert a break when the panel is found, there is
> no MCDE-attached device with more than one panel.
>
> There *exist* the Samsung Gavini device which has a
> LED panel, *and* the same lines attached to a mini-projector
> so these two can be used at the same time. I have no idea
> how to actually deal with that if someone one day want to
> support it. Probably by putting the projector as a side thing
> and not deal with the video stream in the device tree.
Thanks for sharing these info! I'm very happy to know I can break instead
of warning here. Change queued for v2.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/6] drm/mcde: dsi: convert to of_drm_find_and_get_bridge()
2026-01-19 8:57 ` Linus Walleij
@ 2026-01-31 15:27 ` Luca Ceresoli
0 siblings, 0 replies; 11+ messages in thread
From: Luca Ceresoli @ 2026-01-31 15:27 UTC (permalink / raw)
To: Linus Walleij
Cc: Biju Das, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Anitha Chrisanthus, Edmund Dea,
Laurent Pinchart, Tomi Valkeinen, Kieran Bingham,
Geert Uytterhoeven, Magnus Damm, Tomi Valkeinen, Hui Pu, Ian Ray,
Thomas Petazzoni, dri-devel, linux-renesas-soc, linux-kernel
Hello Linus,
On Mon Jan 19, 2026 at 9:57 AM CET, Linus Walleij wrote:
> On Fri, Jan 16, 2026 at 6:33 PM Luca Ceresoli <luca.ceresoli@bootlin.com> wrote:
>
>> 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.
>>
>> We need to handle the two cases: when a panel is found and when it isn't,
>> even though the latter is not supported. So:
>>
>> * in case a panel is not found and bridge is, get a reference to the
>> found bridge
>> * in case a panel is found, get a reference to the panel_bridge when it
>> is added, so the following code always get exactly one reference that
>> it needs to put
>>
>> Finally, use the next_bridge pointer in struct drm_bridge in order to
>> simplify putting the reference.
>>
>> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>
> I do not understand the change as a whole but the approach
> looks sane so:
> Acked-by: Linus Walleij <linusw@kernel.org>
Thanks!
However I'm not adding your A-by to v2. The change you suggested to patch 3
(break instead of warn) made the drm_bridge_put() call in this patch
unnecessary, so I dropped it for v2, making this patch slightly different.
I hope you'll Ack v2 too. :)
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-01-31 15:27 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-01-16 17:32 [PATCH 0/6] drm/bridge: convert users of of_drm_find_bridge(), part 4 Luca Ceresoli
2026-01-16 17:32 ` [PATCH 1/6] drm: renesas: rz-du: rzg2l_du_encoder: convert to of_drm_find_and_get_bridge() Luca Ceresoli
2026-01-16 17:32 ` [PATCH 2/6] drm/kmb/dsi: " Luca Ceresoli
2026-01-16 17:32 ` [PATCH 3/6] drm/mcde: dsi: warn in case of multiple subnodes Luca Ceresoli
2026-01-19 8:54 ` Linus Walleij
2026-01-31 15:26 ` Luca Ceresoli
2026-01-16 17:32 ` [PATCH 4/6] drm/mcde: dsi: convert to of_drm_find_and_get_bridge() Luca Ceresoli
2026-01-19 8:57 ` Linus Walleij
2026-01-31 15:27 ` Luca Ceresoli
2026-01-16 17:32 ` [PATCH 5/6] drm: rcar-du: encoder: " Luca Ceresoli
2026-01-16 17:32 ` [PATCH 6/6] drm/omap: dss: " Luca Ceresoli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®