aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Vadillo <vadillo@ti.com>2011-10-17 19:19:17 -0500
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2017-05-10 23:40:43 +0200
commitfff3bc4c6250a4062458667b6c5aba794ea966c1 (patch)
tree11a4fda8cae08e705db18f307f5a9ae446be92f2
parent84b3179ead3d5fab5b5bb7db391d7232618f73e7 (diff)
downloadkernel_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.c14
-rwxr-xr-xdrivers/remoteproc/remoteproc.c4
-rw-r--r--include/linux/remoteproc.h5
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