1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

remoteproc updates for v6.14

Correct error path in rproc_alloc(), with regards to put_device() and
 freeing of the rproc index ida. The Mediatek SCP remoteproc driver is
 returned to only creating child devices from specific DeviceTree nodes.
 OMAP remoteproc driver is updated to match the cleanups in the OMAP
 iommu driver.
 
 In addition to this, a number of conversions to devres and other small,
 mostly stylistic, code cleanups.
 -----BEGIN PGP SIGNATURE-----
 
 iQJJBAABCAAzFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmeVIZEVHGFuZGVyc3Nv
 bkBrZXJuZWwub3JnAAoJEAsfOT8Nma3FwaMP/10U35ZG0iFhjmMTWusMMS/j/FMv
 ufD1wXCibAROf/Kj3JhITVjUyOVNYisyGKi8gUPmWn9Ti5nMjUFvYDXtUfrBegLf
 Kl1rYIFuXCeldQQbZDbtHXnXTtosneQSqLSoj1lQSiQgC8R0SuQCwm3KyhSBJs1P
 sxXz6B+ewW67U7hpaRI/hzKOzq3ANK7NqMzTxVkage+VRfEcc1xeH+iwTUUseiYR
 GkECXTogol+btjUyAM7QVkVUAA+DqjJoFinWW6kXzOP1Z+L6T4lqcqXVoakItR8K
 hJ2IP5ktoShDtQ1IdXOLXcdS9IL6YPvLjkY5YPv9/fSEyiKBOC3k49ED1tkLuFa4
 0/CDamFLeuAZm3yvnsH2sgpLYrUOdVbm6nkqicBq2BGngJxWr1crVeXclON39TgU
 7wa0jLWW2P1B649NGNRrM+6vsxrZPRRYVdpoT7L6EItdQfUKOo5ra1Min9SIeAjy
 edsAaM7UogOyewYTWW///3ecjS1UDEW2gOzrRnAyxUWd+6yzBxnMsxY+0h1idXPt
 Wbf9PP0YDd4HtbXrCH96t1FtMJJ9TClh7vxCLqpMSS1H508uFpSkMmOpw13FnODu
 evvucZ3QjOs+eujiuZWzbJyjXIqMSfU0wDYz2xSVOJxvctsUkASQzlvirqQZe0uy
 Oe9jfkgPMRdW9jQ9
 =QA3V
 -----END PGP SIGNATURE-----

Merge tag 'rproc-v6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux

Pull remoteproc updates from Bjorn Andersson:

 - Correct error path in rproc_alloc(), with regards to put_device() and
   freeing of the rproc index ida

 - The Mediatek SCP remoteproc driver is returned to only creating child
   devices from specific DeviceTree nodes

 - Update the OMAP remoteproc driver to match the cleanups in the OMAP
   iommu driver

In addition to this, a number of conversions to devres and other small,
mostly stylistic, code cleanups

* tag 'rproc-v6.14' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux:
  remoteproc: st: Use syscon_regmap_lookup_by_phandle_args
  remoteproc: keystone: Use syscon_regmap_lookup_by_phandle_args
  remoteproc: st: Simplify with dev_err_probe
  remoteproc: omap: Simplify returning syscon PTR_ERR
  remoteproc: keystone: Simplify returning syscon PTR_ERR
  remoteproc: k3-r5: Add devm action to release tsp
  remoteproc: k3-r5: Use devm_rproc_add() helper
  remoteproc: k3-r5: Use devm_ioremap_wc() helper
  remoteproc: k3-r5: Use devm_kcalloc() helper
  remoteproc: k3-r5: Add devm action to release reserved memory
  remoteproc: mtk_scp: Only populate devices for SCP cores
  remoteproc: omap: Handle ARM dma_iommu_mapping
  remoteproc: core: Fix ida_free call while not allocated
This commit is contained in:
Linus Torvalds 2025-01-25 16:23:38 -08:00
commit aa22f4da2a
6 changed files with 97 additions and 112 deletions

View file

@ -335,25 +335,16 @@ static int keystone_rproc_of_get_dev_syscon(struct platform_device *pdev,
{
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
int ret;
if (!of_property_read_bool(np, "ti,syscon-dev")) {
dev_err(dev, "ti,syscon-dev property is absent\n");
return -EINVAL;
}
ksproc->dev_ctrl =
syscon_regmap_lookup_by_phandle(np, "ti,syscon-dev");
if (IS_ERR(ksproc->dev_ctrl)) {
ret = PTR_ERR(ksproc->dev_ctrl);
return ret;
}
if (of_property_read_u32_index(np, "ti,syscon-dev", 1,
&ksproc->boot_offset)) {
dev_err(dev, "couldn't read the boot register offset\n");
return -EINVAL;
}
ksproc->dev_ctrl = syscon_regmap_lookup_by_phandle_args(np, "ti,syscon-dev",
1, &ksproc->boot_offset);
if (IS_ERR(ksproc->dev_ctrl))
return PTR_ERR(ksproc->dev_ctrl);
return 0;
}

View file

@ -1326,6 +1326,11 @@ static int scp_cluster_init(struct platform_device *pdev, struct mtk_scp_of_clus
return ret;
}
static const struct of_device_id scp_core_match[] = {
{ .compatible = "mediatek,scp-core" },
{}
};
static int scp_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@ -1357,13 +1362,15 @@ static int scp_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
mutex_init(&scp_cluster->cluster_lock);
ret = devm_of_platform_populate(dev);
ret = of_platform_populate(dev_of_node(dev), scp_core_match, NULL, dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to populate platform devices\n");
ret = scp_cluster_init(pdev, scp_cluster);
if (ret)
if (ret) {
of_platform_depopulate(dev);
return ret;
}
return 0;
}
@ -1379,6 +1386,7 @@ static void scp_remove(struct platform_device *pdev)
rproc_del(scp->rproc);
scp_free(scp);
}
of_platform_depopulate(&pdev->dev);
mutex_destroy(&scp_cluster->cluster_lock);
}

View file

@ -37,6 +37,10 @@
#include <linux/platform_data/dmtimer-omap.h>
#ifdef CONFIG_ARM_DMA_USE_IOMMU
#include <asm/dma-iommu.h>
#endif
#include "omap_remoteproc.h"
#include "remoteproc_internal.h"
@ -1133,7 +1137,6 @@ static int omap_rproc_get_boot_data(struct platform_device *pdev,
struct device_node *np = pdev->dev.of_node;
struct omap_rproc *oproc = rproc->priv;
const struct omap_rproc_dev_data *data;
int ret;
data = of_device_get_match_data(&pdev->dev);
if (!data)
@ -1149,10 +1152,8 @@ static int omap_rproc_get_boot_data(struct platform_device *pdev,
oproc->boot_data->syscon =
syscon_regmap_lookup_by_phandle(np, "ti,bootreg");
if (IS_ERR(oproc->boot_data->syscon)) {
ret = PTR_ERR(oproc->boot_data->syscon);
return ret;
}
if (IS_ERR(oproc->boot_data->syscon))
return PTR_ERR(oproc->boot_data->syscon);
if (of_property_read_u32_index(np, "ti,bootreg", 1,
&oproc->boot_data->boot_reg)) {
@ -1323,6 +1324,19 @@ static int omap_rproc_probe(struct platform_device *pdev)
/* All existing OMAP IPU and DSP processors have an MMU */
rproc->has_iommu = true;
#ifdef CONFIG_ARM_DMA_USE_IOMMU
/*
* Throw away the ARM DMA mapping that we'll never use, so it doesn't
* interfere with the core rproc->domain and we get the right DMA ops.
*/
if (pdev->dev.archdata.mapping) {
struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(&pdev->dev);
arm_iommu_detach_device(&pdev->dev);
arm_iommu_release_mapping(mapping);
}
#endif
ret = omap_rproc_of_get_internal_memories(pdev, rproc);
if (ret)
return ret;

View file

@ -2486,6 +2486,13 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
rproc->dev.driver_data = rproc;
idr_init(&rproc->notifyids);
/* Assign a unique device index and name */
rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL);
if (rproc->index < 0) {
dev_err(dev, "ida_alloc failed: %d\n", rproc->index);
goto put_device;
}
rproc->name = kstrdup_const(name, GFP_KERNEL);
if (!rproc->name)
goto put_device;
@ -2496,13 +2503,6 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
if (rproc_alloc_ops(rproc, ops))
goto put_device;
/* Assign a unique device index and name */
rproc->index = ida_alloc(&rproc_dev_index, GFP_KERNEL);
if (rproc->index < 0) {
dev_err(dev, "ida_alloc failed: %d\n", rproc->index);
goto put_device;
}
dev_set_name(&rproc->dev, "remoteproc%d", rproc->index);
atomic_set(&rproc->power, 0);

View file

@ -290,26 +290,23 @@ static int st_rproc_parse_dt(struct platform_device *pdev)
if (ddata->config->sw_reset) {
ddata->sw_reset = devm_reset_control_get_exclusive(dev,
"sw_reset");
if (IS_ERR(ddata->sw_reset)) {
dev_err(dev, "Failed to get S/W Reset\n");
return PTR_ERR(ddata->sw_reset);
}
if (IS_ERR(ddata->sw_reset))
return dev_err_probe(dev, PTR_ERR(ddata->sw_reset),
"Failed to get S/W Reset\n");
}
if (ddata->config->pwr_reset) {
ddata->pwr_reset = devm_reset_control_get_exclusive(dev,
"pwr_reset");
if (IS_ERR(ddata->pwr_reset)) {
dev_err(dev, "Failed to get Power Reset\n");
return PTR_ERR(ddata->pwr_reset);
}
if (IS_ERR(ddata->pwr_reset))
return dev_err_probe(dev, PTR_ERR(ddata->pwr_reset),
"Failed to get Power Reset\n");
}
ddata->clk = devm_clk_get(dev, NULL);
if (IS_ERR(ddata->clk)) {
dev_err(dev, "Failed to get clock\n");
return PTR_ERR(ddata->clk);
}
if (IS_ERR(ddata->clk))
return dev_err_probe(dev, PTR_ERR(ddata->clk),
"Failed to get clock\n");
err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
if (err) {
@ -317,18 +314,11 @@ static int st_rproc_parse_dt(struct platform_device *pdev)
return err;
}
ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
if (IS_ERR(ddata->boot_base)) {
dev_err(dev, "Boot base not found\n");
return PTR_ERR(ddata->boot_base);
}
err = of_property_read_u32_index(np, "st,syscfg", 1,
&ddata->boot_offset);
if (err) {
dev_err(dev, "Boot offset not found\n");
return -EINVAL;
}
ddata->boot_base = syscon_regmap_lookup_by_phandle_args(np, "st,syscfg",
1, &ddata->boot_offset);
if (IS_ERR(ddata->boot_base))
return dev_err_probe(dev, PTR_ERR(ddata->boot_base),
"Boot base not found\n");
err = clk_prepare(ddata->clk);
if (err)
@ -395,32 +385,32 @@ static int st_rproc_probe(struct platform_device *pdev)
*/
chan = mbox_request_channel_byname(&ddata->mbox_client_vq0, "vq0_rx");
if (IS_ERR(chan)) {
dev_err(&rproc->dev, "failed to request mbox chan 0\n");
ret = PTR_ERR(chan);
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan),
"failed to request mbox chan 0\n");
goto free_clk;
}
ddata->mbox_chan[ST_RPROC_VQ0 * MBOX_MAX + MBOX_RX] = chan;
chan = mbox_request_channel_byname(&ddata->mbox_client_vq0, "vq0_tx");
if (IS_ERR(chan)) {
dev_err(&rproc->dev, "failed to request mbox chan 0\n");
ret = PTR_ERR(chan);
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan),
"failed to request mbox chan 0\n");
goto free_mbox;
}
ddata->mbox_chan[ST_RPROC_VQ0 * MBOX_MAX + MBOX_TX] = chan;
chan = mbox_request_channel_byname(&ddata->mbox_client_vq1, "vq1_rx");
if (IS_ERR(chan)) {
dev_err(&rproc->dev, "failed to request mbox chan 1\n");
ret = PTR_ERR(chan);
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan),
"failed to request mbox chan 1\n");
goto free_mbox;
}
ddata->mbox_chan[ST_RPROC_VQ1 * MBOX_MAX + MBOX_RX] = chan;
chan = mbox_request_channel_byname(&ddata->mbox_client_vq1, "vq1_tx");
if (IS_ERR(chan)) {
dev_err(&rproc->dev, "failed to request mbox chan 1\n");
ret = PTR_ERR(chan);
ret = dev_err_probe(&rproc->dev, PTR_ERR(chan),
"failed to request mbox chan 1\n");
goto free_mbox;
}
ddata->mbox_chan[ST_RPROC_VQ1 * MBOX_MAX + MBOX_TX] = chan;

View file

@ -955,6 +955,13 @@ out:
return ret;
}
static void k3_r5_mem_release(void *data)
{
struct device *dev = data;
of_reserved_mem_device_release(dev);
}
static int k3_r5_reserved_mem_init(struct k3_r5_rproc *kproc)
{
struct device *dev = kproc->dev;
@ -985,27 +992,25 @@ static int k3_r5_reserved_mem_init(struct k3_r5_rproc *kproc)
return ret;
}
ret = devm_add_action_or_reset(dev, k3_r5_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;
}
kproc->rmem = devm_kcalloc(dev, num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
if (!kproc->rmem)
return -ENOMEM;
/* 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);
of_node_put(rmem_np);
if (!rmem) {
ret = -EINVAL;
goto unmap_rmem;
}
if (!rmem)
return -EINVAL;
kproc->rmem[i].bus_addr = rmem->base;
/*
@ -1020,12 +1025,11 @@ static int k3_r5_reserved_mem_init(struct k3_r5_rproc *kproc)
*/
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",
@ -1036,25 +1040,6 @@ static int k3_r5_reserved_mem_init(struct k3_r5_rproc *kproc)
kproc->num_rmems = num_rmems;
return 0;
unmap_rmem:
for (i--; i >= 0; i--)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
release_rmem:
of_reserved_mem_device_release(dev);
return ret;
}
static void k3_r5_reserved_mem_exit(struct k3_r5_rproc *kproc)
{
int i;
for (i = 0; i < kproc->num_rmems; i++)
iounmap(kproc->rmem[i].cpu_addr);
kfree(kproc->rmem);
of_reserved_mem_device_release(kproc->dev);
}
/*
@ -1281,10 +1266,10 @@ init_rmem:
goto out;
}
ret = rproc_add(rproc);
ret = devm_rproc_add(dev, rproc);
if (ret) {
dev_err(dev, "rproc_add failed, ret = %d\n", ret);
goto err_add;
dev_err_probe(dev, ret, "rproc_add failed\n");
goto out;
}
/* create only one rproc in lockstep, single-cpu or
@ -1312,7 +1297,7 @@ init_rmem:
dev_err(dev,
"Timed out waiting for %s core to power up!\n",
rproc->name);
goto err_powerup;
goto out;
}
}
@ -1328,10 +1313,6 @@ err_split:
}
}
err_powerup:
rproc_del(rproc);
err_add:
k3_r5_reserved_mem_exit(kproc);
out:
/* undo core0 upon any failures on core1 in split-mode */
if (cluster->mode == CLUSTER_MODE_SPLIT && core == core1) {
@ -1374,10 +1355,6 @@ static void k3_r5_cluster_rproc_exit(void *data)
}
mbox_free_channel(kproc->mbox);
rproc_del(rproc);
k3_r5_reserved_mem_exit(kproc);
}
}
@ -1510,6 +1487,13 @@ static int k3_r5_core_of_get_sram_memories(struct platform_device *pdev,
return 0;
}
static void k3_r5_release_tsp(void *data)
{
struct ti_sci_proc *tsp = data;
ti_sci_proc_release(tsp);
}
static int k3_r5_core_of_init(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@ -1603,6 +1587,10 @@ static int k3_r5_core_of_init(struct platform_device *pdev)
goto err;
}
ret = devm_add_action_or_reset(dev, k3_r5_release_tsp, core->tsp);
if (ret)
goto err;
platform_set_drvdata(pdev, core);
devres_close_group(dev, k3_r5_core_of_init);
@ -1619,13 +1607,7 @@ err:
*/
static void k3_r5_core_of_exit(struct platform_device *pdev)
{
struct k3_r5_core *core = platform_get_drvdata(pdev);
struct device *dev = &pdev->dev;
int ret;
ret = ti_sci_proc_release(core->tsp);
if (ret)
dev_err(dev, "failed to release proc, ret = %d\n", ret);
platform_set_drvdata(pdev, NULL);
devres_release_group(dev, k3_r5_core_of_init);