// 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-2024 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/platform_device.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;
};

static struct scmi_transport_core_operations *core;

/* 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;
			core->rx_callback(vioch->cinfo,
					  core->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)
			core->rx_callback(vioch->cinfo,
					  core->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 struct virtqueue_info scmi_vio_vqs_info[] = {
	{ "tx", scmi_vio_complete_cb },
	{ "rx", 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 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;
	}

	core->msg->tx_prepare(msg->request, xfer);

	sg_init_one(&sg_out, msg->request, core->msg->command_size(xfer));
	sg_init_one(&sg_in, msg->input, core->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)
		core->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)
		core->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 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 = {
	.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 struct scmi_desc scmi_virtio_desc = {
	.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),
};

static const struct of_device_id scmi_of_match[] = {
	{ .compatible = "arm,scmi-virtio" },
	{ /* Sentinel */ },
};

DEFINE_SCMI_TRANSPORT_DRIVER(scmi_virtio, scmi_virtio_driver, scmi_virtio_desc,
			     scmi_of_match, core);

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_vqs_info, 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);

	ret = platform_driver_register(&scmi_virtio_driver);
	if (ret) {
		vdev->priv = NULL;
		vdev->config->del_vqs(vdev);
		/* Ensure NULLified scmi_vdev is visible */
		smp_store_mb(scmi_vdev, NULL);

		return ret;
	}

	return 0;
}

static void scmi_vio_remove(struct virtio_device *vdev)
{
	platform_driver_unregister(&scmi_virtio_driver);

	/*
	 * 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",
	.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,
};

module_virtio_driver(virtio_scmi_driver);

MODULE_AUTHOR("Igor Skalkin <igor.skalkin@opensynergy.com>");
MODULE_AUTHOR("Peter Hilber <peter.hilber@opensynergy.com>");
MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>");
MODULE_DESCRIPTION("SCMI VirtIO Transport driver");
MODULE_LICENSE("GPL");
