From fff3bc4c6250a4062458667b6c5aba794ea966c1 Mon Sep 17 00:00:00 2001 From: Miguel Vadillo Date: Mon, 17 Oct 2011 19:19:17 -0500 Subject: 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 --- arch/arm/plat-omap/omap_rpmsg.c | 14 ++++++++++++++ drivers/remoteproc/remoteproc.c | 4 +++- include/linux/remoteproc.h | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/arch/arm/plat-omap/omap_rpmsg.c b/arch/arm/plat-omap/omap_rpmsg.c index f4bc0ea..ec861f5 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 9c10b2e..a190643 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 47e7fc8..685a042 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 -- cgit v1.1