Now a panel_bridge is automatically created for every drm_panel, so this
call to devm_drm_panel_bridge_add() would lead to creating a second bridge
for the same panel.

Update and simplify the code by just getting a reference to the
already-existing bridge.

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-0731
Signed-off-by: Luca Ceresoli <[email protected]>
---
 drivers/gpu/drm/bridge/analogix/Kconfig            |  2 --
 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(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig 
b/drivers/gpu/drm/bridge/analogix/Kconfig
index d07431788fcb..1e7726c76361 100644
--- a/drivers/gpu/drm/bridge/analogix/Kconfig
+++ b/drivers/gpu/drm/bridge/analogix/Kconfig
@@ -34,8 +34,6 @@ config DRM_ANALOGIX_DP
        depends on DRM
        depends on OF
        select DRM_DISPLAY_DP_AUX_BUS
-       select DRM_PANEL
-       select DRM_PANEL_BRIDGE
 
 config DRM_ANALOGIX_ANX7625
        tristate "Analogix Anx7625 MIPI to DP interface support"
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 566f1e5eb8cd..233bdaea8012 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -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>
 
@@ -1491,15 +1490,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);
@@ -1571,6 +1561,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);
@@ -1579,14 +1574,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);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_dp.c 
b/drivers/gpu/drm/exynos/exynos_dp.c
index e1c9e2946b8a..82c238829921 100644
--- a/drivers/gpu/drm/exynos/exynos_dp.c
+++ b/drivers/gpu/drm/exynos/exynos_dp.c
@@ -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);
 }
 
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 587e60232ec7..071d31aa5288 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -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);
 }
 
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 0e0b87abee59..6033137b651e 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -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;

-- 
2.55.0

Reply via email to