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