]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm: rcar-du: encoder: convert to of_drm_find_and_get_bridge()
authorLuca Ceresoli <luca.ceresoli@bootlin.com>
Thu, 9 Apr 2026 13:23:29 +0000 (15:23 +0200)
committerLuca Ceresoli <luca.ceresoli@bootlin.com>
Thu, 16 Apr 2026 08:14:43 +0000 (10:14 +0200)
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_bridge is added and when it
isn't. So:

 * in the 'else' case a panel_bridge is not added and bridge is found: use
   of_drm_find_and_get_bridge() to get a reference to the found bridge
 * in the 'then' case a panel_bridge is found using a devm function which
   already takes a refcount and will put it on removal, but we need to take
   another so the following code in this function always get exactly one
   reference that it needs to put

In order to put the reference, add the needed drm_bridge_put() calls in the
existing cleanup function.

Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Link: https://patch.msgid.link/20260409-drm-bridge-alloc-getput-drm_of_find_bridge-4-v5-2-d7381c07788a@bootlin.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.c
drivers/gpu/drm/renesas/rcar-du/rcar_du_encoder.h
drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c

index 7ecec7b04a8d0b0794bdd784fd0d7c7c5ba0a71c..32ea09d65d766bd60e9201c19df3bfc5ef2db800 100644 (file)
@@ -51,7 +51,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 {
        struct rcar_du_encoder *renc;
        struct drm_connector *connector;
-       struct drm_bridge *bridge;
+       struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
        int ret;
 
        /*
@@ -70,19 +70,28 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
                bridge = devm_drm_panel_bridge_add_typed(rcdu->dev, panel,
                                                         DRM_MODE_CONNECTOR_DPI);
                if (IS_ERR(bridge))
-                       return PTR_ERR(bridge);
+                       return PTR_ERR(no_free_ptr(bridge));
+
+               /*
+                * The reference taken by devm_drm_panel_bridge_add_typed() is
+                * released automatically. Take a second one for the __free()
+                * when this function will return.
+                */
+               drm_bridge_get(bridge);
        } else {
-               bridge = of_drm_find_bridge(enc_node);
+               bridge = of_drm_find_and_get_bridge(enc_node);
                if (!bridge)
                        return -EPROBE_DEFER;
 
                if (output == RCAR_DU_OUTPUT_LVDS0 ||
                    output == RCAR_DU_OUTPUT_LVDS1)
-                       rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] = bridge;
+                       rcdu->lvds[output - RCAR_DU_OUTPUT_LVDS0] =
+                               drm_bridge_get(bridge);
 
                if (output == RCAR_DU_OUTPUT_DSI0 ||
                    output == RCAR_DU_OUTPUT_DSI1)
-                       rcdu->dsi[output - RCAR_DU_OUTPUT_DSI0] = bridge;
+                       rcdu->dsi[output - RCAR_DU_OUTPUT_DSI0] =
+                               drm_bridge_get(bridge);
        }
 
        /*
@@ -135,3 +144,13 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
 
        return drm_connector_attach_encoder(connector, &renc->base);
 }
+
+void rcar_du_encoder_cleanup(struct rcar_du_device *rcdu)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(rcdu->lvds); i++)
+               drm_bridge_put(rcdu->lvds[i]);
+       for (i = 0; i < ARRAY_SIZE(rcdu->dsi); i++)
+               drm_bridge_put(rcdu->dsi[i]);
+}
index e5ec8fbb3979e476cb60bf8cef4adf7d443dd9ad..b2b5e93f30f8fd3e9bc805e97de848ed584933ba 100644 (file)
@@ -25,5 +25,6 @@ struct rcar_du_encoder {
 int rcar_du_encoder_init(struct rcar_du_device *rcdu,
                         enum rcar_du_output output,
                         struct device_node *enc_node);
+void rcar_du_encoder_cleanup(struct rcar_du_device *rcdu);
 
 #endif /* __RCAR_DU_ENCODER_H__ */
index b2d0e4651e3523075835a77c7da1a111a164e2ec..1119c84e5fe9fb237836eaa9966d081cc78c4dcd 100644 (file)
@@ -832,6 +832,8 @@ static void rcar_du_modeset_cleanup(struct drm_device *dev, void *res)
 
                put_device(cmm->dev);
        }
+
+       rcar_du_encoder_cleanup(rcdu);
 }
 
 int rcar_du_modeset_init(struct rcar_du_device *rcdu)