This set applies on top of [1] and refactors the STM32 platform code in
order to attach to the M4 remote processor when it has been started by the
boot loader.
New to V5:
1) Added Bjorn's reviewed-by to patch 06.
2) Removed Loic's reviewed-by from patch 08, it has changed too much.
Patches that need to be reviewed: 7, 8, 9 and 10.
Tested on ST's mp157c development board.
Thanks,
Mathieu
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=314523
Mathieu Poirier (11):
remoteproc: stm32: Decouple rproc from memory translation
remoteproc: stm32: Request IRQ with platform device
remoteproc: stm32: Decouple rproc from DT parsing
remoteproc: stm32: Remove memory translation from DT parsing
remoteproc: stm32: Parse syscon that will manage M4 synchronisation
remoteproc: stm32: Properly set co-processor state when attaching
remoteproc: Make function rproc_resource_cleanup() public
remoteproc: stm32: Split function stm32_rproc_parse_fw()
remoteproc: stm32: Properly handle the resource table when attaching
remoteproc: stm32: Introduce new attach() operation
remoteproc: stm32: Update M4 state in stm32_rproc_stop()
drivers/remoteproc/remoteproc_core.c | 3 +-
drivers/remoteproc/stm32_rproc.c | 214 ++++++++++++++++++++++++---
include/linux/remoteproc.h | 1 +
3 files changed, 198 insertions(+), 20 deletions(-)
--
2.25.1
Get from the DT the syncon to probe the state of the remote processor
and the location of the resource table.
Mainly based on the work published by Arnaud Pouliquen [1].
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
Signed-off-by: Mathieu Poirier <[email protected]>
Reviewed-by: Loic Pallardy <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 986f34a336a7..961a53f67ec5 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -71,6 +71,8 @@ struct stm32_rproc {
struct reset_control *rst;
struct stm32_syscon hold_boot;
struct stm32_syscon pdds;
+ struct stm32_syscon m4_state;
+ struct stm32_syscon rsctbl;
int wdg_irq;
u32 nb_rmems;
struct stm32_rproc_mem *rmems;
@@ -607,6 +609,30 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
*auto_boot = of_property_read_bool(np, "st,auto-boot");
+ /*
+ * See if we can check the M4 status, i.e if it was started
+ * from the boot loader or not.
+ */
+ err = stm32_rproc_get_syscon(np, "st,syscfg-m4-state",
+ &ddata->m4_state);
+ if (err) {
+ /* remember this */
+ ddata->m4_state.map = NULL;
+ /* no coprocessor state syscon (optional) */
+ dev_warn(dev, "m4 state not supported\n");
+
+ /* no need to go further */
+ return 0;
+ }
+
+ /* See if we can get the resource table */
+ err = stm32_rproc_get_syscon(np, "st,syscfg-rsc-tbl",
+ &ddata->rsctbl);
+ if (err) {
+ /* no rsc table syscon (optional) */
+ dev_warn(dev, "rsc tbl syscon not supported\n");
+ }
+
return 0;
}
--
2.25.1
Make function rproc_resource_cleanup() public so that it can be
used by platform drivers when allocating resources to be used by
a detached remote processor.
Signed-off-by: Mathieu Poirier <[email protected]>
---
drivers/remoteproc/remoteproc_core.c | 3 ++-
include/linux/remoteproc.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 099c76ab198f..6e0f985e9c9a 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1271,7 +1271,7 @@ static void rproc_coredump_cleanup(struct rproc *rproc)
* This function will free all resources acquired for @rproc, and it
* is called whenever @rproc either shuts down or fails to boot.
*/
-static void rproc_resource_cleanup(struct rproc *rproc)
+void rproc_resource_cleanup(struct rproc *rproc)
{
struct rproc_mem_entry *entry, *tmp;
struct rproc_debug_trace *trace, *ttmp;
@@ -1315,6 +1315,7 @@ static void rproc_resource_cleanup(struct rproc *rproc)
rproc_coredump_cleanup(rproc);
}
+EXPORT_SYMBOL(rproc_resource_cleanup);
static int rproc_start(struct rproc *rproc, const struct firmware *fw)
{
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index cf5e31556780..7c0567029f7c 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -610,6 +610,7 @@ void rproc_put(struct rproc *rproc);
int rproc_add(struct rproc *rproc);
int rproc_del(struct rproc *rproc);
void rproc_free(struct rproc *rproc);
+void rproc_resource_cleanup(struct rproc *rproc);
struct rproc *devm_rproc_alloc(struct device *dev, const char *name,
const struct rproc_ops *ops,
--
2.25.1
Update the co-processor state in function stm32_rproc_stop() so that
it can be used in scenarios where the remoteproc core is attaching
to the M4.
Mainly based on the work published by Arnaud Pouliquen [1].
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
Signed-off-by: Mathieu Poirier <[email protected]>
Reviewed-by: Arnaud Pouliquen <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 7145cd49616e..f4da42fc0eeb 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -504,6 +504,18 @@ static int stm32_rproc_stop(struct rproc *rproc)
}
}
+ /* update coprocessor state to OFF if available */
+ if (ddata->m4_state.map) {
+ err = regmap_update_bits(ddata->m4_state.map,
+ ddata->m4_state.reg,
+ ddata->m4_state.mask,
+ M4_STATE_OFF);
+ if (err) {
+ dev_err(&rproc->dev, "failed to set copro state\n");
+ return err;
+ }
+ }
+
return 0;
}
--
2.25.1
Split function stm32_rproc_parse_fw() in two parts, the first one
to parse the memory regions and the second one to load the
resource table. That way parsing of the memory regions can be
re-used when attaching to the remote processor.
Mainly based on the work published by Arnaud Pouliquen [1].
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
Signed-off-by: Mathieu Poirier <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index cbeb5ceb15c5..9ab58fae252f 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -213,7 +213,7 @@ static int stm32_rproc_elf_load_rsc_table(struct rproc *rproc,
return 0;
}
-static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
+static int stm32_rproc_parse_memory_regions(struct rproc *rproc)
{
struct device *dev = rproc->dev.parent;
struct device_node *np = dev->of_node;
@@ -266,6 +266,16 @@ static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
index++;
}
+ return 0;
+}
+
+static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
+{
+ int ret = stm32_rproc_parse_memory_regions(rproc);
+
+ if (ret)
+ return ret;
+
return stm32_rproc_elf_load_rsc_table(rproc, fw);
}
@@ -693,15 +703,20 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
- if (state == M4_STATE_CRUN)
+ if (state == M4_STATE_CRUN) {
rproc->state = RPROC_DETACHED;
+ ret = stm32_rproc_parse_memory_regions(rproc);
+ if (ret)
+ goto free_resources;
+ }
+
rproc->has_iommu = false;
ddata->workqueue = create_workqueue(dev_name(dev));
if (!ddata->workqueue) {
dev_err(dev, "cannot create workqueue\n");
ret = -ENOMEM;
- goto free_rproc;
+ goto free_resources;
}
platform_set_drvdata(pdev, rproc);
@@ -720,6 +735,8 @@ static int stm32_rproc_probe(struct platform_device *pdev)
stm32_rproc_free_mbox(rproc);
free_wkq:
destroy_workqueue(ddata->workqueue);
+free_resources:
+ rproc_resource_cleanup(rproc);
free_rproc:
if (device_may_wakeup(dev)) {
dev_pm_clear_wake_irq(dev);
--
2.25.1
Request IRQ with platform device rather than remote proc in order to
call stm32_rproc_parse_dt() before rproc_alloc(). That way we can
know whether we need to synchronise with the MCU or not.
Signed-off-by: Mathieu Poirier <[email protected]>
Reviewed-by: Loic Pallardy <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 2973ba201c1d..c00f60d42ab6 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -262,7 +262,8 @@ static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
static irqreturn_t stm32_rproc_wdg(int irq, void *data)
{
- struct rproc *rproc = data;
+ struct platform_device *pdev = data;
+ struct rproc *rproc = platform_get_drvdata(pdev);
rproc_report_crash(rproc, RPROC_WATCHDOG);
@@ -554,7 +555,7 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev)
if (irq > 0) {
err = devm_request_irq(dev, irq, stm32_rproc_wdg, 0,
- dev_name(dev), rproc);
+ dev_name(dev), pdev);
if (err) {
dev_err(dev, "failed to request wdg irq\n");
return err;
--
2.25.1
Introduce new attach function to be used when attaching to a
remote processor.
Mainly based on the work published by Arnaud Pouliquen [1].
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
Signed-off-by: Mathieu Poirier <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 882229f3b1c9..7145cd49616e 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -460,6 +460,13 @@ static int stm32_rproc_start(struct rproc *rproc)
return stm32_rproc_set_hold_boot(rproc, true);
}
+static int stm32_rproc_attach(struct rproc *rproc)
+{
+ stm32_rproc_add_coredump_trace(rproc);
+
+ return stm32_rproc_set_hold_boot(rproc, true);
+}
+
static int stm32_rproc_stop(struct rproc *rproc)
{
struct stm32_rproc *ddata = rproc->priv;
@@ -525,6 +532,7 @@ static void stm32_rproc_kick(struct rproc *rproc, int vqid)
static struct rproc_ops st_rproc_ops = {
.start = stm32_rproc_start,
.stop = stm32_rproc_stop,
+ .attach = stm32_rproc_attach,
.kick = stm32_rproc_kick,
.load = rproc_elf_load_segments,
.parse_fw = stm32_rproc_parse_fw,
--
2.25.1
Introduce the required mechanic to set the state of the M4 in order
to properly deal with scenarios where the co-processor has been
started by another entity.
Mainly based on the work published by Arnaud Pouliquen [1].
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
Signed-off-by: Mathieu Poirier <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 961a53f67ec5..cbeb5ceb15c5 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -39,6 +39,13 @@
#define STM32_MBX_VQ1_ID 1
#define STM32_MBX_SHUTDOWN "shutdown"
+#define M4_STATE_OFF 0
+#define M4_STATE_INI 1
+#define M4_STATE_CRUN 2
+#define M4_STATE_CSTOP 3
+#define M4_STATE_STANDBY 4
+#define M4_STATE_CRASH 5
+
struct stm32_syscon {
struct regmap *map;
u32 reg;
@@ -636,12 +643,30 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
return 0;
}
+static int stm32_rproc_get_m4_status(struct stm32_rproc *ddata,
+ unsigned int *state)
+{
+ /* See stm32_rproc_parse_dt() */
+ if (!ddata->m4_state.map) {
+ /*
+ * We couldn't get the coprocessor's state, assume
+ * it is not running.
+ */
+ state = M4_STATE_OFF;
+ return 0;
+ }
+
+ return regmap_read(ddata->m4_state.map, ddata->m4_state.reg, state);
+}
+
+
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;
struct rproc *rproc;
+ unsigned int state;
int ret;
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
@@ -664,6 +689,13 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
+ ret = stm32_rproc_get_m4_status(ddata, &state);
+ if (ret)
+ goto free_rproc;
+
+ if (state == M4_STATE_CRUN)
+ rproc->state = RPROC_DETACHED;
+
rproc->has_iommu = false;
ddata->workqueue = create_workqueue(dev_name(dev));
if (!ddata->workqueue) {
--
2.25.1
Remove the remote processor from the process of parsing the memory
ranges since there is no correlation between them.
Signed-off-by: Mathieu Poirier <[email protected]>
Reviewed-by: Loic Pallardy <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 062797a447c6..2973ba201c1d 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -128,10 +128,10 @@ static int stm32_rproc_mem_release(struct rproc *rproc,
return 0;
}
-static int stm32_rproc_of_memory_translations(struct rproc *rproc)
+static int stm32_rproc_of_memory_translations(struct platform_device *pdev,
+ struct stm32_rproc *ddata)
{
- struct device *parent, *dev = rproc->dev.parent;
- struct stm32_rproc *ddata = rproc->priv;
+ struct device *parent, *dev = &pdev->dev;
struct device_node *np;
struct stm32_rproc_mem *p_mems;
struct stm32_rproc_mem_ranges *mem_range;
@@ -607,7 +607,7 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev)
rproc->auto_boot = of_property_read_bool(np, "st,auto-boot");
- return stm32_rproc_of_memory_translations(rproc);
+ return stm32_rproc_of_memory_translations(pdev, ddata);
}
static int stm32_rproc_probe(struct platform_device *pdev)
--
2.25.1
Properly set the remote processor's resource table based on where it was
loaded by the external entity when attaching to a remote processor.
Mainly based on the work published by Arnaud Pouliquen [1].
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
Signed-off-by: Mathieu Poirier <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 75 ++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 9ab58fae252f..882229f3b1c9 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -39,6 +39,8 @@
#define STM32_MBX_VQ1_ID 1
#define STM32_MBX_SHUTDOWN "shutdown"
+#define RSC_TBL_SIZE 1024
+
#define M4_STATE_OFF 0
#define M4_STATE_INI 1
#define M4_STATE_CRUN 2
@@ -86,6 +88,7 @@ struct stm32_rproc {
struct stm32_mbox mb[MBOX_NB_MBX];
struct workqueue_struct *workqueue;
bool secured_soc;
+ void __iomem *rsc_va;
};
static int stm32_rproc_pa_to_da(struct rproc *rproc, phys_addr_t pa, u64 *da)
@@ -669,6 +672,74 @@ static int stm32_rproc_get_m4_status(struct stm32_rproc *ddata,
return regmap_read(ddata->m4_state.map, ddata->m4_state.reg, state);
}
+static int stm32_rproc_da_to_pa(struct platform_device *pdev,
+ struct stm32_rproc *ddata,
+ u64 da, phys_addr_t *pa)
+{
+ struct device *dev = &pdev->dev;
+ struct stm32_rproc_mem *p_mem;
+ unsigned int i;
+
+ for (i = 0; i < ddata->nb_rmems; i++) {
+ p_mem = &ddata->rmems[i];
+
+ if (da < p_mem->dev_addr ||
+ da >= p_mem->dev_addr + p_mem->size)
+ continue;
+
+ *pa = da - p_mem->dev_addr + p_mem->bus_addr;
+ dev_dbg(dev, "da %llx to pa %#x\n", da, *pa);
+
+ return 0;
+ }
+
+ dev_err(dev, "can't translate da %llx\n", da);
+
+ return -EINVAL;
+}
+
+static int stm32_rproc_get_loaded_rsc_table(struct platform_device *pdev,
+ struct rproc *rproc,
+ struct stm32_rproc *ddata)
+{
+ struct device *dev = &pdev->dev;
+ phys_addr_t rsc_pa;
+ u32 rsc_da;
+ int err;
+
+ err = regmap_read(ddata->rsctbl.map, ddata->rsctbl.reg, &rsc_da);
+ if (err) {
+ dev_err(dev, "failed to read rsc tbl addr\n");
+ return err;
+ }
+
+ if (!rsc_da)
+ /* no rsc table */
+ return 0;
+
+ err = stm32_rproc_da_to_pa(pdev, ddata, rsc_da, &rsc_pa);
+ if (err)
+ return err;
+
+ ddata->rsc_va = devm_ioremap_wc(dev, rsc_pa, RSC_TBL_SIZE);
+ if (IS_ERR_OR_NULL(ddata->rsc_va)) {
+ dev_err(dev, "Unable to map memory region: %pa+%zx\n",
+ &rsc_pa, RSC_TBL_SIZE);
+ ddata->rsc_va = NULL;
+ return -ENOMEM;
+ }
+
+ /*
+ * The resource table is already loaded in device memory, no need
+ * to work with a cached table.
+ */
+ rproc->cached_table = NULL;
+ /* Assuming the resource table fits in 1kB is fair */
+ rproc->table_sz = RSC_TBL_SIZE;
+ rproc->table_ptr = (struct resource_table *)ddata->rsc_va;
+
+ return 0;
+}
static int stm32_rproc_probe(struct platform_device *pdev)
{
@@ -709,6 +780,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
ret = stm32_rproc_parse_memory_regions(rproc);
if (ret)
goto free_resources;
+
+ ret = stm32_rproc_get_loaded_rsc_table(pdev, rproc, ddata);
+ if (ret)
+ goto free_resources;
}
rproc->has_iommu = false;
--
2.25.1
Other than one has to be done after the other, there is no correlation
between memory translation and DT parsing. As such move function
stm32_rproc_of_memory_translations() to stm32_rproc_probe() so that
stm32_rproc_parse_dt() can be extended to look for attach bindings
in a clean way.
Signed-off-by: Mathieu Poirier <[email protected]>
Reviewed-by: Loic Pallardy <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index cbba995a80a2..986f34a336a7 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -607,7 +607,7 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
*auto_boot = of_property_read_bool(np, "st,auto-boot");
- return stm32_rproc_of_memory_translations(pdev, ddata);
+ return 0;
}
static int stm32_rproc_probe(struct platform_device *pdev)
@@ -634,6 +634,10 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;
+ ret = stm32_rproc_of_memory_translations(pdev, ddata);
+ if (ret)
+ goto free_rproc;
+
rproc->has_iommu = false;
ddata->workqueue = create_workqueue(dev_name(dev));
if (!ddata->workqueue) {
--
2.25.1
Remove the remote processor from the process of parsing the device tree
since (1) there is no correlation between them and (2) to use the
information that was gathered to make a decision on whether to
synchronise with the M4 or not.
Signed-off-by: Mathieu Poirier <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
---
drivers/remoteproc/stm32_rproc.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index c00f60d42ab6..cbba995a80a2 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -539,12 +539,11 @@ static int stm32_rproc_get_syscon(struct device_node *np, const char *prop,
return err;
}
-static int stm32_rproc_parse_dt(struct platform_device *pdev)
+static int stm32_rproc_parse_dt(struct platform_device *pdev,
+ struct stm32_rproc *ddata, bool *auto_boot)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct rproc *rproc = platform_get_drvdata(pdev);
- struct stm32_rproc *ddata = rproc->priv;
struct stm32_syscon tz;
unsigned int tzen;
int err, irq;
@@ -590,7 +589,7 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev)
err = regmap_read(tz.map, tz.reg, &tzen);
if (err) {
- dev_err(&rproc->dev, "failed to read tzen\n");
+ dev_err(dev, "failed to read tzen\n");
return err;
}
ddata->secured_soc = tzen & tz.mask;
@@ -606,7 +605,7 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev)
if (err)
dev_info(dev, "failed to get pdds\n");
- rproc->auto_boot = of_property_read_bool(np, "st,auto-boot");
+ *auto_boot = of_property_read_bool(np, "st,auto-boot");
return stm32_rproc_of_memory_translations(pdev, ddata);
}
@@ -627,9 +626,15 @@ static int stm32_rproc_probe(struct platform_device *pdev)
if (!rproc)
return -ENOMEM;
+ ddata = rproc->priv;
+
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
+
+ ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
+ if (ret)
+ goto free_rproc;
+
rproc->has_iommu = false;
- ddata = rproc->priv;
ddata->workqueue = create_workqueue(dev_name(dev));
if (!ddata->workqueue) {
dev_err(dev, "cannot create workqueue\n");
@@ -639,13 +644,9 @@ static int stm32_rproc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, rproc);
- ret = stm32_rproc_parse_dt(pdev);
- if (ret)
- goto free_wkq;
-
ret = stm32_rproc_request_mbox(rproc);
if (ret)
- goto free_rproc;
+ goto free_wkq;
ret = rproc_add(rproc);
if (ret)
--
2.25.1
Hi Mathieu,
On 7/7/20 11:31 PM, Mathieu Poirier wrote:
> Introduce the required mechanic to set the state of the M4 in order
> to properly deal with scenarios where the co-processor has been
> started by another entity.
>
> Mainly based on the work published by Arnaud Pouliquen [1].
>
> [1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
>
> Signed-off-by: Mathieu Poirier <[email protected]>
> Reviewed-by: Bjorn Andersson <[email protected]>
> ---
> drivers/remoteproc/stm32_rproc.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> index 961a53f67ec5..cbeb5ceb15c5 100644
> --- a/drivers/remoteproc/stm32_rproc.c
> +++ b/drivers/remoteproc/stm32_rproc.c
> @@ -39,6 +39,13 @@
> #define STM32_MBX_VQ1_ID 1
> #define STM32_MBX_SHUTDOWN "shutdown"
>
> +#define M4_STATE_OFF 0
> +#define M4_STATE_INI 1
> +#define M4_STATE_CRUN 2
> +#define M4_STATE_CSTOP 3
> +#define M4_STATE_STANDBY 4
> +#define M4_STATE_CRASH 5
> +
> struct stm32_syscon {
> struct regmap *map;
> u32 reg;
> @@ -636,12 +643,30 @@ static int stm32_rproc_parse_dt(struct platform_device *pdev,
> return 0;
> }
>
> +static int stm32_rproc_get_m4_status(struct stm32_rproc *ddata,
> + unsigned int *state)
> +{
> + /* See stm32_rproc_parse_dt() */
> + if (!ddata->m4_state.map) {
> + /*
> + * We couldn't get the coprocessor's state, assume
> + * it is not running.
> + */
> + state = M4_STATE_OFF;
> + return 0;
> + }
> +
> + return regmap_read(ddata->m4_state.map, ddata->m4_state.reg, state);
> +}
> +
> +
nitpicking: multiple blank lines here
> 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;
> struct rproc *rproc;
> + unsigned int state;
> int ret;
>
> ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
> @@ -664,6 +689,13 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> if (ret)
> goto free_rproc;
>
> + ret = stm32_rproc_get_m4_status(ddata, &state);
> + if (ret)
> + goto free_rproc;
> +
> + if (state == M4_STATE_CRUN)
> + rproc->state = RPROC_DETACHED;
> +
> rproc->has_iommu = false;
> ddata->workqueue = create_workqueue(dev_name(dev));
> if (!ddata->workqueue) {
>
On 7/7/20 11:31 PM, Mathieu Poirier wrote:
> Split function stm32_rproc_parse_fw() in two parts, the first one
> to parse the memory regions and the second one to load the
> resource table. That way parsing of the memory regions can be
> re-used when attaching to the remote processor.
>
> Mainly based on the work published by Arnaud Pouliquen [1].
>
> [1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=239877
>
> Signed-off-by: Mathieu Poirier <[email protected]>
> ---
> drivers/remoteproc/stm32_rproc.c | 23 ++++++++++++++++++++---
> 1 file changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
> index cbeb5ceb15c5..9ab58fae252f 100644
> --- a/drivers/remoteproc/stm32_rproc.c
> +++ b/drivers/remoteproc/stm32_rproc.c
> @@ -213,7 +213,7 @@ static int stm32_rproc_elf_load_rsc_table(struct rproc *rproc,
> return 0;
> }
>
> -static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
> +static int stm32_rproc_parse_memory_regions(struct rproc *rproc)
> {
> struct device *dev = rproc->dev.parent;
> struct device_node *np = dev->of_node;
> @@ -266,6 +266,16 @@ static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
> index++;
> }
>
> + return 0;
> +}
> +
> +static int stm32_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
> +{
> + int ret = stm32_rproc_parse_memory_regions(rproc);
> +
> + if (ret)
> + return ret;
> +
> return stm32_rproc_elf_load_rsc_table(rproc, fw);
> }
>
> @@ -693,15 +703,20 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> if (ret)
> goto free_rproc;
>
> - if (state == M4_STATE_CRUN)
> + if (state == M4_STATE_CRUN) {
> rproc->state = RPROC_DETACHED;
>
> + ret = stm32_rproc_parse_memory_regions(rproc);
> + if (ret)
> + goto free_resources;
> + }
> +
Here you do more than the split, you add the memory registration in the probe
i think updating the commit title and message should be sufficient
> rproc->has_iommu = false;
> ddata->workqueue = create_workqueue(dev_name(dev));
> if (!ddata->workqueue) {
> dev_err(dev, "cannot create workqueue\n");
> ret = -ENOMEM;
> - goto free_rproc;
> + goto free_resources;
> }
>
> platform_set_drvdata(pdev, rproc);
> @@ -720,6 +735,8 @@ static int stm32_rproc_probe(struct platform_device *pdev)
> stm32_rproc_free_mbox(rproc);
> free_wkq:
> destroy_workqueue(ddata->workqueue);
> +free_resources:
> + rproc_resource_cleanup(rproc);
> free_rproc:
> if (device_may_wakeup(dev)) {
> dev_pm_clear_wake_irq(dev);
>
On 7/7/20 11:31 PM, Mathieu Poirier wrote:
> This set applies on top of [1] and refactors the STM32 platform code in
> order to attach to the M4 remote processor when it has been started by the
> boot loader.
>
> New to V5:
> 1) Added Bjorn's reviewed-by to patch 06.
> 2) Removed Loic's reviewed-by from patch 08, it has changed too much.
>
> Patches that need to be reviewed: 7, 8, 9 and 10.
>
> Tested on ST's mp157c development board.
>
> Thanks,
> Mathieu
>
> [1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=314523
>
> Mathieu Poirier (11):
> remoteproc: stm32: Decouple rproc from memory translation
> remoteproc: stm32: Request IRQ with platform device
> remoteproc: stm32: Decouple rproc from DT parsing
> remoteproc: stm32: Remove memory translation from DT parsing
> remoteproc: stm32: Parse syscon that will manage M4 synchronisation
> remoteproc: stm32: Properly set co-processor state when attaching
> remoteproc: Make function rproc_resource_cleanup() public
> remoteproc: stm32: Split function stm32_rproc_parse_fw()
> remoteproc: stm32: Properly handle the resource table when attaching
> remoteproc: stm32: Introduce new attach() operation
> remoteproc: stm32: Update M4 state in stm32_rproc_stop()
>
> drivers/remoteproc/remoteproc_core.c | 3 +-
> drivers/remoteproc/stm32_rproc.c | 214 ++++++++++++++++++++++++---
> include/linux/remoteproc.h | 1 +
> 3 files changed, 198 insertions(+), 20 deletions(-)
>
I tested the series with the [1]
Minor remarks on patch 6 & 8. After fixing them, for the series:
Acked-by: Arnaud Pouliquen <[email protected]>
Thank you very much for your work on this feature.
Arnaud
Hi Mathieu,
I love your patch! Yet something to improve:
[auto build test ERROR on linux/master]
[also build test ERROR on linus/master v5.8-rc5 next-20200714]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Mathieu-Poirier/remoteproc-stm32-Add-support-for-attaching-to-M4/20200708-053515
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9ebcfadb0610322ac537dd7aa5d9cbc2b2894c68
config: arm-randconfig-r011-20200714 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 02946de3802d3bc65bc9f2eb9b8d4969b5a7add8)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install arm cross compiling tool for clang build
# apt-get install binutils-arm-linux-gnueabi
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All errors (new ones prefixed by >>):
>> drivers/remoteproc/stm32_rproc.c:697:18: error: use of undeclared identifier 'RPROC_DETACHED'
rproc->state = RPROC_DETACHED;
^
1 error generated.
vim +/RPROC_DETACHED +697 drivers/remoteproc/stm32_rproc.c
661
662
663 static int stm32_rproc_probe(struct platform_device *pdev)
664 {
665 struct device *dev = &pdev->dev;
666 struct stm32_rproc *ddata;
667 struct device_node *np = dev->of_node;
668 struct rproc *rproc;
669 unsigned int state;
670 int ret;
671
672 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
673 if (ret)
674 return ret;
675
676 rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
677 if (!rproc)
678 return -ENOMEM;
679
680 ddata = rproc->priv;
681
682 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
683
684 ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
685 if (ret)
686 goto free_rproc;
687
688 ret = stm32_rproc_of_memory_translations(pdev, ddata);
689 if (ret)
690 goto free_rproc;
691
692 ret = stm32_rproc_get_m4_status(ddata, &state);
693 if (ret)
694 goto free_rproc;
695
696 if (state == M4_STATE_CRUN)
> 697 rproc->state = RPROC_DETACHED;
698
699 rproc->has_iommu = false;
700 ddata->workqueue = create_workqueue(dev_name(dev));
701 if (!ddata->workqueue) {
702 dev_err(dev, "cannot create workqueue\n");
703 ret = -ENOMEM;
704 goto free_rproc;
705 }
706
707 platform_set_drvdata(pdev, rproc);
708
709 ret = stm32_rproc_request_mbox(rproc);
710 if (ret)
711 goto free_wkq;
712
713 ret = rproc_add(rproc);
714 if (ret)
715 goto free_mb;
716
717 return 0;
718
719 free_mb:
720 stm32_rproc_free_mbox(rproc);
721 free_wkq:
722 destroy_workqueue(ddata->workqueue);
723 free_rproc:
724 if (device_may_wakeup(dev)) {
725 dev_pm_clear_wake_irq(dev);
726 device_init_wakeup(dev, false);
727 }
728 rproc_free(rproc);
729 return ret;
730 }
731
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]
Hi Robot,
On Tue, 14 Jul 2020 at 14:31, kernel test robot <[email protected]> wrote:
>
> Hi Mathieu,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on linux/master]
> [also build test ERROR on linus/master v5.8-rc5 next-20200714]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url: https://github.com/0day-ci/linux/commits/Mathieu-Poirier/remoteproc-stm32-Add-support-for-attaching-to-M4/20200708-053515
> base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9ebcfadb0610322ac537dd7aa5d9cbc2b2894c68
> config: arm-randconfig-r011-20200714 (attached as .config)
> compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 02946de3802d3bc65bc9f2eb9b8d4969b5a7add8)
> reproduce (this is a W=1 build):
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # install arm cross compiling tool for clang build
> # apt-get install binutils-arm-linux-gnueabi
> # save the attached .config to linux build tree
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <[email protected]>
>
> All errors (new ones prefixed by >>):
>
> >> drivers/remoteproc/stm32_rproc.c:697:18: error: use of undeclared identifier 'RPROC_DETACHED'
> rproc->state = RPROC_DETACHED;
> ^
> 1 error generated.
This patchset depends on this one [1], something that is clearly
stated in the cover letter. Compiling this set on top of [1]
generates no error.
[1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=318275
>
> vim +/RPROC_DETACHED +697 drivers/remoteproc/stm32_rproc.c
>
> 661
> 662
> 663 static int stm32_rproc_probe(struct platform_device *pdev)
> 664 {
> 665 struct device *dev = &pdev->dev;
> 666 struct stm32_rproc *ddata;
> 667 struct device_node *np = dev->of_node;
> 668 struct rproc *rproc;
> 669 unsigned int state;
> 670 int ret;
> 671
> 672 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
> 673 if (ret)
> 674 return ret;
> 675
> 676 rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> 677 if (!rproc)
> 678 return -ENOMEM;
> 679
> 680 ddata = rproc->priv;
> 681
> 682 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
> 683
> 684 ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
> 685 if (ret)
> 686 goto free_rproc;
> 687
> 688 ret = stm32_rproc_of_memory_translations(pdev, ddata);
> 689 if (ret)
> 690 goto free_rproc;
> 691
> 692 ret = stm32_rproc_get_m4_status(ddata, &state);
> 693 if (ret)
> 694 goto free_rproc;
> 695
> 696 if (state == M4_STATE_CRUN)
> > 697 rproc->state = RPROC_DETACHED;
> 698
> 699 rproc->has_iommu = false;
> 700 ddata->workqueue = create_workqueue(dev_name(dev));
> 701 if (!ddata->workqueue) {
> 702 dev_err(dev, "cannot create workqueue\n");
> 703 ret = -ENOMEM;
> 704 goto free_rproc;
> 705 }
> 706
> 707 platform_set_drvdata(pdev, rproc);
> 708
> 709 ret = stm32_rproc_request_mbox(rproc);
> 710 if (ret)
> 711 goto free_wkq;
> 712
> 713 ret = rproc_add(rproc);
> 714 if (ret)
> 715 goto free_mb;
> 716
> 717 return 0;
> 718
> 719 free_mb:
> 720 stm32_rproc_free_mbox(rproc);
> 721 free_wkq:
> 722 destroy_workqueue(ddata->workqueue);
> 723 free_rproc:
> 724 if (device_may_wakeup(dev)) {
> 725 dev_pm_clear_wake_irq(dev);
> 726 device_init_wakeup(dev, false);
> 727 }
> 728 rproc_free(rproc);
> 729 return ret;
> 730 }
> 731
>
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/[email protected]
On 7/16/20 6:19 AM, Mathieu Poirier wrote:
> Hi Robot,
>
> On Tue, 14 Jul 2020 at 14:31, kernel test robot <[email protected]> wrote:
>> Hi Mathieu,
>>
>> I love your patch! Yet something to improve:
>>
>> [auto build test ERROR on linux/master]
>> [also build test ERROR on linus/master v5.8-rc5 next-20200714]
>> [If your patch is applied to the wrong git tree, kindly drop us a note.
>> And when submitting patch, we suggest to use as documented in
>> https://git-scm.com/docs/git-format-patch]
>>
>> url: https://github.com/0day-ci/linux/commits/Mathieu-Poirier/remoteproc-stm32-Add-support-for-attaching-to-M4/20200708-053515
>> base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 9ebcfadb0610322ac537dd7aa5d9cbc2b2894c68
>> config: arm-randconfig-r011-20200714 (attached as .config)
>> compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 02946de3802d3bc65bc9f2eb9b8d4969b5a7add8)
>> reproduce (this is a W=1 build):
>> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>> chmod +x ~/bin/make.cross
>> # install arm cross compiling tool for clang build
>> # apt-get install binutils-arm-linux-gnueabi
>> # save the attached .config to linux build tree
>> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm
>>
>> If you fix the issue, kindly add following tag as appropriate
>> Reported-by: kernel test robot <[email protected]>
>>
>> All errors (new ones prefixed by >>):
>>
>>>> drivers/remoteproc/stm32_rproc.c:697:18: error: use of undeclared identifier 'RPROC_DETACHED'
>> rproc->state = RPROC_DETACHED;
>> ^
>> 1 error generated.
> This patchset depends on this one [1], something that is clearly
> stated in the cover letter. Compiling this set on top of [1]
> generates no error.
>
> [1]. https://patchwork.kernel.org/project/linux-remoteproc/list/?series=318275
Hi Mathieu,
Thanks for the feedback, the bot can't parse the base which links to another patchset,
and we can get the base commit if using 'git format-patch --base' to submit patch.
Best Regards,
Rong Chen
>
>> vim +/RPROC_DETACHED +697 drivers/remoteproc/stm32_rproc.c
>>
>> 661
>> 662
>> 663 static int stm32_rproc_probe(struct platform_device *pdev)
>> 664 {
>> 665 struct device *dev = &pdev->dev;
>> 666 struct stm32_rproc *ddata;
>> 667 struct device_node *np = dev->of_node;
>> 668 struct rproc *rproc;
>> 669 unsigned int state;
>> 670 int ret;
>> 671
>> 672 ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
>> 673 if (ret)
>> 674 return ret;
>> 675
>> 676 rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
>> 677 if (!rproc)
>> 678 return -ENOMEM;
>> 679
>> 680 ddata = rproc->priv;
>> 681
>> 682 rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
>> 683
>> 684 ret = stm32_rproc_parse_dt(pdev, ddata, &rproc->auto_boot);
>> 685 if (ret)
>> 686 goto free_rproc;
>> 687
>> 688 ret = stm32_rproc_of_memory_translations(pdev, ddata);
>> 689 if (ret)
>> 690 goto free_rproc;
>> 691
>> 692 ret = stm32_rproc_get_m4_status(ddata, &state);
>> 693 if (ret)
>> 694 goto free_rproc;
>> 695
>> 696 if (state == M4_STATE_CRUN)
>> > 697 rproc->state = RPROC_DETACHED;
>> 698
>> 699 rproc->has_iommu = false;
>> 700 ddata->workqueue = create_workqueue(dev_name(dev));
>> 701 if (!ddata->workqueue) {
>> 702 dev_err(dev, "cannot create workqueue\n");
>> 703 ret = -ENOMEM;
>> 704 goto free_rproc;
>> 705 }
>> 706
>> 707 platform_set_drvdata(pdev, rproc);
>> 708
>> 709 ret = stm32_rproc_request_mbox(rproc);
>> 710 if (ret)
>> 711 goto free_wkq;
>> 712
>> 713 ret = rproc_add(rproc);
>> 714 if (ret)
>> 715 goto free_mb;
>> 716
>> 717 return 0;
>> 718
>> 719 free_mb:
>> 720 stm32_rproc_free_mbox(rproc);
>> 721 free_wkq:
>> 722 destroy_workqueue(ddata->workqueue);
>> 723 free_rproc:
>> 724 if (device_may_wakeup(dev)) {
>> 725 dev_pm_clear_wake_irq(dev);
>> 726 device_init_wakeup(dev, false);
>> 727 }
>> 728 rproc_free(rproc);
>> 729 return ret;
>> 730 }
>> 731
>>
>> ---
>> 0-DAY CI Kernel Test Service, Intel Corporation
>> https://lists.01.org/hyperkitty/list/[email protected]
> _______________________________________________
> kbuild-all mailing list -- [email protected]
> To unsubscribe send an email to [email protected]