]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iommu/mediatek-v1: fix device leaks on probe()
authorJohan Hovold <johan@kernel.org>
Mon, 20 Oct 2025 04:53:13 +0000 (06:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Jan 2026 09:16:55 +0000 (10:16 +0100)
commit 46207625c9f33da0e43bb4ae1e91f0791b6ed633 upstream.

Make sure to drop the references taken to the larb devices during
probe on probe failure (e.g. probe deferral) and on driver unbind.

Fixes: b17336c55d89 ("iommu/mediatek: add support for mtk iommu generation one HW")
Cc: stable@vger.kernel.org # 4.8
Cc: Honghui Zhang <honghui.zhang@mediatek.com>
Acked-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/iommu/mtk_iommu_v1.c

index de9153c0a82f7b08da345ed91de70d8163ee37b6..44b965a2db923b1d5b09302323f7ade92eb42913 100644 (file)
@@ -648,8 +648,10 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
                struct platform_device *plarbdev;
 
                larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
-               if (!larbnode)
-                       return -EINVAL;
+               if (!larbnode) {
+                       ret = -EINVAL;
+                       goto out_put_larbs;
+               }
 
                if (!of_device_is_available(larbnode)) {
                        of_node_put(larbnode);
@@ -659,11 +661,14 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
                plarbdev = of_find_device_by_node(larbnode);
                if (!plarbdev) {
                        of_node_put(larbnode);
-                       return -ENODEV;
+                       ret = -ENODEV;
+                       goto out_put_larbs;
                }
                if (!plarbdev->dev.driver) {
                        of_node_put(larbnode);
-                       return -EPROBE_DEFER;
+                       put_device(&plarbdev->dev);
+                       ret = -EPROBE_DEFER;
+                       goto out_put_larbs;
                }
                data->larb_imu[i].dev = &plarbdev->dev;
 
@@ -675,7 +680,7 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
 
        ret = mtk_iommu_v1_hw_init(data);
        if (ret)
-               return ret;
+               goto out_put_larbs;
 
        ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL,
                                     dev_name(&pdev->dev));
@@ -697,12 +702,17 @@ out_sysfs_remove:
        iommu_device_sysfs_remove(&data->iommu);
 out_clk_unprepare:
        clk_disable_unprepare(data->bclk);
+out_put_larbs:
+       for (i = 0; i < MTK_LARB_NR_MAX; i++)
+               put_device(data->larb_imu[i].dev);
+
        return ret;
 }
 
 static void mtk_iommu_v1_remove(struct platform_device *pdev)
 {
        struct mtk_iommu_v1_data *data = platform_get_drvdata(pdev);
+       int i;
 
        iommu_device_sysfs_remove(&data->iommu);
        iommu_device_unregister(&data->iommu);
@@ -710,6 +720,9 @@ static void mtk_iommu_v1_remove(struct platform_device *pdev)
        clk_disable_unprepare(data->bclk);
        devm_free_irq(&pdev->dev, data->irq, data);
        component_master_del(&pdev->dev, &mtk_iommu_v1_com_ops);
+
+       for (i = 0; i < MTK_LARB_NR_MAX; i++)
+               put_device(data->larb_imu[i].dev);
 }
 
 static int __maybe_unused mtk_iommu_v1_suspend(struct device *dev)