This is the new API for allocating DRM bridges.

This driver embeds an array of channels in the main struct, and each
channel embeds a drm_bridge. This prevents dynamic, refcount-based
deallocation of the bridges.

To make the new, dynamic bridge allocation possible:

 * change the array of channels into an array of channel pointers
 * allocate each channel using devm_drm_bridge_alloc()
 * adapt the code wherever using the channels
 * remove the is_available flag, now "ch != NULL" is equivalent

Signed-off-by: Luca Ceresoli <luca.ceres...@bootlin.com>

---

Cc: Liu Ying <victor....@nxp.com>

Changes in v3:
- fix NULL pointer deref in .remove and remove is_available bool

Changes in v2: none
---
 .../gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c    | 27 +++++++++++-----------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c 
b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c
index 
1f6fd488e7039e943351006d3373009f0c15cb08..8517b1c953d4e0fb9f5b6dbe25fbaaa63eef2b33
 100644
--- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c
+++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c
@@ -63,12 +63,11 @@ struct imx8qxp_pc_channel {
        struct drm_bridge *next_bridge;
        struct imx8qxp_pc *pc;
        unsigned int stream_id;
-       bool is_available;
 };
 
 struct imx8qxp_pc {
        struct device *dev;
-       struct imx8qxp_pc_channel ch[2];
+       struct imx8qxp_pc_channel *ch[2];
        struct clk *clk_apb;
        void __iomem *base;
 };
@@ -307,7 +306,14 @@ static int imx8qxp_pc_bridge_probe(struct platform_device 
*pdev)
                        goto free_child;
                }
 
-               ch = &pc->ch[i];
+               ch = devm_drm_bridge_alloc(dev, struct imx8qxp_pc_channel, 
bridge,
+                                          &imx8qxp_pc_bridge_funcs);
+               if (IS_ERR(ch)) {
+                       ret = PTR_ERR(ch);
+                       goto free_child;
+               }
+
+               pc->ch[i] = ch;
                ch->pc = pc;
                ch->stream_id = i;
 
@@ -333,9 +339,7 @@ static int imx8qxp_pc_bridge_probe(struct platform_device 
*pdev)
                of_node_put(remote);
 
                ch->bridge.driver_private = ch;
-               ch->bridge.funcs = &imx8qxp_pc_bridge_funcs;
                ch->bridge.of_node = child;
-               ch->is_available = true;
 
                drm_bridge_add(&ch->bridge);
        }
@@ -345,8 +349,8 @@ static int imx8qxp_pc_bridge_probe(struct platform_device 
*pdev)
 free_child:
        of_node_put(child);
 
-       if (i == 1 && pc->ch[0].next_bridge)
-               drm_bridge_remove(&pc->ch[0].bridge);
+       if (i == 1 && pc->ch[0]->next_bridge)
+               drm_bridge_remove(&pc->ch[0]->bridge);
 
        pm_runtime_disable(dev);
        return ret;
@@ -359,13 +363,10 @@ static void imx8qxp_pc_bridge_remove(struct 
platform_device *pdev)
        int i;
 
        for (i = 0; i < 2; i++) {
-               ch = &pc->ch[i];
-
-               if (!ch->is_available)
-                       continue;
+               ch = pc->ch[i];
 
-               drm_bridge_remove(&ch->bridge);
-               ch->is_available = false;
+               if (ch)
+                       drm_bridge_remove(&ch->bridge);
        }
 
        pm_runtime_disable(&pdev->dev);

-- 
2.49.0

Reply via email to