summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 3440283)
raw | patch | inline | side by side (parent: 3440283)
author | Suman Anna <s-anna@ti.com> | |
Thu, 1 Mar 2018 00:11:56 +0000 (18:11 -0600) | ||
committer | Suman Anna <s-anna@ti.com> | |
Mon, 11 Mar 2019 16:57:24 +0000 (11:57 -0500) |
This reverts commit 1efa30d0895e7e9a58a59b0880b330b38245be68.
The commit 1efa30d0895e ("remoteproc: Introduce rproc_{start,stop}()
functions") has refactored code out from rproc_boot() and rproc_shutdown()
to optimize resource allocation overheads during the recovery. This
patch was made with an implicit assumption that the same firmware
image will always be used during recovery (rightfully so in a product
environment), and so the resources will also remain the same. The patch
had also changed the rproc state to RPROC_OFFLINE prior to cleaning up
all resources and disabling the MMU in rproc_shutdown(). This does not
play nice with doing any additional processing steps during recovery
in the resource cleanup function.
This patch is a custom revert of the above commit, accounting for all
the changes added to the rproc_start() and rproc_stop() functions since
kernel v4.13 and some additional changes added in commit 20afed1b45bf
("remoteproc: add infrastructure support to allow pre-loaded remoteprocs")
and commit 2794d1693b05 ("remoteproc: Add support to handle device
specific resource types") thereby allowing a new last trace mechanism
to be supported in a subsequent patch.
Signed-off-by: Suman Anna <s-anna@ti.com>
The commit 1efa30d0895e ("remoteproc: Introduce rproc_{start,stop}()
functions") has refactored code out from rproc_boot() and rproc_shutdown()
to optimize resource allocation overheads during the recovery. This
patch was made with an implicit assumption that the same firmware
image will always be used during recovery (rightfully so in a product
environment), and so the resources will also remain the same. The patch
had also changed the rproc state to RPROC_OFFLINE prior to cleaning up
all resources and disabling the MMU in rproc_shutdown(). This does not
play nice with doing any additional processing steps during recovery
in the resource cleanup function.
This patch is a custom revert of the above commit, accounting for all
the changes added to the rproc_start() and rproc_stop() functions since
kernel v4.13 and some additional changes added in commit 20afed1b45bf
("remoteproc: add infrastructure support to allow pre-loaded remoteprocs")
and commit 2794d1693b05 ("remoteproc: Add support to handle device
specific resource types") thereby allowing a new last trace mechanism
to be supported in a subsequent patch.
Signed-off-by: Suman Anna <s-anna@ti.com>
drivers/remoteproc/remoteproc_core.c | patch | blob | history |
index 00a6e855784cd7e276646320f7f332d0f54fd113..7e4ff372f2fa8713baf4656f742ad51fa97f6c24 100644 (file)
rproc_coredump_cleanup(rproc);
}
-static int rproc_start(struct rproc *rproc, const struct firmware *fw)
+/*
+ * take a firmware and boot a remote processor with it.
+ */
+static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
{
- struct resource_table *loaded_table;
struct device *dev = &rproc->dev;
+ const char *name = rproc->firmware;
+ struct resource_table *loaded_table;
int ret;
+ ret = rproc_fw_sanity_check(rproc, fw);
+ if (ret)
+ return ret;
+
+ if (!rproc->skip_firmware_request)
+ dev_info(dev, "Booting fw image %s, size %zd\n",
+ name, fw->size);
+ else
+ dev_info(dev, "Booting unspecified pre-loaded fw image\n");
+
+ /*
+ * if enabling an IOMMU isn't relevant for this rproc, this is
+ * just a nop
+ */
+ ret = rproc_enable_iommu(rproc);
+ if (ret) {
+ dev_err(dev, "can't enable iommu: %d\n", ret);
+ return ret;
+ }
+
+ rproc->bootaddr = rproc_get_boot_addr(rproc, fw);
+
+ /* Load resource table, core dump segment list etc from the firmware */
+ ret = rproc_parse_fw(rproc, fw);
+ if (ret)
+ goto disable_iommu;
+
+ /* reset max_notifyid */
+ rproc->max_notifyid = -1;
+
+ /* handle fw resources which are required to boot rproc */
+ ret = rproc_handle_resources(rproc, rproc_loading_handlers);
+ if (ret) {
+ dev_err(dev, "Failed to process resources: %d\n", ret);
+ goto clean_up_resources;
+ }
+
if (!rproc->skip_load) {
/* load the ELF segments to memory */
ret = rproc_load_segments(rproc, fw);
if (ret) {
dev_err(dev, "Failed to load program segments: %d\n",
ret);
- return ret;
+ goto clean_up_resources;
}
}
rproc_unprepare_subdevices(rproc);
reset_table_ptr:
rproc->table_ptr = rproc->cached_table;
-
- return ret;
-}
-
-/*
- * take a firmware and boot a remote processor with it.
- */
-static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
-{
- struct device *dev = &rproc->dev;
- const char *name = rproc->firmware;
- int ret;
-
- ret = rproc_fw_sanity_check(rproc, fw);
- if (ret)
- return ret;
-
- if (!rproc->skip_firmware_request)
- dev_info(dev, "Booting fw image %s, size %zd\n",
- name, fw->size);
- else
- dev_info(dev, "Booting unspecified pre-loaded fw image\n");
-
- /*
- * if enabling an IOMMU isn't relevant for this rproc, this is
- * just a nop
- */
- ret = rproc_enable_iommu(rproc);
- if (ret) {
- dev_err(dev, "can't enable iommu: %d\n", ret);
- return ret;
- }
-
- rproc->bootaddr = rproc_get_boot_addr(rproc, fw);
-
- /* Load resource table, core dump segment list etc from the firmware */
- ret = rproc_parse_fw(rproc, fw);
- if (ret)
- goto disable_iommu;
-
- /* reset max_notifyid */
- rproc->max_notifyid = -1;
-
- /* handle fw resources which are required to boot rproc */
- ret = rproc_handle_resources(rproc, rproc_loading_handlers);
- if (ret) {
- dev_err(dev, "Failed to process resources: %d\n", ret);
- goto clean_up_resources;
- }
-
- ret = rproc_start(rproc, fw);
- if (ret)
- goto clean_up_resources;
-
- return 0;
-
clean_up_resources:
rproc_resource_cleanup(rproc);
kfree(rproc->cached_table);
rproc->cached_table = NULL;
rproc->table_ptr = NULL;
+ rproc->table_sz = 0;
disable_iommu:
rproc_disable_iommu(rproc);
return ret;
return ret;
}
-static int rproc_stop(struct rproc *rproc, bool crashed)
-{
- struct device *dev = &rproc->dev;
- int ret;
-
- /* Stop any subdevices for the remote processor */
- rproc_stop_subdevices(rproc, crashed);
-
- /* the installed resource table is no longer accessible */
- rproc->table_ptr = rproc->cached_table;
-
- /* power off the remote processor */
- ret = rproc->ops->stop(rproc);
- if (ret) {
- dev_err(dev, "can't stop rproc: %d\n", ret);
- return ret;
- }
-
- rproc_unprepare_subdevices(rproc);
-
- /* if in crash state, perform coredump and unlock crash handler */
- if (rproc->state == RPROC_CRASHED) {
- rproc_coredump(rproc);
-
- complete_all(&rproc->crash_comp);
- }
-
- rproc->state = RPROC_OFFLINE;
-
- dev_info(dev, "stopped remote processor %s\n", rproc->name);
-
- return 0;
-}
-
/**
* rproc_coredump_add_segment() - add segment of device memory to coredump
* @rproc: handle of a remote processor
{
struct device *dev = &rproc->dev;
int ret;
+ bool crashed = false;
ret = mutex_lock_interruptible(&rproc->lock);
if (ret) {
if (!atomic_dec_and_test(&rproc->power))
goto out;
- ret = rproc_stop(rproc, false);
+ if (rproc->state == RPROC_CRASHED)
+ crashed = true;
+
+ /* remove any subdevices for the remote processor */
+ rproc_stop_subdevices(rproc, crashed);
+
+ /* power off the remote processor */
+ ret = rproc->ops->stop(rproc);
if (ret) {
atomic_inc(&rproc->power);
+ dev_err(dev, "can't stop rproc: %d\n", ret);
goto out;
}
+ rproc_unprepare_subdevices(rproc);
+
+ /* generate coredump */
+ if (rproc->state == RPROC_CRASHED)
+ rproc_coredump(rproc);
+
+ /* the installed resource table may no longer be accessible */
+ rproc->table_ptr = rproc->cached_table;
+
/* clean up all acquired resources */
rproc_resource_cleanup(rproc);
kfree(rproc->cached_table);
rproc->cached_table = NULL;
rproc->table_ptr = NULL;
+
+ /* if in crash state, unlock crash handler */
+ if (rproc->state == RPROC_CRASHED)
+ complete_all(&rproc->crash_comp);
+
+ rproc->state = RPROC_OFFLINE;
+
+ dev_info(dev, "stopped remote processor %s\n", rproc->name);
+
out:
mutex_unlock(&rproc->lock);
}