aboutsummaryrefslogtreecommitdiff
path: root/drivers/remoteproc/remoteproc_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/remoteproc/remoteproc_core.c')
-rw-r--r--drivers/remoteproc/remoteproc_core.c44
1 files changed, 26 insertions, 18 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 8b3130f22b42..39656aa723b6 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -57,6 +57,8 @@ static DEFINE_IDA(rproc_dev_index);
static const char * const rproc_crash_names[] = {
[RPROC_MMUFAULT] = "mmufault",
+ [RPROC_WATCHDOG] = "watchdog",
+ [RPROC_FATAL_ERROR] = "fatal error",
};
/* translate rproc_crash_type to string */
@@ -789,6 +791,8 @@ static void rproc_resource_cleanup(struct rproc *rproc)
}
}
+static int __rproc_fw_config_virtio(struct rproc *rproc, const struct firmware *fw);
+
/*
* take a firmware and boot a remote processor with it.
*/
@@ -799,13 +803,16 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
struct resource_table *table, *loaded_table;
int ret, tablesz;
- if (!rproc->table_ptr)
- return -ENOMEM;
-
ret = rproc_fw_sanity_check(rproc, fw);
if (ret)
return ret;
+ if (!rproc->table_ptr) {
+ ret = __rproc_fw_config_virtio(rproc, fw);
+ if (ret)
+ return ret;
+ }
+
dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size);
/*
@@ -854,12 +861,8 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
* copy this information to device memory.
*/
loaded_table = rproc_find_loaded_rsc_table(rproc, fw);
- if (!loaded_table) {
- ret = -EINVAL;
- goto clean_up;
- }
-
- memcpy(loaded_table, rproc->cached_table, tablesz);
+ if (loaded_table)
+ memcpy(loaded_table, rproc->cached_table, tablesz);
/* power up the remote processor */
ret = rproc->ops->start(rproc);
@@ -895,19 +898,15 @@ clean_up:
* to unregister the device. one other option is just to use kref here,
* that might be cleaner).
*/
-static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
+static int __rproc_fw_config_virtio(struct rproc *rproc, const struct firmware *fw)
{
- struct rproc *rproc = context;
struct resource_table *table;
int ret, tablesz;
- if (rproc_fw_sanity_check(rproc, fw) < 0)
- goto out;
-
/* look for the resource table */
table = rproc_find_rsc_table(rproc, fw, &tablesz);
if (!table)
- goto out;
+ return -EINVAL;
rproc->table_csum = crc32(0, table, tablesz);
@@ -919,7 +918,7 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
*/
rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL);
if (!rproc->cached_table)
- goto out;
+ return -ENOMEM;
rproc->table_ptr = rproc->cached_table;
@@ -928,12 +927,21 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
ret = rproc_handle_resources(rproc, tablesz,
rproc_count_vrings_handler);
if (ret)
- goto out;
+ return ret;
/* look for virtio devices and register them */
ret = rproc_handle_resources(rproc, tablesz, rproc_vdev_handler);
-out:
+ return ret;
+}
+
+static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
+{
+ struct rproc *rproc = context;
+
+ if (rproc_fw_sanity_check(rproc, fw) >= 0)
+ __rproc_fw_config_virtio(rproc, fw);
+
release_firmware(fw);
/* allow rproc_del() contexts, if any, to proceed */
complete_all(&rproc->firmware_loading_complete);