drm/panel: embed a drm_bridge into every drm_panel
Subsystems (32)
Luca Ceresoli
reviewerv3 cover drm/panel: embed a drm_bridge into every drm_panel
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@bootlin.com
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/[email protected]/#t
[1] https://lore.kernel.org/all/emuj2innmp6zmzd7pyakqzjqpdzhly6qfhakya3ydwmd63pl26@5jwxaidpikjw/
[2] https://lore.kernel.org/lkml/[email protected]/
---
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/[email protected]
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/[email protected]
---
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,
Signature · 3 lines
Luca Ceresoli, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
Luca Ceresoli
reviewerPATCH v3 1/19 drm: of: move drm_of_find_panel_or_bridge() from drm_of.c to drm_panel.c
We want to move drm_panel.o from the main drm module to a new drm_panel module, but there is one function in the drm module that calls into drm_panel.c code:
drm_of_find_panel_or_bridge() (drm_of.c, drm module)
-> calls of_drm_find_panel (drm_panel.c, future drm_panel module)
Avoid this issue by moving drm_of_find_panel_or_bridge() to drm_panel.c.
Update Kconfig symbols of drivers calling drm_of_find_panel_or_bridge() to select DRM_PANEL when this is not done already.
No functional changes, just moving code around.
--- drivers/gpu/drm/bridge/Kconfig | 2 ++ drivers/gpu/drm/bridge/analogix/Kconfig | 2 ++ drivers/gpu/drm/drm_of.c | 63 --------------------------------- drivers/gpu/drm/drm_panel.c | 63 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/imx/dcss/Kconfig | 1 + drivers/gpu/drm/ingenic/Kconfig | 1 + drivers/gpu/drm/logicvc/Kconfig | 1 + drivers/gpu/drm/mcde/Kconfig | 1 + drivers/gpu/drm/pl111/Kconfig | 1 + drivers/gpu/drm/rockchip/Kconfig | 2 ++ drivers/gpu/drm/stm/Kconfig | 1 + drivers/gpu/drm/tidss/Kconfig | 1 + drivers/gpu/drm/tve200/Kconfig | 1 + include/drm/drm_of.h | 12 ------- include/drm/drm_panel.h | 13 +++++++ 15 files changed, 90 insertions(+), 75 deletions(-)
drivers/gpu/drm/bridge/Kconfig +2 -0
@@ -151,6 +151,7 @@ config DRM_LONTIUM_LT8912B config DRM_LONTIUM_LT9211 tristate "Lontium LT9211 DSI/LVDS/DPI bridge" depends on OF + select DRM_PANEL select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_MIPI_DSI
@@ -498,6 +499,7 @@ config DRM_WAVESHARE_BRIDGE tristate "Waveshare DSI bridge" depends on OF depends on BACKLIGHT_CLASS_DEVICE + select DRM_PANEL select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_MIPI_DSI
drivers/gpu/drm/bridge/analogix/Kconfig +2 -0
@@ -6,6 +6,7 @@ config DRM_ANALOGIX_ANX6345 select DRM_DISPLAY_DP_HELPER select DRM_DISPLAY_HELPER select DRM_KMS_HELPER + select DRM_PANEL select REGMAP_I2C help ANX6345 is an ultra-low power Full-HD DisplayPort/eDP
@@ -32,6 +33,7 @@ config DRM_ANALOGIX_DP depends on DRM depends on OF select DRM_DISPLAY_DP_AUX_BUS + select DRM_PANEL config DRM_ANALOGIX_ANX7625 tristate "Analogix Anx7625 MIPI to DP interface support"
drivers/gpu/drm/drm_of.c +0 -63
69 lines not on this page · raw message
drivers/gpu/drm/drm_panel.c +63 -0
69 lines not on this page · raw message
drivers/gpu/drm/imx/dcss/Kconfig +1 -0
@@ -6,6 +6,7 @@ config DRM_IMX_DCSS select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR select DRM_GEM_DMA_HELPER + select DRM_PANEL select VIDEOMODE_HELPERS depends on DRM && ((ARCH_MXC && ARM64) || COMPILE_TEST) help
drivers/gpu/drm/ingenic/Kconfig +1 -0
@@ -7,6 +7,7 @@ config DRM_INGENIC depends on COMMON_CLK select DRM_BRIDGE select DRM_CLIENT_SELECTION + select DRM_PANEL select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_DISPLAY_HELPER
drivers/gpu/drm/logicvc/Kconfig +1 -0
@@ -6,6 +6,7 @@ config DRM_LOGICVC select DRM_KMS_HELPER select DRM_KMS_DMA_HELPER select DRM_GEM_DMA_HELPER + select DRM_PANEL select REGMAP select REGMAP_MMIO help
drivers/gpu/drm/mcde/Kconfig +1 -0
@@ -9,6 +9,7 @@ config DRM_MCDE select DRM_CLIENT_SELECTION select DRM_MIPI_DSI select DRM_BRIDGE + select DRM_PANEL select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER
drivers/gpu/drm/pl111/Kconfig +1 -0
@@ -9,6 +9,7 @@ config DRM_PL111 select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER select DRM_BRIDGE + select DRM_PANEL select DRM_PANEL_BRIDGE help Choose this option for DRM support for the PL111 CLCD controller.
drivers/gpu/drm/rockchip/Kconfig +2 -0
@@ -124,6 +124,7 @@ config ROCKCHIP_LVDS depends on PINCTRL && OF select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR + select DRM_PANEL help Choose this option to enable support for Rockchip LVDS controllers. Rockchip rk3288 SoC has LVDS TX Controller can be used, and it
@@ -136,6 +137,7 @@ config ROCKCHIP_RGB depends on PINCTRL select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR + select DRM_PANEL help Choose this option to enable support for Rockchip RGB output. Some Rockchip CRTCs, like rv1108, can directly output parallel
drivers/gpu/drm/stm/Kconfig +1 -0
@@ -6,6 +6,7 @@ config DRM_STM select DRM_CLIENT_SELECTION select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER + select DRM_PANEL select DRM_PANEL_BRIDGE select VIDEOMODE_HELPERS select FB_PROVIDE_GET_FB_UNMAPPED_AREA if FB
drivers/gpu/drm/tidss/Kconfig +1 -0
@@ -7,6 +7,7 @@ config DRM_TIDSS select DRM_DISPLAY_HELPER select DRM_BRIDGE_CONNECTOR select DRM_GEM_DMA_HELPER + select DRM_PANEL help The TI Keystone family SoCs introduced a new generation of Display SubSystem. There is currently three Keystone family
drivers/gpu/drm/tve200/Kconfig +1 -0
@@ -7,6 +7,7 @@ config DRM_TVE200 depends on OF select DRM_BRIDGE select DRM_CLIENT_SELECTION + select DRM_PANEL select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER
include/drm/drm_of.h +0 -12
@@ -51,10 +51,6 @@ int drm_of_encoder_active_endpoint(struct device_node *node, struct of_endpoint *endpoint);int drm_of_get_panel_orientation (const struct device_node *np,enum drm_panel_orientation *orientation); -int drm_of_find_panel_or_bridge (const struct device_node *np, -int port,int endpoint, -struct drm_panel **panel, -struct drm_bridge **bridge);int drm_of_lvds_get_dual_link_pixel_order (const struct device_node *port1,const struct device_node *port2); int drm_of_lvds_get_dual_link_pixel_order_sink(struct device_node *port1,
@@ -112,14 +108,6 @@ static inline int drm_of_get_panel_orientation(const struct device_node *np,return -EINVAL ; } -static inline int drm_of_find_panel_or_bridge (const struct device_node *np, -int port,int endpoint, -struct drm_panel **panel, -struct drm_bridge **bridge) -{ -return -EINVAL ; -} -static inline int drm_of_lvds_get_dual_link_pixel_order (const struct device_node *port1,const struct device_node *port2)
include/drm/drm_panel.h +13 -0
@@ -33,6 +33,7 @@struct backlight_device ;struct dentry ;struct device_node ; +struct drm_bridge ;struct drm_connector ;struct drm_panel_follower ;struct drm_panel ;
@@ -337,11 +338,23 @@ int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector#if defined(CONFIG_OF ) && defined(CONFIG_DRM_PANEL )struct drm_panel *of_drm_find_panel (const struct device_node *np); +int drm_of_find_panel_or_bridge (const struct device_node *np, +int port,int endpoint, +struct drm_panel **panel, +struct drm_bridge **bridge);#else static inline struct drm_panel *of_drm_find_panel (const struct device_node *np) {return ERR_PTR (-ENODEV ); } + +static inline int drm_of_find_panel_or_bridge (const struct device_node *np, +int port,int endpoint, +struct drm_panel **panel, +struct drm_bridge **bridge) +{ +return -EINVAL ; +}#endif #if defined(CONFIG_DRM_PANEL )
Signature · 1 line
2.55.0
Re: [PATCH v3 01/19] drm: of: move drm_of_find_panel_or_bridge() from drm_of.c to drm_panel.c
Quoted 7 lines · Luca Ceresoli
We want to move drm_panel.o from the main drm module to a new
drm_panelmodule, but there is one function in the drm module that calls intodrm_panel.ccode:
drm_of_find_panel_or_bridge()(drm_of.c, drm module)[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 2/19 drm: of: remove now unnecessary forward declarations
In reply to Luca CeresoliThese forward declarations are now redundant after having moved drm_of_find_panel_or_bridge():
* struct drm_panel is not referenced in this file
* struct drm_bridge is now referenced only inside an
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
block, and in this case struct drm_bridge is already declared thanks to these lines:
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
...
#include <drm/drm_bridge.h>
#endif--- include/drm/drm_of.h | 2 -- 1 file changed, 2 deletions(-)
include/drm/drm_of.h +0 -2
@@ -14,8 +14,6 @@ struct component_match;struct device ;struct drm_device ;struct drm_encoder ; -struct drm_panel ; -struct drm_bridge ;struct device_node ;struct mipi_dsi_device_info ;struct mipi_dsi_host ;
Signature · 1 line
2.55.0
Re: [PATCH v3 02/19] drm: of: remove now unnecessary forward declarations
Quoted 7 lines · Luca Ceresoli
These forward declarations are now redundant after having moved
drm_of_find_panel_or_bridge():* struct
drm_panelis not referenced in this file[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 3/19 drm/panel: move to a new module
In reply to Luca CeresoliWork is in progress for every drm_panel to embed a drm_bridge, which will make the drm_panel code (currently in the drm module) depend on the drm_kms_helper module.
To avoid the main drm module to depend on other drm modules and create a depepdency loop, move drm_panel.o to a new drm_panel module, so the module dependency will be drm_panel -> drm_kms_helper instead.
--- drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/panel/Kconfig | 2 +- include/drm/drm_panel.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/Makefile +1 -1
@@ -79,7 +79,6 @@ drm-$(CONFIG_DRM_CLIENT) += \ drm_client_modeset.o \ drm_client_sysrq.o drm-$(CONFIG_COMPAT) += drm_ioc32.o -drm-$(CONFIG_DRM_PANEL) += drm_panel.o drm-$(CONFIG_OF) += drm_of.o drm-$(CONFIG_PCI) += drm_pci.o drm-$(CONFIG_DEBUG_FS) += \
@@ -96,6 +95,7 @@ drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o drm-$(CONFIG_DRM_RAS) += drm_ras.o drm_ras_nl.o drm_ras_genl_family.o obj-$(CONFIG_DRM) += drm.o +obj-$(CONFIG_DRM_PANEL) += drm_panel.o obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o obj-$(CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS) += drm_panel_backlight_quirks.o
drivers/gpu/drm/panel/Kconfig +1 -1
@@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only config DRM_PANEL - bool + tristate depends on DRM help Panel registration and lookup framework.
include/drm/drm_panel.h +2 -2
@@ -336,7 +336,7 @@ void drm_panel_disable(struct drm_panel *panel);int drm_panel_get_modes (struct drm_panel *panel,struct drm_connector *connector); -#if defined(CONFIG_OF ) && defined(CONFIG_DRM_PANEL ) +#if defined(CONFIG_OF ) &&IS_ENABLED (CONFIG_DRM_PANEL )struct drm_panel *of_drm_find_panel (const struct device_node *np); int drm_of_find_panel_or_bridge(const struct device_node *np, int port, int endpoint,
@@ -357,7 +357,7 @@ static inline int drm_of_find_panel_or_bridge(const struct device_node *np, }#endif -#if defined(CONFIG_DRM_PANEL ) +#if IS_ENABLED (CONFIG_DRM_PANEL )bool drm_is_panel_follower (struct device *dev);int drm_panel_add_follower (struct device *follower_dev,struct drm_panel_follower *follower);
Signature · 1 line
2.55.0
Luca Ceresoli
reviewerPATCH v3 4/19 drm/bridge: panel: move all code to drm_panel.c
In reply to Luca CeresoliWork is in progress for every drm_panel to embed a drm_bridge, replacing the panel_bridge entirely. However most of the panel_bridge code will be reused for the drm_bridge embedded into the drm_panel, so just move the code there.
Adapt users of the moved functions to include drm_panel.h when necessary.
No functional changes, just moving code around.
--- drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/adp/adp-mipi.c | 1 + drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 1 + drivers/gpu/drm/bridge/aux-bridge.c | 1 + drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 1 + drivers/gpu/drm/bridge/imx/imx93-pdfc.c | 1 + drivers/gpu/drm/bridge/panel.c | 563 ---------------------- drivers/gpu/drm/bridge/ti-tdp158.c | 1 + drivers/gpu/drm/display/drm_bridge_connector.c | 1 + drivers/gpu/drm/drm_panel.c | 574 ++++++++++++++++++++++- drivers/gpu/drm/imx/dc/dc-kms.c | 1 + drivers/gpu/drm/mcde/mcde_display.c | 1 + drivers/gpu/drm/msm/dp/dp_display.c | 1 + drivers/gpu/drm/msm/dsi/dsi.c | 3 +- drivers/gpu/drm/tegra/rgb.c | 1 + include/drm/drm_bridge.h | 52 -- include/drm/drm_of.h | 1 + include/drm/drm_panel.h | 53 +++ 18 files changed, 622 insertions(+), 636 deletions(-)
drivers/gpu/drm/Makefile +0 -1
@@ -156,7 +156,6 @@ drm_kms_helper-y := \ drm_self_refresh_helper.o \ drm_simple_kms_helper.o \ drm_vblank_helper.o -drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
drivers/gpu/drm/adp/adp-mipi.c +1 -0
@@ -8,6 +8,7 @@#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_mipi_dsi.h> +#include <drm/drm_panel.h> #define DSI_GEN_HDR 0x6c#define DSI_GEN_PLD_DATA 0x70
drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +1 -0
@@ -15,6 +15,7 @@#include <drm/drm_print.h> #include <drm/drm_vblank.h> #include <drm/drm_bridge.h> +#include <drm/drm_panel.h> #include "komeda_dev.h" #include "komeda_kms.h"
drivers/gpu/drm/bridge/aux-bridge.c +1 -0
@@ -12,6 +12,7 @@#include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/bridge/aux-bridge.h> +#include <drm/drm_panel.h> static DEFINE_IDA (drm_aux_bridge_ida);
drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +1 -0
@@ -7,6 +7,7 @@#include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_panel.h> #include <drm/drm_probe_helper.h> #include <video/mipi_display.h> #include <video/videomode.h>
drivers/gpu/drm/bridge/imx/imx93-pdfc.c +1 -0
@@ -16,6 +16,7 @@#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_panel.h> #define IMX93_DISPLAY_MUX_REG 0x60#define PARALLEL_DISP_FORMAT GENMASK(10, 8)
drivers/gpu/drm/bridge/panel.c deleted +0 -563
563 lines not on this page · raw message
drivers/gpu/drm/bridge/ti-tdp158.c +1 -0
@@ -8,6 +8,7 @@#include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> +#include <drm/drm_panel.h> struct tdp158 {struct drm_bridge bridge;
drivers/gpu/drm/display/drm_bridge_connector.c +1 -0
@@ -18,6 +18,7 @@#include <drm/drm_edid.h> #include <drm/drm_managed.h> #include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/display/drm_hdcp_helper.h>
drivers/gpu/drm/drm_panel.c +555 -19
597 lines not on this page · raw message
drivers/gpu/drm/imx/dc/dc-kms.c +1 -0
@@ -15,6 +15,7 @@#include <drm/drm_encoder.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_mode_config.h> +#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h>
drivers/gpu/drm/mcde/mcde_display.c +1 -0
@@ -18,6 +18,7 @@#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_dma_helper.h> #include <drm/drm_mipi_dsi.h> +#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_bridge.h> #include <drm/drm_vblank.h>
drivers/gpu/drm/msm/dp/dp_display.c +1 -0
@@ -15,6 +15,7 @@#include <drm/display/drm_dp_aux_bus.h> #include <drm/display/drm_hdmi_audio_helper.h> #include <drm/drm_edid.h> +#include <drm/drm_panel.h> #include "msm_drv.h" #include "msm_kms.h"
drivers/gpu/drm/msm/dsi/dsi.c +2 -1
@@ -5,6 +5,8 @@#include "dsi.h" +#include <drm/drm_panel.h> +bool msm_dsi_is_cmd_mode (struct msm_dsi *msm_dsi) {unsigned long host_flags =msm_dsi_host_get_mode_flags (msm_dsi->host);
@@ -267,4 +269,3 @@ void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsimsm_dsi_host_snapshot (disp_state, msm_dsi->host);msm_dsi_phy_snapshot (disp_state, msm_dsi->phy); } -
drivers/gpu/drm/tegra/rgb.c +1 -0
@@ -10,6 +10,7 @@#include <drm/drm_atomic_helper.h> #include <drm/drm_bridge_connector.h> #include <drm/drm_encoder.h> +#include <drm/drm_panel.h> #include <drm/drm_print.h> #include "drm.h"
include/drm/drm_bridge.h +0 -52
58 lines not on this page · raw message
include/drm/drm_of.h +1 -0
@@ -7,6 +7,7 @@#if IS_ENABLED (CONFIG_OF ) &&IS_ENABLED (CONFIG_DRM_PANEL_BRIDGE )#include <linux/of.h> #include <drm/drm_bridge.h> +#include <drm/drm_panel.h> #endif struct component_master_ops ;
include/drm/drm_panel.h +53 -0
63 lines not on this page · raw message
Signature · 1 line
2.55.0
Re: [PATCH v3 04/19] drm/bridge: panel: move all code to drm_panel.c
Quoted 7 lines · Luca Ceresoli
Work is in progress for every
drm_panelto embed adrm_bridge, replacing thepanel_bridgeentirely. However most of thepanel_bridgecode will be reused for thedrm_bridgeembedded into thedrm_panel, so just move the code there.[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 5/19 drm/panel: embed a drm_bridge into every drm_panel
In reply to Luca CeresoliAdding a drm_panel does currently not add a panel_bridge wrapping it. Usually the panel_bridge creation happens later, when some other driver (e.g. the previous bridge or the encoder) calls *_of_get_bridge() and the following element in the pipeline is a panel.
This has some drawbacks:
* the bridge API is currently the best practice to access various components of the pipeline, especially with complex cards where bridges can be combined in different ways on different hardware
* the panel_bridge is not created in the context of the driver of the underlying physical device (the panel driver), but of some other driver
* that other driver is not aware of whether the returned drm_bridge pointer is a panel_bridge created on the fly, a pre-existing panel_bridge or a non-panel bridge
* removal of a panel_bridge requires calling drm_panel_bridge_remove(), but that other driver doesn't know whether this is needed because it doesn't know whether it has created a panel_bridge or not
Other drivers call [a variant of] drm_panel_bridge_add(), which also has some of the above drawbacks.
So far the current approach was working mostly because devm and drmm ensure the panel bridge would be dealloacted at some later point. However with the upcoming implementation of bridge hotplug and dynamic bridge lifetime this won't happen as needed.
Switch to the new approach: embed a drm_bridge inside every drm_panel, which behaves just like the current drm_panel_bridge. Do this by adapting the panel_bridge code, doing the minimal adaptations needed.
Currently drm_bridge and drm_panel have independent refcounted allocation. As they now become a single struct, just change drm_panel_get/put() to get/put the bridge. As a result, the refcount for a drm_bridge embedded in a drm_panel is:
bridge.refcount == number of drm_bridge_get() calls
+ number of drm_panel_get() calls
- number of drm_bridge_put() calls
- number of drm_panel_put() calls
Now drivers should progressively stop using the panel_bridge API. Until that happens, that API becomes now a wrapper to the new embedded drm_bridge:
* 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; they include:
- all drm_panel_bridge_add() variants
- their removal counterparts
- *_of_get_bridge().
---
Changes in v3:
- previous patches don't duplicate but rather move the panel_bridge code to drm_bridge.c, so adapt to that: as there are no more 2 versions of that code we need to handle right now the fact that existing users of panel_bridge need to be transparently use the embedded bridge
- add missing panel->bridge initializations to drm_panel_add()
This patch is new in v2, and replaces "drm/bridge: panel: add a panel_bridge to every panel" which was based on a different approach.
--- drivers/gpu/drm/drm_panel.c | 184 +++++++++++++++++++------------------------- include/drm/drm_panel.h | 29 ++++--- 2 files changed, 96 insertions(+), 117 deletions(-)
drivers/gpu/drm/drm_panel.c +78 -106
@@ -38,6 +38,18 @@ static LIST_HEAD(panel_list);* take look at drm_panel_bridge_add() and devm_drm_panel_bridge_add(). */ +static inline struct drm_panel * +drm_bridge_to_panel (const struct drm_bridge *bridge) +{ + return container_of(bridge, struct drm_panel, bridge); +} + +static inline struct drm_panel * +drm_connector_to_panel (const struct drm_connector *connector) +{ + return container_of(connector, struct drm_panel, connector); +} +struct panel_bridge {struct drm_bridge bridge;struct drm_connector connector;
@@ -45,24 +57,11 @@ struct panel_bridge {u32 connector_type; }; -static inline struct panel_bridge * -drm_bridge_to_panel_bridge (struct drm_bridge *bridge) -{ - return container_of(bridge, struct panel_bridge, bridge); -} - -static inline struct panel_bridge * -drm_connector_to_panel_bridge (struct drm_connector *connector) -{ - return container_of(connector, struct panel_bridge, connector); -} -static int panel_bridge_connector_get_modes (struct drm_connector *connector) { -struct panel_bridge *panel_bridge = -drm_connector_to_panel_bridge (connector); +struct drm_panel *panel =drm_connector_to_panel (connector); -return drm_panel_get_modes (panel_bridge->panel, connector); +return drm_panel_get_modes (panel, connector); } static const struct drm_connector_helper_funcs
@@ -82,8 +81,8 @@ static int panel_bridge_attach(struct drm_bridge *bridge,struct drm_encoder *encoder, enum drm_bridge_attach_flags flags) { - struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); -struct drm_connector *connector = &panel_bridge->connector; + struct drm_panel *panel = drm_bridge_to_panel(bridge); +struct drm_connector *connector = &panel->connector;int ret;if (flags &DRM_BRIDGE_ATTACH_NO_CONNECTOR )
@@ -94,7 +93,7 @@ static int panel_bridge_attach(struct drm_bridge *bridge, ret =drm_connector_init (bridge->dev, connector, &panel_bridge_connector_funcs, - panel_bridge->connector_type); + panel->connector_type);if (ret) {DRM_ERROR ("Failed to initialize connector\n" );return ret;
@@ -102,8 +101,7 @@ static int panel_bridge_attach(struct drm_bridge *bridge,drm_panel_bridge_set_orientation (connector, bridge); -drm_connector_attach_encoder (&panel_bridge->connector, - encoder); +drm_connector_attach_encoder (connector, encoder);if (bridge->dev->registered) {if (connector->funcs->reset)
@@ -116,16 +114,10 @@ static int panel_bridge_attach(struct drm_bridge *bridge,static void panel_bridge_detach (struct drm_bridge *bridge) { -struct panel_bridge *panel_bridge =drm_bridge_to_panel_bridge (bridge); -struct drm_connector *connector = &panel_bridge->connector; +struct drm_panel *panel =drm_bridge_to_panel (bridge); +struct drm_connector *connector = &panel->connector; -/* -* Cleanup the connector if we know it was initialized. -* -* FIXME: This wouldn't be needed if the panel_bridge structure was -* allocated with drmm_kzalloc(). This might be tricky since the -* drm_device pointer can only be retrieved when the bridge is attached. -*/ +/* Cleanup the connector if we know it was initialized */ if (connector->dev)drm_connector_cleanup (connector); }
@@ -133,7 +125,7 @@ static void panel_bridge_detach(struct drm_bridge *bridge)static void panel_bridge_atomic_pre_enable (struct drm_bridge *bridge,struct drm_atomic_commit *atomic_state) { -struct panel_bridge *panel_bridge =drm_bridge_to_panel_bridge (bridge); +struct drm_panel *panel =drm_bridge_to_panel (bridge);struct drm_encoder *encoder = bridge->encoder;struct drm_crtc *crtc;struct drm_crtc_state *old_crtc_state;
@@ -146,13 +138,13 @@ static void panel_bridge_atomic_pre_enable(struct drm_bridge *bridge,if (old_crtc_state && old_crtc_state->self_refresh_active)return ; -drm_panel_prepare (panel_bridge->panel); +drm_panel_prepare (panel); }static void panel_bridge_atomic_enable (struct drm_bridge *bridge,struct drm_atomic_commit *atomic_state) { -struct panel_bridge *panel_bridge =drm_bridge_to_panel_bridge (bridge); +struct drm_panel *panel =drm_bridge_to_panel (bridge);struct drm_encoder *encoder = bridge->encoder;struct drm_crtc *crtc;struct drm_crtc_state *old_crtc_state;
@@ -165,13 +157,13 @@ static void panel_bridge_atomic_enable(struct drm_bridge *bridge,if (old_crtc_state && old_crtc_state->self_refresh_active)return ; -drm_panel_enable (panel_bridge->panel); +drm_panel_enable (panel); }static void panel_bridge_atomic_disable (struct drm_bridge *bridge,struct drm_atomic_commit *atomic_state) { -struct panel_bridge *panel_bridge =drm_bridge_to_panel_bridge (bridge); +struct drm_panel *panel =drm_bridge_to_panel (bridge);struct drm_encoder *encoder = bridge->encoder;struct drm_crtc *crtc;struct drm_crtc_state *new_crtc_state;
@@ -184,13 +176,13 @@ static void panel_bridge_atomic_disable(struct drm_bridge *bridge,if (new_crtc_state && new_crtc_state->self_refresh_active)return ; -drm_panel_disable (panel_bridge->panel); +drm_panel_disable (panel); }static void panel_bridge_atomic_post_disable (struct drm_bridge *bridge,struct drm_atomic_commit *atomic_state) { -struct panel_bridge *panel_bridge =drm_bridge_to_panel_bridge (bridge); +struct drm_panel *panel =drm_bridge_to_panel (bridge);struct drm_encoder *encoder = bridge->encoder;struct drm_crtc *crtc;struct drm_crtc_state *new_crtc_state;
@@ -203,22 +195,21 @@ static void panel_bridge_atomic_post_disable(struct drm_bridge *bridge,if (new_crtc_state && new_crtc_state->self_refresh_active)return ; -drm_panel_unprepare (panel_bridge->panel); +drm_panel_unprepare (panel); }static int panel_bridge_get_modes (struct drm_bridge *bridge,struct drm_connector *connector) { -struct panel_bridge *panel_bridge =drm_bridge_to_panel_bridge (bridge); +struct drm_panel *panel =drm_bridge_to_panel (bridge); -return drm_panel_get_modes (panel_bridge->panel, connector); +return drm_panel_get_modes (panel, connector); }static void panel_bridge_debugfs_init (struct drm_bridge *bridge,struct dentry *root) { -struct panel_bridge *panel_bridge =drm_bridge_to_panel_bridge (bridge); -struct drm_panel *panel = panel_bridge->panel; +struct drm_panel *panel =drm_bridge_to_panel (bridge); root =debugfs_create_dir ("panel" , root);if (panel->funcs->debugfs_init)
@@ -288,7 +279,7 @@ struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel)EXPORT_SYMBOL (drm_panel_bridge_add);/** -* drm_panel_bridge_add_typed - Creates a &drm_bridge and &drm_connector with +* drm_panel_bridge_add_typed - Pretend to create a &drm_bridge and &drm_connector with * an explicit connector type. * @panel: The drm_panel being wrapped. Must be non-NULL. * @connector_type: The connector type (DRM_MODE_CONNECTOR_*)
@@ -303,27 +294,10 @@ EXPORT_SYMBOL(drm_panel_bridge_add);struct drm_bridge *drm_panel_bridge_add_typed (struct drm_panel *panel,u32 connector_type) { -struct panel_bridge *panel_bridge; -if (!panel)return ERR_PTR (-EINVAL ); - panel_bridge = devm_drm_bridge_alloc(panel->dev, struct panel_bridge, bridge, - &panel_bridge_bridge_funcs); -if (IS_ERR (panel_bridge)) -return (void *)panel_bridge; - - panel_bridge->connector_type = connector_type; - panel_bridge->panel =drm_panel_get (panel); - - panel_bridge->bridge.of_node = panel->dev->of_node; - panel_bridge->bridge.ops =DRM_BRIDGE_OP_MODES ; - panel_bridge->bridge.type = connector_type; - panel_bridge->bridge.pre_enable_prev_first = panel->prepare_prev_first; - -drm_bridge_add (&panel_bridge->bridge); - -return &panel_bridge->bridge; +return drm_bridge_get (&panel->bridge); }EXPORT_SYMBOL (drm_panel_bridge_add_typed);
@@ -335,9 +309,6 @@ EXPORT_SYMBOL(drm_panel_bridge_add_typed);*/ void drm_panel_bridge_remove (struct drm_bridge *bridge) { -struct panel_bridge *panel_bridge; -struct drm_panel *panel; -if (!bridge)return ;
@@ -346,13 +317,7 @@ void drm_panel_bridge_remove(struct drm_bridge *bridge)return ; } - panel_bridge =drm_bridge_to_panel_bridge (bridge); - panel = panel_bridge->panel; - -drm_bridge_remove (bridge); -/* TODO remove this after reworking panel_bridge lifetime */ -devm_drm_put_bridge (panel->dev, bridge); -drm_panel_put (panel); +drm_bridge_put (bridge); }EXPORT_SYMBOL (drm_panel_bridge_remove);
@@ -361,35 +326,27 @@ EXPORT_SYMBOL(drm_panel_bridge_remove);* from the bridge that can be transformed to panel bridge. * * @connector: The connector to be set panel orientation. -* @bridge: The drm_bridge to be transformed to panel bridge. +* @bridge: The drm_bridge whose orientation should be set. * * Returns 0 on success, negative errno on failure. */ int drm_panel_bridge_set_orientation (struct drm_connector *connector,struct drm_bridge *bridge) { -struct panel_bridge *panel_bridge; +struct drm_panel *panel =drm_bridge_to_panel (bridge); - panel_bridge =drm_bridge_to_panel_bridge (bridge); - -return drm_connector_set_orientation_from_panel (connector, - panel_bridge->panel); +return drm_connector_set_orientation_from_panel (connector, panel); }EXPORT_SYMBOL (drm_panel_bridge_set_orientation);static void devm_drm_panel_bridge_release (struct device *dev,void *res) {struct drm_bridge *bridge = *(struct drm_bridge **)res; -struct panel_bridge *panel_bridge; -struct drm_panel *panel;if (!bridge)return ; - panel_bridge =drm_bridge_to_panel_bridge (bridge); - panel = panel_bridge->panel; -drm_bridge_remove (bridge); -drm_panel_put (panel); +drm_bridge_put (bridge); }/**
@@ -446,7 +403,7 @@ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, *ptr = bridge;devres_add (dev, ptr); -return bridge; +return &panel->bridge; }EXPORT_SYMBOL (devm_drm_panel_bridge_add_typed);
@@ -489,21 +446,21 @@ struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm,EXPORT_SYMBOL (drmm_panel_bridge_add);/** -* drm_panel_bridge_connector - return the connector for the panel bridge +* drm_panel_bridge_connector - return the connector for the panel (for +* legacy drivers not using DRM_BRIDGE_ATTACH_NO_CONNECTOR) * @bridge: The drm_bridge. * -* drm_panel_bridge creates the connector. * This function gives external access to the connector. * * Returns: Pointer to drm_connector */ struct drm_connector *drm_panel_bridge_connector (struct drm_bridge *bridge) { -struct panel_bridge *panel_bridge; +struct drm_panel *panel; - panel_bridge =drm_bridge_to_panel_bridge (bridge); + panel =drm_bridge_to_panel (bridge); -return &panel_bridge->connector; +return &panel->connector; }EXPORT_SYMBOL (drm_panel_bridge_connector);
@@ -622,6 +579,13 @@ void drm_panel_add(struct drm_panel *panel)mutex_lock (&panel_lock);list_add_tail (&panel->list, &panel_list);mutex_unlock (&panel_lock); + + panel->bridge.of_node = panel->dev->of_node; + panel->bridge.ops =DRM_BRIDGE_OP_MODES ; + panel->bridge.type = panel->connector_type; + panel->bridge.pre_enable_prev_first = panel->prepare_prev_first; + +drm_bridge_add (&panel->bridge); }EXPORT_SYMBOL (drm_panel_add);
@@ -633,6 +597,7 @@ EXPORT_SYMBOL(drm_panel_add);*/ void drm_panel_remove (struct drm_panel *panel) { +drm_bridge_remove (&panel->bridge);mutex_lock (&panel_lock);list_del_init (&panel->list);mutex_unlock (&panel_lock);
@@ -906,13 +871,6 @@ int drm_panel_get_modes(struct drm_panel *panel, }EXPORT_SYMBOL (drm_panel_get_modes); -static void __drm_panel_free (struct kref *kref) -{ - struct drm_panel *panel = container_of(kref, struct drm_panel, refcount); - -kfree (panel->container); -} -/** * drm_panel_get - Acquire a panel reference * @panel: DRM panel
@@ -923,10 +881,8 @@ static void __drm_panel_free(struct kref *kref)*/ struct drm_panel *drm_panel_get (struct drm_panel *panel) { -if (!panel) -return panel; - -kref_get (&panel->refcount); +if (panel) +drm_bridge_get (&panel->bridge);return panel; }
@@ -942,7 +898,7 @@ EXPORT_SYMBOL(drm_panel_get);void drm_panel_put (struct drm_panel *panel) {if (panel) -kref_put (&panel->refcount, __drm_panel_free); +drm_bridge_put (&panel->bridge); }EXPORT_SYMBOL (drm_panel_put);
@@ -965,8 +921,22 @@ void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset, const struct drm_panel_funcs *funcs, int connector_type) { - void *container; +/* +* Struct embedding and offsets: +* +* |--------------- user container struct ------------| +* : |---------- struct drm_panel ------------| +* : : |----- struct drm_bridge ------| +* A B C +* +* B - A = offset (passed as argument) +* C - B = panel_bridge_offset +* C - A = alloc_bridge_offset +*/ +const size_t panel_bridge_offset = offsetof(struct drm_panel , bridge); +const size_t alloc_bridge_offset = offset + panel_bridge_offset;struct drm_panel *panel; +void *container;int err;if (!funcs) {
@@ -974,14 +944,16 @@ void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,return ERR_PTR (-EINVAL ); } - container =kzalloc (size,GFP_KERNEL ); -if (!container) -return ERR_PTR (-ENOMEM ); + container =__devm_drm_bridge_alloc (dev, size, alloc_bridge_offset, + &panel_bridge_bridge_funcs); +if (IS_ERR (container)) +return container; panel = container + offset; - panel->container = container; panel->funcs = funcs; -kref_init (&panel->refcount); + panel->bridge.of_node = dev->of_node; + +drm_panel_get (panel); err =devm_add_action_or_reset (dev, drm_panel_put_void, panel);if (err)
include/drm/drm_panel.h +18 -11
@@ -30,6 +30,8 @@#include <linux/mutex.h> #include <linux/kref.h> +#include <drm/drm_bridge.h> +struct backlight_device ;struct dentry ;struct device_node ;
@@ -230,6 +232,22 @@ struct drm_panel {*/ const struct drm_panel_funcs *funcs; +/** +* @bridge: +* +* Bridge to access the panel features through the drm_bridge API. +*/ +struct drm_bridge bridge; + +/** +* @connector: +* +* Connector instantiated by the bridge (only for legacy code not +* yet using the drm_bridge_connector and +* DRM_BRIDGE_ATTACH_NO_CONNECTOR). +*/ +struct drm_connector connector; +/** * @connector_type: *
@@ -283,17 +301,6 @@ struct drm_panel {* If true then the panel has been enabled. */ bool enabled; - -/** -* @container: Pointer to the private driver struct embedding this -* @struct drm_panel. -*/ -void *container; - -/** -* @refcount: reference count of users referencing this panel. -*/ -struct kref refcount; }; void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
Signature · 1 line
2.55.0
Quoted 7 lines · Luca Ceresoli
Adding a
drm_paneldoes currently not add apanel_bridgewrapping it. Usually thepanel_bridgecreation happens later, when some other driver (e.g. the previous bridge or the encoder) calls*_of_get_bridge()and the following element in the pipeline is a panel.[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 6/19 drm/bridge: remove devm_drm_put_bridge()
In reply to Luca CeresoliThe deprecated devm_drm_put_bridge() function is not used anymore.
--- Documentation/gpu/todo.rst | 16 ---------------- drivers/gpu/drm/drm_bridge.c | 17 ----------------- include/drm/drm_bridge.h | 2 -- 3 files changed, 35 deletions(-)
Documentation/gpu/todo.rst +0 -16
@@ -484,22 +484,6 @@ Contact: Douglas Anderson <[email protected]> Level: Starter -Remove devm_drm_put_bridge() ----------------------------- - -Due to how the panel bridge handles the drm_bridge object lifetime, special -care must be taken to dispose of the drm_bridge object when the -panel_bridge is removed. This is currently managed using -devm_drm_put_bridge(), but that is an unsafe, temporary workaround. To fix -that, the DRM panel lifetime needs to be reworked. After the rework is -done, remove devm_drm_put_bridge() and the TODO in -drm_panel_bridge_remove(). - -Contact: Maxime Ripard <[email protected]>, - Luca Ceresoli <[email protected]> - -Level: Intermediate - Convert users of of_drm_find_bridge() to of_drm_find_and_get_bridge() ---------------------------------------------------------------------
drivers/gpu/drm/drm_bridge.c +0 -17
@@ -1737,23 +1737,6 @@ struct drm_bridge *of_drm_get_bridge_by_endpoint(const struct device_node *np,EXPORT_SYMBOL_GPL (of_drm_get_bridge_by_endpoint);#endif -/** -* devm_drm_put_bridge - Release a bridge reference obtained via devm -* @dev: device that got the bridge via devm -* @bridge: pointer to a struct drm_bridge obtained via devm -* -* Same as drm_bridge_put() for bridge pointers obtained via devm functions -* such as devm_drm_bridge_alloc(). -* -* This function is a temporary workaround and MUST NOT be used. Manual -* handling of bridge lifetime is inherently unsafe. -*/ -void devm_drm_put_bridge (struct device *dev,struct drm_bridge *bridge) -{ -devm_release_action (dev, drm_bridge_put_void, bridge); -} -EXPORT_SYMBOL (devm_drm_put_bridge); - static void drm_bridge_debugfs_show_bridge(struct drm_printer *p, struct drm_bridge *bridge, unsigned int idx,
include/drm/drm_bridge.h +0 -2
@@ -1473,8 +1473,6 @@ void drm_bridge_hpd_disable(struct drm_bridge *bridge);void drm_bridge_hpd_notify (struct drm_bridge *bridge,enum drm_connector_status status); -void devm_drm_put_bridge (struct device *dev,struct drm_bridge *bridge); -void drm_bridge_debugfs_params (struct dentry *root);void drm_bridge_debugfs_encoder_params (struct dentry *root,struct drm_encoder *encoder);
Signature · 1 line
2.55.0
Re: [PATCH v3 06/19] drm/bridge: remove devm_drm_put_bridge()
Quoted 3 lines · Luca Ceresoli
The deprecated
devm_drm_put_bridge()function is not used anymore.Signed-off-by Luca Ceresoli <[email protected]>
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 7/19 drm/panel: deprecate panel-bridge APIs
In reply to Luca CeresoliNow that a drm_bridge is embedded into every drm_panel, the panel_bridge is not needed anymore. Its APIs are just accessing the embedded drm_bridge transparently.
Deprecate them all, encouraging to use the drm_bridge API.
--- drivers/gpu/drm/drm_panel.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-)
drivers/gpu/drm/drm_panel.c +25 -6
@@ -250,6 +250,9 @@ EXPORT_SYMBOL(drm_bridge_is_panel);* * @panel: The drm_panel being wrapped. Must be non-NULL. * +* This function is deprecated. A drm_bridge is embedded into every panel. +* Don't use it in new drivers and update your driver to stop using it. +* * For drivers converting from directly using drm_panel: The expected * usage pattern is that during either encoder module probe or DSI * host attach, a drm_panel will be looked up through
@@ -287,9 +290,8 @@ EXPORT_SYMBOL(drm_panel_bridge_add);* This is just like drm_panel_bridge_add(), but forces the connector type to * @connector_type instead of infering it from the panel. * -* This function is deprecated and should not be used in new drivers. Use -* drm_panel_bridge_add() instead, and fix panel drivers as necessary if they -* don't report a connector type. +* This function is deprecated. A drm_bridge is embedded into every panel. +* Don't use it in new drivers and update your driver to stop using it. */ struct drm_bridge *drm_panel_bridge_add_typed (struct drm_panel *panel,u32 connector_type)
@@ -306,6 +308,10 @@ EXPORT_SYMBOL(drm_panel_bridge_add_typed);* created by drm_panel_bridge_add(). * * @bridge: The drm_bridge being freed. +* +* This function is deprecated. A drm_bridge is embedded into every panel +* and removed when the panel is removed. Don't use it in new drivers and +* update your driver to stop using it. */ void drm_panel_bridge_remove (struct drm_bridge *bridge) {
@@ -355,6 +361,9 @@ static void devm_drm_panel_bridge_release(struct device *dev, void *res)* @dev: device to tie the bridge lifetime to * @panel: The drm_panel being wrapped. Must be non-NULL. * +* This function is deprecated. A drm_bridge is embedded into every panel. +* Don't use it in new drivers and update your driver to stop using it. +* * This is the managed version of drm_panel_bridge_add() which automatically * calls drm_panel_bridge_remove() when @dev is unbound. */
@@ -379,9 +388,8 @@ EXPORT_SYMBOL(devm_drm_panel_bridge_add);* This is just like devm_drm_panel_bridge_add(), but forces the connector type * to @connector_type instead of infering it from the panel. * -* This function is deprecated and should not be used in new drivers. Use -* devm_drm_panel_bridge_add() instead, and fix panel drivers as necessary if -* they don't report a connector type. +* This function is deprecated. A drm_bridge is embedded into every panel. +* Don't use it in new drivers and update your driver to stop using it. */ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev, struct drm_panel *panel,
@@ -422,6 +430,9 @@ static void drmm_drm_panel_bridge_release(struct drm_device *drm, void *ptr)* @drm: DRM device to tie the bridge lifetime to * @panel: The drm_panel being wrapped. Must be non-NULL. * +* This function is deprecated. A drm_bridge is embedded into every panel. +* Don't use it in new drivers and update your driver to stop using it. +* * This is the DRM-managed version of drm_panel_bridge_add() which * automatically calls drm_panel_bridge_remove() when @dev is cleaned * up.
@@ -472,6 +483,10 @@ EXPORT_SYMBOL(drm_panel_bridge_connector);* @port: port in the device tree node * @endpoint: endpoint in the device tree node * +* This function is deprecated. A drm_bridge is embedded into every panel. +* Don't use it in new drivers and convert your driver to +* of_drm_get_bridge_by_endpoint(). +* * Given a DT node's port and endpoint number, finds the connected node * and returns the associated bridge if any, or creates and returns a * drm panel bridge instance if a panel is connected.
@@ -508,6 +523,10 @@ EXPORT_SYMBOL(devm_drm_of_get_bridge);* @port: port in the device tree node * @endpoint: endpoint in the device tree node * +* This function is deprecated. A drm_bridge is embedded into every panel. +* Don't use it in new drivers and convert your driver to +* of_drm_get_bridge_by_endpoint(). +* * Given a DT node's port and endpoint number, finds the connected node * and returns the associated bridge if any, or creates and returns a * drm panel bridge instance if a panel is connected.
Signature · 1 line
2.55.0
Re: [PATCH v3 07/19] drm/panel: deprecate panel-bridge APIs
Quoted 7 lines · Luca Ceresoli
Now that a
drm_bridgeis embedded into everydrm_panel, thepanel_bridgeis not needed anymore. Its APIs are just accessing the embeddeddrm_bridgetransparently.Deprecate them all, encouraging to use the
drm_bridgeAPI.[ ... ]
Thanks!
Maxime
Re: [PATCH v3 07/19] drm/panel: deprecate panel-bridge APIs
In reply to Luca CeresoliQuoted 7 lines · Luca Ceresoli
Now that a
drm_bridgeis embedded into everydrm_panel, thepanel_bridgeis not needed anymore. Its APIs are just accessing the embeddeddrm_bridgetransparently.Deprecate them all, encouraging to use the
drm_bridgeAPI.Signed-off-by Luca Ceresoli <[email protected]>
Yours,
Linus Walleij
Luca Ceresoli
reviewerPATCH v3 8/19 drm/todo: add entry for removing the panel_bridge API
In reply to Luca CeresoliNow that a drm-bridge is embedded into every drm_panel during the panel creation, the panel_bridge does not really exist anymore. Its API has been deprecated and kept until drivers convert to the bridge API.
--- Documentation/gpu/todo.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
Documentation/gpu/todo.rst +25 -0
@@ -484,6 +484,31 @@ Contact: Douglas Anderson <[email protected]> Level: Starter +Remove panel_bridge API functions +--------------------------------- + +Now that a drm_bridge is embedded into every drm_panel, the panel_bridge is +not needed anymore. Its APIs are just accessing the embedded drm_bridge +transparently, and the are deprecated. + +The funcions to remove are: + - drm_panel_bridge_add_typed() + - devm_drm_of_get_bridge() + - drmm_of_get_bridge() + - drm_panel_bridge_remove() + - drmm_drm_panel_bridge_release() + - devm_drm_panel_bridge_release() + - their direct or indirect callers + +Convert users of those functions and eventually remove them when unused, or +make them static drm_panel.c functions when used internally by the +``drm_panel.c`` code. + +Contact: Luca Ceresoli <[email protected]> + Maxime Ripard <[email protected]>, + +Level: Easy + Convert users of of_drm_find_bridge() to of_drm_find_and_get_bridge() ---------------------------------------------------------------------
Signature · 1 line
2.55.0
Re: [PATCH v3 08/19] drm/todo: add entry for removing the panel_bridge API
Quoted 7 lines · Luca Ceresoli
Now that a drm-bridge is embedded into every
drm_panelduring the panel creation, thepanel_bridgedoes not really exist anymore. Its API has been deprecated and kept until drivers convert to the bridge API.Signed-off-by Luca Ceresoli <[email protected]>[ ... ]
Thanks!
Maxime
Re: [PATCH v3 08/19] drm/todo: add entry for removing the panel_bridge API
In reply to Luca CeresoliQuoted 5 lines · Luca Ceresoli
Now that a drm-bridge is embedded into every
drm_panelduring the panel creation, thepanel_bridgedoes not really exist anymore. Its API has been deprecated and kept until drivers convert to the bridge API.Signed-off-by Luca Ceresoli <[email protected]>
Yours,
Linus Walleij
Luca Ceresoli
reviewerPATCH v3 9/19 drm/bridge: tc358767: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_get_bridge_by_endpoint().
As of_drm_get_bridge_by_endpoint() returns a refcounted bridge, take care of putting the bridge reference by using bridge->next_bridge.
--- drivers/gpu/drm/bridge/Kconfig | 2 -- drivers/gpu/drm/bridge/tc358767.c | 64 ++++++++++++--------------------------- 2 files changed, 20 insertions(+), 46 deletions(-)
drivers/gpu/drm/bridge/Kconfig +0 -2
@@ -402,8 +402,6 @@ config DRM_TOSHIBA_TC358767 select DRM_KMS_HELPER select REGMAP_I2C select DRM_MIPI_DSI - select DRM_PANEL - select DRM_PANEL_BRIDGE help Toshiba TC358767 eDP bridge chip driver.
drivers/gpu/drm/bridge/tc358767.c +20 -44
121 lines not on this page · raw message
Signature · 1 line
2.55.0
Re: [PATCH v3 09/19] drm/bridge: tc358767: don't create a panel_bridge
Quoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 10/19 drm/bridge: waveshare-dsi: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_get_bridge_by_endpoint().
As of_drm_get_bridge_by_endpoint() returns a refcounted bridge, take care of putting the bridge reference by using bridge->next_bridge.
--- drivers/gpu/drm/bridge/waveshare-dsi.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-)
drivers/gpu/drm/bridge/waveshare-dsi.c +5 -12
@@ -16,11 +16,9 @@#include <drm/drm_bridge.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> struct ws_bridge {struct drm_bridge bridge; -struct drm_bridge *next_bridge;struct backlight_device *backlight;struct device *dev;struct regmap *reg_map;
@@ -89,7 +87,7 @@ static int ws_bridge_bridge_attach(struct drm_bridge *bridge, {struct ws_bridge *ws =bridge_to_ws_bridge (bridge); -return drm_bridge_attach (encoder, ws->next_bridge, +return drm_bridge_attach (encoder, ws->bridge.next_bridge, &ws->bridge, flags); }
@@ -150,7 +148,6 @@ static struct backlight_device *ws_bridge_create_backlight(struct ws_bridge *ws)static int ws_bridge_probe (struct i2c_client *i2c) {struct device *dev = &i2c->dev; -struct drm_panel *panel;struct ws_bridge *ws;int ret;
@@ -164,14 +161,10 @@ static int ws_bridge_probe(struct i2c_client *i2c)if (IS_ERR (ws->reg_map))return dev_err_probe (dev,PTR_ERR (ws->reg_map),"Failed to allocate regmap\n" ); - ret =drm_of_find_panel_or_bridge (dev->of_node,1 ,-1 , &panel,NULL ); -if (ret) -return dev_err_probe (dev, ret,"Failed to find remote panel\n" ); - - ws->next_bridge =devm_drm_panel_bridge_add (dev, panel); -drm_panel_put (panel); -if (IS_ERR (ws->next_bridge)) -return PTR_ERR (ws->next_bridge); + ws->bridge.next_bridge =of_drm_get_bridge_by_endpoint (dev->of_node,1 ,-1 ); +if (IS_ERR (ws->bridge.next_bridge)) +return dev_err_probe (dev,PTR_ERR (ws->bridge.next_bridge), +"Failed to find remote bridge\n" ); ws->backlight =ws_bridge_create_backlight (ws);if (IS_ERR (ws->backlight)) {
Signature · 1 line
2.55.0
Re: [PATCH v3 10/19] drm/bridge: waveshare-dsi: don't create a panel_bridge
Quoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 11/19 drm/mcde: dsi: remove unused includes
In reply to Luca CeresoliThe helpers are included but unused.
However symbols from drm_atomic_helper.h are used, and were previously available as a side effect of drm_atomic_helper.h including drm_atomic_state_helper.h. Add drm_atomic_state_helper.h.
---
New patch in v2
--- drivers/gpu/drm/mcde/mcde_dsi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/gpu/drm/mcde/mcde_dsi.c +1 -3
@@ -11,17 +11,15 @@#include <linux/regulator/consumer.h> #include <video/mipi_display.h> -#include <drm/drm_atomic_helper.h> +#include <drm/drm_atomic_state_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_device.h> #include <drm/drm_drv.h> #include <drm/drm_encoder.h> #include <drm/drm_mipi_dsi.h> -#include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_of.h> #include <drm/drm_panel.h> #include <drm/drm_print.h> -#include <drm/drm_probe_helper.h> #include "mcde_drm.h" #include "mcde_dsi_regs.h"
Signature · 1 line
2.55.0
Re: [PATCH v3 11/19] drm/mcde: dsi: remove unused includes
Quoted 7 lines · Luca Ceresoli
The helpers are included but unused.
However symbols from
drm_atomic_helper.hare used, and were previously available as a side effect ofdrm_atomic_helper.hincludingdrm_atomic_state_helper.h. Adddrm_atomic_state_helper.h.Signed-off-by Luca Ceresoli <[email protected]>
Yours,
Linus Walleij
Re: [PATCH v3 11/19] drm/mcde: dsi: remove unused includes
In reply to Luca CeresoliQuoted 7 lines · Luca Ceresoli
The helpers are included but unused.
However symbols from
drm_atomic_helper.hare used, and were previously available as a side effect ofdrm_atomic_helper.hincludingdrm_atomic_state_helper.h. Adddrm_atomic_state_helper.h.[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 12/19 drm/mcde: dsi: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_find_and_get_bridge().
Also keep the "connected to non-panel bridge (unsupported)\n" error logic by using the drm_bridge_is_panel() function.
--- drivers/gpu/drm/mcde/Kconfig | 1 - drivers/gpu/drm/mcde/mcde_dsi.c | 41 +++++++++-------------------------------- 2 files changed, 9 insertions(+), 33 deletions(-)
drivers/gpu/drm/mcde/Kconfig +0 -1
@@ -10,7 +10,6 @@ config DRM_MCDE select DRM_MIPI_DSI select DRM_BRIDGE select DRM_PANEL - select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER help
drivers/gpu/drm/mcde/mcde_dsi.c +9 -32
71 lines not on this page · raw message
Signature · 1 line
2.55.0
Re: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
Quoted 10 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_find_and_get_bridge().Also keep the "connected to non-panel bridge (unsupported)\n" error logic by using the
drm_bridge_is_panel()function.Signed-off-by Luca Ceresoli <[email protected]>
Yours,
Linus Walleij
Maxime Ripard
maintainerRe: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
In reply to Luca CeresoliQuoted 81 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_find_and_get_bridge().Also keep the "connected to non-panel bridge (unsupported)\n" error logic by using the
drm_bridge_is_panel()function.Signed-off-by Luca Ceresoli <[email protected]>--- drivers/gpu/drm/mcde/Kconfig | 1 - drivers/gpu/drm/mcde/mcde_dsi.c | 41 +++++++++-------------------------------- 2 files changed, 9 insertions(+), 33 deletions(-)drivers/gpu/drm/mcde/Kconfig +0
-1@@ -10,7 +10,6 @@ config DRM_MCDE select DRM_MIPI_DSI select DRM_BRIDGE select DRM_PANEL - select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER helpdrivers/gpu/drm/mcde/mcde_dsi.c +5
-24@@ -37,7 +37,6 @@ struct mcde_dsi {struct device *dev;struct mcde *mcde;struct drm_bridge bridge; -struct drm_panel *panel;struct mipi_dsi_host dsi_host;struct mipi_dsi_device *mdsi;const struct drm_display_mode *mode;@@ -1074,7 +1073,6 @@ static int mcde_dsi_bind(struct device *dev, struct device *master,struct drm_device *drm = data;struct mcde *mcde =to_mcde (drm);struct mcde_dsi *d =dev_get_drvdata (dev); -struct drm_panel *panel =NULL ; struct drm_bridge *bridge __free(drm_bridge_put) = NULL;if (!of_get_available_child_count (dev->of_node)) {@@ -1102,40 +1100,21 @@ 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_scoped (dev->of_node, child) { - panel =of_drm_find_panel (child); -if (IS_ERR (panel)) { -dev_err (dev,"failed to find panel try bridge (%ld)\n" , -PTR_ERR (panel)); - panel =NULL ; - - bridge =of_drm_find_and_get_bridge (child); -if (!bridge) { -dev_err (dev,"failed to find bridge\n" ); -return -EINVAL ; - } + bridge =of_drm_find_and_get_bridge (child); +if (!bridge) { +dev_err (dev,"failed to find bridge\n" ); +return -EINVAL ; } -if (panel || bridge) -break ; +break ; } -if (panel) { - bridge =drm_panel_bridge_add_typed (panel, -DRM_MODE_CONNECTOR_DSI ); -drm_panel_put (panel); -if (IS_ERR (bridge)) { -dev_err (dev,"error adding panel bridge\n" ); -return PTR_ERR (bridge); - } -drm_bridge_get (bridge);
drivers/gpu/drm/mcde/mcde_dsi.c static int mcde_dsi_bind(struct device *dev, struct device *master, · line 1117
Quoted 10 lines
drivers/gpu/drm/mcde/mcde_dsi.c +4
-3-dev_info (dev,"connected to panel\n" ); - d->panel = panel; - }else if (bridge) { +if (!bridge) { +dev_err (dev,"no bridge\n" ); +return -ENODEV ; + }else if (!drm_bridge_is_panel (bridge)) {/* TODO: AV8100 HDMI encoder goes here for example */ dev_info (dev,"connected to non-panel bridge (unsupported)\n" );return -ENODEV ;
I wonder if we still need that branch. Every panel is a bridge now, and it looks like we don't have any specific panel handling in this driver, so I guess it supports bridges already?
Linus, do you know why this condition was here in the first place?
Maxime
Luca Ceresoli
reviewerRe: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
Hi Linus, Maxime,
Quoted 11 lines · Maxime Ripard
Quoted 10 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_find_and_get_bridge().Also keep the "connected to non-panel bridge (unsupported)\n" error logic by using the
drm_bridge_is_panel()function.Signed-off-by Luca Ceresoli <[email protected]>
[...]
Quoted 49 lines
Quoted 34 lines
drivers/gpu/drm/mcde/mcde_dsi.c +5
-22@@ -1102,40 +1100,21 @@ 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_scoped (dev->of_node, child) { - panel =of_drm_find_panel (child); -if (IS_ERR (panel)) { -dev_err (dev,"failed to find panel try bridge (%ld)\n" , -PTR_ERR (panel)); - panel =NULL ; - - bridge =of_drm_find_and_get_bridge (child); -if (!bridge) { -dev_err (dev,"failed to find bridge\n" ); -return -EINVAL ; - } + bridge =of_drm_find_and_get_bridge (child); +if (!bridge) { +dev_err (dev,"failed to find bridge\n" ); +return -EINVAL ; } -if (panel || bridge) -break ; +break ; } -if (panel) { - bridge =drm_panel_bridge_add_typed (panel, -DRM_MODE_CONNECTOR_DSI ); -drm_panel_put (panel); -if (IS_ERR (bridge)) { -dev_err (dev,"error adding panel bridge\n" ); -return PTR_ERR (bridge); - } -drm_bridge_get (bridge);drivers/gpu/drm/mcde/mcde_dsi.c static int mcde_dsi_bind(struct device *dev, struct device *master, · line 1117
Quoted 10 lines
drivers/gpu/drm/mcde/mcde_dsi.c +4
-3-dev_info (dev,"connected to panel\n" ); - d->panel = panel; - }else if (bridge) { +if (!bridge) { +dev_err (dev,"no bridge\n" ); +return -ENODEV ; + }else if (!drm_bridge_is_panel (bridge)) {/* TODO: AV8100 HDMI encoder goes here for example */ dev_info (dev,"connected to non-panel bridge (unsupported)\n" );return -ENODEV ;I wonder if we still need that branch. Every panel is a bridge now, and it looks like we don't have any specific panel handling in this driver, so I guess it supports bridges already?
Quoted 1 line
Linus, do you know why this condition was here in the first place?
I had the same thought while writing the patch, but I chose to be conservative.
Linus, unless you have more info I'm going to apply the patch as is. Removing this special case would be welcome as a later patch.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Linus Walleij
maintainerRe: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
Hi Luca,
sorry for my slowness!
Quoted 15 lines · Luca Ceresoli
Quoted 13 lines · Maxime Ripard
drivers/gpu/drm/mcde/mcde_dsi.c static int mcde_dsi_bind(struct device *dev, struct device *master, · line 1117
Quoted 8 lines
drivers/gpu/drm/mcde/mcde_dsi.c +4
-1- }else if (bridge) { +if (!bridge) { +dev_err (dev,"no bridge\n" ); +return -ENODEV ; + }else if (!drm_bridge_is_panel (bridge)) {/* TODO: AV8100 HDMI encoder goes here for example */ dev_info (dev,"connected to non-panel bridge (unsupported)\n" );return -ENODEV ;I wonder if we still need that branch. Every panel is a bridge now, and it looks like we don't have any specific panel handling in this driver, so I guess it supports bridges already?
Quoted 7 lines
Quoted 1 line
Linus, do you know why this condition was here in the first place?
I had the same thought while writing the patch, but I chose to be conservative.
Linus, unless you have more info I'm going to apply the patch as is. Removing this special case would be welcome as a later patch.
I'd say go ahead as-is.
I do have the idea to code up and submit the AV8100 encoder and I have the hardware to test it, but every other user should be using panels directly, and I would be the only non-panel user so I can deal with it when it comes up.
Yours,
Linus Walleij
Maxime Ripard
maintainerRe: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
Quoted 22 lines · Linus Walleij
Hi Luca,
sorry for my slowness!
Quoted 17 lines · Luca Ceresoli
Quoted 14 lines · Maxime Ripard
drivers/gpu/drm/mcde/mcde_dsi.c static int mcde_dsi_bind(struct device *dev, struct device *master, · line 1117
Quoted 8 lines
drivers/gpu/drm/mcde/mcde_dsi.c +4
-1- }else if (bridge) { +if (!bridge) { +dev_err (dev,"no bridge\n" ); +return -ENODEV ; + }else if (!drm_bridge_is_panel (bridge)) {/* TODO: AV8100 HDMI encoder goes here for example */ dev_info (dev,"connected to non-panel bridge (unsupported)\n" );return -ENODEV ;I wonder if we still need that branch. Every panel is a bridge now, and it looks like we don't have any specific panel handling in this driver, so I guess it supports bridges already?
Linus, do you know why this condition was here in the first place?
Quoted 7 lines
Quoted 5 lines
I had the same thought while writing the patch, but I chose to be conservative.
Linus, unless you have more info I'm going to apply the patch as is. Removing this special case would be welcome as a later patch.
I'd say go ahead as-is.
I'm fine with that, but I really want this removed at some point.
Quoted 4 lines
I do have the idea to code up and submit the AV8100 encoder and I have the hardware to test it, but every other user should be using panels directly, and I would be the only non-panel user so I can deal with it when it comes up.
It won't change a thing. All existing "panel" users will be bridge users after this patch is merged. So whether you want to enable a bridge or not shouldn't matter, the only thing that does is whether the existing users would still work.
Maxime
Linus Walleij
maintainerRe: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
Quoted 8 lines · Maxime Ripard
Quoted 4 lines · Linus Walleij
Quoted 2 lines
Linus, unless you have more info I'm going to apply the patch as is. Removing this special case would be welcome as a later patch.
I'd say go ahead as-is.
I'm fine with that, but I really want this removed at some point.
If Luca wanna fix this up (drop this path) that's fine by me, else send a patch immediately after this is applied and I'll ACK it.
Quoted 9 lines
Quoted 4 lines
I do have the idea to code up and submit the AV8100 encoder and I have the hardware to test it, but every other user should be using panels directly, and I would be the only non-panel user so I can deal with it when it comes up.
It won't change a thing. All existing "panel" users will be bridge users after this patch is merged. So whether you want to enable a bridge or not shouldn't matter, the only thing that does is whether the existing users would still work.
I know, all it does is create a snag that I would run into myself.
But it's not gonna be a problem for anyone else, that's all I meant.
Yours,
Linus Walleij
Luca Ceresoli
reviewerRe: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
Hello Linus,
Quoted 6 lines · Linus Walleij
Quoted 5 lines · Maxime Ripard
Quoted 3 lines · Linus Walleij
Quoted 2 lines
Linus, unless you have more info I'm going to apply the patch as is. Removing this special case would be welcome as a later patch.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
I'd say go ahead as-is.
I'm fine with that, but I really want this removed at some point.
If Luca wanna fix this up (drop this path) that's fine by me, else send a patch immediately after this is applied and I'll ACK it.
To avoid postponing this series I plan to apply as is on Monday. I can send another patch later to remove the !panel case.
Thanks for the feedback!
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Maxime Ripard
maintainerRe: [PATCH v3 12/19] drm/mcde: dsi: don't create a panel_bridge
Quoted 11 lines · Luca Ceresoli
Hello Linus,
Quoted 8 lines · Linus Walleij
Quoted 7 lines · Maxime Ripard
Quoted 4 lines · Linus Walleij
Quoted 2 lines
Linus, unless you have more info I'm going to apply the patch as is. Removing this special case would be welcome as a later patch.
I'd say go ahead as-is.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
I'm fine with that, but I really want this removed at some point.
If Luca wanna fix this up (drop this path) that's fine by me, else send a patch immediately after this is applied and I'll ACK it.
To avoid postponing this series I plan to apply as is on Monday. I can send another patch later to remove the !panel case.
Works for me :)
Maxime
Luca Ceresoli
reviewerPATCH v3 13/19 drm/bridge: fsl-ldb: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_find_and_get_bridge().
And since of_drm_find_and_get_bridge() returns a refcounted bridge, take care of putting the bridge reference by using bridge->next_bridge.
--- drivers/gpu/drm/bridge/Kconfig | 1 - drivers/gpu/drm/bridge/fsl-ldb.c | 19 +++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-)
drivers/gpu/drm/bridge/Kconfig +0 -1
@@ -87,7 +87,6 @@ config DRM_FSL_LDB depends on OF depends on ARCH_MXC || COMPILE_TEST select DRM_KMS_HELPER - select DRM_PANEL_BRIDGE help Support for i.MX8MP DPI-to-LVDS on-SoC encoder.
drivers/gpu/drm/bridge/fsl-ldb.c +5 -14
@@ -15,7 +15,6 @@#include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #define LDB_CTRL_CH0_ENABLE BIT(0)#define LDB_CTRL_CH0_DI_SELECT BIT(1)
@@ -86,7 +85,6 @@ static const struct fsl_ldb_devdata fsl_ldb_devdata[] = {struct fsl_ldb {struct device *dev;struct drm_bridge bridge; -struct drm_bridge *panel_bridge;struct clk *clk;struct regmap *regmap;const struct fsl_ldb_devdata *devdata;
@@ -119,7 +117,7 @@ static int fsl_ldb_attach(struct drm_bridge *bridge, {struct fsl_ldb *fsl_ldb =to_fsl_ldb (bridge); -return drm_bridge_attach (encoder, fsl_ldb->panel_bridge, +return drm_bridge_attach (encoder, fsl_ldb->bridge.next_bridge, bridge, flags); }
@@ -298,7 +296,6 @@ static int fsl_ldb_probe(struct platform_device *pdev)struct device *dev = &pdev->dev;struct device_node *panel_node;struct device_node *remote1, *remote2; -struct drm_panel *panel;struct fsl_ldb *fsl_ldb;int dual_link;
@@ -339,19 +336,13 @@ static int fsl_ldb_probe(struct platform_device *pdev)fsl_ldb_is_dual (fsl_ldb) ?"dual-link mode" : fsl_ldb->ch0_enabled ? "channel 0" : "channel 1"); - panel =of_drm_find_panel (panel_node); -of_node_put (panel_node); -if (IS_ERR (panel)) -return PTR_ERR (panel); -if (of_property_present (dev->of_node,"nxp,enable-termination-resistor" )) fsl_ldb->use_termination_resistor = true; - fsl_ldb->panel_bridge =devm_drm_panel_bridge_add (dev, panel); -drm_panel_put (panel); -if (IS_ERR (fsl_ldb->panel_bridge)) -return PTR_ERR (fsl_ldb->panel_bridge); - + fsl_ldb->bridge.next_bridge =of_drm_find_and_get_bridge (panel_node); +of_node_put (panel_node); +if (!fsl_ldb->bridge.next_bridge) +return -ENODEV ;if (fsl_ldb_is_dual (fsl_ldb)) {struct device_node *port1, *port2;
Signature · 1 line
2.55.0
Re: [PATCH v3 13/19] drm/bridge: fsl-ldb: don't create a panel_bridge
Hi Luca,
Quoted 10 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_find_and_get_bridge().And since
of_drm_find_and_get_bridge()returns a refcounted bridge, take care of putting the bridge reference by usingbridge->next_bridge.Signed-off-by Luca Ceresoli <[email protected]>
Signature · 2 lines
Thanks, Laurentiu
Re: [PATCH v3 13/19] drm/bridge: fsl-ldb: don't create a panel_bridge
In reply to Luca CeresoliQuoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_find_and_get_bridge().[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 14/19 drm/bridge: samsung-dsim: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_find_and_get_bridge().
--- drivers/gpu/drm/bridge/Kconfig | 1 - drivers/gpu/drm/bridge/samsung-dsim.c | 24 +++++------------------- 2 files changed, 5 insertions(+), 20 deletions(-)
drivers/gpu/drm/bridge/Kconfig +0 -1
@@ -302,7 +302,6 @@ config DRM_SAMSUNG_DSIM depends on OF && HAS_IOMEM select DRM_KMS_HELPER select DRM_MIPI_DSI - select DRM_PANEL_BRIDGE select GENERIC_PHY select GENERIC_PHY_MIPI_DPHY help
drivers/gpu/drm/bridge/samsung-dsim.c +5 -19
@@ -25,7 +25,6 @@#include <video/mipi_display.h> #include <drm/bridge/samsung-dsim.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> /* returns true iff both arguments logically differs */
@@ -1898,7 +1897,6 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host,struct device *dev = dsi->dev;struct device_node *np = dev->of_node;struct device_node *remote; -struct drm_panel *panel;int ret =0 ;/*
@@ -1913,7 +1911,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host, of_node_name_eq(remote, "ports"))continue ; - goto of_find_panel_or_bridge; + goto of_find_bridge; }/*
@@ -1927,25 +1925,13 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host, remote =of_graph_get_remote_node (np,1 ,0 ); -of_find_panel_or_bridge: +of_find_bridge:if (!remote)return -ENODEV ; - panel =of_drm_find_panel (remote); -if (!IS_ERR (panel)) { - next_bridge =devm_drm_panel_bridge_add (dev, panel); -drm_panel_put (panel); -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_and_get_bridge (remote); -if (!next_bridge) - ret = -EINVAL ; - } + next_bridge =of_drm_find_and_get_bridge (remote); +if (!next_bridge) + ret = -EINVAL ;of_node_put (remote);
Signature · 1 line
2.55.0
Re: [PATCH v3 14/19] drm/bridge: samsung-dsim: don't create a panel_bridge
Quoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_find_and_get_bridge().[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 15/19 drm/bridge: tc358768: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_get_bridge_by_endpoint().
As of_drm_get_bridge_by_endpoint() returns a refcounted bridge, take care of putting the bridge reference when not used anymore.
--- drivers/gpu/drm/bridge/Kconfig | 2 -- drivers/gpu/drm/bridge/tc358768.c | 25 ++++++------------------- 2 files changed, 6 insertions(+), 21 deletions(-)
drivers/gpu/drm/bridge/Kconfig +0 -2
@@ -408,8 +408,6 @@ config DRM_TOSHIBA_TC358768 depends on OF select DRM_KMS_HELPER select REGMAP_I2C - select DRM_PANEL - select DRM_PANEL_BRIDGE select DRM_MIPI_DSI select VIDEOMODE_HELPERS help
drivers/gpu/drm/bridge/tc358768.c +6 -19
@@ -22,7 +22,6 @@#include <drm/drm_drv.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <video/mipi_display.h> #include <video/videomode.h>
@@ -137,7 +136,6 @@ static const char * const tc358768_supplies[] = {struct tc358768_dsi_output {struct mipi_dsi_device *dev; -struct drm_panel *panel;struct drm_bridge *bridge; };
@@ -443,7 +441,6 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host, {struct tc358768_priv *priv =dsi_host_to_tc358768 (host);struct drm_bridge *bridge; -struct drm_panel *panel;struct device_node *ep;int ret;
@@ -471,24 +468,15 @@ static int tc358768_dsi_host_attach(struct mipi_dsi_host *host,return -ENOTSUPP ; } - ret =drm_of_find_panel_or_bridge (host->dev->of_node,1 ,0 , &panel, - &bridge); -if (ret) -return ret; + bridge =of_drm_get_bridge_by_endpoint (host->dev->of_node,1 ,0 ); +if (IS_ERR (bridge)) +return PTR_ERR (bridge); -if (panel) { - bridge =drm_panel_bridge_add_typed (panel, -DRM_MODE_CONNECTOR_DSI ); -drm_panel_put (panel); -if (IS_ERR (bridge)) -return PTR_ERR (bridge); - - bridge->pre_enable_prev_first = true; - } + bridge->type =DRM_MODE_CONNECTOR_DSI ; + bridge->pre_enable_prev_first = true; priv->output.dev = dev; priv->output.bridge = bridge; - priv->output.panel = panel; priv->dsi_lanes = dev->lanes; priv->dsi_bpp =mipi_dsi_pixel_format_to_bpp (dev->format);
@@ -518,8 +506,7 @@ static int tc358768_dsi_host_detach(struct mipi_dsi_host *host,struct tc358768_priv *priv =dsi_host_to_tc358768 (host);drm_bridge_remove (&priv->bridge); -if (priv->output.panel) -drm_panel_bridge_remove (priv->output.bridge); +drm_bridge_put (priv->output.bridge);return 0 ; }
Signature · 1 line
2.55.0
Re: [PATCH v3 15/19] drm/bridge: tc358768: don't create a panel_bridge
Quoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 16/19 drm/bridge: ssd2825: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_get_bridge_by_endpoint().
As of_drm_get_bridge_by_endpoint() returns a refcounted bridge, take care of putting the bridge reference when not used anymore.
--- drivers/gpu/drm/bridge/Kconfig | 2 -- drivers/gpu/drm/bridge/ssd2825.c | 23 +++++------------------ 2 files changed, 5 insertions(+), 20 deletions(-)
drivers/gpu/drm/bridge/Kconfig +0 -2
@@ -349,8 +349,6 @@ config DRM_SOLOMON_SSD2825 depends on SPI_MASTER && OF select DRM_MIPI_DSI select DRM_KMS_HELPER - select DRM_PANEL - select DRM_PANEL_BRIDGE help Say Y here if you want support for the Solomon SSD2825 RGB/DSI SPI bridge driver.
drivers/gpu/drm/bridge/ssd2825.c +5 -18
@@ -17,7 +17,6 @@#include <drm/drm_drv.h> #include <drm/drm_mipi_dsi.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <video/mipi_display.h> #define SSD2825_DEVICE_ID_REG 0xb0
@@ -114,7 +113,6 @@ static const struct regulator_bulk_data ssd2825_supplies[] = {struct ssd2825_dsi_output {struct mipi_dsi_device *dev; -struct drm_panel *panel;struct drm_bridge *bridge; };
@@ -277,7 +275,6 @@ static int ssd2825_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_d {struct ssd2825_priv *priv =dsi_host_to_ssd2825 (host);struct drm_bridge *bridge; -struct drm_panel *panel;struct device_node *ep;int ret;
@@ -295,20 +292,14 @@ static int ssd2825_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_dreturn -EOPNOTSUPP ; } - ret =drm_of_find_panel_or_bridge (host->dev->of_node,1 ,0 , &panel, &bridge); -if (ret) -return ret; + bridge =of_drm_get_bridge_by_endpoint (host->dev->of_node,1 ,0 ); +if (IS_ERR (bridge)) +return PTR_ERR (bridge); -if (panel) { - bridge =drm_panel_bridge_add_typed (panel,DRM_MODE_CONNECTOR_DSI ); -drm_panel_put (panel); -if (IS_ERR (bridge)) -return PTR_ERR (bridge); - } + bridge->type =DRM_MODE_CONNECTOR_DSI ; priv->output.dev = dev; priv->output.bridge = bridge; - priv->output.panel = panel; priv->dsi_lanes = dev->lanes;
@@ -333,8 +324,7 @@ static int ssd2825_dsi_host_detach(struct mipi_dsi_host *host, struct mipi_dsi_dstruct ssd2825_priv *priv =dsi_host_to_ssd2825 (host);drm_bridge_remove (&priv->bridge); -if (priv->output.panel) -drm_panel_bridge_remove (priv->output.bridge); +drm_bridge_put (priv->output.bridge);return 0 ; }
@@ -579,9 +569,6 @@ static void ssd2825_bridge_atomic_pre_enable(struct drm_bridge *bridge,/* Initial DSI configuration register set */ ssd2825_write_reg (priv,SSD2825_CONFIGURATION_REG , config);ssd2825_write_reg (priv,SSD2825_VC_CTRL_REG ,0 ); - -if (priv->output.panel) -drm_panel_enable (priv->output.panel); } static void ssd2825_bridge_atomic_enable(struct drm_bridge *bridge,
Signature · 1 line
2.55.0
Re: [PATCH v3 16/19] drm/bridge: ssd2825: don't create a panel_bridge
Quoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().[ ... ]
Thanks!
Maxime
Luca Ceresoli
reviewerPATCH v3 17/19 drm/omap: dss: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_get_bridge_by_endpoint().
--- drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 - drivers/gpu/drm/omapdrm/dss/output.c | 42 ++++------------------------------- 2 files changed, 4 insertions(+), 39 deletions(-)
drivers/gpu/drm/omapdrm/dss/omapdss.h +0 -1
@@ -204,7 +204,6 @@ struct omap_dss_device {struct dss_device *dss;struct drm_bridge *bridge;struct drm_bridge *next_bridge; -struct drm_panel *panel;struct list_head list;
drivers/gpu/drm/omapdrm/dss/output.c +4 -38
72 lines not on this page · raw message
Signature · 1 line
2.55.0
Re: [PATCH v3 17/19] drm/omap: dss: don't create a panel_bridge
Quoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().[ ... ]
Thanks!
Maxime
Re: [PATCH v3 17/19] drm/omap: dss: don't create a panel_bridge
In reply to Luca CeresoliQuoted 7 lines · On Wed, 16 Sep 2026 15:45:41 +0200 Luca Ceresoli <[email protected]>…
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().Signed-off-by Luca Ceresoli <[email protected]>
This breaks the display on GTA04/OMAPDRM.
Panel is panel-tpo-td028ttec1 attached via DPI, controlled via spi_gpio.
I get
[ 12.050201] omapdrm omapdrm.0: [drm] No compatible format found [ 12.050231] omapdrm omapdrm.0: [drm] Cannot find any crtc or sizes
Workaround:
rmmod omapdrm
modprobe omapdrm
Regards,
Andreas
Quoted 98 lines
--- drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 - drivers/gpu/drm/omapdrm/dss/output.c | 42 ++++------------------------------- 2 files changed, 4 insertions(+), 39 deletions(-)drivers/gpu/drm/omapdrm/dss/omapdss.h +0
-1@@ -204,7 +204,6 @@ struct omap_dss_device {struct dss_device *dss;struct drm_bridge *bridge;struct drm_bridge *next_bridge; -struct drm_panel *panel;struct list_head list;drivers/gpu/drm/omapdrm/dss/output.c +4
-38@@ -12,7 +12,6 @@#include <linux/of_graph.h> #include <drm/drm_bridge.h> -#include <drm/drm_panel.h> #include "dss.h" #include "omapdss.h" @@ -20,40 +19,16 @@int omapdss_device_init_output (struct omap_dss_device *out,struct drm_bridge *local_bridge) { -struct device_node *remote_node; +struct drm_bridge *bridge;int ret; - remote_node =of_graph_get_remote_node (out->dev->of_node, - out->of_port,0 ); -if (!remote_node) { + bridge =of_drm_get_bridge_by_endpoint (out->dev->of_node, out->of_port,0 ); +if (IS_ERR (bridge)) {dev_dbg (out->dev,"failed to find video sink\n" );return 0 ; } - 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) { -struct drm_bridge *bridge; - - bridge =drm_panel_bridge_add (out->panel); -drm_panel_put (out->panel); -if (IS_ERR (bridge)) { -dev_err (out->dev, -"unable to create panel bridge (%ld)\n" , -PTR_ERR (bridge)); - ret =PTR_ERR (bridge); - goto error; - } - - out->bridge =drm_bridge_get (bridge); - } + out->bridge = bridge;if (local_bridge) {if (!out->bridge) {@@ -65,11 +40,6 @@ int omapdss_device_init_output(struct omap_dss_device *out, out->bridge =drm_bridge_get (local_bridge); } -if (!out->bridge) { - ret = -EPROBE_DEFER ; - goto error; - } -return 0 ; error:@@ -79,10 +49,6 @@ int omapdss_device_init_output(struct omap_dss_device *out,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); }
Luca Ceresoli
reviewerPATCH v3 18/19 drm/tve200: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_get_bridge_by_endpoint().
And since of_drm_find_and_get_bridge() returns a refcounted bridge, take care of putting the bridge reference.
--- drivers/gpu/drm/tve200/Kconfig | 1 - drivers/gpu/drm/tve200/tve200_drm.h | 1 - drivers/gpu/drm/tve200/tve200_drv.c | 30 +++++++----------------------- 3 files changed, 7 insertions(+), 25 deletions(-)
drivers/gpu/drm/tve200/Kconfig +0 -1
@@ -8,7 +8,6 @@ config DRM_TVE200 select DRM_BRIDGE select DRM_CLIENT_SELECTION select DRM_PANEL - select DRM_PANEL_BRIDGE select DRM_KMS_HELPER select DRM_GEM_DMA_HELPER help
drivers/gpu/drm/tve200/tve200_drm.h +0 -1
@@ -103,7 +103,6 @@ struct tve200_drm_dev_private {struct drm_device *drm;struct drm_connector *connector; -struct drm_panel *panel;struct drm_bridge *bridge;struct drm_plane plane;struct drm_crtc crtc;
drivers/gpu/drm/tve200/tve200_drv.c +7 -23
@@ -65,7 +65,6 @@ static int tve200_modeset_init(struct drm_device *dev) {struct drm_mode_config *mode_config;struct tve200_drm_dev_private *priv = dev->dev_private; -struct drm_panel *panel;struct drm_bridge *bridge;int ret;
@@ -77,19 +76,10 @@ static int tve200_modeset_init(struct drm_device *dev) mode_config->min_height =240 ; mode_config->max_height =576 ; - ret =drm_of_find_panel_or_bridge (dev->dev->of_node, -0 ,0 , &panel, &bridge); -if (ret && ret != -ENODEV ) -return ret; -if (panel) { - bridge =drm_panel_bridge_add_typed (panel, - DRM_MODE_CONNECTOR_Unknown); -drm_panel_put (panel); -if (IS_ERR (bridge)) { - ret =PTR_ERR (bridge); - goto out_bridge; - } - }else { + bridge =of_drm_get_bridge_by_endpoint (dev->dev->of_node,0 ,0 ); +if (IS_ERR (bridge) &&PTR_ERR (bridge) != -ENODEV ) +return PTR_ERR (bridge); +if (IS_ERR (bridge) || !drm_bridge_is_panel (bridge)) {/* * TODO: when we are using a different bridge than a panel * (such as a dumb VGA connector) we need to devise a different
@@ -100,6 +90,8 @@ static int tve200_modeset_init(struct drm_device *dev) goto out_bridge; } + bridge->type = DRM_MODE_CONNECTOR_Unknown; + ret =tve200_display_init (dev);if (ret) {dev_err (dev->dev,"failed to init display\n" );
@@ -121,9 +113,6 @@ static int tve200_modeset_init(struct drm_device *dev) goto out_bridge; } -dev_info (dev->dev,"attached to panel %s\n" , -dev_name (panel->dev)); - ret =drm_vblank_init (dev,1 );if (ret) {dev_err (dev->dev,"failed to init vblank\n" );
@@ -136,8 +125,6 @@ static int tve200_modeset_init(struct drm_device *dev) goto finish; out_bridge: -if (panel) -drm_panel_bridge_remove (bridge);drm_mode_config_cleanup (dev); finish:return ret;
@@ -233,8 +220,6 @@ static int tve200_probe(struct platform_device *pdev)return 0 ; mode_config_cleanup: -if (priv->panel) -drm_panel_bridge_remove (priv->bridge);drm_mode_config_cleanup (drm); clk_disable:clk_disable_unprepare (priv->pclk);
@@ -248,10 +233,9 @@ static void tve200_remove(struct platform_device *pdev)struct drm_device *drm =platform_get_drvdata (pdev);struct tve200_drm_dev_private *priv = drm->dev_private; +drm_bridge_put (priv->bridge);drm_dev_unregister (drm);drm_atomic_helper_shutdown (drm); -if (priv->panel) -drm_panel_bridge_remove (priv->bridge);drm_mode_config_cleanup (drm);clk_disable_unprepare (priv->pclk);drm_dev_put (drm);
Signature · 1 line
2.55.0
Luca Ceresoli
reviewerRe: [PATCH v3 18/19] drm/tve200: don't create a panel_bridge
Hello,
Quoted 10 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().And since
of_drm_find_and_get_bridge()returns a refcounted bridge, take care of putting the bridge reference.Signed-off-by Luca Ceresoli <[email protected]>
I just found this patch fails building on current drm-misc-next due to another patch landed earlier this week. Will be fixed in v4.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [PATCH v3 18/19] drm/tve200: don't create a panel_bridge
In reply to Luca CeresoliQuoted 7 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().[ ... ]
Thanks!
Maxime
Re: [PATCH v3 18/19] drm/tve200: don't create a panel_bridge
In reply to Luca CeresoliQuoted 10 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().And since
of_drm_find_and_get_bridge()returns a refcounted bridge, take care of putting the bridge reference.Signed-off-by Luca Ceresoli <[email protected]>
Yours,
Linus Walleij
Luca Ceresoli
reviewerPATCH v3 19/19 drm/bridge: analogix_dp: don't create a panel_bridge
In reply to Luca CeresoliNow a panel_bridge is automatically created for every drm_panel and the panel-bridge API is just a deprecated wrapper to access it.
Update and simplify the code by just getting a reference to the already-existing bridge using of_drm_get_bridge_by_endpoint().
As of_drm_get_bridge_by_endpoint() returns a refcounted bridge, take care of putting the bridge reference. This is not easily done in the remove path due to the different probe paths of the user drivers, so add a devm action to ensure the reference is put only when it was taken.
--- drivers/gpu/drm/bridge/analogix/Kconfig | 1 - drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 40 +++++++++++++--------- drivers/gpu/drm/exynos/exynos_dp.c | 36 ++----------------- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 ----- include/drm/bridge/analogix_dp.h | 1 - 5 files changed, 25 insertions(+), 62 deletions(-)
drivers/gpu/drm/bridge/analogix/Kconfig +0 -1
@@ -33,7 +33,6 @@ config DRM_ANALOGIX_DP depends on DRM depends on OF select DRM_DISPLAY_DP_AUX_BUS - select DRM_PANEL config DRM_ANALOGIX_ANX7625 tristate "Analogix Anx7625 MIPI to DP interface support"
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +23 -17
@@ -29,7 +29,6 @@#include <drm/drm_device.h> #include <drm/drm_edid.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h>
@@ -1567,15 +1566,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)if (ret) goto err_unregister_aux; -if (dp->plat_data->panel) { - dp->plat_data->next_bridge =devm_drm_panel_bridge_add (dp->dev, - dp->plat_data->panel); -if (IS_ERR (dp->plat_data->next_bridge)) { - ret =PTR_ERR (dp->plat_data->next_bridge); - goto err_unregister_aux; - } - } - ret =drm_bridge_attach (dp->encoder, bridge,NULL ,DRM_BRIDGE_ATTACH_NO_CONNECTOR );if (ret) {DRM_ERROR ("failed to create bridge (%d)\n" , ret);
@@ -1647,6 +1637,11 @@ struct drm_dp_aux *analogix_dp_get_aux(struct analogix_dp_device *dp) }EXPORT_SYMBOL_GPL (analogix_dp_get_aux); +static void analogix_dp_put_bridge (void *data) +{ +drm_bridge_put (data); +} +static int analogix_dp_aux_done_probing (struct drm_dp_aux *aux) {struct analogix_dp_device *dp =to_dp (aux);
@@ -1655,14 +1650,25 @@ static int analogix_dp_aux_done_probing(struct drm_dp_aux *aux)int ret;/* -* If drm_of_find_panel_or_bridge() returns -ENODEV, there may be no valid panel -* or bridge nodes. The driver should go on for the driver-free bridge or the DP -* mode applications. +* If of_drm_get_bridge_by_endpoint() returns -ENODEV, there may be no +* valid panel or bridge nodes. The driver should go on for the +* driver-free bridge or the DP mode applications. */ - ret =drm_of_find_panel_or_bridge (dp->dev->of_node, port,0 , - &plat_data->panel, &plat_data->next_bridge); -if (ret && ret != -ENODEV ) -return ret; + plat_data->next_bridge =of_drm_get_bridge_by_endpoint (dp->dev->of_node, + port,0 ); +if (IS_ERR (plat_data->next_bridge)) { +if (PTR_ERR (plat_data->next_bridge) == -ENODEV ) + plat_data->next_bridge =NULL ; +else +return PTR_ERR (plat_data->next_bridge); + } + +if (plat_data->next_bridge) { + ret =devm_add_action_or_reset (dp->dev, analogix_dp_put_bridge, + plat_data->next_bridge); +if (ret) +return ret; + }return component_add (dp->dev, plat_data->ops); }
drivers/gpu/drm/exynos/exynos_dp.c +2 -34
@@ -26,7 +26,6 @@#include <drm/drm_crtc.h> #include <drm/drm_encoder.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/exynos_drm.h>
@@ -147,7 +146,6 @@ static const struct component_ops exynos_dp_ops = {static int exynos_dp_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev; -struct device_node *np;struct exynos_dp_device *dp; dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
@@ -163,18 +161,6 @@ static int exynos_dp_probe(struct platform_device *pdev)*/ platform_set_drvdata (pdev, dp); -/* This is for the backward compatibility. */ - np =of_parse_phandle (dev->of_node,"panel" ,0 ); -if (np) { - dp->plat_data.panel =of_drm_find_panel (np); - -of_node_put (np); -if (IS_ERR (dp->plat_data.panel)) -return PTR_ERR (dp->plat_data.panel); - - goto out; - } -if (of_get_display_timings (dev->of_node)) { dp->plat_data.next_bridge = devm_drm_of_display_mode_bridge(dp->dev, dp->dev->of_node,
@@ -189,19 +175,11 @@ static int exynos_dp_probe(struct platform_device *pdev) dp->plat_data.power_off = exynos_dp_poweroff; dp->plat_data.ops = &exynos_dp_ops; -out: dp->adp =analogix_dp_probe (dev, &dp->plat_data); -if (IS_ERR (dp->adp)) { -/* -* The driver core does not invoke remove() for failed probes, -* so release the probe-time panel reference here. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); +if (IS_ERR (dp->adp))return PTR_ERR (dp->adp); - } -if (dp->plat_data.panel || dp->plat_data.next_bridge) +if (dp->plat_data.next_bridge)return component_add (&pdev->dev, &exynos_dp_ops);else return analogix_dp_finish_probe (dp->adp);
@@ -209,16 +187,6 @@ static int exynos_dp_probe(struct platform_device *pdev)static void exynos_dp_remove (struct platform_device *pdev) { -struct exynos_dp_device *dp =platform_get_drvdata (pdev); - -/* -* Release the probe-time reference from of_drm_find_panel(). If bind -* ran, the panel_bridge holds a second reference that devm cleanup -* will release when the bridge is destroyed after remove() returns. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); -component_del (&pdev->dev, &exynos_dp_ops); }
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +0 -9
@@ -28,7 +28,6 @@#include <drm/drm_bridge_connector.h> #include <drm/bridge/analogix_dp.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h>
@@ -488,14 +487,6 @@ static void rockchip_dp_remove(struct platform_device *pdev) {struct rockchip_dp_device *dp =platform_get_drvdata (pdev); -/* -* Release the probe-time reference from of_drm_find_panel(). If bind -* ran, the panel_bridge holds a second reference that devm cleanup -* will release when the bridge is destroyed after remove() returns. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); -component_del (&pdev->dev, &rockchip_dp_component_ops); }
include/drm/bridge/analogix_dp.h +0 -1
@@ -35,7 +35,6 @@ static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type)struct analogix_dp_plat_data {enum analogix_dp_devtype dev_type; -struct drm_panel *panel;struct drm_bridge *next_bridge;struct drm_encoder *encoder;struct drm_connector *connector;
Signature · 1 line
2.55.0
Re: [PATCH v3 19/19] drm/bridge: analogix_dp: don't create a panel_bridge
Hi Luca,
Quoted 132 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().As
of_drm_get_bridge_by_endpoint()returns a refcounted bridge, take care of putting the bridge reference. This is not easily done in the remove path due to the different probe paths of the user drivers, so add a devm action to ensure the reference is put only when it was taken.Assisted-by opencode:deepseek-v4-flash-0731Signed-off-by Luca Ceresoli <[email protected]>--- drivers/gpu/drm/bridge/analogix/Kconfig | 1 - drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 40 +++++++++++++--------- drivers/gpu/drm/exynos/exynos_dp.c | 36 ++----------------- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 ----- include/drm/bridge/analogix_dp.h | 1 - 5 files changed, 25 insertions(+), 62 deletions(-)drivers/gpu/drm/bridge/analogix/Kconfig +0
-1@@ -33,7 +33,6 @@ config DRM_ANALOGIX_DP depends on DRM depends on OF select DRM_DISPLAY_DP_AUX_BUS - select DRM_PANEL config DRM_ANALOGIX_ANX7625 tristate "Analogix Anx7625 MIPI to DP interface support"drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +23
-17@@ -29,7 +29,6 @@#include <drm/drm_device.h> #include <drm/drm_edid.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> @@ -1567,15 +1566,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)if (ret) goto err_unregister_aux; -if (dp->plat_data->panel) { - dp->plat_data->next_bridge =devm_drm_panel_bridge_add (dp->dev, - dp->plat_data->panel); -if (IS_ERR (dp->plat_data->next_bridge)) { - ret =PTR_ERR (dp->plat_data->next_bridge); - goto err_unregister_aux; - } - } - ret =drm_bridge_attach (dp->encoder, bridge,NULL ,DRM_BRIDGE_ATTACH_NO_CONNECTOR );if (ret) {DRM_ERROR ("failed to create bridge (%d)\n" , ret);@@ -1647,6 +1637,11 @@ struct drm_dp_aux *analogix_dp_get_aux(struct analogix_dp_device *dp) }EXPORT_SYMBOL_GPL (analogix_dp_get_aux); +static void analogix_dp_put_bridge (void *data) +{ +drm_bridge_put (data); +} +static int analogix_dp_aux_done_probing (struct drm_dp_aux *aux) {struct analogix_dp_device *dp =to_dp (aux);@@ -1655,14 +1650,25 @@ static int analogix_dp_aux_done_probing(struct drm_dp_aux *aux)int ret;/* -* If drm_of_find_panel_or_bridge() returns -ENODEV, there may be no valid panel -* or bridge nodes. The driver should go on for the driver-free bridge or the DP -* mode applications. +* If of_drm_get_bridge_by_endpoint() returns -ENODEV, there may be no +* valid panel or bridge nodes. The driver should go on for the +* driver-free bridge or the DP mode applications. */ - ret =drm_of_find_panel_or_bridge (dp->dev->of_node, port,0 , - &plat_data->panel, &plat_data->next_bridge); -if (ret && ret != -ENODEV ) -return ret; + plat_data->next_bridge =of_drm_get_bridge_by_endpoint (dp->dev->of_node, + port,0 ); +if (IS_ERR (plat_data->next_bridge)) { +if (PTR_ERR (plat_data->next_bridge) == -ENODEV ) + plat_data->next_bridge =NULL ; +else +return PTR_ERR (plat_data->next_bridge); + } + +if (plat_data->next_bridge) { + ret =devm_add_action_or_reset (dp->dev, analogix_dp_put_bridge, + plat_data->next_bridge); +if (ret) +return ret; + }return component_add (dp->dev, plat_data->ops); }drivers/gpu/drm/exynos/exynos_dp.c +0
-4@@ -26,7 +26,6 @@#include <drm/drm_crtc.h> #include <drm/drm_encoder.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/exynos_drm.h> @@ -147,7 +146,6 @@ static const struct component_ops exynos_dp_ops = {static int exynos_dp_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev; -struct device_node *np;struct exynos_dp_device *dp; dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),@@ -163,18 +161,6 @@ static int exynos_dp_probe(struct platform_device *pdev)*/ platform_set_drvdata (pdev, dp); -/* This is for the backward compatibility. */ - np =of_parse_phandle (dev->of_node,"panel" ,0 );
drivers/gpu/drm/exynos/exynos_dp.c static int exynos_dp_probe(struct platform_device *pdev) · line 177
Quoted 10 lines
drivers/gpu/drm/exynos/exynos_dp.c +0
-10-if (np) { - dp->plat_data.panel =of_drm_find_panel (np); - -of_node_put (np); -if (IS_ERR (dp->plat_data.panel)) -return PTR_ERR (dp->plat_data.panel); - - goto out; - } -
TIP: In my WIP v3 patch series, I use of_drm_find_panel() together with devm_drm_panel_bridge_add() to maintain this backward compatibility. But I also think this old approach should be deprecated now. Shall we add some notes in the commit message to mention the deprecation of this method?
Quoted 75 lines
drivers/gpu/drm/exynos/exynos_dp.c +2
-20if (of_get_display_timings (dev->of_node)) { dp->plat_data.next_bridge = devm_drm_of_display_mode_bridge(dp->dev, dp->dev->of_node,@@ -189,19 +175,11 @@ static int exynos_dp_probe(struct platform_device *pdev) dp->plat_data.power_off = exynos_dp_poweroff; dp->plat_data.ops = &exynos_dp_ops; -out: dp->adp =analogix_dp_probe (dev, &dp->plat_data); -if (IS_ERR (dp->adp)) { -/* -* The driver core does not invoke remove() for failed probes, -* so release the probe-time panel reference here. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); +if (IS_ERR (dp->adp))return PTR_ERR (dp->adp); - } -if (dp->plat_data.panel || dp->plat_data.next_bridge) +if (dp->plat_data.next_bridge)return component_add (&pdev->dev, &exynos_dp_ops);else return analogix_dp_finish_probe (dp->adp);@@ -209,16 +187,6 @@ static int exynos_dp_probe(struct platform_device *pdev)static void exynos_dp_remove (struct platform_device *pdev) { -struct exynos_dp_device *dp =platform_get_drvdata (pdev); - -/* -* Release the probe-time reference from of_drm_find_panel(). If bind -* ran, the panel_bridge holds a second reference that devm cleanup -* will release when the bridge is destroyed after remove() returns. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); -component_del (&pdev->dev, &exynos_dp_ops); }drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +0
-9@@ -28,7 +28,6 @@#include <drm/drm_bridge_connector.h> #include <drm/bridge/analogix_dp.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> @@ -488,14 +487,6 @@ static void rockchip_dp_remove(struct platform_device *pdev) {struct rockchip_dp_device *dp =platform_get_drvdata (pdev); -/* -* Release the probe-time reference from of_drm_find_panel(). If bind -* ran, the panel_bridge holds a second reference that devm cleanup -* will release when the bridge is destroyed after remove() returns. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); -component_del (&pdev->dev, &rockchip_dp_component_ops); }include/drm/bridge/analogix_dp.h +0
-0
include/drm/bridge/analogix_dp.h static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type) · line 40
Quoted 7 lines
include/drm/bridge/analogix_dp.h +0
-1@@ -35,7 +35,6 @@ static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type)struct analogix_dp_plat_data {enum analogix_dp_devtype dev_type; -struct drm_panel *panel;struct drm_bridge *next_bridge;struct drm_encoder *encoder;struct drm_connector *connector;
I apply this patch series with the related one[0], and the eDP work well on my RK3576 board.
In my patch series for Analogix DP HPD support, Heiko also pointed out that devm_drm_of_get_bridge()(deprecated now) can be used to get the panel bridge directly, and the redundant &analogix_dp_plat_data.panel can be removed[1]. Since your patch series already contains these optimizations, I will rebase my patch series on top of yours for subsequent updates.
[0] https://lore.kernel.org/all/20260915-drm-bridge-drm_panel-cleanup-v4-0-30401d9406f3@bootlin.com/
[1] https://lore.kernel.org/all/5609825.iZASKD2KPV@diego/
Re: [PATCH v3 19/19] drm/bridge: analogix_dp: don't create a panel_bridge
Quoted 26 lines · Damon Ding
Hi Luca,
Quoted 23 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().As
of_drm_get_bridge_by_endpoint()returns a refcounted bridge, take care of putting the bridge reference. This is not easily done in the remove path due to the different probe paths of the user drivers, so add a devm action to ensure the reference is put only when it was taken.Assisted-by opencode:deepseek-v4-flash-0731Signed-off-by Luca Ceresoli <[email protected]>---
drivers/gpu/drm/bridge/analogix/Kconfig | 1 -drivers/gpu/drm/bridge/analogix/analogix_dp_core.c| 40 +++++++++++++--------- drivers/gpu/drm/exynos/exynos_dp.c | 36 + +----------------- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 ----- include/drm/bridge/analogix_dp.h | 1 - 5 files changed, 25 insertions(+), 62 deletions(-)
[snip]
Quoted 4 lines
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c static void rockchip_dp_remove(struct · line 489
Quoted 4 lines
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +0
-0@@ -488,14 +487,6 @@ static void rockchip_dp_remove(struct platform_device *pdev) { struct rockchip_dp_device *dp = platform_get_drvdata(pdev);
The above unused &rockchip_dp_device could be also remved.
Quoted 27 lines
Quoted 17 lines
(quoted diff) +0
-2- /* - * Release the probe-time reference from of_drm_find_panel(). Ifbind
- * ran, thepanel_bridgeholds a second reference that devm cleanup - * will release when the bridge is destroyed afterremove()returns. - */
- if (dp->plat_data.panel)
-drm_panel_put(dp->plat_data.panel);
-
component_del(&pdev->dev, &rockchip_dp_component_ops); }include/drm/bridge/analogix_dp.h +0
-0include/drm/bridge/analogix_dp.h static inline bool analogix_dp_is_rockchip(enum · line 40
Quoted 7 lines
include/drm/bridge/analogix_dp.h +0
-1@@ -35,7 +35,6 @@ static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type) struct analogix_dp_plat_data { enum analogix_dp_devtype dev_type; - struct drm_panel *panel; struct drm_bridge *next_bridge; struct drm_encoder *encoder; struct drm_connector *connector;I apply this patch series with the related one[0], and the eDP work well on my RK3576 board.
Quoted 9 lines
Tested-by Damon Ding <[email protected]>In my patch series for Analogix DP HPD support, Heiko also pointed out that devm_drm_of_get_bridge()(deprecated now) can be used to get the panel bridge directly, and the redundant &analogix_dp_plat_data.panel can be removed[1]. Since your patch series already contains these optimizations, I will rebase my patch series on top of yours for subsequent updates.
Reviewed-by Damon Ding <[email protected]>[0] https://lore.kernel.org/all/20260915-drm-bridge-drm_panel-cleanup- [email protected]/
[1] https://lore.kernel.org/all/5609825.iZASKD2KPV@diego/
Best regards,
Damon
_______________________________________________
Linux-rockchip mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-rockchip
Luca Ceresoli
reviewerRe: [PATCH v3 19/19] drm/bridge: analogix_dp: don't create a panel_bridge
Hello Damon,
Quoted 30 lines · Damon Ding
Quoted 28 lines · Damon Ding
Hi Luca,
Quoted 25 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().As
of_drm_get_bridge_by_endpoint()returns a refcounted bridge, take care of putting the bridge reference. This is not easily done in the remove path
due to the different probe paths of the user drivers, so add a devm action
to ensure the reference is put only when it was taken.Assisted-by opencode:deepseek-v4-flash-0731Signed-off-by Luca Ceresoli <[email protected]>---
drivers/gpu/drm/bridge/analogix/Kconfig | 1 -drivers/gpu/drm/bridge/analogix/analogix_dp_core.c| 40 +++++++++++++--------- drivers/gpu/drm/exynos/exynos_dp.c | 36 + +----------------- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 ----- include/drm/bridge/analogix_dp.h | 1 - 5 files changed, 25 insertions(+), 62 deletions(-)
Quoted 8 lines
[snip]
Quoted 4 lines
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c static void rockchip_dp_remove(struct · line 489
Quoted 4 lines
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +0
-0@@ -488,14 +487,6 @@ static void rockchip_dp_remove(struct platform_device *pdev) { struct rockchip_dp_device *dp = platform_get_drvdata(pdev);The above unused
&rockchip_dp_devicecould be also remved.
Ah, indeed!
I guess I can keep your review tags if applying this patch with only this line removed. Correct?
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Re: [PATCH v3 19/19] drm/bridge: analogix_dp: don't create a panel_bridge
Quoted 42 lines · Luca Ceresoli
Hello Damon,
Quoted 30 lines · Damon Ding
Quoted 28 lines · Damon Ding
Hi Luca,
Quoted 25 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().As
of_drm_get_bridge_by_endpoint()returns a refcounted bridge, take care of putting the bridge reference. This is not easily done in the remove path
due to the different probe paths of the user drivers, so add a devm action
to ensure the reference is put only when it was taken.Assisted-by opencode:deepseek-v4-flash-0731Signed-off-by Luca Ceresoli <[email protected]>--- drivers/gpu/drm/bridge/analogix/Kconfig | 1 - drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 40 ++++++++++++ +--------- drivers/gpu/drm/exynos/exynos_dp.c | 36 + +----------------- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 ----- include/drm/bridge/analogix_dp.h | 1 - 5 files changed, 25 insertions(+), 62 deletions(-)Quoted 8 lines
[snip]
Quoted 4 lines
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c static void rockchip_dp_remove(struct · line 489
Quoted 4 lines
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +0
-0@@ -488,14 +487,6 @@ static void rockchip_dp_remove(struct platform_device *pdev) { struct rockchip_dp_device *dp = platform_get_drvdata(pdev);The above unused
&rockchip_dp_devicecould be also remved.
Quoted 5 lines
Ah, indeed!
I guess I can keep your review tags if applying this patch with only this line removed. Correct?
Yeah, sure!
Best regards,
Damon
Luca Ceresoli
reviewerRe: [PATCH v3 19/19] drm/bridge: analogix_dp: don't create a panel_bridge
In reply to Damon DingHello Damon,
Quoted 142 lines · Damon Ding
Hi Luca,
Quoted 139 lines · Luca Ceresoli
Now a
panel_bridgeis automatically created for everydrm_paneland the panel-bridge API is just a deprecated wrapper to access it.Update and simplify the code by just getting a reference to the already-existing bridge using
of_drm_get_bridge_by_endpoint().As
of_drm_get_bridge_by_endpoint()returns a refcounted bridge, take care of putting the bridge reference. This is not easily done in the remove path due to the different probe paths of the user drivers, so add a devm action to ensure the reference is put only when it was taken.Assisted-by opencode:deepseek-v4-flash-0731Signed-off-by Luca Ceresoli <[email protected]>--- drivers/gpu/drm/bridge/analogix/Kconfig | 1 - drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 40 +++++++++++++--------- drivers/gpu/drm/exynos/exynos_dp.c | 36 ++----------------- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 ----- include/drm/bridge/analogix_dp.h | 1 - 5 files changed, 25 insertions(+), 62 deletions(-)drivers/gpu/drm/bridge/analogix/Kconfig +0
-1@@ -33,7 +33,6 @@ config DRM_ANALOGIX_DP depends on DRM depends on OF select DRM_DISPLAY_DP_AUX_BUS - select DRM_PANEL config DRM_ANALOGIX_ANX7625 tristate "Analogix Anx7625 MIPI to DP interface support"drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +23
-17@@ -29,7 +29,6 @@#include <drm/drm_device.h> #include <drm/drm_edid.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> @@ -1567,15 +1566,6 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)if (ret) goto err_unregister_aux; -if (dp->plat_data->panel) { - dp->plat_data->next_bridge =devm_drm_panel_bridge_add (dp->dev, - dp->plat_data->panel); -if (IS_ERR (dp->plat_data->next_bridge)) { - ret =PTR_ERR (dp->plat_data->next_bridge); - goto err_unregister_aux; - } - } - ret =drm_bridge_attach (dp->encoder, bridge,NULL ,DRM_BRIDGE_ATTACH_NO_CONNECTOR );if (ret) {DRM_ERROR ("failed to create bridge (%d)\n" , ret);@@ -1647,6 +1637,11 @@ struct drm_dp_aux *analogix_dp_get_aux(struct analogix_dp_device *dp) }EXPORT_SYMBOL_GPL (analogix_dp_get_aux); +static void analogix_dp_put_bridge (void *data) +{ +drm_bridge_put (data); +} +static int analogix_dp_aux_done_probing (struct drm_dp_aux *aux) {struct analogix_dp_device *dp =to_dp (aux);@@ -1655,14 +1650,25 @@ static int analogix_dp_aux_done_probing(struct drm_dp_aux *aux)int ret;/* -* If drm_of_find_panel_or_bridge() returns -ENODEV, there may be no valid panel -* or bridge nodes. The driver should go on for the driver-free bridge or the DP -* mode applications. +* If of_drm_get_bridge_by_endpoint() returns -ENODEV, there may be no +* valid panel or bridge nodes. The driver should go on for the +* driver-free bridge or the DP mode applications. */ - ret =drm_of_find_panel_or_bridge (dp->dev->of_node, port,0 , - &plat_data->panel, &plat_data->next_bridge); -if (ret && ret != -ENODEV ) -return ret; + plat_data->next_bridge =of_drm_get_bridge_by_endpoint (dp->dev->of_node, + port,0 ); +if (IS_ERR (plat_data->next_bridge)) { +if (PTR_ERR (plat_data->next_bridge) == -ENODEV ) + plat_data->next_bridge =NULL ; +else +return PTR_ERR (plat_data->next_bridge); + } + +if (plat_data->next_bridge) { + ret =devm_add_action_or_reset (dp->dev, analogix_dp_put_bridge, + plat_data->next_bridge); +if (ret) +return ret; + }return component_add (dp->dev, plat_data->ops); }drivers/gpu/drm/exynos/exynos_dp.c +0
-11@@ -26,7 +26,6 @@#include <drm/drm_crtc.h> #include <drm/drm_encoder.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/exynos_drm.h> @@ -147,7 +146,6 @@ static const struct component_ops exynos_dp_ops = {static int exynos_dp_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev; -struct device_node *np;struct exynos_dp_device *dp; dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),@@ -163,18 +161,6 @@ static int exynos_dp_probe(struct platform_device *pdev)*/ platform_set_drvdata (pdev, dp); -/* This is for the backward compatibility. */ - np =of_parse_phandle (dev->of_node,"panel" ,0 ); -if (np) { - dp->plat_data.panel =of_drm_find_panel (np); - -of_node_put (np); -if (IS_ERR (dp->plat_data.panel)) -return PTR_ERR (dp->plat_data.panel); -
Quoted 8 lines
drivers/gpu/drm/exynos/exynos_dp.c static int exynos_dp_probe(struct platform_device *pdev) · line 177
Quoted 3 lines
drivers/gpu/drm/exynos/exynos_dp.c +0
-3- goto out; - } -TIP: In my WIP v3 patch series, I use
of_drm_find_panel()together withdevm_drm_panel_bridge_add()to maintain this backward compatibility. But I also think this old approach should be deprecated now. Shall we add some notes in the commit message to mention the deprecation of this method?
What is the "WIP v3" series exactly? Do you have a link (to v2 in case v3 is not yet public)?
Quoted 86 lines
Quoted 75 lines
drivers/gpu/drm/exynos/exynos_dp.c +2
-20if (of_get_display_timings (dev->of_node)) { dp->plat_data.next_bridge = devm_drm_of_display_mode_bridge(dp->dev, dp->dev->of_node,@@ -189,19 +175,11 @@ static int exynos_dp_probe(struct platform_device *pdev) dp->plat_data.power_off = exynos_dp_poweroff; dp->plat_data.ops = &exynos_dp_ops; -out: dp->adp =analogix_dp_probe (dev, &dp->plat_data); -if (IS_ERR (dp->adp)) { -/* -* The driver core does not invoke remove() for failed probes, -* so release the probe-time panel reference here. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); +if (IS_ERR (dp->adp))return PTR_ERR (dp->adp); - } -if (dp->plat_data.panel || dp->plat_data.next_bridge) +if (dp->plat_data.next_bridge)return component_add (&pdev->dev, &exynos_dp_ops);else return analogix_dp_finish_probe (dp->adp);@@ -209,16 +187,6 @@ static int exynos_dp_probe(struct platform_device *pdev)static void exynos_dp_remove (struct platform_device *pdev) { -struct exynos_dp_device *dp =platform_get_drvdata (pdev); - -/* -* Release the probe-time reference from of_drm_find_panel(). If bind -* ran, the panel_bridge holds a second reference that devm cleanup -* will release when the bridge is destroyed after remove() returns. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); -component_del (&pdev->dev, &exynos_dp_ops); }drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +0
-9@@ -28,7 +28,6 @@#include <drm/drm_bridge_connector.h> #include <drm/bridge/analogix_dp.h> #include <drm/drm_of.h> -#include <drm/drm_panel.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> @@ -488,14 +487,6 @@ static void rockchip_dp_remove(struct platform_device *pdev) {struct rockchip_dp_device *dp =platform_get_drvdata (pdev); -/* -* Release the probe-time reference from of_drm_find_panel(). If bind -* ran, the panel_bridge holds a second reference that devm cleanup -* will release when the bridge is destroyed after remove() returns. -*/ -if (dp->plat_data.panel) -drm_panel_put (dp->plat_data.panel); -component_del (&pdev->dev, &rockchip_dp_component_ops); }include/drm/bridge/analogix_dp.h +0
-0include/drm/bridge/analogix_dp.h static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type) · line 40
Quoted 7 lines
include/drm/bridge/analogix_dp.h +0
-1@@ -35,7 +35,6 @@ static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type)struct analogix_dp_plat_data {enum analogix_dp_devtype dev_type; -struct drm_panel *panel;struct drm_bridge *next_bridge;struct drm_encoder *encoder;struct drm_connector *connector;I apply this patch series with the related one[0], and the eDP work well on my RK3576 board.
Quoted 8 lines
Tested-by Damon Ding <[email protected]>In my patch series for Analogix DP HPD support, Heiko also pointed out that devm_drm_of_get_bridge()(deprecated now) can be used to get the panel bridge directly, and the redundant &analogix_dp_plat_data.panel can be removed[1]. Since your patch series already contains these optimizations, I will rebase my patch series on top of yours for subsequent updates.
Yes, I confirm with this series devm_drm_of_get_bridge() becomes a complicated equivalent of of_drm_get_bridge_by_endpoint(). So what Heiko suggested is correct for current upstream code, but this patch goes a step further, using just the bridge API as the new recommended practice will be as soon as this series is applied.
FYI this series is now fully acked, so I plan to apply it by the end of this week or early next week.
Quoted 5 lines
Reviewed-by Damon Ding <[email protected]>[0]
https://lore.kernel.org/all/20260915-drm-bridge-drm_panel-cleanup-v4-0-30401d9406f3@bootlin.com/
[1] https://lore.kernel.org/all/5609825.iZASKD2KPV@diego/
Thanks for reviewing and testing!
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
Heiko Stuebner
maintainerRe: [PATCH v3 19/19] drm/bridge: analogix_dp: don't create a panel_bridge
Hi Luca,
Am Dienstag, 22. September 2026, 10:12:41 Mitteleuropäische Sommerzeit schrieb Luca Ceresoli:
Quoted 2 lines · Damon Ding
Quoted 1 line · Luca Ceresoli
[...]
Quoted 22 lines
Quoted 13 lines
Quoted 13 lines
drivers/gpu/drm/exynos/exynos_dp.c +0
-9@@ -163,18 +161,6 @@ static int exynos_dp_probe(struct platform_device *pdev)*/ platform_set_drvdata (pdev, dp); -/* This is for the backward compatibility. */ - np =of_parse_phandle (dev->of_node,"panel" ,0 ); -if (np) { - dp->plat_data.panel =of_drm_find_panel (np); - -of_node_put (np); -if (IS_ERR (dp->plat_data.panel)) -return PTR_ERR (dp->plat_data.panel); -Quoted 8 lines
drivers/gpu/drm/exynos/exynos_dp.c static int exynos_dp_probe(struct platform_device *pdev) · line 177
Quoted 3 lines
drivers/gpu/drm/exynos/exynos_dp.c +0
-3- goto out; - } -TIP: In my WIP v3 patch series, I use
of_drm_find_panel()together withdevm_drm_panel_bridge_add()to maintain this backward compatibility. But I also think this old approach should be deprecated now. Shall we add some notes in the commit message to mention the deprecation of this method?
Quoted 2 lines
What is the "WIP v3" series exactly? Do you have a link (to v2 in case v3 is not yet public)?
https://lore.kernel.org/linux-rockchip/[email protected]/
is the series in question.
Heiko
Re: [PATCH v3 19/19] drm/bridge: analogix_dp: don't create a panel_bridge
Hi Heiko,
Quoted 30 lines · Heiko Stuebner
Hi Luca,
Am Dienstag, 22. September 2026, 10:12:41 Mitteleuropäische Sommerzeit schrieb Luca Ceresoli:
Quoted 2 lines · Damon Ding
Quoted 1 line · Luca Ceresoli
[...]
Quoted 22 lines
Quoted 21 lines
Quoted 6 lines
drivers/gpu/drm/exynos/exynos_dp.c +0
-2@@ -163,18 +161,6 @@ static int exynos_dp_probe(struct platform_device *pdev)*/ platform_set_drvdata (pdev, dp); -/* This is for the backward compatibility. */ - np =of_parse_phandle (dev->of_node,"panel" ,0 );drivers/gpu/drm/exynos/exynos_dp.c static int exynos_dp_probe(struct platform_device *pdev) · line 177
Quoted 10 lines
drivers/gpu/drm/exynos/exynos_dp.c +0
-10-if (np) { - dp->plat_data.panel =of_drm_find_panel (np); - -of_node_put (np); -if (IS_ERR (dp->plat_data.panel)) -return PTR_ERR (dp->plat_data.panel); - - goto out; - } -TIP: In my WIP v3 patch series, I use
of_drm_find_panel()together withdevm_drm_panel_bridge_add()to maintain this backward compatibility. But I also think this old approach should be deprecated now. Shall we add some notes in the commit message to mention the deprecation of this method?
Quoted 7 lines
Quoted 2 lines
What is the "WIP v3" series exactly? Do you have a link (to v2 in case v3 is not yet public)?
https://lore.kernel.org/linux-rockchip/[email protected]/
is the series in question.
Sorry for the confusion. I was discussing another separate series in this thread, which caused misunderstanding. I mentioned earlier that I will try to post its v3 update within this week.[0]
Best regards,
Damon
Luca Ceresoli
reviewerQuoted 2 lines · Luca Ceresoli
This series embeds a
drm_bridgeinto everydrm_panel, as previously discussed [1][2] and in previous iterations.
Series applied to drm-misc-next.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com