From b327c72753d6a78de37aed6c35756f2ef62897ee Mon Sep 17 00:00:00 2001 From: Joakim Zhang Date: Sun, 17 Dec 2023 13:36:59 +0800 Subject: [PATCH 01/30] remoteproc: virtio: Fix wdg cannot recovery remote processor Recovery remote processor failed when wdg irq received: [ 0.842574] remoteproc remoteproc0: crash detected in cix-dsp-rproc: type watchdog [ 0.842750] remoteproc remoteproc0: handling crash #1 in cix-dsp-rproc [ 0.842824] remoteproc remoteproc0: recovering cix-dsp-rproc [ 0.843342] remoteproc remoteproc0: stopped remote processor cix-dsp-rproc [ 0.847901] rproc-virtio rproc-virtio.0.auto: Failed to associate buffer [ 0.847979] remoteproc remoteproc0: failed to probe subdevices for cix-dsp-rproc: -16 The reason is that dma coherent mem would not be released when recovering the remote processor, due to rproc_virtio_remove() would not be called, where the mem released. It will fail when it try to allocate and associate buffer again. Releasing reserved memory from rproc_virtio_dev_release(), instead of rproc_virtio_remove(). Fixes: 1d7b61c06dc3 ("remoteproc: virtio: Create platform device for the remoteproc_virtio") Signed-off-by: Joakim Zhang Acked-by: Arnaud Pouliquen Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20231217053659.3245745-1-joakim.zhang@cixtech.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/remoteproc_virtio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index 83d76915a6ad..25b66b113b69 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -351,6 +351,9 @@ static void rproc_virtio_dev_release(struct device *dev) kfree(vdev); + of_reserved_mem_device_release(&rvdev->pdev->dev); + dma_release_coherent_memory(&rvdev->pdev->dev); + put_device(&rvdev->pdev->dev); } @@ -584,9 +587,6 @@ static void rproc_virtio_remove(struct platform_device *pdev) rproc_remove_subdev(rproc, &rvdev->subdev); rproc_remove_rvdev(rvdev); - of_reserved_mem_device_release(&pdev->dev); - dma_release_coherent_memory(&pdev->dev); - put_device(&rproc->dev); } From 32381bbccba4c21145c571701f8f7fb1d9b3a92e Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Wed, 17 Jan 2024 14:53:11 +0100 Subject: [PATCH 02/30] remoteproc: stm32: Fix incorrect type in assignment for va The sparse tool complains about the attribute conversion between a _iomem void * and a void *: stm32_rproc.c:122:12: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected void *va @@ got void [noderef] __iomem * @@ stm32_rproc.c:122:12: sparse: expected void *va stm32_rproc.c:122:12: sparse: got void [noderef] __iomem * Add '__force' to explicitly specify that the cast is intentional. This conversion is necessary to cast to virtual addresses pointer,used, by the remoteproc core. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202312150052.HCiNKlqB-lkp@intel.com/ Fixes: 13140de09cc2 ("remoteproc: stm32: add an ST stm32_rproc driver") Signed-off-by: Arnaud Pouliquen Link: https://lore.kernel.org/r/20240117135312.3381936-2-arnaud.pouliquen@foss.st.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/stm32_rproc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index 4f469f0bcf8b..2c28635219eb 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -120,7 +120,7 @@ static int stm32_rproc_mem_alloc(struct rproc *rproc, void *va; dev_dbg(dev, "map memory: %pad+%zx\n", &mem->dma, mem->len); - va = ioremap_wc(mem->dma, mem->len); + va = (__force void *)ioremap_wc(mem->dma, mem->len); if (IS_ERR_OR_NULL(va)) { dev_err(dev, "Unable to map memory region: %pad+0x%zx\n", &mem->dma, mem->len); @@ -137,7 +137,7 @@ static int stm32_rproc_mem_release(struct rproc *rproc, struct rproc_mem_entry *mem) { dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma); - iounmap(mem->va); + iounmap((__force __iomem void *)mem->va); return 0; } From c77b35ce66af25bdd6fde60b62e35b9b316ea5c2 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Wed, 17 Jan 2024 14:53:12 +0100 Subject: [PATCH 03/30] remoteproc: stm32: Fix incorrect type assignment returned by stm32_rproc_get_loaded_rsc_tablef The sparse tool complains about the remove of the _iomem attribute. stm32_rproc.c:660:17: warning: cast removes address space '__iomem' of expression Add '__force' to explicitly specify that the cast is intentional. This conversion is necessary to cast to addresses pointer, which are then managed by the remoteproc core as a pointer to a resource_table structure. Fixes: 8a471396d21c ("remoteproc: stm32: Move resource table setup to rproc_ops") Signed-off-by: Arnaud Pouliquen Link: https://lore.kernel.org/r/20240117135312.3381936-3-arnaud.pouliquen@foss.st.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/stm32_rproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index 2c28635219eb..10b442c6f632 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -657,7 +657,7 @@ done: * entire area by overwriting it with the initial values stored in rproc->clean_table. */ *table_sz = RSC_TBL_SIZE; - return (struct resource_table *)ddata->rsc_va; + return (__force struct resource_table *)ddata->rsc_va; } static const struct rproc_ops st_rproc_ops = { From 64e17ec2504a542acd239f91589927ed266bca13 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:49:06 -0600 Subject: [PATCH 04/30] remoteproc: k3-dsp: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184913.725435-1-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index ab882e3b7130..93fbc89307d6 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -690,8 +690,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "failed to parse firmware-name property\n"); - rproc = rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops, fw_name, - sizeof(*kproc)); + rproc = devm_rproc_alloc(dev, dev_name(dev), &k3_dsp_rproc_ops, + fw_name, sizeof(*kproc)); if (!rproc) return -ENOMEM; @@ -707,12 +707,9 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) kproc->data = data; kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci"); - if (IS_ERR(kproc->ti_sci)) { - ret = dev_err_probe(dev, PTR_ERR(kproc->ti_sci), - "failed to get ti-sci handle\n"); - kproc->ti_sci = NULL; - goto free_rproc; - } + if (IS_ERR(kproc->ti_sci)) + return dev_err_probe(dev, PTR_ERR(kproc->ti_sci), + "failed to get ti-sci handle\n"); ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id); if (ret) { @@ -810,8 +807,6 @@ put_sci: ret1 = ti_sci_put_handle(kproc->ti_sci); if (ret1) dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret1)); -free_rproc: - rproc_free(rproc); return ret; } @@ -844,7 +839,6 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev) dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret)); k3_dsp_reserved_mem_exit(kproc); - rproc_free(kproc->rproc); } static const struct k3_dsp_mem_data c66_mems[] = { From 961a919a6dbd24b670766ae0613085d63e9c79e3 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:49:07 -0600 Subject: [PATCH 05/30] remoteproc: k3-dsp: Add devm action to release reserved memory Use a device lifecycle managed action to release reserved memory. This helps prevent mistakes like releasing out of order in cleanup functions and forgetting to release on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184913.725435-2-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index 93fbc89307d6..0cb00146fe97 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -550,6 +550,13 @@ static int k3_dsp_rproc_of_get_memories(struct platform_device *pdev, return 0; } +static void k3_dsp_mem_release(void *data) +{ + struct device *dev = data; + + of_reserved_mem_device_release(dev); +} + static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) { struct device *dev = kproc->dev; @@ -579,13 +586,14 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) ERR_PTR(ret)); return ret; } + ret = devm_add_action_or_reset(dev, k3_dsp_mem_release, dev); + if (ret) + return ret; num_rmems--; kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL); - if (!kproc->rmem) { - ret = -ENOMEM; - goto release_rmem; - } + if (!kproc->rmem) + return -ENOMEM; /* use remaining reserved memory regions for static carveouts */ for (i = 0; i < num_rmems; i++) { @@ -628,8 +636,6 @@ unmap_rmem: for (i--; i >= 0; i--) iounmap(kproc->rmem[i].cpu_addr); kfree(kproc->rmem); -release_rmem: - of_reserved_mem_device_release(kproc->dev); return ret; } @@ -640,8 +646,6 @@ static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc) for (i = 0; i < kproc->num_rmems; i++) iounmap(kproc->rmem[i].cpu_addr); kfree(kproc->rmem); - - of_reserved_mem_device_release(kproc->dev); } static From 92a0915ac3eb571fc014c249c66db802be7fdac9 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:49:08 -0600 Subject: [PATCH 06/30] remoteproc: k3-dsp: Use devm_kcalloc() helper Use a device lifecycle managed action to free memory. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184913.725435-3-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index 0cb00146fe97..a13552c71f44 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -591,7 +591,7 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) return ret; num_rmems--; - kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL); + kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL); if (!kproc->rmem) return -ENOMEM; @@ -635,7 +635,6 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) unmap_rmem: for (i--; i >= 0; i--) iounmap(kproc->rmem[i].cpu_addr); - kfree(kproc->rmem); return ret; } @@ -645,7 +644,6 @@ static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc) for (i = 0; i < kproc->num_rmems; i++) iounmap(kproc->rmem[i].cpu_addr); - kfree(kproc->rmem); } static From 8f12de7913af990230d0a97f996a4e51f05fea9b Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:24 -0600 Subject: [PATCH 07/30] remoteproc: imx_dsp_rproc: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-1-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/imx_dsp_rproc.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c index a1c62d15f16c..56a799cb8b36 100644 --- a/drivers/remoteproc/imx_dsp_rproc.c +++ b/drivers/remoteproc/imx_dsp_rproc.c @@ -1104,8 +1104,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev) return ret; } - rproc = rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, fw_name, - sizeof(*priv)); + rproc = devm_rproc_alloc(dev, "imx-dsp-rproc", &imx_dsp_rproc_ops, + fw_name, sizeof(*priv)); if (!rproc) return -ENOMEM; @@ -1125,14 +1125,14 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev) ret = imx_dsp_rproc_detect_mode(priv); if (ret) { dev_err(dev, "failed on imx_dsp_rproc_detect_mode\n"); - goto err_put_rproc; + return ret; } /* There are multiple power domains required by DSP on some platform */ ret = imx_dsp_attach_pm_domains(priv); if (ret) { dev_err(dev, "failed on imx_dsp_attach_pm_domains\n"); - goto err_put_rproc; + return ret; } /* Get clocks */ ret = imx_dsp_rproc_clk_get(priv); @@ -1155,8 +1155,6 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev) err_detach_domains: imx_dsp_detach_pm_domains(priv); -err_put_rproc: - rproc_free(rproc); return ret; } @@ -1169,7 +1167,6 @@ static void imx_dsp_rproc_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); rproc_del(rproc); imx_dsp_detach_pm_domains(priv); - rproc_free(rproc); } /* pm runtime functions */ From f1e05cc10a3e129c669c169b88fb935e7d3c64ec Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:25 -0600 Subject: [PATCH 08/30] remoteproc: imx_rproc: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-2-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/imx_rproc.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 8bb293b9f327..55ecce3ab5f7 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -1104,16 +1104,14 @@ static int imx_rproc_probe(struct platform_device *pdev) int ret; /* set some other name then imx */ - rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, - NULL, sizeof(*priv)); + rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, + NULL, sizeof(*priv)); if (!rproc) return -ENOMEM; dcfg = of_device_get_match_data(dev); - if (!dcfg) { - ret = -EINVAL; - goto err_put_rproc; - } + if (!dcfg) + return -EINVAL; priv = rproc->priv; priv->rproc = rproc; @@ -1124,8 +1122,7 @@ static int imx_rproc_probe(struct platform_device *pdev) priv->workqueue = create_workqueue(dev_name(dev)); if (!priv->workqueue) { dev_err(dev, "cannot create workqueue\n"); - ret = -ENOMEM; - goto err_put_rproc; + return -ENOMEM; } ret = imx_rproc_xtr_mbox_init(rproc); @@ -1167,8 +1164,6 @@ err_put_mbox: imx_rproc_free_mbox(rproc); err_put_wkq: destroy_workqueue(priv->workqueue); -err_put_rproc: - rproc_free(rproc); return ret; } @@ -1183,7 +1178,6 @@ static void imx_rproc_remove(struct platform_device *pdev) imx_rproc_put_scu(rproc); imx_rproc_free_mbox(rproc); destroy_workqueue(priv->workqueue); - rproc_free(rproc); } static const struct of_device_id imx_rproc_of_match[] = { From 173d2c6326e39a9d87cadab179e2177a1d76294e Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:31 -0600 Subject: [PATCH 09/30] remoteproc: st: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-8-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/st_remoteproc.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c index cb163766c56d..1340be9d0110 100644 --- a/drivers/remoteproc/st_remoteproc.c +++ b/drivers/remoteproc/st_remoteproc.c @@ -347,23 +347,21 @@ static int st_rproc_probe(struct platform_device *pdev) int enabled; int ret, i; - rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata)); + rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata)); if (!rproc) return -ENOMEM; rproc->has_iommu = false; ddata = rproc->priv; ddata->config = (struct st_rproc_config *)device_get_match_data(dev); - if (!ddata->config) { - ret = -ENODEV; - goto free_rproc; - } + if (!ddata->config) + return -ENODEV; platform_set_drvdata(pdev, rproc); ret = st_rproc_parse_dt(pdev); if (ret) - goto free_rproc; + return ret; enabled = st_rproc_state(pdev); if (enabled < 0) { @@ -439,8 +437,7 @@ free_mbox: mbox_free_channel(ddata->mbox_chan[i]); free_clk: clk_unprepare(ddata->clk); -free_rproc: - rproc_free(rproc); + return ret; } @@ -456,8 +453,6 @@ static void st_rproc_remove(struct platform_device *pdev) for (i = 0; i < ST_RPROC_MAX_VRING * MBOX_MAX; i++) mbox_free_channel(ddata->mbox_chan[i]); - - rproc_free(rproc); } static struct platform_driver st_rproc_driver = { From e160d811c5603f6205fd260cb6f5a4a22e84b80f Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:32 -0600 Subject: [PATCH 10/30] remoteproc: stm32: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-9-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/stm32_rproc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index 10b442c6f632..88623df7d0c3 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -843,7 +843,7 @@ static int stm32_rproc_probe(struct platform_device *pdev) if (ret) return ret; - rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata)); + rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata)); if (!rproc) return -ENOMEM; @@ -897,7 +897,6 @@ free_rproc: dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); } - rproc_free(rproc); return ret; } @@ -918,7 +917,6 @@ static void stm32_rproc_remove(struct platform_device *pdev) dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); } - rproc_free(rproc); } static int stm32_rproc_suspend(struct device *dev) From 48f9a0858bfc502767206cca1d465b173cc0d650 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 5 Feb 2024 12:27:49 -0600 Subject: [PATCH 11/30] remoteproc: k3-dsp: Use devm_ti_sci_get_by_phandle() helper Use the device lifecycle managed TI-SCI get() function. This helps prevent mistakes like not put()'ing in the wrong order in cleanup functions and forgetting to put() on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240205182753.36978-2-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 32 +++++++---------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index a13552c71f44..64ec5759c4ec 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -708,30 +708,24 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) kproc->dev = dev; kproc->data = data; - kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci"); + kproc->ti_sci = devm_ti_sci_get_by_phandle(dev, "ti,sci"); if (IS_ERR(kproc->ti_sci)) return dev_err_probe(dev, PTR_ERR(kproc->ti_sci), "failed to get ti-sci handle\n"); ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id); - if (ret) { - dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n"); - goto put_sci; - } + if (ret) + return dev_err_probe(dev, ret, "missing 'ti,sci-dev-id' property\n"); kproc->reset = devm_reset_control_get_exclusive(dev, NULL); - if (IS_ERR(kproc->reset)) { - ret = dev_err_probe(dev, PTR_ERR(kproc->reset), - "failed to get reset\n"); - goto put_sci; - } + if (IS_ERR(kproc->reset)) + return dev_err_probe(dev, PTR_ERR(kproc->reset), + "failed to get reset\n"); kproc->tsp = k3_dsp_rproc_of_get_tsp(dev, kproc->ti_sci); - if (IS_ERR(kproc->tsp)) { - ret = dev_err_probe(dev, PTR_ERR(kproc->tsp), - "failed to construct ti-sci proc control\n"); - goto put_sci; - } + if (IS_ERR(kproc->tsp)) + return dev_err_probe(dev, PTR_ERR(kproc->tsp), + "failed to construct ti-sci proc control\n"); ret = ti_sci_proc_request(kproc->tsp); if (ret < 0) { @@ -805,10 +799,6 @@ release_tsp: dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1)); free_tsp: kfree(kproc->tsp); -put_sci: - ret1 = ti_sci_put_handle(kproc->ti_sci); - if (ret1) - dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret1)); return ret; } @@ -836,10 +826,6 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev) kfree(kproc->tsp); - ret = ti_sci_put_handle(kproc->ti_sci); - if (ret) - dev_err(dev, "failed to put ti_sci handle (%pe)\n", ERR_PTR(ret)); - k3_dsp_reserved_mem_exit(kproc); } From 585fc027a7f4fc38b6862eeb614c7446f2d5db4a Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 5 Feb 2024 12:27:50 -0600 Subject: [PATCH 12/30] remoteproc: k3-dsp: Use devm_kzalloc() helper Use device lifecycle managed devm_kzalloc() helper function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on all error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240205182753.36978-3-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index 64ec5759c4ec..b9332c66a52a 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -659,7 +659,7 @@ struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev, if (ret < 0) return ERR_PTR(ret); - tsp = kzalloc(sizeof(*tsp), GFP_KERNEL); + tsp = devm_kzalloc(dev, sizeof(*tsp), GFP_KERNEL); if (!tsp) return ERR_PTR(-ENOMEM); @@ -730,7 +730,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) ret = ti_sci_proc_request(kproc->tsp); if (ret < 0) { dev_err_probe(dev, ret, "ti_sci_proc_request failed\n"); - goto free_tsp; + return ret; } ret = k3_dsp_rproc_of_get_memories(pdev, kproc); @@ -797,8 +797,6 @@ release_tsp: ret1 = ti_sci_proc_release(kproc->tsp); if (ret1) dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1)); -free_tsp: - kfree(kproc->tsp); return ret; } @@ -824,8 +822,6 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev) if (ret) dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret)); - kfree(kproc->tsp); - k3_dsp_reserved_mem_exit(kproc); } From 57ec3c126889604f1323acfadf768c113d9858d8 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 5 Feb 2024 12:27:51 -0600 Subject: [PATCH 13/30] remoteproc: k3-dsp: Add devm action to release tsp Use a device lifecycle managed action to release tps ti_sci_proc handle. This helps prevent mistakes like releasing out of order in cleanup functions and forgetting to release on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240205182753.36978-4-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 27 +++++++++++------------ 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index b9332c66a52a..800c8c676708 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -646,6 +646,13 @@ static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc) iounmap(kproc->rmem[i].cpu_addr); } +static void k3_dsp_release_tsp(void *data) +{ + struct ti_sci_proc *tsp = data; + + ti_sci_proc_release(tsp); +} + static struct ti_sci_proc *k3_dsp_rproc_of_get_tsp(struct device *dev, const struct ti_sci_handle *sci) @@ -682,7 +689,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) const char *fw_name; bool p_state = false; int ret = 0; - int ret1; data = of_device_get_match_data(dev); if (!data) @@ -732,16 +738,17 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) dev_err_probe(dev, ret, "ti_sci_proc_request failed\n"); return ret; } + ret = devm_add_action_or_reset(dev, k3_dsp_release_tsp, kproc->tsp); + if (ret) + return ret; ret = k3_dsp_rproc_of_get_memories(pdev, kproc); if (ret) - goto release_tsp; + return ret; ret = k3_dsp_reserved_mem_init(kproc); - if (ret) { - dev_err_probe(dev, ret, "reserved memory init failed\n"); - goto release_tsp; - } + if (ret) + return dev_err_probe(dev, ret, "reserved memory init failed\n"); ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id, NULL, &p_state); @@ -793,10 +800,6 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) release_mem: k3_dsp_reserved_mem_exit(kproc); -release_tsp: - ret1 = ti_sci_proc_release(kproc->tsp); - if (ret1) - dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret1)); return ret; } @@ -818,10 +821,6 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev) rproc_del(kproc->rproc); - ret = ti_sci_proc_release(kproc->tsp); - if (ret) - dev_err(dev, "failed to release proc (%pe)\n", ERR_PTR(ret)); - k3_dsp_reserved_mem_exit(kproc); } From 8a5d6899e9a5377e8f3e95bf0a64a6d331876b6c Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 5 Feb 2024 12:27:52 -0600 Subject: [PATCH 14/30] remoteproc: k3-dsp: Use devm_ioremap_wc() helper Use a device lifecycle managed ioremap helper function. This helps prevent mistakes like unmapping out of order in cleanup functions and forgetting to unmap on all error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240205182753.36978-5-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 48 +++++------------------ 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index 800c8c676708..f799f74734b4 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -598,16 +598,13 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) /* use remaining reserved memory regions for static carveouts */ for (i = 0; i < num_rmems; i++) { rmem_np = of_parse_phandle(np, "memory-region", i + 1); - if (!rmem_np) { - ret = -EINVAL; - goto unmap_rmem; - } + if (!rmem_np) + return -EINVAL; rmem = of_reserved_mem_lookup(rmem_np); if (!rmem) { of_node_put(rmem_np); - ret = -EINVAL; - goto unmap_rmem; + return -EINVAL; } of_node_put(rmem_np); @@ -615,12 +612,11 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) /* 64-bit address regions currently not supported */ kproc->rmem[i].dev_addr = (u32)rmem->base; kproc->rmem[i].size = rmem->size; - kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size); + kproc->rmem[i].cpu_addr = devm_ioremap_wc(dev, rmem->base, rmem->size); if (!kproc->rmem[i].cpu_addr) { dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n", i + 1, &rmem->base, &rmem->size); - ret = -ENOMEM; - goto unmap_rmem; + return -ENOMEM; } dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n", @@ -631,19 +627,6 @@ static int k3_dsp_reserved_mem_init(struct k3_dsp_rproc *kproc) kproc->num_rmems = num_rmems; return 0; - -unmap_rmem: - for (i--; i >= 0; i--) - iounmap(kproc->rmem[i].cpu_addr); - return ret; -} - -static void k3_dsp_reserved_mem_exit(struct k3_dsp_rproc *kproc) -{ - int i; - - for (i = 0; i < kproc->num_rmems; i++) - iounmap(kproc->rmem[i].cpu_addr); } static void k3_dsp_release_tsp(void *data) @@ -752,10 +735,8 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id, NULL, &p_state); - if (ret) { - dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n"); - goto release_mem; - } + if (ret) + return dev_err_probe(dev, ret, "failed to get initial state, mode cannot be determined\n"); /* configure J721E devices for either remoteproc or IPC-only mode */ if (p_state) { @@ -779,8 +760,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) if (data->uses_lreset) { ret = reset_control_status(kproc->reset); if (ret < 0) { - dev_err_probe(dev, ret, "failed to get reset status\n"); - goto release_mem; + return dev_err_probe(dev, ret, "failed to get reset status\n"); } else if (ret == 0) { dev_warn(dev, "local reset is deasserted for device\n"); k3_dsp_rproc_reset(kproc); @@ -789,18 +769,12 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) } ret = rproc_add(rproc); - if (ret) { - dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n"); - goto release_mem; - } + if (ret) + return dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n"); platform_set_drvdata(pdev, kproc); return 0; - -release_mem: - k3_dsp_reserved_mem_exit(kproc); - return ret; } static void k3_dsp_rproc_remove(struct platform_device *pdev) @@ -820,8 +794,6 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev) } rproc_del(kproc->rproc); - - k3_dsp_reserved_mem_exit(kproc); } static const struct k3_dsp_mem_data c66_mems[] = { From 456a75ab51967c4c594519795a9f49c40662c291 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 5 Feb 2024 12:27:53 -0600 Subject: [PATCH 15/30] remoteproc: k3-dsp: Use devm_rproc_add() helper Use device lifecycle managed devm_rproc_add() helper function. This helps prevent mistakes like deleting out of order in cleanup functions and forgetting to delete on all error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240205182753.36978-6-afd@ti.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/ti_k3_dsp_remoteproc.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/remoteproc/ti_k3_dsp_remoteproc.c b/drivers/remoteproc/ti_k3_dsp_remoteproc.c index f799f74734b4..3555b535b168 100644 --- a/drivers/remoteproc/ti_k3_dsp_remoteproc.c +++ b/drivers/remoteproc/ti_k3_dsp_remoteproc.c @@ -768,7 +768,7 @@ static int k3_dsp_rproc_probe(struct platform_device *pdev) } } - ret = rproc_add(rproc); + ret = devm_rproc_add(dev, rproc); if (ret) return dev_err_probe(dev, ret, "failed to add register device with remoteproc core\n"); @@ -786,14 +786,9 @@ static void k3_dsp_rproc_remove(struct platform_device *pdev) if (rproc->state == RPROC_ATTACHED) { ret = rproc_detach(rproc); - if (ret) { - /* Note this error path leaks resources */ + if (ret) dev_err(dev, "failed to detach proc (%pe)\n", ERR_PTR(ret)); - return; - } } - - rproc_del(kproc->rproc); } static const struct k3_dsp_mem_data c66_mems[] = { From 3c28bf48065b38b3551b1944c0b5d37529e98ff2 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 23 Jan 2024 09:51:02 +0100 Subject: [PATCH 16/30] dt-bindings: remoteproc: qcom,sm8550-pas: document the SM8650 PAS Document the DSP Peripheral Authentication Service on the SM8650 Platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20240123-topic-sm8650-upstream-remoteproc-v7-1-61283f50162f@linaro.org Signed-off-by: Bjorn Andersson --- .../bindings/remoteproc/qcom,sm8550-pas.yaml | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index 58120829fb06..5f63b6b9a8f5 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -19,6 +19,9 @@ properties: - qcom,sm8550-adsp-pas - qcom,sm8550-cdsp-pas - qcom,sm8550-mpss-pas + - qcom,sm8650-adsp-pas + - qcom,sm8650-cdsp-pas + - qcom,sm8650-mpss-pas reg: maxItems: 1 @@ -49,6 +52,8 @@ properties: - description: Memory region for main Firmware authentication - description: Memory region for Devicetree Firmware authentication - description: DSM Memory region + - description: DSM Memory region 2 + - description: Memory region for Qlink Logging required: - compatible @@ -63,6 +68,7 @@ allOf: enum: - qcom,sm8550-adsp-pas - qcom,sm8550-cdsp-pas + - qcom,sm8650-adsp-pas then: properties: interrupts: @@ -71,7 +77,26 @@ allOf: maxItems: 5 memory-region: maxItems: 2 - else: + - if: + properties: + compatible: + enum: + - qcom,sm8650-cdsp-pas + then: + properties: + interrupts: + maxItems: 5 + interrupt-names: + maxItems: 5 + memory-region: + minItems: 3 + maxItems: 3 + - if: + properties: + compatible: + enum: + - qcom,sm8550-mpss-pas + then: properties: interrupts: minItems: 6 @@ -79,12 +104,28 @@ allOf: minItems: 6 memory-region: minItems: 3 + maxItems: 3 + - if: + properties: + compatible: + enum: + - qcom,sm8650-mpss-pas + then: + properties: + interrupts: + minItems: 6 + interrupt-names: + minItems: 6 + memory-region: + minItems: 5 + maxItems: 5 - if: properties: compatible: enum: - qcom,sm8550-adsp-pas + - qcom,sm8650-adsp-pas then: properties: power-domains: @@ -101,6 +142,7 @@ allOf: compatible: enum: - qcom,sm8550-mpss-pas + - qcom,sm8650-mpss-pas then: properties: power-domains: @@ -116,6 +158,7 @@ allOf: compatible: enum: - qcom,sm8550-cdsp-pas + - qcom,sm8650-cdsp-pas then: properties: power-domains: From 1abd3130cf55c206689c76fee41299dbf58577bc Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 23 Jan 2024 09:51:03 +0100 Subject: [PATCH 17/30] remoteproc: qcom: pas: make region assign more generic The current memory region assign only supports a single memory region. But new platforms introduces more regions to make the memory requirements more flexible for various use cases. Those new platforms also shares the memory region between the DSP and HLOS. To handle this, make the region assign more generic in order to support more than a single memory region and also permit setting the regions permissions as shared. Reviewed-by: Mukesh Ojha Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20240123-topic-sm8650-upstream-remoteproc-v7-2-61283f50162f@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 100 +++++++++++++++++++---------- 1 file changed, 66 insertions(+), 34 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index a9dd58608052..09e8ad9f08c4 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -33,6 +33,8 @@ #define ADSP_DECRYPT_SHUTDOWN_DELAY_MS 100 +#define MAX_ASSIGN_COUNT 3 + struct adsp_data { int crash_reason_smem; const char *firmware_name; @@ -51,6 +53,9 @@ struct adsp_data { int ssctl_id; int region_assign_idx; + int region_assign_count; + bool region_assign_shared; + int region_assign_vmid; }; struct qcom_adsp { @@ -87,15 +92,18 @@ struct qcom_adsp { phys_addr_t dtb_mem_phys; phys_addr_t mem_reloc; phys_addr_t dtb_mem_reloc; - phys_addr_t region_assign_phys; + phys_addr_t region_assign_phys[MAX_ASSIGN_COUNT]; void *mem_region; void *dtb_mem_region; size_t mem_size; size_t dtb_mem_size; - size_t region_assign_size; + size_t region_assign_size[MAX_ASSIGN_COUNT]; int region_assign_idx; - u64 region_assign_perms; + int region_assign_count; + bool region_assign_shared; + int region_assign_vmid; + u64 region_assign_owners[MAX_ASSIGN_COUNT]; struct qcom_rproc_glink glink_subdev; struct qcom_rproc_subdev smd_subdev; @@ -590,37 +598,53 @@ static int adsp_alloc_memory_region(struct qcom_adsp *adsp) static int adsp_assign_memory_region(struct qcom_adsp *adsp) { - struct reserved_mem *rmem = NULL; - struct qcom_scm_vmperm perm; + struct qcom_scm_vmperm perm[MAX_ASSIGN_COUNT]; struct device_node *node; + unsigned int perm_size; + int offset; int ret; if (!adsp->region_assign_idx) return 0; - node = of_parse_phandle(adsp->dev->of_node, "memory-region", adsp->region_assign_idx); - if (node) - rmem = of_reserved_mem_lookup(node); - of_node_put(node); - if (!rmem) { - dev_err(adsp->dev, "unable to resolve shareable memory-region\n"); - return -EINVAL; - } + for (offset = 0; offset < adsp->region_assign_count; ++offset) { + struct reserved_mem *rmem = NULL; - perm.vmid = QCOM_SCM_VMID_MSS_MSA; - perm.perm = QCOM_SCM_PERM_RW; + node = of_parse_phandle(adsp->dev->of_node, "memory-region", + adsp->region_assign_idx + offset); + if (node) + rmem = of_reserved_mem_lookup(node); + of_node_put(node); + if (!rmem) { + dev_err(adsp->dev, "unable to resolve shareable memory-region index %d\n", + offset); + return -EINVAL; + } - adsp->region_assign_phys = rmem->base; - adsp->region_assign_size = rmem->size; - adsp->region_assign_perms = BIT(QCOM_SCM_VMID_HLOS); + if (adsp->region_assign_shared) { + perm[0].vmid = QCOM_SCM_VMID_HLOS; + perm[0].perm = QCOM_SCM_PERM_RW; + perm[1].vmid = adsp->region_assign_vmid; + perm[1].perm = QCOM_SCM_PERM_RW; + perm_size = 2; + } else { + perm[0].vmid = adsp->region_assign_vmid; + perm[0].perm = QCOM_SCM_PERM_RW; + perm_size = 1; + } - ret = qcom_scm_assign_mem(adsp->region_assign_phys, - adsp->region_assign_size, - &adsp->region_assign_perms, - &perm, 1); - if (ret < 0) { - dev_err(adsp->dev, "assign memory failed\n"); - return ret; + adsp->region_assign_phys[offset] = rmem->base; + adsp->region_assign_size[offset] = rmem->size; + adsp->region_assign_owners[offset] = BIT(QCOM_SCM_VMID_HLOS); + + ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset], + adsp->region_assign_size[offset], + &adsp->region_assign_owners[offset], + perm, perm_size); + if (ret < 0) { + dev_err(adsp->dev, "assign memory %d failed\n", offset); + return ret; + } } return 0; @@ -629,20 +653,23 @@ static int adsp_assign_memory_region(struct qcom_adsp *adsp) static void adsp_unassign_memory_region(struct qcom_adsp *adsp) { struct qcom_scm_vmperm perm; + int offset; int ret; - if (!adsp->region_assign_idx) + if (!adsp->region_assign_idx || adsp->region_assign_shared) return; - perm.vmid = QCOM_SCM_VMID_HLOS; - perm.perm = QCOM_SCM_PERM_RW; + for (offset = 0; offset < adsp->region_assign_count; ++offset) { + perm.vmid = QCOM_SCM_VMID_HLOS; + perm.perm = QCOM_SCM_PERM_RW; - ret = qcom_scm_assign_mem(adsp->region_assign_phys, - adsp->region_assign_size, - &adsp->region_assign_perms, - &perm, 1); - if (ret < 0) - dev_err(adsp->dev, "unassign memory failed\n"); + ret = qcom_scm_assign_mem(adsp->region_assign_phys[offset], + adsp->region_assign_size[offset], + &adsp->region_assign_owners[offset], + &perm, 1); + if (ret < 0) + dev_err(adsp->dev, "unassign memory %d failed\n", offset); + } } static int adsp_probe(struct platform_device *pdev) @@ -696,6 +723,9 @@ static int adsp_probe(struct platform_device *pdev) adsp->info_name = desc->sysmon_name; adsp->decrypt_shutdown = desc->decrypt_shutdown; adsp->region_assign_idx = desc->region_assign_idx; + adsp->region_assign_count = min_t(int, MAX_ASSIGN_COUNT, desc->region_assign_count); + adsp->region_assign_vmid = desc->region_assign_vmid; + adsp->region_assign_shared = desc->region_assign_shared; if (dtb_fw_name) { adsp->dtb_firmware_name = dtb_fw_name; adsp->dtb_pas_id = desc->dtb_pas_id; @@ -1163,6 +1193,8 @@ static const struct adsp_data sm8550_mpss_resource = { .sysmon_name = "modem", .ssctl_id = 0x12, .region_assign_idx = 2, + .region_assign_count = 1, + .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, }; static const struct adsp_data sc7280_wpss_resource = { From a3dd84d308c561f5600c8e2260f693857022a2c4 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 23 Jan 2024 09:51:04 +0100 Subject: [PATCH 18/30] remoteproc: qcom: pas: Add SM8650 remoteproc support Add DSP Peripheral Authentication Service support for the SM8650 platform. Reviewed-by: Dmitry Baryshkov Signed-off-by: Neil Armstrong Acked-by: Mukesh Ojha Link: https://lore.kernel.org/r/20240123-topic-sm8650-upstream-remoteproc-v7-3-61283f50162f@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 09e8ad9f08c4..d0b1f0f38347 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -1213,6 +1213,53 @@ static const struct adsp_data sc7280_wpss_resource = { .ssctl_id = 0x19, }; +static const struct adsp_data sm8650_cdsp_resource = { + .crash_reason_smem = 601, + .firmware_name = "cdsp.mdt", + .dtb_firmware_name = "cdsp_dtb.mdt", + .pas_id = 18, + .dtb_pas_id = 0x25, + .minidump_id = 7, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "cx", + "mxc", + "nsp", + NULL + }, + .load_state = "cdsp", + .ssr_name = "cdsp", + .sysmon_name = "cdsp", + .ssctl_id = 0x17, + .region_assign_idx = 2, + .region_assign_count = 1, + .region_assign_shared = true, + .region_assign_vmid = QCOM_SCM_VMID_CDSP, +}; + +static const struct adsp_data sm8650_mpss_resource = { + .crash_reason_smem = 421, + .firmware_name = "modem.mdt", + .dtb_firmware_name = "modem_dtb.mdt", + .pas_id = 4, + .dtb_pas_id = 0x26, + .minidump_id = 3, + .auto_boot = false, + .decrypt_shutdown = true, + .proxy_pd_names = (char*[]){ + "cx", + "mss", + NULL + }, + .load_state = "modem", + .ssr_name = "mpss", + .sysmon_name = "modem", + .ssctl_id = 0x12, + .region_assign_idx = 2, + .region_assign_count = 3, + .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, +}; + static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, @@ -1268,6 +1315,9 @@ static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,sm8550-adsp-pas", .data = &sm8550_adsp_resource}, { .compatible = "qcom,sm8550-cdsp-pas", .data = &sm8550_cdsp_resource}, { .compatible = "qcom,sm8550-mpss-pas", .data = &sm8550_mpss_resource}, + { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource}, + { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource}, + { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource}, { }, }; MODULE_DEVICE_TABLE(of, adsp_of_match); From 8b46dc5cfa5ffea279aed0fc05dc4b1c39a51517 Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Tue, 30 Jan 2024 07:48:49 -0800 Subject: [PATCH 19/30] remoteproc: Make rproc_get_by_phandle() work for clusters Multi-cluster remoteproc designs typically have the following DT declaration: remoteproc-cluster { compatible = "soc,remoteproc-cluster"; core0: core0 { compatible = "soc,remoteproc-core" memory-region; sram; }; core1: core1 { compatible = "soc,remoteproc-core" memory-region; sram; } }; A driver exists for the cluster rather than the individual cores themselves so that operation mode and HW specific configurations applicable to the cluster can be made. Because the driver exists at the cluster level and not the individual core level, function rproc_get_by_phandle() fails to return the remoteproc associated with the phandled it is called for. This patch enhances rproc_get_by_phandle() by looking for the cluster's driver when the driver for the immediate remoteproc's parent is not found. Reported-by: Ben Levinsky Signed-off-by: Mathieu Poirier Co-developed-by: Tarak Reddy Signed-off-by: Tarak Reddy Co-developed-by: Tanmay Shah Signed-off-by: Tanmay Shah Link: https://lore.kernel.org/r/20240130154849.1018666-1-tanmay.shah@amd.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 29 ++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 695cce218e8c..f276956f2c5c 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -2112,6 +2113,7 @@ EXPORT_SYMBOL(rproc_detach); struct rproc *rproc_get_by_phandle(phandle phandle) { struct rproc *rproc = NULL, *r; + struct device_driver *driver; struct device_node *np; np = of_find_node_by_phandle(phandle); @@ -2122,7 +2124,26 @@ struct rproc *rproc_get_by_phandle(phandle phandle) list_for_each_entry_rcu(r, &rproc_list, node) { if (r->dev.parent && device_match_of_node(r->dev.parent, np)) { /* prevent underlying implementation from being removed */ - if (!try_module_get(r->dev.parent->driver->owner)) { + + /* + * If the remoteproc's parent has a driver, the + * remoteproc is not part of a cluster and we can use + * that driver. + */ + driver = r->dev.parent->driver; + + /* + * If the remoteproc's parent does not have a driver, + * look for the driver associated with the cluster. + */ + if (!driver) { + if (r->dev.parent->parent) + driver = r->dev.parent->parent->driver; + if (!driver) + break; + } + + if (!try_module_get(driver->owner)) { dev_err(&r->dev, "can't get owner\n"); break; } @@ -2533,7 +2554,11 @@ EXPORT_SYMBOL(rproc_free); */ void rproc_put(struct rproc *rproc) { - module_put(rproc->dev.parent->driver->owner); + if (rproc->dev.parent->driver) + module_put(rproc->dev.parent->driver->owner); + else + module_put(rproc->dev.parent->parent->driver->owner); + put_device(&rproc->dev); } EXPORT_SYMBOL(rproc_put); From 9e63836703a43950f4556d1304cf60fd1221e0a1 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 4 Mar 2024 19:03:34 +0200 Subject: [PATCH 20/30] remoteproc: qcom: pas: correct data indentation Correct indentation of several struct adsp_data instances to always use a single TAB character instead of two. Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20240304-qcom-pd-mapper-v3-4-6858fa1ac1c8@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 124 ++++++++++++++--------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index d0b1f0f38347..3235249d703d 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -807,24 +807,24 @@ static void adsp_remove(struct platform_device *pdev) } static const struct adsp_data adsp_resource_init = { - .crash_reason_smem = 423, - .firmware_name = "adsp.mdt", - .pas_id = 1, - .auto_boot = true, - .ssr_name = "lpass", - .sysmon_name = "adsp", - .ssctl_id = 0x14, + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", + .pas_id = 1, + .auto_boot = true, + .ssr_name = "lpass", + .sysmon_name = "adsp", + .ssctl_id = 0x14, }; static const struct adsp_data sdm845_adsp_resource_init = { - .crash_reason_smem = 423, - .firmware_name = "adsp.mdt", - .pas_id = 1, - .auto_boot = true, - .load_state = "adsp", - .ssr_name = "lpass", - .sysmon_name = "adsp", - .ssctl_id = 0x14, + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", + .pas_id = 1, + .auto_boot = true, + .load_state = "adsp", + .ssr_name = "lpass", + .sysmon_name = "adsp", + .ssctl_id = 0x14, }; static const struct adsp_data sm6350_adsp_resource = { @@ -859,18 +859,18 @@ static const struct adsp_data sm6375_mpss_resource = { }; static const struct adsp_data sm8150_adsp_resource = { - .crash_reason_smem = 423, - .firmware_name = "adsp.mdt", - .pas_id = 1, - .auto_boot = true, - .proxy_pd_names = (char*[]){ - "cx", - NULL - }, - .load_state = "adsp", - .ssr_name = "lpass", - .sysmon_name = "adsp", - .ssctl_id = 0x14, + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", + .pas_id = 1, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "cx", + NULL + }, + .load_state = "adsp", + .ssr_name = "lpass", + .sysmon_name = "adsp", + .ssctl_id = 0x14, }; static const struct adsp_data sm8250_adsp_resource = { @@ -906,17 +906,17 @@ static const struct adsp_data sm8350_adsp_resource = { }; static const struct adsp_data msm8996_adsp_resource = { - .crash_reason_smem = 423, - .firmware_name = "adsp.mdt", - .pas_id = 1, - .auto_boot = true, - .proxy_pd_names = (char*[]){ - "cx", - NULL - }, - .ssr_name = "lpass", - .sysmon_name = "adsp", - .ssctl_id = 0x14, + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", + .pas_id = 1, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "cx", + NULL + }, + .ssr_name = "lpass", + .sysmon_name = "adsp", + .ssctl_id = 0x14, }; static const struct adsp_data cdsp_resource_init = { @@ -1063,33 +1063,33 @@ static const struct adsp_data sc8180x_mpss_resource = { }; static const struct adsp_data msm8996_slpi_resource_init = { - .crash_reason_smem = 424, - .firmware_name = "slpi.mdt", - .pas_id = 12, - .auto_boot = true, - .proxy_pd_names = (char*[]){ - "ssc_cx", - NULL - }, - .ssr_name = "dsps", - .sysmon_name = "slpi", - .ssctl_id = 0x16, + .crash_reason_smem = 424, + .firmware_name = "slpi.mdt", + .pas_id = 12, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "ssc_cx", + NULL + }, + .ssr_name = "dsps", + .sysmon_name = "slpi", + .ssctl_id = 0x16, }; static const struct adsp_data sdm845_slpi_resource_init = { - .crash_reason_smem = 424, - .firmware_name = "slpi.mdt", - .pas_id = 12, - .auto_boot = true, - .proxy_pd_names = (char*[]){ - "lcx", - "lmx", - NULL - }, - .load_state = "slpi", - .ssr_name = "dsps", - .sysmon_name = "slpi", - .ssctl_id = 0x16, + .crash_reason_smem = 424, + .firmware_name = "slpi.mdt", + .pas_id = 12, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "lcx", + "lmx", + NULL + }, + .load_state = "slpi", + .ssr_name = "dsps", + .sysmon_name = "slpi", + .ssctl_id = 0x16, }; static const struct adsp_data wcss_resource_init = { From 9023bd9b8a41ae118dd5155b8565ac657427113e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 26 Feb 2024 13:28:54 +0100 Subject: [PATCH 21/30] dt-bindings: remoteproc: qcom,glink-rpm-edge: drop redundant type from label dtschema defines label as string, so $ref in other bindings is redundant. Signed-off-by: Krzysztof Kozlowski Acked-by: Rob Herring Link: https://lore.kernel.org/r/20240226122854.86197-1-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/remoteproc/qcom,glink-rpm-edge.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,glink-rpm-edge.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,glink-rpm-edge.yaml index 884158bccd50..3766d4513b37 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,glink-rpm-edge.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,glink-rpm-edge.yaml @@ -18,7 +18,6 @@ properties: const: qcom,glink-rpm label: - $ref: /schemas/types.yaml#/definitions/string description: Name of the edge, used for debugging and identification purposes. The node name will be used if this is not present. From 506355c5778fdaac942215b14273176f6a39c3c4 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 15 Jan 2024 19:20:31 +0100 Subject: [PATCH 22/30] dt-bindings: remoteproc: do not override firmware-name $ref dtschema package defines firmware-name as string-array, so individual bindings should not make it a string but instead just narrow the number of expected firmware file names. Signed-off-by: Krzysztof Kozlowski Reviewed-by: AngeloGioacchino Del Regno Reviewed-by: Mathieu Poirier Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20240115182031.1610088-1-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml | 4 ++-- .../devicetree/bindings/remoteproc/qcom,qcs404-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sc7180-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sm6115-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sm6350-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sm6375-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,sm8350-pas.yaml | 2 +- .../devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml index 09102dda4942..507f98f73d23 100644 --- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml +++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml @@ -47,7 +47,7 @@ properties: maxItems: 1 firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: If present, name (or relative path) of the file within the firmware search path containing the firmware image used when @@ -115,7 +115,7 @@ patternProperties: maxItems: 1 firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: If present, name (or relative path) of the file within the firmware search path containing the firmware image used when diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,qcs404-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,qcs404-pas.yaml index eb868a7ff4cd..ad45fd00ae34 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,qcs404-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,qcs404-pas.yaml @@ -46,7 +46,7 @@ properties: description: Reference to the reserved-memory for the Hexagon core firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core required: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sc7180-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sc7180-pas.yaml index c054b84fdcd5..66b455d0a8e3 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sc7180-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sc7180-pas.yaml @@ -45,7 +45,7 @@ properties: smd-edge: false firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core required: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml index b6bd33438584..9381c7022ff4 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sc7280-wpss-pil.yaml @@ -80,7 +80,7 @@ properties: description: Reference to the reserved-memory for the Hexagon core firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: The name of the firmware which should be loaded for this remote processor. diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml index 4744a37b2b5d..45ee9fbe0966 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml @@ -42,7 +42,7 @@ properties: description: Reference to the reserved-memory for the Hexagon core firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core required: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm6115-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm6115-pas.yaml index 028287235912..758adb06c8dd 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm6115-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm6115-pas.yaml @@ -47,7 +47,7 @@ properties: smd-edge: false firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core required: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm6350-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm6350-pas.yaml index f7e40fb166da..c1a3cc308bdb 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm6350-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm6350-pas.yaml @@ -42,7 +42,7 @@ properties: smd-edge: false firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core required: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm6375-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm6375-pas.yaml index 3e4a03eb4532..7286b2baa19f 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm6375-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm6375-pas.yaml @@ -36,7 +36,7 @@ properties: description: Reference to the reserved-memory for the Hexagon core firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core smd-edge: false diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml index 238c6e5e67c5..d67386c50fa4 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml @@ -46,7 +46,7 @@ properties: smd-edge: false firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core required: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8350-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8350-pas.yaml index 53cea8e53a31..4b9fb74fb9e9 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8350-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8350-pas.yaml @@ -47,7 +47,7 @@ properties: description: Reference to the reserved-memory for the Hexagon core firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Firmware name for the Hexagon core required: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml index 45eb42bd3c2c..8e033b22d28c 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml @@ -51,7 +51,7 @@ properties: - const: stop-ack firmware-name: - $ref: /schemas/types.yaml#/definitions/string + maxItems: 1 description: Relative firmware image path for the WCNSS core. Defaults to "wcnss.mdt". From 5789e877b93bc798f2cf0c13510b0602f96549f7 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:26 -0600 Subject: [PATCH 23/30] remoteproc: qcom_q6v5_adsp: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-3-afd@ti.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_adsp.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c index 6c67514cc493..34ac996a93b2 100644 --- a/drivers/remoteproc/qcom_q6v5_adsp.c +++ b/drivers/remoteproc/qcom_q6v5_adsp.c @@ -683,8 +683,8 @@ static int adsp_probe(struct platform_device *pdev) return ret; } - rproc = rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, - firmware_name, sizeof(*adsp)); + rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &adsp_ops, + firmware_name, sizeof(*adsp)); if (!rproc) { dev_err(&pdev->dev, "unable to allocate remoteproc\n"); return -ENOMEM; @@ -709,17 +709,17 @@ static int adsp_probe(struct platform_device *pdev) ret = adsp_alloc_memory_region(adsp); if (ret) - goto free_rproc; + return ret; ret = adsp_init_clock(adsp, desc->clk_ids); if (ret) - goto free_rproc; + return ret; ret = qcom_rproc_pds_attach(adsp->dev, adsp, desc->proxy_pd_names); if (ret < 0) { dev_err(&pdev->dev, "Failed to attach proxy power domains\n"); - goto free_rproc; + return ret; } adsp->proxy_pd_count = ret; @@ -755,9 +755,6 @@ static int adsp_probe(struct platform_device *pdev) disable_pm: qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); -free_rproc: - rproc_free(rproc); - return ret; } @@ -772,7 +769,6 @@ static void adsp_remove(struct platform_device *pdev) qcom_remove_sysmon_subdev(adsp->sysmon); qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); qcom_rproc_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); - rproc_free(adsp->rproc); } static const struct adsp_pil_data adsp_resource_init = { From 2f09fa9f7afb1352edbd5b59f42871fb2227bb9a Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:27 -0600 Subject: [PATCH 24/30] remoteproc: qcom_q6v5_mss: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-4-afd@ti.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_mss.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 394b2c1cb5e2..1779fc890e10 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -1990,8 +1990,8 @@ static int q6v5_probe(struct platform_device *pdev) return ret; } - rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, - mba_image, sizeof(*qproc)); + rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, + mba_image, sizeof(*qproc)); if (!rproc) { dev_err(&pdev->dev, "failed to allocate rproc\n"); return -ENOMEM; @@ -2008,7 +2008,7 @@ static int q6v5_probe(struct platform_device *pdev) 1, &qproc->hexagon_mdt_image); if (ret < 0 && ret != -EINVAL) { dev_err(&pdev->dev, "unable to read mpss firmware-name\n"); - goto free_rproc; + return ret; } platform_set_drvdata(pdev, qproc); @@ -2019,17 +2019,17 @@ static int q6v5_probe(struct platform_device *pdev) qproc->has_spare_reg = desc->has_spare_reg; ret = q6v5_init_mem(qproc, pdev); if (ret) - goto free_rproc; + return ret; ret = q6v5_alloc_memory_region(qproc); if (ret) - goto free_rproc; + return ret; ret = q6v5_init_clocks(&pdev->dev, qproc->proxy_clks, desc->proxy_clk_names); if (ret < 0) { dev_err(&pdev->dev, "Failed to get proxy clocks.\n"); - goto free_rproc; + return ret; } qproc->proxy_clk_count = ret; @@ -2037,7 +2037,7 @@ static int q6v5_probe(struct platform_device *pdev) desc->reset_clk_names); if (ret < 0) { dev_err(&pdev->dev, "Failed to get reset clocks.\n"); - goto free_rproc; + return ret; } qproc->reset_clk_count = ret; @@ -2045,7 +2045,7 @@ static int q6v5_probe(struct platform_device *pdev) desc->active_clk_names); if (ret < 0) { dev_err(&pdev->dev, "Failed to get active clocks.\n"); - goto free_rproc; + return ret; } qproc->active_clk_count = ret; @@ -2053,7 +2053,7 @@ static int q6v5_probe(struct platform_device *pdev) desc->proxy_supply); if (ret < 0) { dev_err(&pdev->dev, "Failed to get proxy regulators.\n"); - goto free_rproc; + return ret; } qproc->proxy_reg_count = ret; @@ -2061,7 +2061,7 @@ static int q6v5_probe(struct platform_device *pdev) desc->active_supply); if (ret < 0) { dev_err(&pdev->dev, "Failed to get active regulators.\n"); - goto free_rproc; + return ret; } qproc->active_reg_count = ret; @@ -2074,12 +2074,12 @@ static int q6v5_probe(struct platform_device *pdev) desc->fallback_proxy_supply); if (ret < 0) { dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n"); - goto free_rproc; + return ret; } qproc->fallback_proxy_reg_count = ret; } else if (ret < 0) { dev_err(&pdev->dev, "Failed to init power domains\n"); - goto free_rproc; + return ret; } else { qproc->proxy_pd_count = ret; } @@ -2127,8 +2127,6 @@ remove_subdevs: qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); detach_proxy_pds: q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); -free_rproc: - rproc_free(rproc); return ret; } @@ -2149,8 +2147,6 @@ static void q6v5_remove(struct platform_device *pdev) qcom_remove_glink_subdev(rproc, &qproc->glink_subdev); q6v5_pds_detach(qproc, qproc->proxy_pds, qproc->proxy_pd_count); - - rproc_free(rproc); } static const struct rproc_hexagon_res sc7180_mss = { From 35049a98a4dcfe2906c8dc127bee451799d3a8c3 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:28 -0600 Subject: [PATCH 25/30] remoteproc: qcom_q6v5_pas: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-5-afd@ti.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 3235249d703d..452e96392525 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -705,7 +705,7 @@ static int adsp_probe(struct platform_device *pdev) if (desc->minidump_id) ops = &adsp_minidump_ops; - rproc = rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp)); + rproc = devm_rproc_alloc(&pdev->dev, pdev->name, ops, fw_name, sizeof(*adsp)); if (!rproc) { dev_err(&pdev->dev, "unable to allocate remoteproc\n"); @@ -784,7 +784,6 @@ detach_proxy_pds: adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); free_rproc: device_init_wakeup(adsp->dev, false); - rproc_free(rproc); return ret; } @@ -803,7 +802,6 @@ static void adsp_remove(struct platform_device *pdev) qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev); adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count); device_init_wakeup(adsp->dev, false); - rproc_free(adsp->rproc); } static const struct adsp_data adsp_resource_init = { From 41854ea92baad3788bd8735312375e6dd3a54ad3 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:29 -0600 Subject: [PATCH 26/30] remoteproc: qcom_q6v5_wcss: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-6-afd@ti.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_wcss.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c index cff1fa07d1de..94f68c919ee6 100644 --- a/drivers/remoteproc/qcom_q6v5_wcss.c +++ b/drivers/remoteproc/qcom_q6v5_wcss.c @@ -1011,8 +1011,8 @@ static int q6v5_wcss_probe(struct platform_device *pdev) if (!desc) return -EINVAL; - rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops, - desc->firmware_name, sizeof(*wcss)); + rproc = devm_rproc_alloc(&pdev->dev, pdev->name, desc->ops, + desc->firmware_name, sizeof(*wcss)); if (!rproc) { dev_err(&pdev->dev, "failed to allocate rproc\n"); return -ENOMEM; @@ -1027,29 +1027,29 @@ static int q6v5_wcss_probe(struct platform_device *pdev) ret = q6v5_wcss_init_mmio(wcss, pdev); if (ret) - goto free_rproc; + return ret; ret = q6v5_alloc_memory_region(wcss); if (ret) - goto free_rproc; + return ret; if (wcss->version == WCSS_QCS404) { ret = q6v5_wcss_init_clock(wcss); if (ret) - goto free_rproc; + return ret; ret = q6v5_wcss_init_regulator(wcss); if (ret) - goto free_rproc; + return ret; } ret = q6v5_wcss_init_reset(wcss, desc); if (ret) - goto free_rproc; + return ret; ret = qcom_q6v5_init(&wcss->q6v5, pdev, rproc, desc->crash_reason_smem, NULL, NULL); if (ret) - goto free_rproc; + return ret; qcom_add_glink_subdev(rproc, &wcss->glink_subdev, "q6wcss"); qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss"); @@ -1061,16 +1061,11 @@ static int q6v5_wcss_probe(struct platform_device *pdev) ret = rproc_add(rproc); if (ret) - goto free_rproc; + return ret; platform_set_drvdata(pdev, rproc); return 0; - -free_rproc: - rproc_free(rproc); - - return ret; } static void q6v5_wcss_remove(struct platform_device *pdev) @@ -1080,7 +1075,6 @@ static void q6v5_wcss_remove(struct platform_device *pdev) qcom_q6v5_deinit(&wcss->q6v5); rproc_del(rproc); - rproc_free(rproc); } static const struct wcss_data wcss_ipq8074_res_init = { From c92ab8aaf42e84f33d690ea9cb292483dd9c2761 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 23 Jan 2024 12:46:30 -0600 Subject: [PATCH 27/30] remoteproc: qcom_wcnss: Use devm_rproc_alloc() helper Use the device lifecycle managed allocation function. This helps prevent mistakes like freeing out of order in cleanup functions and forgetting to free on error paths. Signed-off-by: Andrew Davis Link: https://lore.kernel.org/r/20240123184632.725054-7-afd@ti.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_wcnss.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index 90de22c81da9..a7bb9da27029 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -555,8 +555,8 @@ static int wcnss_probe(struct platform_device *pdev) if (ret < 0 && ret != -EINVAL) return ret; - rproc = rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops, - fw_name, sizeof(*wcnss)); + rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops, + fw_name, sizeof(*wcnss)); if (!rproc) { dev_err(&pdev->dev, "unable to allocate remoteproc\n"); return -ENOMEM; @@ -574,14 +574,12 @@ static int wcnss_probe(struct platform_device *pdev) mutex_init(&wcnss->iris_lock); mmio = devm_platform_ioremap_resource_byname(pdev, "pmu"); - if (IS_ERR(mmio)) { - ret = PTR_ERR(mmio); - goto free_rproc; - } + if (IS_ERR(mmio)) + return PTR_ERR(mmio); ret = wcnss_alloc_memory_region(wcnss); if (ret) - goto free_rproc; + return ret; wcnss->pmu_cfg = mmio + data->pmu_offset; wcnss->spare_out = mmio + data->spare_offset; @@ -592,7 +590,7 @@ static int wcnss_probe(struct platform_device *pdev) */ ret = wcnss_init_pds(wcnss, data->pd_names); if (ret && (ret != -ENODATA || !data->num_pd_vregs)) - goto free_rproc; + return ret; ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs, data->num_pd_vregs); @@ -656,8 +654,6 @@ remove_iris: qcom_iris_remove(wcnss->iris); detach_pds: wcnss_release_pds(wcnss); -free_rproc: - rproc_free(rproc); return ret; } @@ -673,7 +669,6 @@ static void wcnss_remove(struct platform_device *pdev) qcom_remove_sysmon_subdev(wcnss->sysmon); qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev); wcnss_release_pds(wcnss); - rproc_free(wcnss->rproc); } static const struct of_device_id wcnss_of_match[] = { From 9e93276d6639a0bb701e69d393680c6fb07bc12e Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Mon, 12 Feb 2024 19:02:42 +0200 Subject: [PATCH 28/30] dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & cDSP Document the aDSP and cDSP Peripheral Authentication Service on the X1E80100 Platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Abel Vesa Link: https://lore.kernel.org/r/20240212-x1e80100-remoteproc-v2-1-604614367f38@linaro.org Signed-off-by: Bjorn Andersson --- .../devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index 5f63b6b9a8f5..73fda7565cd1 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -22,6 +22,8 @@ properties: - qcom,sm8650-adsp-pas - qcom,sm8650-cdsp-pas - qcom,sm8650-mpss-pas + - qcom,x1e80100-adsp-pas + - qcom,x1e80100-cdsp-pas reg: maxItems: 1 @@ -69,6 +71,8 @@ allOf: - qcom,sm8550-adsp-pas - qcom,sm8550-cdsp-pas - qcom,sm8650-adsp-pas + - qcom,x1e80100-adsp-pas + - qcom,x1e80100-cdsp-pas then: properties: interrupts: @@ -126,6 +130,7 @@ allOf: enum: - qcom,sm8550-adsp-pas - qcom,sm8650-adsp-pas + - qcom,x1e80100-adsp-pas then: properties: power-domains: @@ -159,6 +164,7 @@ allOf: enum: - qcom,sm8550-cdsp-pas - qcom,sm8650-cdsp-pas + - qcom,x1e80100-cdsp-pas then: properties: power-domains: From 1d7823f28631f139294646bb189de94b8a07c7f1 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Mon, 12 Feb 2024 19:02:43 +0200 Subject: [PATCH 29/30] remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP Add support for PIL loading on ADSP and CDSP on X1E80100 SoCs. Signed-off-by: Sibi Sankar Reviewed-by: Dmitry Baryshkov Signed-off-by: Abel Vesa Link: https://lore.kernel.org/r/20240212-x1e80100-remoteproc-v2-2-604614367f38@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 41 ++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 452e96392525..3e2ced63a3e1 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -1012,6 +1012,45 @@ static const struct adsp_data sc8280xp_nsp1_resource = { .ssctl_id = 0x20, }; +static const struct adsp_data x1e80100_adsp_resource = { + .crash_reason_smem = 423, + .firmware_name = "adsp.mdt", + .dtb_firmware_name = "adsp_dtb.mdt", + .pas_id = 1, + .dtb_pas_id = 0x24, + .minidump_id = 5, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "lcx", + "lmx", + NULL + }, + .load_state = "adsp", + .ssr_name = "lpass", + .sysmon_name = "adsp", + .ssctl_id = 0x14, +}; + +static const struct adsp_data x1e80100_cdsp_resource = { + .crash_reason_smem = 601, + .firmware_name = "cdsp.mdt", + .dtb_firmware_name = "cdsp_dtb.mdt", + .pas_id = 18, + .dtb_pas_id = 0x25, + .minidump_id = 7, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "cx", + "mxc", + "nsp", + NULL + }, + .load_state = "cdsp", + .ssr_name = "cdsp", + .sysmon_name = "cdsp", + .ssctl_id = 0x17, +}; + static const struct adsp_data sm8350_cdsp_resource = { .crash_reason_smem = 601, .firmware_name = "cdsp.mdt", @@ -1316,6 +1355,8 @@ static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource}, { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource}, { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource}, + { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource}, + { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource}, { }, }; MODULE_DEVICE_TABLE(of, adsp_of_match); From 62210f7509e13a2caa7b080722a45229b8f17a0a Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Mon, 12 Feb 2024 19:02:44 +0200 Subject: [PATCH 30/30] remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP The UEFI loads a lite variant of the ADSP firmware to support charging use cases. The kernel needs to unload and reload it with the firmware that has full feature support for audio. This patch arbitarily shutsdown the lite firmware before loading the full firmware. Signed-off-by: Sibi Sankar Signed-off-by: Abel Vesa Link: https://lore.kernel.org/r/20240212-x1e80100-remoteproc-v2-3-604614367f38@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 3e2ced63a3e1..54d8005d40a3 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -41,6 +41,7 @@ struct adsp_data { const char *dtb_firmware_name; int pas_id; int dtb_pas_id; + int lite_pas_id; unsigned int minidump_id; bool auto_boot; bool decrypt_shutdown; @@ -77,6 +78,7 @@ struct qcom_adsp { const char *dtb_firmware_name; int pas_id; int dtb_pas_id; + int lite_pas_id; unsigned int minidump_id; int crash_reason_smem; bool decrypt_shutdown; @@ -218,6 +220,9 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw) /* Store firmware handle to be used in adsp_start() */ adsp->firmware = fw; + if (adsp->lite_pas_id) + ret = qcom_scm_pas_shutdown(adsp->lite_pas_id); + if (adsp->dtb_pas_id) { ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev); if (ret) { @@ -720,6 +725,7 @@ static int adsp_probe(struct platform_device *pdev) adsp->rproc = rproc; adsp->minidump_id = desc->minidump_id; adsp->pas_id = desc->pas_id; + adsp->lite_pas_id = desc->lite_pas_id; adsp->info_name = desc->sysmon_name; adsp->decrypt_shutdown = desc->decrypt_shutdown; adsp->region_assign_idx = desc->region_assign_idx; @@ -1018,6 +1024,7 @@ static const struct adsp_data x1e80100_adsp_resource = { .dtb_firmware_name = "adsp_dtb.mdt", .pas_id = 1, .dtb_pas_id = 0x24, + .lite_pas_id = 0x1f, .minidump_id = 5, .auto_boot = true, .proxy_pd_names = (char*[]){