[PATCH RFC v2 00/19] drm/panel: embed a drm_bridge into every drm_panel

From: Luca Ceresoli

Date: Thu Sep 03 2026 - 04:18:40 EST


This series embeds a drm_bridge into every drm_panel, as previously
discussed [1][2] and in v1.

This will allow bridges and encoders to interact with the next pipeline
component always with the bridge API, not caring whether it is a panel or
another device (e.g. a bridge from a bus to another bus).

Currently a drm_panel does not have a corresponding drm_bridge when it is
created. A panel_bridge is often created afterwards by the component
accessing it (typically the previous bridge or encoder). This creates a
mismatch between the drm_panel and the drm_bridge (part of the
panel_bridge), in terms of lifetime and devm ownership. It also makes
implementing bridge hotplug close to impossible in some cases.

This work leverages the work done by Anusha Srivatsa and Albert Esteve to
implement drm_panel lifetime.

== RFC status

Embedding a drm_bridge does not automatically prevent the creation of the
now-legacy one (panel_bridge). All drivers have to be adapted to not create
a panel_bridge, or there would be two drm_bridges for the same drm_panel.

This is an RFC because not all drivers are converted yet. The goal now is
discussing the core changes, while driver conversion progresses.

When all drivers are converted, the entire panel_bridge (bridge/panel.c)
and related functions such as drm_of_find_panel_or_bridge() can be removed.

== Series outline

1. move code to modules to prevent dependency loops during the transition

drm: of: move drm_of_find_panel_or_bridge() from drm_of.c to bridge/panel.c
drm/bridge: panel: move to a new module
drm/panel: move to a new module
drm/bridge: panel: rename drm_bridge_is_panel() -> drm_bridge_is_panel_bridge()

2. The main commit

drm/panel: embed a drm_bridge into every drm_panel

3. Update *some* drivers to not create a panel_bridge for the same panel

drm/bridge: tc358767: don't create a panel_bridge
drm/bridge: waveshare-dsi: don't create a panel_bridge
drm/mcde: dsi: simplify device_node management using scoped for_each variant
drm/mcde: dsi: remove unused includes
drm/mcde: dsi: don't create a panel_bridge
drm/bridge: fsl-ldb: don't create a panel_bridge
drm/bridge: samsung-dsim: don't create a panel_bridge
drm/bridge: tc358768: don't create a panel_bridge
drm/bridge: ssd2825: don't create a panel_bridge
drm/omap: dsi: remove unused includes
drm/omap: dss: don't create a panel_bridge
drm/tve200: remove unused includes
drm/tve200: don't create a panel_bridge
drm/bridge: analogix_dp: don't create a panel_bridge

4. Remove bridge/panel.c, drm_of_find_panel_or_bridge() and related code

TODO

== Dependencies

This series depends on:

* "drm/bridge: Kconfig: cleanup DRM_PANEL usage"
https://lore.kernel.org/r/20260831-drm-bridge-drm_panel-cleanup-v3-0-50efd8168b3e@xxxxxxxxxxx
Reason: trivial, both touch drivers/gpu/drm/bridge/Kconfig, would
conflict otherwise

== Grand plan

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 (v7.2)
7. ✔ of_drm_find_bridge
a. ✔ add of_drm_get_bridge() (v7.0),
convert basic direct users (v7.0-v7.1)
b. ✔ convert direct of_drm_get_bridge() users, part 2 (v7.0)
c. ✔ convert direct of_drm_get_bridge() users, part 3 (v7.0)
d. ✔ convert direct of_drm_get_bridge() users, part 4 (v7.1-v7.2)
e. ✔ bridge-only drm_of_find_panel_or_bridge() users (v7.2)
8. ➜ panel_bridge lifetime
a. … cleanup DRM_PANEL in bridge drivers
b. ➜ add a panel_bridge to every panel
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_bridge_enter/exit() to protect device resources (v7.0)
B. ✔ Add drm_bridge_clear_and_put() (v7.1)
3. … DSI host-device driver interaction
4. ✔ removing the need for the "always-disconnected" connector
5. ✔ Migrate i.MX LCDIF driver to bridge-connector (v7.2)
6. … DRM bridge hotplug
A. … Bridge hotplug management in the DRM core
1. ✔ bridge-connector: attach encoder to the connector (v7.2)
2. … drm bridge hotplug
B. Device tree description

[0] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-0-9d6f2c9c3058@xxxxxxxxxxx/#t

[1] https://lore.kernel.org/all/emuj2innmp6zmzd7pyakqzjqpdzhly6qfhakya3ydwmd63pl26@5jwxaidpikjw/
[2] https://lore.kernel.org/lkml/20250206-hotplug-drm-bridge-v6-8-9d6f2c9c3058@xxxxxxxxxxx/

Signed-off-by: Luca Ceresoli <luca.ceresoli@xxxxxxxxxxx>
---
Changes in v2:
- Totally new approach: embed a drm_bridge, don't create it dynamically
- New approach to module dependencies management: new drm_panel module etc
- Convert more drivers, including a complex, multi-user one (analogix_dp)
- Add Albert and Anusha to Cc list
- Minor improvements
- Link to v1: https://patch.msgid.link/20260814-drm-bridge-every-panel-v1-0-19cd5277cc8d@xxxxxxxxxxx

---
Luca Ceresoli (19):
drm: of: move drm_of_find_panel_or_bridge() from drm_of.c to bridge/panel.c
drm/bridge: panel: move to a new module
drm/panel: move to a new module
drm/bridge: panel: rename drm_bridge_is_panel() -> drm_bridge_is_panel_bridge()
drm/panel: embed a drm_bridge into every drm_panel
drm/bridge: tc358767: don't create a panel_bridge
drm/bridge: waveshare-dsi: don't create a panel_bridge
drm/mcde: dsi: simplify device_node management using scoped for_each variant
drm/mcde: dsi: remove unused includes
drm/mcde: dsi: don't create a panel_bridge
drm/bridge: fsl-ldb: don't create a panel_bridge
drm/bridge: samsung-dsim: don't create a panel_bridge
drm/bridge: tc358768: don't create a panel_bridge
drm/bridge: ssd2825: don't create a panel_bridge
drm/omap: dsi: remove unused includes
drm/omap: dss: don't create a panel_bridge
drm/tve200: remove unused includes
drm/tve200: don't create a panel_bridge
drm/bridge: analogix_dp: don't create a panel_bridge

drivers/gpu/drm/Makefile | 5 +-
drivers/gpu/drm/bridge/Kconfig | 12 +-
drivers/gpu/drm/bridge/analogix/Kconfig | 2 +
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 40 ++--
drivers/gpu/drm/bridge/fsl-ldb.c | 19 +-
drivers/gpu/drm/bridge/panel.c | 74 +++++-
drivers/gpu/drm/bridge/samsung-dsim.c | 24 +-
drivers/gpu/drm/bridge/ssd2825.c | 23 +-
drivers/gpu/drm/bridge/tc358767.c | 64 ++---
drivers/gpu/drm/bridge/tc358768.c | 25 +-
drivers/gpu/drm/bridge/waveshare-dsi.c | 17 +-
drivers/gpu/drm/display/drm_bridge_connector.c | 2 +-
drivers/gpu/drm/drm_of.c | 63 -----
drivers/gpu/drm/drm_panel.c | 258 +++++++++++++++++++--
drivers/gpu/drm/exynos/exynos_dp.c | 36 +--
drivers/gpu/drm/fsl-dcu/Kconfig | 1 +
drivers/gpu/drm/imx/dcss/Kconfig | 2 +
drivers/gpu/drm/ingenic/Kconfig | 1 +
drivers/gpu/drm/logicvc/Kconfig | 2 +
drivers/gpu/drm/mcde/Kconfig | 2 +-
drivers/gpu/drm/mcde/mcde_dsi.c | 50 +---
drivers/gpu/drm/omapdrm/dss/dsi.c | 1 -
drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 -
drivers/gpu/drm/omapdrm/dss/output.c | 42 +---
drivers/gpu/drm/omapdrm/omap_drv.c | 1 -
drivers/gpu/drm/panel/Kconfig | 2 +-
drivers/gpu/drm/pl111/Kconfig | 1 +
drivers/gpu/drm/renesas/rcar-du/Kconfig | 1 +
drivers/gpu/drm/rockchip/Kconfig | 4 +
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 -
drivers/gpu/drm/stm/Kconfig | 1 +
drivers/gpu/drm/sun4i/Kconfig | 1 +
drivers/gpu/drm/tegra/Kconfig | 1 +
drivers/gpu/drm/tidss/Kconfig | 2 +
drivers/gpu/drm/tve200/Kconfig | 2 +-
drivers/gpu/drm/tve200/tve200_display.c | 1 -
drivers/gpu/drm/tve200/tve200_drm.h | 1 -
drivers/gpu/drm/tve200/tve200_drv.c | 31 +--
include/drm/bridge/analogix_dp.h | 1 -
include/drm/drm_bridge.h | 20 +-
include/drm/drm_of.h | 12 -
include/drm/drm_panel.h | 37 +--
42 files changed, 475 insertions(+), 419 deletions(-)
---
base-commit: 0097858c2acde041f2c4c9f5ac90ab251b5bc647
change-id: 20260812-drm-bridge-every-panel-a1596d6efea4

Best regards,
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com