rpmsg: remote_dev: add API to check if remote is ready
authorWendy Liang <jliang@xilinx.com>
Tue, 24 Jan 2017 20:00:08 +0000 (12:00 -0800)
committerWendy Liang <jliang@xilinx.com>
Fri, 3 Feb 2017 21:41:22 +0000 (13:41 -0800)
Add an API to check if the remote is ready.

Signed-off-by: Wendy Liang <jliang@xilinx.com>
lib/include/openamp/rpmsg_core.h
lib/rpmsg/remote_device.c

index 62a410b2a6b7e5c7bf8bd0b9b7b530593caea0ba..118a1b7d6ac40bb12a3831b9f29e0eb78ed3eda5 100644 (file)
@@ -172,6 +172,7 @@ int rpmsg_rdev_init(struct hil_proc *proc,
                    rpmsg_chnl_cb_t channel_destroyed,
                    rpmsg_rx_cb_t default_cb);
 void rpmsg_rdev_deinit(struct remote_device *rdev);
+int rpmsg_rdev_remote_ready(struct remote_device *rdev);
 struct rpmsg_channel *rpmsg_rdev_get_chnl_from_id(struct remote_device *rdev,
                                               char *rp_chnl_id);
 struct rpmsg_endpoint *rpmsg_rdev_get_endpoint_from_addr(
index 3d6a916f150840b746a8df3a7ef9f7ca7ac0326b..223e3cce59109fe44eff20469337262a12d35299 100644 (file)
@@ -52,6 +52,7 @@
 #include "metal/utilities.h"
 #include "metal/alloc.h"
 #include "metal/atomic.h"
+#include "metal/cpu.h"
 
 /* Macro to initialize vring HW info */
 #define INIT_VRING_ALLOC_INFO(ring_info,vring_hw)                             \
@@ -368,6 +369,28 @@ int rpmsg_rdev_init_channels(struct remote_device *rdev)
        return RPMSG_SUCCESS;
 }
 
+/**
+ * check if the remote is ready to start RPMsg communication
+ */
+int rpmsg_rdev_remote_ready(struct remote_device *rdev)
+{
+       struct virtio_device *vdev = &rdev->virt_dev;
+       uint8_t status;
+       if (rdev->role == RPMSG_MASTER) {
+               while (1) {
+                       /* Busy wait until the remote is ready */
+                       status = vdev->func->get_status(vdev);
+                       if (status & VIRTIO_CONFIG_STATUS_DRIVER_OK)
+                               return true;
+                       metal_cpu_yield();
+               }
+       } else {
+               return true;
+       }
+       /* Never come here */
+       return false;
+}
+
 static void rpmsg_memset_io(struct metal_io_region *io, void *dst, int c, size_t count)
 {
        if ((io->mem_flags & METAL_IO_MAPPED)) {