mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 12:21:22 -05:00
iommu/mediatek-v1: fix device leaks on probe()
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: b17336c55d ("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>
This commit is contained in:
committed by
Joerg Roedel
parent
c77ad28bfe
commit
46207625c9
@@ -651,8 +651,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);
|
||||
@@ -662,11 +664,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;
|
||||
|
||||
@@ -678,7 +683,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));
|
||||
@@ -700,12 +705,17 @@ static int mtk_iommu_v1_probe(struct platform_device *pdev)
|
||||
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);
|
||||
@@ -713,6 +723,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)
|
||||
|
||||
Reference in New Issue
Block a user