]> Gentwo Git Trees - linux/.git/commitdiff
drm/mediatek: Fix probe resource leaks
authorJohan Hovold <johan@kernel.org>
Tue, 23 Sep 2025 15:23:36 +0000 (17:23 +0200)
committerChun-Kuang Hu <chunkuang.hu@kernel.org>
Mon, 17 Nov 2025 15:04:41 +0000 (15:04 +0000)
Make sure to unmap and release the component iomap and clock on probe
failure (e.g. probe deferral) and on driver unbind.

Note that unlike of_iomap(), devm_of_iomap() also checks whether the
region is already mapped.

Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
Cc: stable@vger.kernel.org # 4.7
Cc: CK Hu <ck.hu@mediatek.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patchwork.kernel.org/project/dri-devel/patch/20250923152340.18234-2-johan@kernel.org/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
drivers/gpu/drm/mediatek/mtk_ddp_comp.c
drivers/gpu/drm/mediatek/mtk_ddp_comp.h
drivers/gpu/drm/mediatek/mtk_drm_drv.c

index ac6620e10262e3b9a4a82093f13c3101f79520de..0264017806adc73000f904bd2692cf9731b211fe 100644 (file)
@@ -621,15 +621,20 @@ int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev)
        return ret;
 }
 
-int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
+static void mtk_ddp_comp_clk_put(void *_clk)
+{
+       struct clk *clk = _clk;
+
+       clk_put(clk);
+}
+
+int mtk_ddp_comp_init(struct device *dev, struct device_node *node, struct mtk_ddp_comp *comp,
                      unsigned int comp_id)
 {
        struct platform_device *comp_pdev;
        enum mtk_ddp_comp_type type;
        struct mtk_ddp_comp_dev *priv;
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
        int ret;
-#endif
 
        if (comp_id >= DDP_COMPONENT_DRM_ID_MAX)
                return -EINVAL;
@@ -670,11 +675,18 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
        if (!priv)
                return -ENOMEM;
 
-       priv->regs = of_iomap(node, 0);
+       priv->regs = devm_of_iomap(dev, node, 0, NULL);
+       if (IS_ERR(priv->regs))
+               return PTR_ERR(priv->regs);
+
        priv->clk = of_clk_get(node, 0);
        if (IS_ERR(priv->clk))
                return PTR_ERR(priv->clk);
 
+       ret = devm_add_action_or_reset(dev, mtk_ddp_comp_clk_put, priv->clk);
+       if (ret)
+               return ret;
+
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
        ret = cmdq_dev_get_client_reg(comp->dev, &priv->cmdq_reg, 0);
        if (ret)
index 7289b3dcf22f22f344016beee0c7c144cf7b93c8..3f3d43f4330da480f2780e54c4ba86d5da07c400 100644 (file)
@@ -350,7 +350,7 @@ static inline void mtk_ddp_comp_encoder_index_set(struct mtk_ddp_comp *comp)
 int mtk_ddp_comp_get_id(struct device_node *node,
                        enum mtk_ddp_comp_type comp_type);
 int mtk_find_possible_crtcs(struct drm_device *drm, struct device *dev);
-int mtk_ddp_comp_init(struct device_node *comp_node, struct mtk_ddp_comp *comp,
+int mtk_ddp_comp_init(struct device *dev, struct device_node *comp_node, struct mtk_ddp_comp *comp,
                      unsigned int comp_id);
 enum mtk_ddp_comp_type mtk_ddp_comp_get_type(unsigned int comp_id);
 void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
index eb5537f0ac90d87f59133c8e42e206d9ac62e050..384b0510272c230abcb3e40c9684b0190dce17f8 100644 (file)
@@ -1133,7 +1133,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
                                                            (void *)private->mmsys_dev,
                                                            sizeof(*private->mmsys_dev));
                private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR].dev = &ovl_adaptor->dev;
-               mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR],
+               mtk_ddp_comp_init(dev, NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVL_ADAPTOR],
                                  DDP_COMPONENT_DRM_OVL_ADAPTOR);
                component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
        }
@@ -1199,7 +1199,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
                                                   node);
                }
 
-               ret = mtk_ddp_comp_init(node, &private->ddp_comp[comp_id], comp_id);
+               ret = mtk_ddp_comp_init(dev, node, &private->ddp_comp[comp_id], comp_id);
                if (ret) {
                        of_node_put(node);
                        goto err_node;