OSDN Git Service

remoteproc: stm32: add capability to detach
authorArnaud Pouliquen <arnaud.pouliquen@foss.st.com>
Wed, 31 Mar 2021 07:33:47 +0000 (09:33 +0200)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Wed, 14 Apr 2021 14:59:21 +0000 (09:59 -0500)
A mechanism similar to the shutdown mailbox signal is implemented to
detach a remote processor.

Upon detachment, a signal is sent to the remote firmware, allowing it
to perform specific actions such as stopping rpmsg communication.

The Cortex-M hold boot is also disabled to allow the remote processor
to restart in case of crash.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Tested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Link: https://lore.kernel.org/r/20210331073347.8293-3-arnaud.pouliquen@foss.st.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/remoteproc/stm32_rproc.c

index 3d45f51..7353f9e 100644 (file)
@@ -28,7 +28,7 @@
 #define RELEASE_BOOT           1
 
 #define MBOX_NB_VQ             2
-#define MBOX_NB_MBX            3
+#define MBOX_NB_MBX            4
 
 #define STM32_SMC_RCC          0x82001000
 #define STM32_SMC_REG_WRITE    0x1
@@ -38,6 +38,7 @@
 #define STM32_MBX_VQ1          "vq1"
 #define STM32_MBX_VQ1_ID       1
 #define STM32_MBX_SHUTDOWN     "shutdown"
+#define STM32_MBX_DETACH       "detach"
 
 #define RSC_TBL_SIZE           1024
 
@@ -336,6 +337,15 @@ static const struct stm32_mbox stm32_rproc_mbox[MBOX_NB_MBX] = {
                        .tx_done = NULL,
                        .tx_tout = 500, /* 500 ms time out */
                },
+       },
+       {
+               .name = STM32_MBX_DETACH,
+               .vq_id = -1,
+               .client = {
+                       .tx_block = true,
+                       .tx_done = NULL,
+                       .tx_tout = 200, /* 200 ms time out to detach should be fair enough */
+               },
        }
 };
 
@@ -461,6 +471,25 @@ static int stm32_rproc_attach(struct rproc *rproc)
        return stm32_rproc_set_hold_boot(rproc, true);
 }
 
+static int stm32_rproc_detach(struct rproc *rproc)
+{
+       struct stm32_rproc *ddata = rproc->priv;
+       int err, dummy_data, idx;
+
+       /* Inform the remote processor of the detach */
+       idx = stm32_rproc_mbox_idx(rproc, STM32_MBX_DETACH);
+       if (idx >= 0 && ddata->mb[idx].chan) {
+               /* A dummy data is sent to allow to block on transmit */
+               err = mbox_send_message(ddata->mb[idx].chan,
+                                       &dummy_data);
+               if (err < 0)
+                       dev_warn(&rproc->dev, "warning: remote FW detach without ack\n");
+       }
+
+       /* Allow remote processor to auto-reboot */
+       return stm32_rproc_set_hold_boot(rproc, false);
+}
+
 static int stm32_rproc_stop(struct rproc *rproc)
 {
        struct stm32_rproc *ddata = rproc->priv;
@@ -597,7 +626,12 @@ stm32_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
        }
 
 done:
-       /* Assuming the resource table fits in 1kB is fair */
+       /*
+        * Assuming the resource table fits in 1kB is fair.
+        * Notice for the detach, that this 1 kB memory area has to be reserved in the coprocessor
+        * firmware for the resource table. On detach, the remoteproc core re-initializes this
+        * 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;
 }
@@ -607,6 +641,7 @@ static const struct rproc_ops st_rproc_ops = {
        .start          = stm32_rproc_start,
        .stop           = stm32_rproc_stop,
        .attach         = stm32_rproc_attach,
+       .detach         = stm32_rproc_detach,
        .kick           = stm32_rproc_kick,
        .load           = rproc_elf_load_segments,
        .parse_fw       = stm32_rproc_parse_fw,