In mt8195, there are some larbs connect with the smi-sub-common, then
connect with smi-common.

Before we create device link between smi-larb with smi-common. If we have
sub-common, we should use device link the smi-larb and smi-sub-common,
then use device link between the smi-sub-common with smi-common. This is
for enabling clock/power automatically.

Move the device link code to a new interface for reusing.

Signed-off-by: Yong Wu <yong...@mediatek.com>
Reviewed-by: Ikjoon Jang <i...@chromium.org>
---
 drivers/memory/mtk-smi.c | 75 +++++++++++++++++++++++++++-------------
 1 file changed, 51 insertions(+), 24 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index b362d528944e..5c2bd5795cfd 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -61,7 +61,8 @@
 
 enum mtk_smi_type {
        MTK_SMI_GEN1,
-       MTK_SMI_GEN2
+       MTK_SMI_GEN2,           /* gen2 smi common */
+       MTK_SMI_GEN2_SUB_COMM,  /* gen2 smi sub common */
 };
 
 #define MTK_SMI_CLK_NR_MAX                     4
@@ -99,13 +100,14 @@ struct mtk_smi {
                void __iomem            *smi_ao_base; /* only for gen1 */
                void __iomem            *base;        /* only for gen2 */
        };
+       struct device                   *smi_common_dev; /* for sub common */
        const struct mtk_smi_common_plat *plat;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
        struct mtk_smi                  smi;
        void __iomem                    *base;
-       struct device                   *smi_common_dev;
+       struct device                   *smi_common_dev; /* common or 
sub-common dev */
        const struct mtk_smi_larb_gen   *larb_gen;
        int                             larbid;
        u32                             *mmu;
@@ -268,6 +270,38 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
        {}
 };
 
+static int mtk_smi_device_link_common(struct device *dev, struct device 
**com_dev)
+{
+       struct platform_device *smi_com_pdev;
+       struct device_node *smi_com_node;
+       struct device *smi_com_dev;
+       struct device_link *link;
+
+       smi_com_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
+       if (!smi_com_node)
+               return -EINVAL;
+
+       smi_com_pdev = of_find_device_by_node(smi_com_node);
+       of_node_put(smi_com_node);
+       if (smi_com_pdev) {
+               /* smi common is the supplier, Make sure it is ready before */
+               if (!platform_get_drvdata(smi_com_pdev))
+                       return -EPROBE_DEFER;
+               smi_com_dev = &smi_com_pdev->dev;
+               link = device_link_add(dev, smi_com_dev,
+                                      DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+               if (!link) {
+                       dev_err(dev, "Unable to link smi-common dev\n");
+                       return -ENODEV;
+               }
+               *com_dev = smi_com_dev;
+       } else {
+               dev_err(dev, "Failed to get the smi_common device\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
 static int mtk_smi_dts_clk_init(struct device *dev, struct mtk_smi *smi,
                                const char * const clks[],
                                unsigned int clk_nr_required,
@@ -294,9 +328,6 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
        struct mtk_smi_larb *larb;
        struct resource *res;
        struct device *dev = &pdev->dev;
-       struct device_node *smi_node;
-       struct platform_device *smi_pdev;
-       struct device_link *link;
        int ret;
 
        larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
@@ -315,26 +346,10 @@ static int mtk_smi_larb_probe(struct platform_device 
*pdev)
                return ret;
 
        larb->smi.dev = dev;
-       smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
-       if (!smi_node)
-               return -EINVAL;
 
-       smi_pdev = of_find_device_by_node(smi_node);
-       of_node_put(smi_node);
-       if (smi_pdev) {
-               if (!platform_get_drvdata(smi_pdev))
-                       return -EPROBE_DEFER;
-               larb->smi_common_dev = &smi_pdev->dev;
-               link = device_link_add(dev, larb->smi_common_dev,
-                                      DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
-               if (!link) {
-                       dev_err(dev, "Unable to link smi-common dev\n");
-                       return -ENODEV;
-               }
-       } else {
-               dev_err(dev, "Failed to get the smi_common device\n");
-               return -EINVAL;
-       }
+       ret = mtk_smi_device_link_common(dev, &larb->smi_common_dev);
+       if (ret < 0)
+               return ret;
 
        pm_runtime_enable(dev);
        platform_set_drvdata(pdev, larb);
@@ -483,6 +498,14 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
                if (IS_ERR(common->base))
                        return PTR_ERR(common->base);
        }
+
+       /* link its smi-common if this is smi-sub-common */
+       if (common->plat->type == MTK_SMI_GEN2_SUB_COMM) {
+               ret = mtk_smi_device_link_common(dev, &common->smi_common_dev);
+               if (ret < 0)
+                       return ret;
+       }
+
        pm_runtime_enable(dev);
        platform_set_drvdata(pdev, common);
        return 0;
@@ -490,6 +513,10 @@ static int mtk_smi_common_probe(struct platform_device 
*pdev)
 
 static int mtk_smi_common_remove(struct platform_device *pdev)
 {
+       struct mtk_smi *common = dev_get_drvdata(&pdev->dev);
+
+       if (common->plat->type == MTK_SMI_GEN2_SUB_COMM)
+               device_link_remove(&pdev->dev, common->smi_common_dev);
        pm_runtime_disable(&pdev->dev);
        return 0;
 }
-- 
2.18.0

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to