mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
iommu/mediatek-v1: fix device leaks on probe()
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: 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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
e7bcedf59b
commit
83f3010de7
@@ -654,8 +654,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);
|
||||
@@ -665,11 +667,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;
|
||||
|
||||
@@ -681,7 +686,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));
|
||||
@@ -703,12 +708,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);
|
||||
@@ -716,6 +726,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