of_drm_find_bridge() is deprecated. Move to its replacement
of_drm_find_and_get_bridge() which gets a bridge reference, and ensure it
is put when done.

We need to handle the two cases: when a panel is found and when it isn't,
even though the latter is not supported. So:

 * in case a panel is not found and bridge is, get a reference to the
   found bridge
 * in case a panel is found, get a reference to the panel_bridge when it
   is added, so the following code always get exactly one reference that
   it needs to put

Finally, use the next_bridge pointer in struct drm_bridge in order to
simplify putting the reference.

Signed-off-by: Luca Ceresoli <[email protected]>
---
 drivers/gpu/drm/mcde/mcde_dsi.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c
index 3faebe571fc2..bd2135fd4293 100644
--- a/drivers/gpu/drm/mcde/mcde_dsi.c
+++ b/drivers/gpu/drm/mcde/mcde_dsi.c
@@ -40,7 +40,6 @@ struct mcde_dsi {
        struct mcde *mcde;
        struct drm_bridge bridge;
        struct drm_panel *panel;
-       struct drm_bridge *bridge_out;
        struct mipi_dsi_host dsi_host;
        struct mipi_dsi_device *mdsi;
        const struct drm_display_mode *mode;
@@ -1060,7 +1059,7 @@ static int mcde_dsi_bridge_attach(struct drm_bridge 
*bridge,
        }
 
        /* Attach the DSI bridge to the output (panel etc) bridge */
-       return drm_bridge_attach(encoder, d->bridge_out, bridge, flags);
+       return drm_bridge_attach(encoder, d->bridge.next_bridge, bridge, flags);
 }
 
 static const struct drm_bridge_funcs mcde_dsi_bridge_funcs = {
@@ -1076,7 +1075,7 @@ static int mcde_dsi_bind(struct device *dev, struct 
device *master,
        struct mcde_dsi *d = dev_get_drvdata(dev);
        struct device_node *child;
        struct drm_panel *panel = NULL;
-       struct drm_bridge *bridge = NULL;
+       struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
 
        if (!of_get_available_child_count(dev->of_node)) {
                dev_info(dev, "unused DSI interface\n");
@@ -1112,7 +1111,8 @@ static int mcde_dsi_bind(struct device *dev, struct 
device *master,
                                PTR_ERR(panel));
                        panel = NULL;
 
-                       bridge = of_drm_find_bridge(child);
+                       drm_bridge_put(bridge); // In case of multiple matching 
loops
+                       bridge = of_drm_find_and_get_bridge(child);
                        if (!bridge) {
                                dev_err(dev, "failed to find bridge\n");
                                of_node_put(child);
@@ -1127,6 +1127,7 @@ static int mcde_dsi_bind(struct device *dev, struct 
device *master,
                        dev_err(dev, "error adding panel bridge\n");
                        return PTR_ERR(bridge);
                }
+               drm_bridge_get(bridge);
                dev_info(dev, "connected to panel\n");
                d->panel = panel;
        } else if (bridge) {
@@ -1138,7 +1139,7 @@ static int mcde_dsi_bind(struct device *dev, struct 
device *master,
                return -ENODEV;
        }
 
-       d->bridge_out = bridge;
+       d->bridge.next_bridge = drm_bridge_get(bridge);
 
        /* Create a bridge for this DSI channel */
        d->bridge.of_node = dev->of_node;
@@ -1158,7 +1159,7 @@ static void mcde_dsi_unbind(struct device *dev, struct 
device *master,
        struct mcde_dsi *d = dev_get_drvdata(dev);
 
        if (d->panel)
-               drm_panel_bridge_remove(d->bridge_out);
+               drm_panel_bridge_remove(d->bridge.next_bridge);
        regmap_update_bits(d->prcmu, PRCM_DSI_SW_RESET,
                           PRCM_DSI_SW_RESET_DSI0_SW_RESETN, 0);
 }

-- 
2.52.0

Reply via email to