summaryrefslogtreecommitdiff
path: root/drivers/remoteproc/remoteproc_virtio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 19:00:06 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 19:00:06 +0300
commit2f194646fecaa9fd4607b670ee9ef84d9ed04566 (patch)
tree5012f3fc7232f509102ee6a3007997043e987390 /drivers/remoteproc/remoteproc_virtio.c
parentdc2535be1fd547fbd56aff091370280007b0a1af (diff)
parentd664ce75ae1c7c1e0e3fd8fa71f7ca779906a9be (diff)
downloadlinux-2f194646fecaa9fd4607b670ee9ef84d9ed04566.tar.xz
Merge tag 'rproc-v5.1' of git://github.com/andersson/remoteproc
Pull remoteproc updates from Bjorn Andersson: "This contains the last patches in Loic's remoteproc resource table handling changes, a number of updates to documentation, support for invoking the crash handler (for testing purposes), a fix for the handling of virtio devices during recovery, performance state votes in Qualcomm modem driver, support for specifying board specific firmware path for Qualcomm modem driver and improved support for graceful shutdown of Qualcomm remoteprocs" * tag 'rproc-v5.1' of git://github.com/andersson/remoteproc: (33 commits) remoteproc: fix for "dma-mapping: remove the DMA_MEMORY_EXCLUSIVE flag" remoteproc: fix rproc_check_carveout_da() returned error and comments remoteproc: fix trace buffer va initialization remoteproc: fix rproc_alloc_carveout() for rproc with iommu domain remoteproc: add warning on resource table cast remoteproc: fix rproc_alloc_carveout() bad variable cast remoteproc: fix rproc_da_to_va in case of unallocated carveout remoteproc: correct rproc_mem_entry_init() comments remoteproc: fix recovery procedure rpmsg: virtio: change header file sort style rpmsg: virtio: allocate buffer from parent remoteproc: st: add reserved memory support remoteproc: create vdev subdevice with specific dma memory pool remoteproc: q6v5_adsp: Remove voting for lpass_aon clock dt-binding: remoteproc: Remove lpass_aon clock from adsp pil clock list remoteproc: q6v5-mss: Active powerdomain for SDM845 remoteproc: q6v5-mss: Vote for rpmh power domains remoteproc: qcom: Add support for parsing fw dt bindings remoteproc: qcom_q6v5: don't auto boot remote processor remoteproc: qcom: Wait for shutdown-ack/ind on sysmon shutdown ...
Diffstat (limited to 'drivers/remoteproc/remoteproc_virtio.c')
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c61
1 files changed, 56 insertions, 5 deletions
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 2d7cd344f3bf..44774de6f17b 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -17,7 +17,9 @@
* GNU General Public License for more details.
*/
+#include <linux/dma-mapping.h>
#include <linux/export.h>
+#include <linux/of_reserved_mem.h>
#include <linux/remoteproc.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
@@ -316,6 +318,8 @@ static void rproc_virtio_dev_release(struct device *dev)
struct rproc_vdev *rvdev = vdev_to_rvdev(vdev);
struct rproc *rproc = vdev_to_rproc(vdev);
+ kfree(vdev);
+
kref_put(&rvdev->refcount, rproc_vdev_release);
put_device(&rproc->dev);
@@ -333,10 +337,53 @@ static void rproc_virtio_dev_release(struct device *dev)
int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
{
struct rproc *rproc = rvdev->rproc;
- struct device *dev = &rproc->dev;
- struct virtio_device *vdev = &rvdev->vdev;
+ struct device *dev = &rvdev->dev;
+ struct virtio_device *vdev;
+ struct rproc_mem_entry *mem;
int ret;
+ /* Try to find dedicated vdev buffer carveout */
+ mem = rproc_find_carveout_by_name(rproc, "vdev%dbuffer", rvdev->index);
+ if (mem) {
+ phys_addr_t pa;
+
+ if (mem->of_resm_idx != -1) {
+ struct device_node *np = rproc->dev.parent->of_node;
+
+ /* Associate reserved memory to vdev device */
+ ret = of_reserved_mem_device_init_by_idx(dev, np,
+ mem->of_resm_idx);
+ if (ret) {
+ dev_err(dev, "Can't associate reserved memory\n");
+ goto out;
+ }
+ } else {
+ if (mem->va) {
+ dev_warn(dev, "vdev %d buffer already mapped\n",
+ rvdev->index);
+ pa = rproc_va_to_pa(mem->va);
+ } else {
+ /* Use dma address as carveout no memmapped yet */
+ pa = (phys_addr_t)mem->dma;
+ }
+
+ /* Associate vdev buffer memory pool to vdev subdev */
+ ret = dma_declare_coherent_memory(dev, pa,
+ mem->da,
+ mem->len);
+ if (ret < 0) {
+ dev_err(dev, "Failed to associate buffer\n");
+ goto out;
+ }
+ }
+ }
+
+ /* Allocate virtio device */
+ vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
+ if (!vdev) {
+ ret = -ENOMEM;
+ goto out;
+ }
vdev->id.device = id,
vdev->config = &rproc_virtio_config_ops,
vdev->dev.parent = dev;
@@ -370,11 +417,15 @@ out:
/**
* rproc_remove_virtio_dev() - remove an rproc-induced virtio device
- * @rvdev: the remote vdev
+ * @dev: the virtio device
+ * @data: must be null
*
* This function unregisters an existing virtio device.
*/
-void rproc_remove_virtio_dev(struct rproc_vdev *rvdev)
+int rproc_remove_virtio_dev(struct device *dev, void *data)
{
- unregister_virtio_device(&rvdev->vdev);
+ struct virtio_device *vdev = dev_to_virtio(dev);
+
+ unregister_virtio_device(vdev);
+ return 0;
}