Re: [PATCH v2 1/1] remoteproc: add support for co-processor booted before kernel

From: Bjorn Andersson
Date: Fri Nov 08 2019 - 20:20:46 EST


On Mon 04 Nov 02:49 PST 2019, Loic Pallardy wrote:

> Remote processor could boot independently or be started before Linux
> kernel by bootloader or any firmware.
> This patch introduces a new property in rproc core, named preloaded,
> to be able to allocate resources and sub-devices like vdev and to
> synchronize with current state without loading firmware from file system.
> It is platform driver responsibility to implement the right firmware
> load ops according to HW specificities.
>

Is it just preloaded or already started?

> Signed-off-by: Loic Pallardy <loic.pallardy@xxxxxx>
>
> ---
> Change from v1:
> - Keep bool in struct rproc
> ---
> drivers/remoteproc/remoteproc_core.c | 37 +++++++++++++++++++++++++++---------
> include/linux/remoteproc.h | 2 ++
> 2 files changed, 30 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> index 3c5fbbbfb0f1..7eaf0f949afa 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -1372,7 +1372,11 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
> if (ret)
> return ret;
>
> - dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
> + if (fw)
> + dev_info(dev, "Booting fw image %s, size %zd\n", name,
> + fw->size);
> + else
> + dev_info(dev, "Synchronizing with preloaded co-processor\n");
>
> /*
> * if enabling an IOMMU isn't relevant for this rproc, this is
> @@ -1728,7 +1732,7 @@ static void rproc_crash_handler_work(struct work_struct *work)
> */
> int rproc_boot(struct rproc *rproc)
> {
> - const struct firmware *firmware_p;
> + const struct firmware *firmware_p = NULL;
> struct device *dev;
> int ret;
>
> @@ -1759,11 +1763,17 @@ int rproc_boot(struct rproc *rproc)
>
> dev_info(dev, "powering up %s\n", rproc->name);
>
> - /* load firmware */
> - ret = request_firmware(&firmware_p, rproc->firmware, dev);
> - if (ret < 0) {
> - dev_err(dev, "request_firmware failed: %d\n", ret);
> - goto downref_rproc;
> + if (!rproc->preloaded) {
> + /* load firmware */
> + ret = request_firmware(&firmware_p, rproc->firmware, dev);
> + if (ret < 0) {
> + dev_err(dev, "request_firmware failed: %d\n", ret);
> + goto downref_rproc;
> + }
> + } else {
> + /* set firmware name to null as unknown */
> + kfree(rproc->firmware);
> + rproc->firmware = NULL;

What happens when the remoteproc crashes? What happens if I stop it and
try to start it again?

> }
>
> ret = rproc_fw_boot(rproc, firmware_p);
> @@ -1917,8 +1927,17 @@ int rproc_add(struct rproc *rproc)
> /* create debugfs entries */
> rproc_create_debug_dir(rproc);
>
> - /* if rproc is marked always-on, request it to boot */
> - if (rproc->auto_boot) {
> + if (rproc->preloaded) {
> + /*
> + * If rproc is marked already booted, no need to wait
> + * for firmware.
> + * Just handle associated resources and start sub devices
> + */
> + ret = rproc_boot(rproc);

This will trickle down to your remoteproc driver's start() callback. If
you really mean that "preloaded" means "already started", then I presume
you're having some logic in your start() to turn it into a nop?

> + if (ret < 0)
> + return ret;
> + } else if (rproc->auto_boot) {
> + /* if rproc is marked always-on, request it to boot */
> ret = rproc_trigger_auto_boot(rproc);
> if (ret < 0)
> return ret;
> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> index 16ad66683ad0..b68fbd576a77 100644
> --- a/include/linux/remoteproc.h
> +++ b/include/linux/remoteproc.h
> @@ -479,6 +479,7 @@ struct rproc_dump_segment {
> * @table_sz: size of @cached_table
> * @has_iommu: flag to indicate if remote processor is behind an MMU
> * @auto_boot: flag to indicate if remote processor should be auto-started
> + * @preloaded: remote processor has been preloaded before start sequence

I think this should be "skip_firmware_load", or if you really mean that
the bootloader started the remote process perhaps this should be
"@fw_booted: remote processor was booted by firmware" (or something
similar).

Regards,
Bjorn

> * @dump_segments: list of segments in the firmware
> * @nb_vdev: number of vdev currently handled by rproc
> */
> @@ -512,6 +513,7 @@ struct rproc {
> size_t table_sz;
> bool has_iommu;
> bool auto_boot;
> + bool preloaded;
> struct list_head dump_segments;
> int nb_vdev;
> };
> --
> 2.7.4
>