remoteproc: mediatek: Probe SCP cluster on single-core SCP
authorTinghan Shen <tinghan.shen@mediatek.com>
Fri, 1 Sep 2023 08:09:28 +0000 (16:09 +0800)
committerMathieu Poirier <mathieu.poirier@linaro.org>
Wed, 13 Sep 2023 17:45:40 +0000 (11:45 -0600)
This is the 3rd preliminary step for probing multi-core SCP.
Rewrite the probing flow of single-core SCP to adapt with the 'cluster'
concept needed by the multi-core SCP. The SCP core object(s)
is maintained at the cluster list.

Signed-off-by: Tinghan Shen <tinghan.shen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20230901080935.14571-8-tinghan.shen@mediatek.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
drivers/remoteproc/mtk_common.h
drivers/remoteproc/mtk_scp.c

index b04d71277c1f38f7015bc4c0ce6c8911e4366aaf..1438159ae736b1c13d3b391ef023ed14afff3a01 100644 (file)
@@ -105,6 +105,7 @@ struct mtk_scp_of_cluster {
        void __iomem *l1tcm_base;
        size_t l1tcm_size;
        phys_addr_t l1tcm_phys;
+       struct list_head mtk_scp_list;
 };
 
 struct mtk_scp {
@@ -132,6 +133,7 @@ struct mtk_scp {
 
        struct rproc_subdev *rpmsg_subdev;
 
+       struct list_head elem;
        struct mtk_scp_of_cluster *cluster;
 };
 
index 7a2ba1e1e95a62ebc757575adb582bf9f7f4f537..d67dcabdab9e4e1e1460c6c6ce796914f70413f1 100644 (file)
@@ -854,8 +854,8 @@ static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
        }
 }
 
-static int scp_rproc_init(struct platform_device *pdev,
-                         struct mtk_scp_of_cluster *scp_cluster)
+static struct mtk_scp *scp_rproc_init(struct platform_device *pdev,
+                                     struct mtk_scp_of_cluster *scp_cluster)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
@@ -867,11 +867,13 @@ static int scp_rproc_init(struct platform_device *pdev,
 
        ret = rproc_of_parse_firmware(dev, 0, &fw_name);
        if (ret < 0 && ret != -EINVAL)
-               return ret;
+               return ERR_PTR(ret);
 
        rproc = devm_rproc_alloc(dev, np->name, &scp_ops, fw_name, sizeof(*scp));
-       if (!rproc)
-               return dev_err_probe(dev, -ENOMEM, "unable to allocate remoteproc\n");
+       if (!rproc) {
+               dev_err(dev, "unable to allocate remoteproc\n");
+               return ERR_PTR(-ENOMEM);
+       }
 
        scp = rproc->priv;
        scp->rproc = rproc;
@@ -882,20 +884,21 @@ static int scp_rproc_init(struct platform_device *pdev,
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
        scp->sram_base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(scp->sram_base))
-               return dev_err_probe(dev, PTR_ERR(scp->sram_base),
-                                    "Failed to parse and map sram memory\n");
+       if (IS_ERR(scp->sram_base)) {
+               dev_err(dev, "Failed to parse and map sram memory\n");
+               return ERR_CAST(scp->sram_base);
+       }
 
        scp->sram_size = resource_size(res);
        scp->sram_phys = res->start;
 
        ret = scp->data->scp_clk_get(scp);
        if (ret)
-               return ret;
+               return ERR_PTR(ret);
 
        ret = scp_map_memory_region(scp);
        if (ret)
-               return ret;
+               return ERR_PTR(ret);
 
        mutex_init(&scp->send_lock);
        for (i = 0; i < SCP_IPI_MAX; i++)
@@ -922,11 +925,7 @@ static int scp_rproc_init(struct platform_device *pdev,
                goto remove_subdev;
        }
 
-       ret = rproc_add(rproc);
-       if (ret)
-               goto remove_subdev;
-
-       return 0;
+       return scp;
 
 remove_subdev:
        scp_remove_rpmsg_subdev(scp);
@@ -937,7 +936,43 @@ release_dev_mem:
                mutex_destroy(&scp->ipi_desc[i].lock);
        mutex_destroy(&scp->send_lock);
 
-       return ret;
+       return ERR_PTR(ret);
+}
+
+static void scp_free(struct mtk_scp *scp)
+{
+       int i;
+
+       scp_remove_rpmsg_subdev(scp);
+       scp_ipi_unregister(scp, SCP_IPI_INIT);
+       scp_unmap_memory_region(scp);
+       for (i = 0; i < SCP_IPI_MAX; i++)
+               mutex_destroy(&scp->ipi_desc[i].lock);
+       mutex_destroy(&scp->send_lock);
+}
+
+static int scp_cluster_init(struct platform_device *pdev,
+                           struct mtk_scp_of_cluster *scp_cluster)
+{
+       struct device *dev = &pdev->dev;
+       struct list_head *scp_list = &scp_cluster->mtk_scp_list;
+       struct mtk_scp *scp;
+       int ret;
+
+       scp = scp_rproc_init(pdev, scp_cluster);
+       if (IS_ERR(scp))
+               return PTR_ERR(scp);
+
+       ret = rproc_add(scp->rproc);
+       if (ret) {
+               dev_err(dev, "Failed to add rproc\n");
+               scp_free(scp);
+               return ret;
+       }
+
+       list_add_tail(&scp->elem, scp_list);
+
+       return 0;
 }
 
 static int scp_probe(struct platform_device *pdev)
@@ -970,7 +1005,9 @@ static int scp_probe(struct platform_device *pdev)
                scp_cluster->l1tcm_phys = res->start;
        }
 
-       ret = scp_rproc_init(pdev, scp_cluster);
+       INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
+
+       ret = scp_cluster_init(pdev, scp_cluster);
        if (ret)
                return ret;
 
@@ -980,15 +1017,14 @@ static int scp_probe(struct platform_device *pdev)
 static void scp_remove(struct platform_device *pdev)
 {
        struct mtk_scp *scp = platform_get_drvdata(pdev);
-       int i;
+       struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
+       struct mtk_scp *temp;
 
-       rproc_del(scp->rproc);
-       scp_remove_rpmsg_subdev(scp);
-       scp_ipi_unregister(scp, SCP_IPI_INIT);
-       scp_unmap_memory_region(scp);
-       for (i = 0; i < SCP_IPI_MAX; i++)
-               mutex_destroy(&scp->ipi_desc[i].lock);
-       mutex_destroy(&scp->send_lock);
+       list_for_each_entry_safe_reverse(scp, temp, &scp_cluster->mtk_scp_list, elem) {
+               list_del(&scp->elem);
+               rproc_del(scp->rproc);
+               scp_free(scp);
+       }
 }
 
 static const struct mtk_scp_of_data mt8183_of_data = {