[v7,5/6] iommu/mediatek: Improve safety for mediatek,smi property in larb nodes
Commit Message
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: Guenter Roeck <groeck@chromium.org>
Signed-off-by: Yong Wu <yong.wu@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/iommu/mtk_iommu.c | 53 +++++++++++++++++++++++++++------------
1 file changed, 37 insertions(+), 16 deletions(-)
Comments
On 18/10/2022 04:42, Yong Wu wrote:
> 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: Guenter Roeck <groeck@chromium.org>
> 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>
> ---
> drivers/iommu/mtk_iommu.c | 53 +++++++++++++++++++++++++++------------
> 1 file changed, 37 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 9cbff48f03c0..f7ac102e343f 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -1042,7 +1042,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;
> @@ -1054,6 +1054,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);
> @@ -1094,27 +1095,47 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
> goto err_larbdev_put;
> }
>
> + /* Get smi-(sub)-common dev from the last larb. */
> + smi_subcomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
> + 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
> + * has a new mediatek,smi property. otherwise it is smi-commmon.
> + */
> + smicomm_node = of_parse_phandle(smi_subcomm_node, "mediatek,smi", 0);
> + if (smicomm_node)
> + of_node_put(smi_subcomm_node);
> + else
> + smicomm_node = smi_subcomm_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);
> }
>
> - /* Get smi-(sub)-common dev from the last larb. */
> - smi_subcomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
> - if (!smi_subcomm_node)
> + if (!frst_avail_smicomm_node)
> return -EINVAL;
>
> - /*
> - * It may have two level smi-common. the node is smi-sub-common if it
> - * has a new mediatek,smi property. otherwise it is smi-commmon.
> - */
> - smicomm_node = of_parse_phandle(smi_subcomm_node, "mediatek,smi", 0);
> - if (smicomm_node)
> - of_node_put(smi_subcomm_node);
> - else
> - smicomm_node = smi_subcomm_node;
> -
> - pcommdev = of_find_device_by_node(smicomm_node);
> - of_node_put(smicomm_node);
> + 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;
@@ -1042,7 +1042,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;
@@ -1054,6 +1054,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);
@@ -1094,27 +1095,47 @@ static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **m
goto err_larbdev_put;
}
+ /* Get smi-(sub)-common dev from the last larb. */
+ smi_subcomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
+ 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
+ * has a new mediatek,smi property. otherwise it is smi-commmon.
+ */
+ smicomm_node = of_parse_phandle(smi_subcomm_node, "mediatek,smi", 0);
+ if (smicomm_node)
+ of_node_put(smi_subcomm_node);
+ else
+ smicomm_node = smi_subcomm_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);
}
- /* Get smi-(sub)-common dev from the last larb. */
- smi_subcomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
- if (!smi_subcomm_node)
+ if (!frst_avail_smicomm_node)
return -EINVAL;
- /*
- * It may have two level smi-common. the node is smi-sub-common if it
- * has a new mediatek,smi property. otherwise it is smi-commmon.
- */
- smicomm_node = of_parse_phandle(smi_subcomm_node, "mediatek,smi", 0);
- if (smicomm_node)
- of_node_put(smi_subcomm_node);
- else
- smicomm_node = smi_subcomm_node;
-
- pcommdev = of_find_device_by_node(smicomm_node);
- of_node_put(smicomm_node);
+ 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;