iommu/mediatek: Add error path for loop of mm_dts_parse

The mtk_iommu_mm_dts_parse will parse the smi larbs nodes. if the i+1
larb is parsed fail, we should put_device for the i..0 larbs.

There are two places need to comment:
1) The larbid may be not linear mapping, we should loop whole
   the array in the error path.
2) I move this line position: "data->larb_imu[id].dev = &plarbdev->dev;"
   before "if (!plarbdev->dev.driver)", That means set
   data->larb_imu[id].dev before the error path. then we don't need
   "platform_device_put(plarbdev)" again in probe_defer case. All depend
   on "put_device" of the error path in error cases.

Fixes: d2e9a1102c ("iommu/mediatek: Contain MM IOMMU flow with the MM TYPE")
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Link: https://lore.kernel.org/r/20221018024258.19073-4-yong.wu@mediatek.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
Yong Wu 2022-10-18 10:42:55 +08:00 committed by Joerg Roedel
parent b5765a1b44
commit 2659392856

View File

@ -1067,8 +1067,10 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
u32 id; u32 id;
larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
if (!larbnode) if (!larbnode) {
return -EINVAL; ret = -EINVAL;
goto err_larbdev_put;
}
if (!of_device_is_available(larbnode)) { if (!of_device_is_available(larbnode)) {
of_node_put(larbnode); of_node_put(larbnode);
@ -1081,15 +1083,17 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
plarbdev = of_find_device_by_node(larbnode); plarbdev = of_find_device_by_node(larbnode);
of_node_put(larbnode); of_node_put(larbnode);
if (!plarbdev) if (!plarbdev) {
return -ENODEV; ret = -ENODEV;
goto err_larbdev_put;
if (!plarbdev->dev.driver) {
platform_device_put(plarbdev);
return -EPROBE_DEFER;
} }
data->larb_imu[id].dev = &plarbdev->dev; data->larb_imu[id].dev = &plarbdev->dev;
if (!plarbdev->dev.driver) {
ret = -EPROBE_DEFER;
goto err_larbdev_put;
}
component_match_add(dev, match, component_compare_dev, &plarbdev->dev); component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
platform_device_put(plarbdev); platform_device_put(plarbdev);
} }
@ -1123,6 +1127,15 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
err_larbdev_put:
/* id may be not linear mapping, loop whole the array */
for (i = MTK_LARB_NR_MAX - 1; i >= 0; i++) {
if (!data->larb_imu[i].dev)
continue;
put_device(data->larb_imu[i].dev);
}
return ret;
} }
static int mtk_iommu_probe(struct platform_device *pdev) static int mtk_iommu_probe(struct platform_device *pdev)