aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiguel Vadillo <vadillo@ti.com>2011-10-17 19:19:17 -0500
committerPaul Kocialkowski <contact@paulk.fr>2014-06-29 23:03:16 +0200
commit51c7b5bf8e360dc915e3b2197801a3ef09315750 (patch)
tree9e7e9fa1e797251ceae9497809ab1206facbe046
parentdaf88fa5b9fcc747addec1bb5789e119cfab55a3 (diff)
downloadkernel_samsung_tuna-51c7b5bf8e360dc915e3b2197801a3ef09315750.zip
kernel_samsung_tuna-51c7b5bf8e360dc915e3b2197801a3ef09315750.tar.gz
kernel_samsung_tuna-51c7b5bf8e360dc915e3b2197801a3ef09315750.tar.bz2
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
-rw-r--r--drivers/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 847f3d0..2b68ef3 100644
--- a/arch/arm/plat-omap/omap_rpmsg.c
+++ b/arch/arm/plat-omap/omap_rpmsg.c
@@ -251,6 +251,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);
@@ -284,6 +296,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 12dd4dd..457a07a 100644
--- a/drivers/remoteproc/remoteproc.c
+++ b/drivers/remoteproc/remoteproc.c
@@ -1117,7 +1117,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);
@@ -1174,6 +1174,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 cd0105d..f87aeed 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