Commit 6cde583d authored by Yong Wu's avatar Yong Wu Committed by Joerg Roedel
Browse files

iommu/mediatek: Improve safety for mediatek,smi property in larb nodes



No functional change. Just improve safety from dts.

All the larbs that connect to one IOMMU must connect with the same
smi-common. This patch checks all the mediatek,smi property for each
larb, If their mediatek,smi are different, it will return fails.
Also avoid there is no available smi-larb nodes.

Suggested-by: default avatarGuenter Roeck <groeck@chromium.org>
Signed-off-by: default avatarYong Wu <yong.wu@mediatek.com>
Reviewed-by: default avatarAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: default avatarMatthias Brugger <matthias.bgg@gmail.com>
Link: https://lore.kernel.org/r/20221018024258.19073-6-yong.wu@mediatek.com


Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent ef693a84
Loading
Loading
Loading
Loading
+37 −16
Original line number Diff line number Diff line
@@ -1054,7 +1054,7 @@ static const struct component_master_ops mtk_iommu_com_ops = {
static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **match,
				  struct mtk_iommu_data *data)
{
	struct device_node *larbnode, *smicomm_node, *smi_subcomm_node;
	struct device_node *larbnode, *frst_avail_smicomm_node = NULL;
	struct platform_device *plarbdev, *pcommdev;
	struct device_link *link;
	int i, larb_nr, ret;
@@ -1066,6 +1066,7 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
		return -EINVAL;

	for (i = 0; i < larb_nr; i++) {
		struct device_node *smicomm_node, *smi_subcomm_node;
		u32 id;

		larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
@@ -1106,14 +1107,12 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
			goto err_larbdev_put;
		}

		component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
		platform_device_put(plarbdev);
	}

		/* Get smi-(sub)-common dev from the last larb. */
		smi_subcomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
	if (!smi_subcomm_node)
		return -EINVAL;
		if (!smi_subcomm_node) {
			ret = -EINVAL;
			goto err_larbdev_put;
		}

		/*
		 * It may have two level smi-common. the node is smi-sub-common if it
@@ -1125,8 +1124,30 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
		else
			smicomm_node = smi_subcomm_node;

	pcommdev = of_find_device_by_node(smicomm_node);
		/*
		 * All the larbs that connect to one IOMMU must connect with the same
		 * smi-common.
		 */
		if (!frst_avail_smicomm_node) {
			frst_avail_smicomm_node = smicomm_node;
		} else if (frst_avail_smicomm_node != smicomm_node) {
			dev_err(dev, "mediatek,smi property is not right @larb%d.", id);
			of_node_put(smicomm_node);
			ret = -EINVAL;
			goto err_larbdev_put;
		} else {
			of_node_put(smicomm_node);
		}

		component_match_add(dev, match, component_compare_dev, &plarbdev->dev);
		platform_device_put(plarbdev);
	}

	if (!frst_avail_smicomm_node)
		return -EINVAL;

	pcommdev = of_find_device_by_node(frst_avail_smicomm_node);
	of_node_put(frst_avail_smicomm_node);
	if (!pcommdev)
		return -ENODEV;
	data->smicomm_dev = &pcommdev->dev;