diff options
author | Miguel Vadillo <vadillo@ti.com> | 2011-10-17 19:19:17 -0500 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2017-05-10 23:40:43 +0200 |
commit | fff3bc4c6250a4062458667b6c5aba794ea966c1 (patch) | |
tree | 11a4fda8cae08e705db18f307f5a9ae446be92f2 | |
parent | 84b3179ead3d5fab5b5bb7db391d7232618f73e7 (diff) | |
download | kernel_samsung_tuna-fff3bc4c6250a4062458667b6c5aba794ea966c1.tar.gz kernel_samsung_tuna-fff3bc4c6250a4062458667b6c5aba794ea966c1.tar.bz2 kernel_samsung_tuna-fff3bc4c6250a4062458667b6c5aba794ea966c1.zip |
omap: remoteproc: add a notification for loading error
When calling rproc_get for the first time, the loading of
the remoteproc image will be requested using a non-blocking
request_firmware_no_wait, and the caller can continue before
the actual loading is complete.
The loader later can return an error due to a non-existing
or wrong image and there should be a way to notify about this
to users having a rproc handle.
This functionality is added and is leveraged by rpmsg to
release some resources it had already acquired since requesting
a firmware load.
Change-Id: I1d3523efbcfd613bca74d363084791ceaaaa9989
Signed-off-by: Miguel Vadillo <vadillo@ti.com>
-rw-r--r-- | arch/arm/plat-omap/omap_rpmsg.c | 14 | ||||
-rwxr-xr-x | drivers/remoteproc/remoteproc.c | 4 | ||||
-rw-r--r-- | include/linux/remoteproc.h | 5 |
3 files changed, 22 insertions, 1 deletions
diff --git a/arch/arm/plat-omap/omap_rpmsg.c b/arch/arm/plat-omap/omap_rpmsg.c index f4bc0eabe32..ec861f5b269 100644 --- a/arch/arm/plat-omap/omap_rpmsg.c +++ b/arch/arm/plat-omap/omap_rpmsg.c @@ -257,6 +257,18 @@ static int rpmsg_rproc_pos_suspend(struct omap_rpmsg_vproc *rpdev) return NOTIFY_DONE; } +static int rpmsg_rproc_load_error(struct omap_rpmsg_vproc *rpdev) +{ + mutex_lock(&rpdev->lock); + if (rpdev->mbox) { + omap_mbox_put(rpdev->mbox, &rpdev->nb); + rpdev->mbox = NULL; + } + mutex_unlock(&rpdev->lock); + + return NOTIFY_DONE; +} + static int rpmsg_rproc_resume(struct omap_rpmsg_vproc *rpdev) { mutex_lock(&rpdev->lock); @@ -290,6 +302,8 @@ static int rpmsg_rproc_events(struct notifier_block *this, return rpmsg_rproc_suspend(rpdev); case RPROC_POS_SUSPEND: return rpmsg_rproc_pos_suspend(rpdev); + case RPROC_LOAD_ERROR: + return rpmsg_rproc_load_error(rpdev); case RPROC_RESUME: return rpmsg_rproc_resume(rpdev); case RPROC_SECURE: diff --git a/drivers/remoteproc/remoteproc.c b/drivers/remoteproc/remoteproc.c index 9c10b2e2a03..a19064384b9 100755 --- a/drivers/remoteproc/remoteproc.c +++ b/drivers/remoteproc/remoteproc.c @@ -1128,7 +1128,7 @@ static void rproc_loader_cont(const struct firmware *fw, void *context) u64 bootaddr = 0; struct fw_header *image; struct fw_section *section; - int left, ret; + int left, ret = -EINVAL; if (!fw) { dev_err(dev, "%s: failed to load %s\n", __func__, fwfile); @@ -1188,6 +1188,8 @@ out: complete_fw: /* allow all contexts calling rproc_put() to proceed */ complete_all(&rproc->firmware_loading_complete); + if (ret) + _event_notify(rproc, RPROC_LOAD_ERROR, NULL); } static int rproc_loader(struct rproc *rproc) diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 47e7fc8588e..685a042db8f 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -201,6 +201,10 @@ enum rproc_state { * POS_SUSPEND event. * * @RPROC_SECURE: remote processor secure mode has changed. + * + * @RPROC_LOAD_ERROR: an error has occurred during loading the remote processor + * binary. users can use this event to release any resources + * acquired after a request to start the processor. */ enum rproc_event { RPROC_ERROR, @@ -208,6 +212,7 @@ enum rproc_event { RPROC_POS_SUSPEND, RPROC_RESUME, RPROC_SECURE, + RPROC_LOAD_ERROR, }; #define RPROC_MAX_NAME 100 |