summaryrefslogtreecommitdiff
path: root/drivers/remoteproc/remoteproc_core.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-07-07 20:50:03 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2021-07-07 20:50:03 +0300
commitd0fe3f47ef09bf5a74f7d20e129b2d15b4a824d0 (patch)
tree5d31bb1126a7276d2ee8dcf8015b4fcb894ba004 /drivers/remoteproc/remoteproc_core.c
parent77d34a4683b053108ecd466cc7c4193b45805528 (diff)
parentaef6a521e5bf61b3be4567f6c88776956a6d8b32 (diff)
downloadlinux-d0fe3f47ef09bf5a74f7d20e129b2d15b4a824d0.tar.xz
Merge tag 'rproc-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc
Pull remoteproc updates from Bjorn Andersson: "This adds support for controlling the PRU and R5F clusters on the TI AM64x, the remote processor in i.MX7ULP, i.MX8MN/P and i.MX8ULP NXP and the audio, compute and modem remoteprocs in the Qualcomm SC8180x platform. It fixes improper ordering of cdev and device creation of the remoteproc control interface and it fixes resource leaks in the error handling path of rproc_add() and the Qualcomm modem and wifi remoteproc drivers. Lastly it fixes a few build warnings and replace the dummy parameter passed in the mailbox api of the stm32 driver to something not living on the stack" * tag 'rproc-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc: (32 commits) remoteproc: qcom: pas: Add SC8180X adsp, cdsp and mpss dt-bindings: remoteproc: qcom: pas: Add SC8180X adsp, cdsp and mpss remoteproc: imx_rproc: support i.MX8ULP dt-bindings: remoteproc: imx_rproc: support i.MX8ULP remoteproc: stm32: fix mbox_send_message call remoteproc: core: Cleanup device in case of failure remoteproc: core: Fix cdev remove and rproc del remoteproc: core: Move validate before device add remoteproc: core: Move cdev add before device add remoteproc: pru: Add support for various PRU cores on K3 AM64x SoCs dt-bindings: remoteproc: pru: Update bindings for K3 AM64x SoCs remoteproc: qcom_wcnss: Use devm_qcom_smem_state_get() remoteproc: qcom_q6v5: Use devm_qcom_smem_state_get() to fix missing put() soc: qcom: smem_state: Add devm_qcom_smem_state_get() dt-bindings: remoteproc: qcom: pas: Fix indentation warnings remoteproc: imx-rproc: Fix IMX_REMOTEPROC configuration remoteproc: imx_rproc: support i.MX8MN/P remoteproc: imx_rproc: support i.MX7ULP remoteproc: imx_rproc: make clk optional remoteproc: imx_rproc: initial support for mutilple start/stop method ...
Diffstat (limited to 'drivers/remoteproc/remoteproc_core.c')
-rw-r--r--drivers/remoteproc/remoteproc_core.c72
1 files changed, 49 insertions, 23 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 39cf44cb0803..7de5905d276a 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -166,6 +166,7 @@ EXPORT_SYMBOL(rproc_va_to_pa);
* @rproc: handle of a remote processor
* @da: remoteproc device address to translate
* @len: length of the memory region @da is pointing to
+ * @is_iomem: optional pointer filled in to indicate if @da is iomapped memory
*
* Some remote processors will ask us to allocate them physically contiguous
* memory regions (which we call "carveouts"), and map them to specific
@@ -183,12 +184,12 @@ EXPORT_SYMBOL(rproc_va_to_pa);
* translations on the internal remoteproc memory regions through a platform
* implementation specific da_to_va ops, if present.
*
- * The function returns a valid kernel address on success or NULL on failure.
- *
* Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too,
* but only on kernel direct mapped RAM memory. Instead, we're just using
* here the output of the DMA API for the carveouts, which should be more
* correct.
+ *
+ * Return: a valid kernel address on success or NULL on failure
*/
void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{
@@ -509,7 +510,7 @@ static int copy_dma_range_map(struct device *to, struct device *from)
* use RSC_DEVMEM resource entries to map their required @da to the physical
* address of their base CMA region (ouch, hacky!).
*
- * Returns 0 on success, or an appropriate error code otherwise
+ * Return: 0 on success, or an appropriate error code otherwise
*/
static int rproc_handle_vdev(struct rproc *rproc, void *ptr,
int offset, int avail)
@@ -644,7 +645,7 @@ void rproc_vdev_release(struct kref *ref)
* support dynamically allocating this address using the generic
* DMA API (but currently there isn't a use case for that).
*
- * Returns 0 on success, or an appropriate error code otherwise
+ * Return: 0 on success, or an appropriate error code otherwise
*/
static int rproc_handle_trace(struct rproc *rproc, void *ptr,
int offset, int avail)
@@ -721,6 +722,8 @@ static int rproc_handle_trace(struct rproc *rproc, void *ptr,
* tell us ranges of physical addresses the firmware is allowed to request,
* and not allow firmwares to request access to physical addresses that
* are outside those ranges.
+ *
+ * Return: 0 on success, or an appropriate error code otherwise
*/
static int rproc_handle_devmem(struct rproc *rproc, void *ptr,
int offset, int avail)
@@ -783,6 +786,8 @@ out:
*
* This function allocate specified memory entry @mem using
* dma_alloc_coherent() as default allocator
+ *
+ * Return: 0 on success, or an appropriate error code otherwise
*/
static int rproc_alloc_carveout(struct rproc *rproc,
struct rproc_mem_entry *mem)
@@ -889,6 +894,8 @@ dma_free:
*
* This function releases specified memory entry @mem allocated via
* rproc_alloc_carveout() function by @rproc.
+ *
+ * Return: 0 on success, or an appropriate error code otherwise
*/
static int rproc_release_carveout(struct rproc *rproc,
struct rproc_mem_entry *mem)
@@ -918,6 +925,8 @@ static int rproc_release_carveout(struct rproc *rproc,
* (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
* needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
* pressure is important; it may have a substantial impact on performance.
+ *
+ * Return: 0 on success, or an appropriate error code otherwise
*/
static int rproc_handle_carveout(struct rproc *rproc,
void *ptr, int offset, int avail)
@@ -1006,6 +1015,8 @@ EXPORT_SYMBOL(rproc_add_carveout);
*
* This function allocates a rproc_mem_entry struct and fill it with parameters
* provided by client.
+ *
+ * Return: a valid pointer on success, or NULL on failure
*/
__printf(8, 9)
struct rproc_mem_entry *
@@ -1050,6 +1061,8 @@ EXPORT_SYMBOL(rproc_mem_entry_init);
*
* This function allocates a rproc_mem_entry struct and fill it with parameters
* provided by client.
+ *
+ * Return: a valid pointer on success, or NULL on failure
*/
__printf(5, 6)
struct rproc_mem_entry *
@@ -1881,6 +1894,8 @@ static int __rproc_detach(struct rproc *rproc)
* remoteproc functional again.
*
* This function can sleep, so it cannot be called from atomic context.
+ *
+ * Return: 0 on success or a negative value upon failure
*/
int rproc_trigger_recovery(struct rproc *rproc)
{
@@ -1965,7 +1980,7 @@ static void rproc_crash_handler_work(struct work_struct *work)
* If the remote processor is already powered on, this function immediately
* returns (successfully).
*
- * Returns 0 on success, and an appropriate error value otherwise.
+ * Return: 0 on success, and an appropriate error value otherwise
*/
int rproc_boot(struct rproc *rproc)
{
@@ -2100,6 +2115,8 @@ EXPORT_SYMBOL(rproc_shutdown);
* no longer available. From there it should be possible to remove the
* platform driver and even power cycle the application processor (if the HW
* supports it) without needing to switch off the remote processor.
+ *
+ * Return: 0 on success, and an appropriate error value otherwise
*/
int rproc_detach(struct rproc *rproc)
{
@@ -2152,7 +2169,7 @@ EXPORT_SYMBOL(rproc_detach);
* This function increments the remote processor's refcount, so always
* use rproc_put() to decrement it back once rproc isn't needed anymore.
*
- * Returns the rproc handle on success, and NULL on failure.
+ * Return: rproc handle on success, and NULL on failure
*/
#ifdef CONFIG_OF
struct rproc *rproc_get_by_phandle(phandle phandle)
@@ -2302,8 +2319,6 @@ static int rproc_validate(struct rproc *rproc)
* This is called by the platform-specific rproc implementation, whenever
* a new remote processor device is probed.
*
- * Returns 0 on success and an appropriate error code otherwise.
- *
* Note: this function initiates an asynchronous firmware loading
* context, which will look for virtio devices supported by the rproc's
* firmware.
@@ -2311,35 +2326,39 @@ static int rproc_validate(struct rproc *rproc)
* If found, those virtio devices will be created and added, so as a result
* of registering this remote processor, additional virtio drivers might be
* probed.
+ *
+ * Return: 0 on success and an appropriate error code otherwise
*/
int rproc_add(struct rproc *rproc)
{
struct device *dev = &rproc->dev;
int ret;
- ret = device_add(dev);
+ ret = rproc_validate(rproc);
if (ret < 0)
return ret;
- ret = rproc_validate(rproc);
+ /* add char device for this remoteproc */
+ ret = rproc_char_device_add(rproc);
if (ret < 0)
return ret;
+ ret = device_add(dev);
+ if (ret < 0) {
+ put_device(dev);
+ goto rproc_remove_cdev;
+ }
+
dev_info(dev, "%s is available\n", rproc->name);
/* create debugfs entries */
rproc_create_debug_dir(rproc);
- /* add char device for this remoteproc */
- ret = rproc_char_device_add(rproc);
- if (ret < 0)
- return ret;
-
/* if rproc is marked always-on, request it to boot */
if (rproc->auto_boot) {
ret = rproc_trigger_auto_boot(rproc);
if (ret < 0)
- return ret;
+ goto rproc_remove_dev;
}
/* expose to rproc_get_by_phandle users */
@@ -2348,6 +2367,13 @@ int rproc_add(struct rproc *rproc)
mutex_unlock(&rproc_list_mutex);
return 0;
+
+rproc_remove_dev:
+ rproc_delete_debug_dir(rproc);
+ device_del(dev);
+rproc_remove_cdev:
+ rproc_char_device_remove(rproc);
+ return ret;
}
EXPORT_SYMBOL(rproc_add);
@@ -2364,7 +2390,7 @@ static void devm_rproc_remove(void *rproc)
* This function performs like rproc_add() but the registered rproc device will
* automatically be removed on driver detach.
*
- * Returns: 0 on success, negative errno on failure
+ * Return: 0 on success, negative errno on failure
*/
int devm_rproc_add(struct device *dev, struct rproc *rproc)
{
@@ -2472,10 +2498,10 @@ static int rproc_alloc_ops(struct rproc *rproc, const struct rproc_ops *ops)
* implementations should then call rproc_add() to complete
* the registration of the remote processor.
*
- * On success the new rproc is returned, and on failure, NULL.
- *
* Note: _never_ directly deallocate @rproc, even if it was not registered
* yet. Instead, when you need to unroll rproc_alloc(), use rproc_free().
+ *
+ * Return: new rproc pointer on success, and NULL on failure
*/
struct rproc *rproc_alloc(struct device *dev, const char *name,
const struct rproc_ops *ops,
@@ -2588,7 +2614,7 @@ EXPORT_SYMBOL(rproc_put);
* of the outstanding reference created by rproc_alloc. To decrement that
* one last refcount, one still needs to call rproc_free().
*
- * Returns 0 on success and -EINVAL if @rproc isn't valid.
+ * Return: 0 on success and -EINVAL if @rproc isn't valid
*/
int rproc_del(struct rproc *rproc)
{
@@ -2603,7 +2629,6 @@ int rproc_del(struct rproc *rproc)
mutex_unlock(&rproc->lock);
rproc_delete_debug_dir(rproc);
- rproc_char_device_remove(rproc);
/* the rproc is downref'ed as soon as it's removed from the klist */
mutex_lock(&rproc_list_mutex);
@@ -2614,6 +2639,7 @@ int rproc_del(struct rproc *rproc)
synchronize_rcu();
device_del(&rproc->dev);
+ rproc_char_device_remove(rproc);
return 0;
}
@@ -2635,7 +2661,7 @@ static void devm_rproc_free(struct device *dev, void *res)
* This function performs like rproc_alloc() but the acquired rproc device will
* automatically be released on driver detach.
*
- * Returns: new rproc instance, or NULL on failure
+ * Return: new rproc instance, or NULL on failure
*/
struct rproc *devm_rproc_alloc(struct device *dev, const char *name,
const struct rproc_ops *ops,
@@ -2687,7 +2713,7 @@ EXPORT_SYMBOL(rproc_remove_subdev);
* rproc_get_by_child() - acquire rproc handle of @dev's ancestor
* @dev: child device to find ancestor of
*
- * Returns the ancestor rproc instance, or NULL if not found.
+ * Return: the ancestor rproc instance, or NULL if not found
*/
struct rproc *rproc_get_by_child(struct device *dev)
{