From ab8531e642661380956100d5c58abb66b54a5060 Mon Sep 17 00:00:00 2001 From: Courtney Cavin Date: Mon, 5 Jan 2015 10:07:57 -0800 Subject: [PATCH] remoteproc: Support loading firmware from lately mounted fs (HACK) If the firmware isn't available during boot then table_ptr will be NULL and subsequent attempts to load the firmware will fail. Move things around and reattempt the load upon trying to boot the rproc. Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 34 ++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 2bd365f7c03c..9b0d73289d75 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -791,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. */ @@ -801,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); /* @@ -893,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); @@ -917,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; @@ -926,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); -- 2.39.5