diff options
Diffstat (limited to 'drivers/remoteproc/stm32_rproc.c')
| -rw-r--r-- | drivers/remoteproc/stm32_rproc.c | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index cf073bac79f7..c28679d3b43c 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -12,9 +12,9 @@ #include <linux/mailbox_client.h> #include <linux/mfd/syscon.h> #include <linux/module.h> -#include <linux/of_address.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/of_reserved_mem.h> +#include <linux/platform_device.h> #include <linux/pm_wakeirq.h> #include <linux/regmap.h> #include <linux/remoteproc.h> @@ -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; } @@ -213,60 +213,52 @@ static int stm32_rproc_prepare(struct rproc *rproc) { struct device *dev = rproc->dev.parent; struct device_node *np = dev->of_node; - struct of_phandle_iterator it; struct rproc_mem_entry *mem; - struct reserved_mem *rmem; u64 da; - int index = 0; + int index = 0, mr = 0; /* Register associated reserved memory regions */ - of_phandle_iterator_init(&it, np, "memory-region", NULL, 0); - while (of_phandle_iterator_next(&it) == 0) { - rmem = of_reserved_mem_lookup(it.node); - if (!rmem) { - of_node_put(it.node); - dev_err(dev, "unable to acquire memory-region\n"); - return -EINVAL; - } + while (1) { + struct resource res; + int ret; - if (stm32_rproc_pa_to_da(rproc, rmem->base, &da) < 0) { - of_node_put(it.node); - dev_err(dev, "memory region not valid %pa\n", - &rmem->base); + ret = of_reserved_mem_region_to_resource(np, mr++, &res); + if (ret) + return 0; + + if (stm32_rproc_pa_to_da(rproc, res.start, &da) < 0) { + dev_err(dev, "memory region not valid %pR\n", &res); return -EINVAL; } /* No need to map vdev buffer */ - if (strcmp(it.node->name, "vdev0buffer")) { + if (!strstarts(res.name, "vdev0buffer")) { /* Register memory region */ mem = rproc_mem_entry_init(dev, NULL, - (dma_addr_t)rmem->base, - rmem->size, da, + (dma_addr_t)res.start, + resource_size(&res), da, stm32_rproc_mem_alloc, stm32_rproc_mem_release, - it.node->name); - + "%.*s", strchrnul(res.name, '@') - res.name, + res.name); if (mem) rproc_coredump_add_segment(rproc, da, - rmem->size); + resource_size(&res)); } else { /* Register reserved memory for vdev buffer alloc */ mem = rproc_of_resm_mem_entry_init(dev, index, - rmem->size, - rmem->base, - it.node->name); + resource_size(&res), + res.start, + "vdev0buffer"); } if (!mem) { - of_node_put(it.node); return -ENOMEM; } rproc_add_carveout(rproc, mem); index++; } - - return 0; } static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) @@ -294,7 +286,7 @@ static void stm32_rproc_mb_vq_work(struct work_struct *work) mutex_lock(&rproc->lock); - if (rproc->state != RPROC_RUNNING) + if (rproc->state != RPROC_RUNNING && rproc->state != RPROC_ATTACHED) goto unlock_mutex; if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) @@ -657,7 +649,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 = { @@ -712,9 +704,9 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev, unsigned int tzen; int err, irq; - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); if (irq == -EPROBE_DEFER) - return dev_err_probe(dev, irq, "failed to get interrupt\n"); + return irq; if (irq > 0) { err = devm_request_irq(dev, irq, stm32_rproc_wdg, 0, @@ -835,6 +827,7 @@ static int stm32_rproc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct stm32_rproc *ddata; struct device_node *np = dev->of_node; + const char *fw_name; struct rproc *rproc; unsigned int state; int ret; @@ -843,7 +836,12 @@ 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)); + /* Look for an optional firmware name */ + ret = rproc_of_parse_firmware(dev, 0, &fw_name); + if (ret < 0 && ret != -EINVAL) + return ret; + + rproc = devm_rproc_alloc(dev, np->name, &st_rproc_ops, fw_name, sizeof(*ddata)); if (!rproc) return -ENOMEM; @@ -897,7 +895,6 @@ free_rproc: dev_pm_clear_wake_irq(dev); device_init_wakeup(dev, false); } - rproc_free(rproc); return ret; } @@ -918,10 +915,9 @@ 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 __maybe_unused stm32_rproc_suspend(struct device *dev) +static int stm32_rproc_suspend(struct device *dev) { struct rproc *rproc = dev_get_drvdata(dev); struct stm32_rproc *ddata = rproc->priv; @@ -932,7 +928,7 @@ static int __maybe_unused stm32_rproc_suspend(struct device *dev) return 0; } -static int __maybe_unused stm32_rproc_resume(struct device *dev) +static int stm32_rproc_resume(struct device *dev) { struct rproc *rproc = dev_get_drvdata(dev); struct stm32_rproc *ddata = rproc->priv; @@ -943,16 +939,16 @@ static int __maybe_unused stm32_rproc_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops, - stm32_rproc_suspend, stm32_rproc_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops, + stm32_rproc_suspend, stm32_rproc_resume); static struct platform_driver stm32_rproc_driver = { .probe = stm32_rproc_probe, - .remove_new = stm32_rproc_remove, + .remove = stm32_rproc_remove, .driver = { .name = "stm32-rproc", - .pm = &stm32_rproc_pm_ops, - .of_match_table = of_match_ptr(stm32_rproc_match), + .pm = pm_ptr(&stm32_rproc_pm_ops), + .of_match_table = stm32_rproc_match, }, }; module_platform_driver(stm32_rproc_driver); |
