// SPDX-License-Identifier: GPL-2.0
/*
 * Virtio Transport driver for Arm System Control and Management Interface
 * (SCMI).
 *
 * Copyright (C) 2020-2022 OpenSynergy.
 * Copyright (C) 2021-2022 ARM Ltd.
 */

/**
 * DOC: Theory of Operation
 *
 * The scmi-virtio transport implements a driver for the virtio SCMI device.
 *
 * There is one Tx channel (virtio cmdq, A2P channel) and at most one Rx
 * channel (virtio eventq, P2A channel). Each channel is implemented through a
 * virtqueue. Access to each virtqueue is protected by spinlocks.
 */

#include <linux/completion.h>
#include <linux/errno.h>
#include <linux/refcount.h>
#include <linux/slab.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>

#include <uapi/linux/virtio_ids.h>
#include <uapi/linux/virtio_scmi.h>

#include "common.h"

#define VIRTIO_MAX_RX_TIMEOUT_MS	60000
#define VIRTIO_SCMI_MAX_MSG_SIZE 128 /* Value may be increased. */
#define VIRTIO_SCMI_MAX_PDU_SIZE \
	(VIRTIO_SCMI_MAX_MSG_SIZE + SCMI_MSG_MAX_PROT_OVERHEAD)
#define DESCRIPTORS_PER_TX_MSG 2

/**
 * struct scmi_vio_channel - Transport channel information
 *
 * @vqueue: Associated virtqueue
 * @cinfo: SCMI Tx or Rx channel
 * @free_lock: Protects access to the @free_list.
 * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
 * @deferred_tx_work: Worker for TX deferred replies processing
 * @deferred_tx_wq: Workqueue for TX deferred replies
 * @pending_lock: Protects access to the @pending_cmds_list.
 * @pending_cmds_list: List of pre-fetched commands queueud for later processing
 * @is_rx: Whether channel is an Rx channel
 * @max_msg: Maximum number of pending messages for this channel.
 * @lock: Protects access to all members except users, free_list and
 *	  pending_cmds_list.
 * @shutdown_done: A reference to a completion used when freeing this channel.
 * @users: A reference count to currently active users of this channel.
 */
struct scmi_vio_channel {
	struct virtqueue *vqueue;
	struct scmi_chan_info *cinfo;
	/* lock to protect access to the free list. */
	spinlock_t free_lock;
	struct list_head free_list;
	/* lock to protect access to the pending list. */
	spinlock_t pending_lock;
	struct list_head pending_cmds_list;
	struct work_struct deferred_tx_work;
	struct workqueue_struct *deferred_tx_wq;
	bool is_rx;
	unsigned int max_msg;
	/*
	 * Lock to protect access to all members except users, free_list and
	 * pending_cmds_list
	 */
	spinlock_t lock;
	struct completion *shutdown_done;
	refcount_t users;
};

enum poll_states {
	VIO_MSG_NOT_POLLED,
	VIO_MSG_POLL_TIMEOUT,
	VIO_MSG_POLLING,
	VIO_MSG_POLL_DONE,
};

/**
 * struct scmi_vio_msg - Transport PDU information
 *
 * @request: SDU used for commands
 * @input: SDU used for (delayed) responses and notifications
 * @list: List which scmi_vio_msg may be part of
 * @rx_len: Input SDU size in bytes, once input has been received
 * @poll_idx: Last used index registered for polling purposes if this message
 *	      transaction reply was configured for polling.
 * @poll_status: Polling state for this message.
 * @poll_lock: A lock to protect @poll_status
 * @users: A reference count to track this message users and avoid premature
 *	   freeing (and reuse) when polling and IRQ execution paths interleave.
 */
struct scmi_vio_msg {
	struct scmi_msg_payld *request;
	struct scmi_msg_payld *input;
	struct list_head list;
	unsigned int rx_len;
	unsigned int poll_idx;
	enum poll_states poll_status;
	/* Lock to protect access to poll_status */
	spinlock_t poll_lock;
	refcount_t users;
};

/* Only one SCMI VirtIO device can possibly exist */
static struct virtio_device *scmi_vdev;

static void scmi_vio_channel_ready(struct scmi_vio_channel *vioch,
				   struct scmi_chan_info *cinfo)
{
	unsigned long flags;

	spin_lock_irqsave(&vioch->lock, flags);
	cinfo->transport_info = vioch;
	/* Indirectly setting channel not available any more */
	vioch->cinfo = cinfo;
	spin_unlock_irqrestore(&vioch->lock, flags);

	refcount_set(&vioch->users, 1);
}

static inline bool scmi_vio_channel_acquire(struct scmi_vio_channel *vioch)
{
	return refcount_inc_not_zero(&vioch->users);
}

static inline void scmi_vio_channel_release(struct scmi_vio_channel *vioch)
{
	if (refcount_dec_and_test(&vioch->users)) {
		unsigned long flags;

		spin_lock_irqsave(&vioch->lock, flags);
		if (vioch->shutdown_done) {
			vioch->cinfo = NULL;
			complete(vioch->shutdown_done);
		}
		spin_unlock_irqrestore(&vioch->lock, flags);
	}
}

static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch)
{
	unsigned long flags;
	DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done);

	/*
	 * Prepare to wait for the last release if not already released
	 * or in progress.
	 */
	spin_lock_irqsave(&vioch->lock, flags);
	if (!vioch->cinfo || vioch->shutdown_done) {
		spin_unlock_irqrestore(&vioch->lock, flags);
		return;
	}

	vioch->shutdown_done = &vioch_shutdown_done;
	if (!vioch->is_rx && vioch->deferred_tx_wq)
		/* Cannot be kicked anymore after this...*/
		vioch->deferred_tx_wq = NULL;
	spin_unlock_irqrestore(&vioch->lock, flags);

	scmi_vio_channel_release(vioch);

	/* Let any possibly concurrent RX path release the channel */
	wait_for_completion(vioch->shutdown_done);
}

/* Assumes to be called with vio channel acquired already */
static struct scmi_vio_msg *
scmi_virtio_get_free_msg(struct scmi_vio_channel *vioch)
{
	unsigned long flags;
	struct scmi_vio_msg *msg;

	spin_lock_irqsave(&vioch->free_lock, flags);
	if (list_empty(&vioch->free_list)) {
		spin_unlock_irqrestore(&vioch->free_lock, flags);
		return NULL;
	}

	msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
	list_del_init(&msg->list);
	spin_unlock_irqrestore(&vioch->free_lock, flags);

	/* Still no users, no need to acquire poll_lock */
	msg->poll_status = VIO_MSG_NOT_POLLED;
	refcount_set(&msg->users, 1);

	return msg;
}

static inline bool scmi_vio_msg_acquire(struct scmi_vio_msg *msg)
{
	return refcount_inc_not_zero(&msg->users);
}

/* Assumes to be called with vio channel acquired already */
static inline bool scmi_vio_msg_release(struct scmi_vio_channel *vioch,
					struct scmi_vio_msg *msg)
{
	bool ret;

	ret = refcount_dec_and_test(&msg->users);
	if (ret) {
		unsigned long flags;

		spin_lock_irqsave(&vioch->free_lock, flags);
		list_add_tail(&msg->list, &vioch->free_list);
		spin_unlock_irqrestore(&vioch->free_lock, flags);
	}

	return ret;
}

static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
{
	return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
}

static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
			       struct scmi_vio_msg *msg)
{
	struct scatterlist sg_in;
	int rc;
	unsigned long flags;
	struct device *dev = &vioch->vqueue->vdev->dev;

	sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);

	spin_lock_irqsave(&vioch->lock, flags);

	rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
	if (rc)
		dev_err(dev, "failed to add to RX virtqueue (%d)\n", rc);
	else
		virtqueue_kick(vioch->vqueue);

	spin_unlock_irqrestore(&vioch->lock, flags);

	return rc;
}

/*
 * Assume to be called with channel already acquired or not ready at all;
 * vioch->lock MUST NOT have been already acquired.
 */
static void scmi_finalize_message(struct scmi_vio_channel *vioch,
				  struct scmi_vio_msg *msg)
{
	if (vioch->is_rx)
		scmi_vio_feed_vq_rx(vioch, msg);
	else
		scmi_vio_msg_release(vioch, msg);
}

static void scmi_vio_complete_cb(struct virtqueue *vqueue)
{
	unsigned long flags;
	unsigned int length;
	struct scmi_vio_channel *vioch;
	struct scmi_vio_msg *msg;
	bool cb_enabled = true;

	if (WARN_ON_ONCE(!vqueue->vdev->priv))
		return;
	vioch = &((struct scmi_vio_channel *)vqueue->vdev->priv)[vqueue->index];

	for (;;) {
		if (!scmi_vio_channel_acquire(vioch))
			return;

		spin_lock_irqsave(&vioch->lock, flags);
		if (cb_enabled) {
			virtqueue_disable_cb(vqueue);
			cb_enabled = false;
		}

		msg = virtqueue_get_buf(vqueue, &length);
		if (!msg) {
			if (virtqueue_enable_cb(vqueue)) {
				spin_unlock_irqrestore(&vioch->lock, flags);
				scmi_vio_channel_release(vioch);
				return;
			}
			cb_enabled = true;
		}
		spin_unlock_irqrestore(&vioch->lock, flags);

		if (msg) {
			msg->rx_len = length;
			scmi_rx_callback(vioch->cinfo,
					 msg_read_header(msg->input), msg);

			scmi_finalize_message(vioch, msg);
		}

		/*
		 * Release vio channel between loop iterations to allow
		 * virtio_chan_free() to eventually fully release it when
		 * shutting down; in such a case, any outstanding message will
		 * be ignored since this loop will bail out at the next
		 * iteration.
		 */
		scmi_vio_channel_release(vioch);
	}
}

static void scmi_vio_deferred_tx_worker(struct work_struct *work)
{
	unsigned long flags;
	struct scmi_vio_channel *vioch;
	struct scmi_vio_msg *msg, *tmp;

	vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work);

	if (!scmi_vio_channel_acquire(vioch))
		return;

	/*
	 * Process pre-fetched messages: these could be non-polled messages or
	 * late timed-out replies to polled messages dequeued by chance while
	 * polling for some other messages: this worker is in charge to process
	 * the valid non-expired messages and anyway finally free all of them.
	 */
	spin_lock_irqsave(&vioch->pending_lock, flags);

	/* Scan the list of possibly pre-fetched messages during polling. */
	list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) {
		list_del(&msg->list);

		/*
		 * Channel is acquired here (cannot vanish) and this message
		 * is no more processed elsewhere so no poll_lock needed.
		 */
		if (msg->poll_status == VIO_MSG_NOT_POLLED)
			scmi_rx_callback(vioch->cinfo,
					 msg_read_header(msg->input), msg);

		/* Free the processed message once done */
		scmi_vio_msg_release(vioch, msg);
	}

	spin_unlock_irqrestore(&vioch->pending_lock, flags);

	/* Process possibly still pending messages */
	scmi_vio_complete_cb(vioch->vqueue);

	scmi_vio_channel_release(vioch);
}

static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };

static vq_callback_t *scmi_vio_complete_callbacks[] = {
	scmi_vio_complete_cb,
	scmi_vio_complete_cb
};

static unsigned int virtio_get_max_msg(struct scmi_chan_info *base_cinfo)
{
	struct scmi_vio_channel *vioch = base_cinfo->transport_info;

	return vioch->max_msg;
}

static int virtio_link_supplier(struct device *dev)
{
	if (!scmi_vdev) {
		dev_notice(dev,
			   "Deferring probe after not finding a bound scmi-virtio device\n");
		return -EPROBE_DEFER;
	}

	if (!device_link_add(dev, &scmi_vdev->dev,
			     DL_FLAG_AUTOREMOVE_CONSUMER)) {
		dev_err(dev, "Adding link to supplier virtio device failed\n");
		return -ECANCELED;
	}

	return 0;
}

static bool virtio_chan_available(struct device_node *of_node, int idx)
{
	struct scmi_vio_channel *channels, *vioch = NULL;

	if (WARN_ON_ONCE(!scmi_vdev))
		return false;

	channels = (struct scmi_vio_channel *)scmi_vdev->priv;

	switch (idx) {
	case VIRTIO_SCMI_VQ_TX:
		vioch = &channels[VIRTIO_SCMI_VQ_TX];
		break;
	case VIRTIO_SCMI_VQ_RX:
		if (scmi_vio_have_vq_rx(scmi_vdev))
			vioch = &channels[VIRTIO_SCMI_VQ_RX];
		break;
	default:
		return false;
	}

	return vioch && !vioch->cinfo;
}

static void scmi_destroy_tx_workqueue(void *deferred_tx_wq)
{
	destroy_workqueue(deferred_tx_wq);
}

static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
			     bool tx)
{
	struct scmi_vio_channel *vioch;
	int index = tx ? VIRTIO_SCMI_VQ_TX : VIRTIO_SCMI_VQ_RX;
	int i;

	if (!scmi_vdev)
		return -EPROBE_DEFER;

	vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];

	/* Setup a deferred worker for polling. */
	if (tx && !vioch->deferred_tx_wq) {
		int ret;

		vioch->deferred_tx_wq =
			alloc_workqueue(dev_name(&scmi_vdev->dev),
					WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
					0);
		if (!vioch->deferred_tx_wq)
			return -ENOMEM;

		ret = devm_add_action_or_reset(dev, scmi_destroy_tx_workqueue,
					       vioch->deferred_tx_wq);
		if (ret)
			return ret;

		INIT_WORK(&vioch->deferred_tx_work,
			  scmi_vio_deferred_tx_worker);
	}

	for (i = 0; i < vioch->max_msg; i++) {
		struct scmi_vio_msg *msg;

		msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL);
		if (!msg)
			return -ENOMEM;

		if (tx) {
			msg->request = devm_kzalloc(dev,
						    VIRTIO_SCMI_MAX_PDU_SIZE,
						    GFP_KERNEL);
			if (!msg->request)
				return -ENOMEM;
			spin_lock_init(&msg->poll_lock);
			refcount_set(&msg->users, 1);
		}

		msg->input = devm_kzalloc(dev, VIRTIO_SCMI_MAX_PDU_SIZE,
					  GFP_KERNEL);
		if (!msg->input)
			return -ENOMEM;

		scmi_finalize_message(vioch, msg);
	}

	scmi_vio_channel_ready(vioch, cinfo);

	return 0;
}

static int virtio_chan_free(int id, void *p, void *data)
{
	struct scmi_chan_info *cinfo = p;
	struct scmi_vio_channel *vioch = cinfo->transport_info;

	/*
	 * Break device to inhibit further traffic flowing while shutting down
	 * the channels: doing it later holding vioch->lock creates unsafe
	 * locking dependency chains as reported by LOCKDEP.
	 */
	virtio_break_device(vioch->vqueue->vdev);
	scmi_vio_channel_cleanup_sync(vioch);

	return 0;
}

static int virtio_send_message(struct scmi_chan_info *cinfo,
			       struct scmi_xfer *xfer)
{
	struct scmi_vio_channel *vioch = cinfo->transport_info;
	struct scatterlist sg_out;
	struct scatterlist sg_in;
	struct scatterlist *sgs[DESCRIPTORS_PER_TX_MSG] = { &sg_out, &sg_in };
	unsigned long flags;
	int rc;
	struct scmi_vio_msg *msg;

	if (!scmi_vio_channel_acquire(vioch))
		return -EINVAL;

	msg = scmi_virtio_get_free_msg(vioch);
	if (!msg) {
		scmi_vio_channel_release(vioch);
		return -EBUSY;
	}

	msg_tx_prepare(msg->request, xfer);

	sg_init_one(&sg_out, msg->request, msg_command_size(xfer));
	sg_init_one(&sg_in, msg->input, msg_response_size(xfer));

	spin_lock_irqsave(&vioch->lock, flags);

	/*
	 * If polling was requested for this transaction:
	 *  - retrieve last used index (will be used as polling reference)
	 *  - bind the polled message to the xfer via .priv
	 *  - grab an additional msg refcount for the poll-path
	 */
	if (xfer->hdr.poll_completion) {
		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
		/* Still no users, no need to acquire poll_lock */
		msg->poll_status = VIO_MSG_POLLING;
		scmi_vio_msg_acquire(msg);
		/* Ensure initialized msg is visibly bound to xfer */
		smp_store_mb(xfer->priv, msg);
	}

	rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);
	if (rc)
		dev_err(vioch->cinfo->dev,
			"failed to add to TX virtqueue (%d)\n", rc);
	else
		virtqueue_kick(vioch->vqueue);

	spin_unlock_irqrestore(&vioch->lock, flags);

	if (rc) {
		/* Ensure order between xfer->priv clear and vq feeding */
		smp_store_mb(xfer->priv, NULL);
		if (xfer->hdr.poll_completion)
			scmi_vio_msg_release(vioch, msg);
		scmi_vio_msg_release(vioch, msg);
	}

	scmi_vio_channel_release(vioch);

	return rc;
}

static void virtio_fetch_response(struct scmi_chan_info *cinfo,
				  struct scmi_xfer *xfer)
{
	struct scmi_vio_msg *msg = xfer->priv;

	if (msg)
		msg_fetch_response(msg->input, msg->rx_len, xfer);
}

static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
				      size_t max_len, struct scmi_xfer *xfer)
{
	struct scmi_vio_msg *msg = xfer->priv;

	if (msg)
		msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
}

/**
 * virtio_mark_txdone  - Mark transmission done
 *
 * Free only completed polling transfer messages.
 *
 * Note that in the SCMI VirtIO transport we never explicitly release still
 * outstanding but timed-out messages by forcibly re-adding them to the
 * free-list inside the TX code path; we instead let IRQ/RX callbacks, or the
 * TX deferred worker, eventually clean up such messages once, finally, a late
 * reply is received and discarded (if ever).
 *
 * This approach was deemed preferable since those pending timed-out buffers are
 * still effectively owned by the SCMI platform VirtIO device even after timeout
 * expiration: forcibly freeing and reusing them before they had been returned
 * explicitly by the SCMI platform could lead to subtle bugs due to message
 * corruption.
 * An SCMI platform VirtIO device which never returns message buffers is
 * anyway broken and it will quickly lead to exhaustion of available messages.
 *
 * For this same reason, here, we take care to free only the polled messages
 * that had been somehow replied (only if not by chance already processed on the
 * IRQ path - the initial scmi_vio_msg_release() takes care of this) and also
 * any timed-out polled message if that indeed appears to have been at least
 * dequeued from the virtqueues (VIO_MSG_POLL_DONE): this is needed since such
 * messages won't be freed elsewhere. Any other polled message is marked as
 * VIO_MSG_POLL_TIMEOUT.
 *
 * Possible late replies to timed-out polled messages will be eventually freed
 * by RX callbacks if delivered on the IRQ path or by the deferred TX worker if
 * dequeued on some other polling path.
 *
 * @cinfo: SCMI channel info
 * @ret: Transmission return code
 * @xfer: Transfer descriptor
 */
static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret,
			       struct scmi_xfer *xfer)
{
	unsigned long flags;
	struct scmi_vio_channel *vioch = cinfo->transport_info;
	struct scmi_vio_msg *msg = xfer->priv;

	if (!msg || !scmi_vio_channel_acquire(vioch))
		return;

	/* Ensure msg is unbound from xfer anyway at this point */
	smp_store_mb(xfer->priv, NULL);

	/* Must be a polled xfer and not already freed on the IRQ path */
	if (!xfer->hdr.poll_completion || scmi_vio_msg_release(vioch, msg)) {
		scmi_vio_channel_release(vioch);
		return;
	}

	spin_lock_irqsave(&msg->poll_lock, flags);
	/* Do not free timedout polled messages only if still inflight */
	if (ret != -ETIMEDOUT || msg->poll_status == VIO_MSG_POLL_DONE)
		scmi_vio_msg_release(vioch, msg);
	else if (msg->poll_status == VIO_MSG_POLLING)
		msg->poll_status = VIO_MSG_POLL_TIMEOUT;
	spin_unlock_irqrestore(&msg->poll_lock, flags);

	scmi_vio_channel_release(vioch);
}

/**
 * virtio_poll_done  - Provide polling support for VirtIO transport
 *
 * @cinfo: SCMI channel info
 * @xfer: Reference to the transfer being poll for.
 *
 * VirtIO core provides a polling mechanism based only on last used indexes:
 * this means that it is possible to poll the virtqueues waiting for something
 * new to arrive from the host side, but the only way to check if the freshly
 * arrived buffer was indeed what we were waiting for is to compare the newly
 * arrived message descriptor with the one we are polling on.
 *
 * As a consequence it can happen to dequeue something different from the buffer
 * we were poll-waiting for: if that is the case such early fetched buffers are
 * then added to a the @pending_cmds_list list for later processing by a
 * dedicated deferred worker.
 *
 * So, basically, once something new is spotted we proceed to de-queue all the
 * freshly received used buffers until we found the one we were polling on, or,
 * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
 * in the vqueue at the end of the polling loop (possible due to inherent races
 * in virtqueues handling mechanisms), we similarly kick the deferred worker
 * and let it process those, to avoid indefinitely looping in the .poll_done
 * busy-waiting helper.
 *
 * Finally, we delegate to the deferred worker also the final free of any timed
 * out reply to a polled message that we should dequeue.
 *
 * Note that, since we do NOT have per-message suppress notification mechanism,
 * the message we are polling for could be alternatively delivered via usual
 * IRQs callbacks on another core which happened to have IRQs enabled while we
 * are actively polling for it here: in such a case it will be handled as such
 * by scmi_rx_callback() and the polling loop in the SCMI Core TX path will be
 * transparently terminated anyway.
 *
 * Return: True once polling has successfully completed.
 */
static bool virtio_poll_done(struct scmi_chan_info *cinfo,
			     struct scmi_xfer *xfer)
{
	bool pending, found = false;
	unsigned int length, any_prefetched = 0;
	unsigned long flags;
	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
	struct scmi_vio_channel *vioch = cinfo->transport_info;

	if (!msg)
		return true;

	/*
	 * Processed already by other polling loop on another CPU ?
	 *
	 * Note that this message is acquired on the poll path so cannot vanish
	 * while inside this loop iteration even if concurrently processed on
	 * the IRQ path.
	 *
	 * Avoid to acquire poll_lock since polled_status can be changed
	 * in a relevant manner only later in this same thread of execution:
	 * any other possible changes made concurrently by other polling loops
	 * or by a reply delivered on the IRQ path have no meaningful impact on
	 * this loop iteration: in other words it is harmless to allow this
	 * possible race but let has avoid spinlocking with irqs off in this
	 * initial part of the polling loop.
	 */
	if (msg->poll_status == VIO_MSG_POLL_DONE)
		return true;

	if (!scmi_vio_channel_acquire(vioch))
		return true;

	/* Has cmdq index moved at all ? */
	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
	if (!pending) {
		scmi_vio_channel_release(vioch);
		return false;
	}

	spin_lock_irqsave(&vioch->lock, flags);
	virtqueue_disable_cb(vioch->vqueue);

	/*
	 * Process all new messages till the polled-for message is found OR
	 * the vqueue is empty.
	 */
	while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) {
		bool next_msg_done = false;

		/*
		 * Mark any dequeued buffer message as VIO_MSG_POLL_DONE so
		 * that can be properly freed even on timeout in mark_txdone.
		 */
		spin_lock(&next_msg->poll_lock);
		if (next_msg->poll_status == VIO_MSG_POLLING) {
			next_msg->poll_status = VIO_MSG_POLL_DONE;
			next_msg_done = true;
		}
		spin_unlock(&next_msg->poll_lock);

		next_msg->rx_len = length;
		/* Is the message we were polling for ? */
		if (next_msg == msg) {
			found = true;
			break;
		} else if (next_msg_done) {
			/* Skip the rest if this was another polled msg */
			continue;
		}

		/*
		 * Enqueue for later processing any non-polled message and any
		 * timed-out polled one that we happen to have dequeued.
		 */
		spin_lock(&next_msg->poll_lock);
		if (next_msg->poll_status == VIO_MSG_NOT_POLLED ||
		    next_msg->poll_status == VIO_MSG_POLL_TIMEOUT) {
			spin_unlock(&next_msg->poll_lock);

			any_prefetched++;
			spin_lock(&vioch->pending_lock);
			list_add_tail(&next_msg->list,
				      &vioch->pending_cmds_list);
			spin_unlock(&vioch->pending_lock);
		} else {
			spin_unlock(&next_msg->poll_lock);
		}
	}

	/*
	 * When the polling loop has successfully terminated if something
	 * else was queued in the meantime, it will be served by a deferred
	 * worker OR by the normal IRQ/callback OR by other poll loops.
	 *
	 * If we are still looking for the polled reply, the polling index has
	 * to be updated to the current vqueue last used index.
	 */
	if (found) {
		pending = !virtqueue_enable_cb(vioch->vqueue);
	} else {
		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
		pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
	}

	if (vioch->deferred_tx_wq && (any_prefetched || pending))
		queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work);

	spin_unlock_irqrestore(&vioch->lock, flags);

	scmi_vio_channel_release(vioch);

	return found;
}

static const struct scmi_transport_ops scmi_virtio_ops = {
	.link_supplier = virtio_link_supplier,
	.chan_available = virtio_chan_available,
	.chan_setup = virtio_chan_setup,
	.chan_free = virtio_chan_free,
	.get_max_msg = virtio_get_max_msg,
	.send_message = virtio_send_message,
	.fetch_response = virtio_fetch_response,
	.fetch_notification = virtio_fetch_notification,
	.mark_txdone = virtio_mark_txdone,
	.poll_done = virtio_poll_done,
};

static int scmi_vio_probe(struct virtio_device *vdev)
{
	struct device *dev = &vdev->dev;
	struct scmi_vio_channel *channels;
	bool have_vq_rx;
	int vq_cnt;
	int i;
	int ret;
	struct virtqueue *vqs[VIRTIO_SCMI_VQ_MAX_CNT];

	/* Only one SCMI VirtiO device allowed */
	if (scmi_vdev) {
		dev_err(dev,
			"One SCMI Virtio device was already initialized: only one allowed.\n");
		return -EBUSY;
	}

	have_vq_rx = scmi_vio_have_vq_rx(vdev);
	vq_cnt = have_vq_rx ? VIRTIO_SCMI_VQ_MAX_CNT : 1;

	channels = devm_kcalloc(dev, vq_cnt, sizeof(*channels), GFP_KERNEL);
	if (!channels)
		return -ENOMEM;

	if (have_vq_rx)
		channels[VIRTIO_SCMI_VQ_RX].is_rx = true;

	ret = virtio_find_vqs(vdev, vq_cnt, vqs, scmi_vio_complete_callbacks,
			      scmi_vio_vqueue_names, NULL);
	if (ret) {
		dev_err(dev, "Failed to get %d virtqueue(s)\n", vq_cnt);
		return ret;
	}

	for (i = 0; i < vq_cnt; i++) {
		unsigned int sz;

		spin_lock_init(&channels[i].lock);
		spin_lock_init(&channels[i].free_lock);
		INIT_LIST_HEAD(&channels[i].free_list);
		spin_lock_init(&channels[i].pending_lock);
		INIT_LIST_HEAD(&channels[i].pending_cmds_list);
		channels[i].vqueue = vqs[i];

		sz = virtqueue_get_vring_size(channels[i].vqueue);
		/* Tx messages need multiple descriptors. */
		if (!channels[i].is_rx)
			sz /= DESCRIPTORS_PER_TX_MSG;

		if (sz > MSG_TOKEN_MAX) {
			dev_info(dev,
				 "%s virtqueue could hold %d messages. Only %ld allowed to be pending.\n",
				 channels[i].is_rx ? "rx" : "tx",
				 sz, MSG_TOKEN_MAX);
			sz = MSG_TOKEN_MAX;
		}
		channels[i].max_msg = sz;
	}

	vdev->priv = channels;
	/* Ensure initialized scmi_vdev is visible */
	smp_store_mb(scmi_vdev, vdev);

	return 0;
}

static void scmi_vio_remove(struct virtio_device *vdev)
{
	/*
	 * Once we get here, virtio_chan_free() will have already been called by
	 * the SCMI core for any existing channel and, as a consequence, all the
	 * virtio channels will have been already marked NOT ready, causing any
	 * outstanding message on any vqueue to be ignored by complete_cb: now
	 * we can just stop processing buffers and destroy the vqueues.
	 */
	virtio_reset_device(vdev);
	vdev->config->del_vqs(vdev);
	/* Ensure scmi_vdev is visible as NULL */
	smp_store_mb(scmi_vdev, NULL);
}

static int scmi_vio_validate(struct virtio_device *vdev)
{
#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
	if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
		dev_err(&vdev->dev,
			"device does not comply with spec version 1.x\n");
		return -EINVAL;
	}
#endif
	return 0;
}

static unsigned int features[] = {
	VIRTIO_SCMI_F_P2A_CHANNELS,
};

static const struct virtio_device_id id_table[] = {
	{ VIRTIO_ID_SCMI, VIRTIO_DEV_ANY_ID },
	{ 0 }
};

static struct virtio_driver virtio_scmi_driver = {
	.driver.name = "scmi-virtio",
	.driver.owner = THIS_MODULE,
	.feature_table = features,
	.feature_table_size = ARRAY_SIZE(features),
	.id_table = id_table,
	.probe = scmi_vio_probe,
	.remove = scmi_vio_remove,
	.validate = scmi_vio_validate,
};

static int __init virtio_scmi_init(void)
{
	return register_virtio_driver(&virtio_scmi_driver);
}

static void virtio_scmi_exit(void)
{
	unregister_virtio_driver(&virtio_scmi_driver);
}

const struct scmi_desc scmi_virtio_desc = {
	.transport_init = virtio_scmi_init,
	.transport_exit = virtio_scmi_exit,
	.ops = &scmi_virtio_ops,
	/* for non-realtime virtio devices */
	.max_rx_timeout_ms = VIRTIO_MAX_RX_TIMEOUT_MS,
	.max_msg = 0, /* overridden by virtio_get_max_msg() */
	.max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
	.atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE),
};
