diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index f80af913965..5f835160238 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -70,6 +70,7 @@ struct rptun_priv_s pid_t tid; #ifdef CONFIG_RPTUN_PM bool stay; + uint16_t headrx; #endif }; @@ -222,8 +223,40 @@ static inline void rptun_pm_action(FAR struct rptun_priv_s *priv, leave_critical_section(flags); } +static inline void rptun_update_rx(FAR struct rptun_priv_s *priv) +{ + FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; + FAR struct virtqueue *rvq = rvdev->rvq; + + if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) + { + priv->headrx = rvq->vq_ring.used->idx; + } + else + { + priv->headrx = rvq->vq_ring.avail->idx; + } +} + +static inline bool rptun_available_rx(FAR struct rptun_priv_s *priv) +{ + FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; + FAR struct virtqueue *rvq = rvdev->rvq; + + if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) + { + return priv->headrx != rvq->vq_used_cons_idx; + } + else + { + return priv->headrx != rvq->vq_available_idx; + } +} + #else # define rptun_pm_action(priv, stay) +# define rptun_update_rx(priv) +# define rptun_available_rx(priv) true #endif static void rptun_start_worker(FAR void *arg) @@ -240,7 +273,10 @@ static void rptun_worker(FAR void *arg) { FAR struct rptun_priv_s *priv = arg; - remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL); + if (rptun_available_rx(priv)) + { + remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL); + } } static int rptun_thread(int argc, FAR char *argv[]) @@ -291,10 +327,8 @@ static int rptun_callback(FAR void *arg, uint32_t vqid) if (vqid == RPTUN_NOTIFY_ALL || vqid == vdev->vrings_info[rvq->vq_queue_index].notifyid) { - if (rptun_buffer_nused(&priv->rvdev, true)) - { - rptun_wakeup_rx(priv); - } + rptun_update_rx(priv); + rptun_wakeup_rx(priv); } if (vqid == RPTUN_NOTIFY_ALL || @@ -811,6 +845,8 @@ static int rptun_dev_start(FAR struct remoteproc *rproc) /* Register callback to mbox for receiving remote message */ RPTUN_REGISTER_CALLBACK(priv->dev, rptun_callback, priv); + + rptun_update_rx(priv); rptun_wakeup_rx(priv); /* Broadcast device_created to all registers */