[PATCH v3 00/19] drm/panel: embed a drm_bridge into every drm_panel
From: Luca Ceresoli
Date: Wed Sep 16 2026 - 09:54:48 EST
This series embeds a drm_bridge into every drm_panel, as previously
discussed [1][2] and in previous iterations.
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.
== panel_bridge API impact
This series moves the panel_bridge code inside drm_panel.c and changes it
to be reusable by the panel code. However this implies the old panel_bridge
behaviour (drm_panel_bridge_add() and derivatives create a panel_bridge, to
name one) cannot coexist with the new behaviour (devm_drm_panel_alloc()
allocates an embedded drm_bridge and initializes it).
To handle this, the old panel_bridge API is kept to not break its users,
but now behaves differently:
* drm_panel_bridge_add() and derivatives don't create a bridge, they
just drm_bridge_get() and return a pointer to the existing one
* drm_panel_bridge_remove() and devm_drm_panel_bridge_release() don't
remove the bridge, they just drm-bridge_put() it
* The other panel_bridge functions stack on those listed in the previous 2
bullets, so their behaviour is changed correspondingly
As a result, all drivers using the panel_bridge now behave the new way
without any changes. Converting them to not stop using the panel_bridge is
a goal, but can be done over time. Still this series converts a few
drivers.
== Series outline
1. move code around in preparation
drm: of: move drm_of_find_panel_or_bridge() from drm_of.c to drm_panel.c
drm: of: remove now unnecessary forward declarations
drm/panel: move to a new module
drm/bridge: panel: move all code to drm_panel.c
2. The main change
drm/panel: embed a drm_bridge into every drm_panel
3. API cleanup
drm/bridge: remove devm_drm_put_bridge()
drm/panel: deprecate panel-bridge APIs
drm/todo: add entry for removing the panel_bridge API
4. Update some drivers to not create a panel_bridge
drm/bridge: tc358767: don't create a panel_bridge
drm/bridge: waveshare-dsi: don't create a panel_bridge
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: dss: don't create a panel_bridge
drm/tve200: don't create a panel_bridge
drm/bridge: analogix_dp: don't create a panel_bridge
== Dependencies
This series depends on:
* "drm/bridge: Kconfig: cleanup DRM_PANEL usage"
https://lore.kernel.org/r/20260915-drm-bridge-drm_panel-cleanup-v4-0-30401d9406f3@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 v3:
- Move the panel_bridge code to drm_panel.c, don't duplicate it, and change
the panel_bridge API to just wrap the newly embedded drm_bridge
- Remove deprecated devm_drm_put_bridge() and TODO entry
- Deprecate panel_bridge APIA, add TODO entry for its removal
- Link to v2: https://patch.msgid.link/20260903-drm-bridge-every-panel-v2-0-2ab8ee24538e@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 drm_panel.c
drm: of: remove now unnecessary forward declarations
drm/panel: move to a new module
drm/bridge: panel: move all code to drm_panel.c
drm/panel: embed a drm_bridge into every drm_panel
drm/bridge: remove devm_drm_put_bridge()
drm/panel: deprecate panel-bridge APIs
drm/todo: add entry for removing the panel_bridge API
drm/bridge: tc358767: don't create a panel_bridge
drm/bridge: waveshare-dsi: don't create a panel_bridge
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: dss: don't create a panel_bridge
drm/tve200: don't create a panel_bridge
drm/bridge: analogix_dp: don't create a panel_bridge
Documentation/gpu/todo.rst | 33 +-
drivers/gpu/drm/Makefile | 3 +-
drivers/gpu/drm/adp/adp-mipi.c | 1 +
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 1 +
drivers/gpu/drm/bridge/Kconfig | 10 +-
drivers/gpu/drm/bridge/analogix/Kconfig | 1 +
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 40 +-
drivers/gpu/drm/bridge/aux-bridge.c | 1 +
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 1 +
drivers/gpu/drm/bridge/fsl-ldb.c | 19 +-
drivers/gpu/drm/bridge/imx/imx93-pdfc.c | 1 +
drivers/gpu/drm/bridge/panel.c | 563 -----------------
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/ti-tdp158.c | 1 +
drivers/gpu/drm/bridge/waveshare-dsi.c | 17 +-
drivers/gpu/drm/display/drm_bridge_connector.c | 1 +
drivers/gpu/drm/drm_bridge.c | 17 -
drivers/gpu/drm/drm_of.c | 63 --
drivers/gpu/drm/drm_panel.c | 664 +++++++++++++++++++--
drivers/gpu/drm/exynos/exynos_dp.c | 36 +-
drivers/gpu/drm/imx/dc/dc-kms.c | 1 +
drivers/gpu/drm/imx/dcss/Kconfig | 1 +
drivers/gpu/drm/ingenic/Kconfig | 1 +
drivers/gpu/drm/logicvc/Kconfig | 1 +
drivers/gpu/drm/mcde/Kconfig | 2 +-
drivers/gpu/drm/mcde/mcde_display.c | 1 +
drivers/gpu/drm/mcde/mcde_dsi.c | 45 +-
drivers/gpu/drm/msm/dp/dp_display.c | 1 +
drivers/gpu/drm/msm/dsi/dsi.c | 3 +-
drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 -
drivers/gpu/drm/omapdrm/dss/output.c | 42 +-
drivers/gpu/drm/panel/Kconfig | 2 +-
drivers/gpu/drm/pl111/Kconfig | 1 +
drivers/gpu/drm/rockchip/Kconfig | 2 +
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 -
drivers/gpu/drm/stm/Kconfig | 1 +
drivers/gpu/drm/tegra/rgb.c | 1 +
drivers/gpu/drm/tidss/Kconfig | 1 +
drivers/gpu/drm/tve200/Kconfig | 2 +-
drivers/gpu/drm/tve200/tve200_drm.h | 1 -
drivers/gpu/drm/tve200/tve200_drv.c | 30 +-
include/drm/bridge/analogix_dp.h | 1 -
include/drm/drm_bridge.h | 54 --
include/drm/drm_of.h | 15 +-
include/drm/drm_panel.h | 99 ++-
48 files changed, 855 insertions(+), 1072 deletions(-)
---
base-commit: acb05c825e393b0584adb5472bfbb17c8033a99f
change-id: 20260812-drm-bridge-every-panel-a1596d6efea4
prerequisite-change-id: 20260812-drm-bridge-drm_panel-cleanup-09ed5cc10948:v4
prerequisite-patch-id: e15ab172f92263f58d86253708d0ad31d0a876e2
prerequisite-patch-id: 8e8841279db302d98d060c2311781c51673031cd
prerequisite-patch-id: 45c8dac16aad1187d7573c3680117954544b75ff
prerequisite-patch-id: 9afefac08440b7aab2979bb919baf78ba60af1c0
prerequisite-patch-id: 904a81179c02e6a3fe9e85d9a356cf265a4f4d11
prerequisite-patch-id: 665576b9273a19567a410888e2eaf1ac3221ae3e
prerequisite-patch-id: 9578cfffb25341935a89501736a5a59e59c50c56
prerequisite-patch-id: ec32062a627672377ee6621cf73a7a1b99680403
prerequisite-patch-id: d311eba3ac81be3b6af2264442369ff2b8fd5e48
Best regards,
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com