diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 03:22:19 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-19 03:22:19 +0300 |
commit | 97f00905ec98472050d65c46629237b299f29035 (patch) | |
tree | 0187931abfe9d5088dfabe0c0de8129fa4055a75 | |
parent | 676d9735cd010fc439566e2b6e9b6adc3e1179ef (diff) | |
parent | b3d39032d7b33029373fbce6459aff6ac316e130 (diff) | |
download | linux-97f00905ec98472050d65c46629237b299f29035.tar.xz |
Merge tag 'rproc-v4.7' of git://github.com/andersson/remoteproc
Pull remoteproc updates from Bjorn Andersson:
"Introduce a synchronization point between the async firmware loading
and clients requesting the remote processor to boot, as well as
support for remote processors that are not interested in the resource
table information"
* tag 'rproc-v4.7' of git://github.com/andersson/remoteproc:
remoteproc: Add additional crash reasons
remoteproc: core: Make the loaded resource table optional
remoteproc: core: Task sync during rproc_fw_boot()
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 39 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_internal.h | 1 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_virtio.c | 2 | ||||
-rw-r--r-- | include/linux/remoteproc.h | 4 |
4 files changed, 37 insertions, 9 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 3d7d58a109d8..db3958b3f094 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -57,6 +57,8 @@ static DEFINE_IDA(rproc_dev_index); static const char * const rproc_crash_names[] = { [RPROC_MMUFAULT] = "mmufault", + [RPROC_WATCHDOG] = "watchdog", + [RPROC_FATAL_ERROR] = "fatal error", }; /* translate rproc_crash_type to string */ @@ -856,12 +858,8 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) * copy this information to device memory. */ loaded_table = rproc_find_loaded_rsc_table(rproc, fw); - if (!loaded_table) { - ret = -EINVAL; - goto clean_up; - } - - memcpy(loaded_table, rproc->cached_table, tablesz); + if (loaded_table) + memcpy(loaded_table, rproc->cached_table, tablesz); /* power up the remote processor */ ret = rproc->ops->start(rproc); @@ -1030,8 +1028,9 @@ static void rproc_crash_handler_work(struct work_struct *work) } /** - * rproc_boot() - boot a remote processor + * __rproc_boot() - boot a remote processor * @rproc: handle of a remote processor + * @wait: wait for rproc registration completion * * Boot a remote processor (i.e. load its firmware, power it on, ...). * @@ -1040,7 +1039,7 @@ static void rproc_crash_handler_work(struct work_struct *work) * * Returns 0 on success, and an appropriate error value otherwise. */ -int rproc_boot(struct rproc *rproc) +static int __rproc_boot(struct rproc *rproc, bool wait) { const struct firmware *firmware_p; struct device *dev; @@ -1088,6 +1087,10 @@ int rproc_boot(struct rproc *rproc) goto downref_rproc; } + /* if rproc virtio is not yet configured, wait */ + if (wait) + wait_for_completion(&rproc->firmware_loading_complete); + ret = rproc_fw_boot(rproc, firmware_p); release_firmware(firmware_p); @@ -1101,9 +1104,29 @@ unlock_mutex: mutex_unlock(&rproc->lock); return ret; } + +/** + * rproc_boot() - boot a remote processor + * @rproc: handle of a remote processor + */ +int rproc_boot(struct rproc *rproc) +{ + return __rproc_boot(rproc, true); +} EXPORT_SYMBOL(rproc_boot); /** + * rproc_boot_nowait() - boot a remote processor + * @rproc: handle of a remote processor + * + * Same as rproc_boot() but don't wait for rproc registration completion + */ +int rproc_boot_nowait(struct rproc *rproc) +{ + return __rproc_boot(rproc, false); +} + +/** * rproc_shutdown() - power off the remote processor * @rproc: the remote processor * diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index 8041b95cb058..57e1de59bec8 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -48,6 +48,7 @@ struct rproc_fw_ops { /* from remoteproc_core.c */ void rproc_release(struct kref *kref); irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id); +int rproc_boot_nowait(struct rproc *rproc); /* from remoteproc_virtio.c */ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id); diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index e44872fb9e5e..cc91556313e1 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -161,7 +161,7 @@ static int rproc_virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs, } /* now that the vqs are all set, boot the remote processor */ - ret = rproc_boot(rproc); + ret = rproc_boot_nowait(rproc); if (ret) { dev_err(&rproc->dev, "rproc_boot() failed %d\n", ret); goto error; diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 9c4e1384f636..1c457a8dd5a6 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -365,6 +365,8 @@ enum rproc_state { /** * enum rproc_crash_type - remote processor crash types * @RPROC_MMUFAULT: iommu fault + * @RPROC_WATCHDOG: watchdog bite + * @RPROC_FATAL_ERROR fatal error * * Each element of the enum is used as an array index. So that, the value of * the elements should be always something sane. @@ -373,6 +375,8 @@ enum rproc_state { */ enum rproc_crash_type { RPROC_MMUFAULT, + RPROC_WATCHDOG, + RPROC_FATAL_ERROR, }; /** |