// SPDX-License-Identifier: GPL-2.0
/*
 * System Control and Management Interface (SCMI) Raw mode support
 *
 * Copyright (C) 2022 ARM Ltd.
 */
/**
 * DOC: Theory of operation
 *
 * When enabled the SCMI Raw mode support exposes a userspace API which allows
 * to send and receive SCMI commands, replies and notifications from a user
 * application through injection and snooping of bare SCMI messages in binary
 * little-endian format.
 *
 * Such injected SCMI transactions will then be routed through the SCMI core
 * stack towards the SCMI backend server using whatever SCMI transport is
 * currently configured on the system under test.
 *
 * It is meant to help in running any sort of SCMI backend server testing, no
 * matter where the server is placed, as long as it is normally reachable via
 * the transport configured on the system.
 *
 * It is activated by a Kernel configuration option since it is NOT meant to
 * be used in production but only during development and in CI deployments.
 *
 * In order to avoid possible interferences between the SCMI Raw transactions
 * originated from a test-suite and the normal operations of the SCMI drivers,
 * when Raw mode is enabled, by default, all the regular SCMI drivers are
 * inhibited, unless CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX is enabled: in this
 * latter case the regular SCMI stack drivers will be loaded as usual and it is
 * up to the user of this interface to take care of manually inhibiting the
 * regular SCMI drivers in order to avoid interferences during the test runs.
 *
 * The exposed API is as follows.
 *
 * All SCMI Raw entries are rooted under a common top /raw debugfs top directory
 * which in turn is rooted under the corresponding underlying  SCMI instance.
 *
 * /sys/kernel/debug/scmi/
 * `-- 0
 *     |-- atomic_threshold_us
 *     |-- instance_name
 *     |-- raw
 *     |   |-- channels
 *     |   |   |-- 0x10
 *     |   |   |   |-- message
 *     |   |   |   `-- message_async
 *     |   |   `-- 0x13
 *     |   |       |-- message
 *     |   |       `-- message_async
 *     |   |-- errors
 *     |   |-- message
 *     |   |-- message_async
 *     |   |-- notification
 *     |   `-- reset
 *     `-- transport
 *         |-- is_atomic
 *         |-- max_msg_size
 *         |-- max_rx_timeout_ms
 *         |-- rx_max_msg
 *         |-- tx_max_msg
 *         `-- type
 *
 * where:
 *
 *  - errors: used to read back timed-out and unexpected replies
 *  - message*: used to send sync/async commands and read back immediate and
 *		delayed reponses (if any)
 *  - notification: used to read any notification being emitted by the system
 *		    (if previously enabled by the user app)
 *  - reset: used to flush the queues of messages (of any kind) still pending
 *	     to be read; this is useful at test-suite start/stop to get
 *	     rid of any unread messages from the previous run.
 *
 * with the per-channel entries rooted at /channels being present only on a
 * system where multiple transport channels have been configured.
 *
 * Such per-channel entries can be used to explicitly choose a specific channel
 * for SCMI bare message injection, in contrast with the general entries above
 * where, instead, the selection of the proper channel to use is automatically
 * performed based the protocol embedded in the injected message and on how the
 * transport is configured on the system.
 *
 * Note that other common general entries are available under transport/ to let
 * the user applications properly make up their expectations in terms of
 * timeouts and message characteristics.
 *
 * Each write to the message* entries causes one command request to be built
 * and sent while the replies or delayed response are read back from those same
 * entries one message at time (receiving an EOF at each message boundary).
 *
 * The user application running the test is in charge of handling timeouts
 * on replies and properly choosing SCMI sequence numbers for the outgoing
 * requests (using the same sequence number is supported but discouraged).
 *
 * Injection of multiple in-flight requests is supported as long as the user
 * application uses properly distinct sequence numbers for concurrent requests
 * and takes care to properly manage all the related issues about concurrency
 * and command/reply pairing. Keep in mind that, anyway, the real level of
 * parallelism attainable in such scenario is dependent on the characteristics
 * of the underlying transport being used.
 *
 * Since the SCMI core regular stack is partially used to deliver and collect
 * the messages, late replies arrived after timeouts and any other sort of
 * unexpected message can be identified by the SCMI core as usual and they will
 * be reported as messages under "errors" for later analysis.
 */

#include <linux/bitmap.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/xarray.h>

#include "common.h"

#include "raw_mode.h"

#include <trace/events/scmi.h>

#define SCMI_XFER_RAW_MAX_RETRIES	10

/**
 * struct scmi_raw_queue  - Generic Raw queue descriptor
 *
 * @free_bufs: A freelists listhead used to keep unused raw buffers
 * @free_bufs_lock: Spinlock used to protect access to @free_bufs
 * @msg_q: A listhead to a queue of snooped messages waiting to be read out
 * @msg_q_lock: Spinlock used to protect access to @msg_q
 * @wq: A waitqueue used to wait and poll on related @msg_q
 */
struct scmi_raw_queue {
	struct list_head free_bufs;
	/* Protect free_bufs[] lists */
	spinlock_t free_bufs_lock;
	struct list_head msg_q;
	/* Protect msg_q[] lists */
	spinlock_t msg_q_lock;
	wait_queue_head_t wq;
};

/**
 * struct scmi_raw_mode_info  - Structure holding SCMI Raw instance data
 *
 * @id: Sequential Raw instance ID.
 * @handle: Pointer to SCMI entity handle to use
 * @desc: Pointer to the transport descriptor to use
 * @tx_max_msg: Maximum number of concurrent TX in-flight messages
 * @q: An array of Raw queue descriptors
 * @chans_q: An XArray mapping optional additional per-channel queues
 * @free_waiters: Head of freelist for unused waiters
 * @free_mtx: A mutex to protect the waiters freelist
 * @active_waiters: Head of list for currently active and used waiters
 * @active_mtx: A mutex to protect the active waiters list
 * @waiters_work: A work descriptor to be used with the workqueue machinery
 * @wait_wq: A workqueue reference to the created workqueue
 * @dentry: Top debugfs root dentry for SCMI Raw
 * @gid: A group ID used for devres accounting
 *
 * Note that this descriptor is passed back to the core after SCMI Raw is
 * initialized as an opaque handle to use by subsequent SCMI Raw call hooks.
 *
 */
struct scmi_raw_mode_info {
	unsigned int id;
	const struct scmi_handle *handle;
	const struct scmi_desc *desc;
	int tx_max_msg;
	struct scmi_raw_queue *q[SCMI_RAW_MAX_QUEUE];
	struct xarray chans_q;
	struct list_head free_waiters;
	/* Protect free_waiters list */
	struct mutex free_mtx;
	struct list_head active_waiters;
	/* Protect active_waiters list */
	struct mutex active_mtx;
	struct work_struct waiters_work;
	struct workqueue_struct	*wait_wq;
	struct dentry *dentry;
	void *gid;
};

/**
 * struct scmi_xfer_raw_waiter  - Structure to describe an xfer to be waited for
 *
 * @start_jiffies: The timestamp in jiffies of when this structure was queued.
 * @cinfo: A reference to the channel to use for this transaction
 * @xfer: A reference to the xfer to be waited for
 * @async_response: A completion to be, optionally, used for async waits: it
 *		    will be setup by @scmi_do_xfer_raw_start, if needed, to be
 *		    pointed at by xfer->async_done.
 * @node: A list node.
 */
struct scmi_xfer_raw_waiter {
	unsigned long start_jiffies;
	struct scmi_chan_info *cinfo;
	struct scmi_xfer *xfer;
	struct completion async_response;
	struct list_head node;
};

/**
 * struct scmi_raw_buffer  - Structure to hold a full SCMI message
 *
 * @max_len: The maximum allowed message size (header included) that can be
 *	     stored into @msg
 * @msg: A message buffer used to collect a full message grabbed from an xfer.
 * @node: A list node.
 */
struct scmi_raw_buffer {
	size_t max_len;
	struct scmi_msg msg;
	struct list_head node;
};

/**
 * struct scmi_dbg_raw_data  - Structure holding data needed by the debugfs
 * layer
 *
 * @chan_id: The preferred channel to use: if zero the channel is automatically
 *	     selected based on protocol.
 * @raw: A reference to the Raw instance.
 * @tx: A message buffer used to collect TX message on write.
 * @tx_size: The effective size of the TX message.
 * @tx_req_size: The final expected size of the complete TX message.
 * @rx: A message buffer to collect RX message on read.
 * @rx_size: The effective size of the RX message.
 */
struct scmi_dbg_raw_data {
	u8 chan_id;
	struct scmi_raw_mode_info *raw;
	struct scmi_msg tx;
	size_t tx_size;
	size_t tx_req_size;
	struct scmi_msg rx;
	size_t rx_size;
};

static struct scmi_raw_queue *
scmi_raw_queue_select(struct scmi_raw_mode_info *raw, unsigned int idx,
		      unsigned int chan_id)
{
	if (!chan_id)
		return raw->q[idx];

	return xa_load(&raw->chans_q, chan_id);
}

static struct scmi_raw_buffer *scmi_raw_buffer_get(struct scmi_raw_queue *q)
{
	unsigned long flags;
	struct scmi_raw_buffer *rb = NULL;
	struct list_head *head = &q->free_bufs;

	spin_lock_irqsave(&q->free_bufs_lock, flags);
	if (!list_empty(head)) {
		rb = list_first_entry(head, struct scmi_raw_buffer, node);
		list_del_init(&rb->node);
	}
	spin_unlock_irqrestore(&q->free_bufs_lock, flags);

	return rb;
}

static void scmi_raw_buffer_put(struct scmi_raw_queue *q,
				struct scmi_raw_buffer *rb)
{
	unsigned long flags;

	/* Reset to full buffer length */
	rb->msg.len = rb->max_len;

	spin_lock_irqsave(&q->free_bufs_lock, flags);
	list_add_tail(&rb->node, &q->free_bufs);
	spin_unlock_irqrestore(&q->free_bufs_lock, flags);
}

static void scmi_raw_buffer_enqueue(struct scmi_raw_queue *q,
				    struct scmi_raw_buffer *rb)
{
	unsigned long flags;

	spin_lock_irqsave(&q->msg_q_lock, flags);
	list_add_tail(&rb->node, &q->msg_q);
	spin_unlock_irqrestore(&q->msg_q_lock, flags);

	wake_up_interruptible(&q->wq);
}

static struct scmi_raw_buffer*
scmi_raw_buffer_dequeue_unlocked(struct scmi_raw_queue *q)
{
	struct scmi_raw_buffer *rb = NULL;

	if (!list_empty(&q->msg_q)) {
		rb = list_first_entry(&q->msg_q, struct scmi_raw_buffer, node);
		list_del_init(&rb->node);
	}

	return rb;
}

static struct scmi_raw_buffer *scmi_raw_buffer_dequeue(struct scmi_raw_queue *q)
{
	unsigned long flags;
	struct scmi_raw_buffer *rb;

	spin_lock_irqsave(&q->msg_q_lock, flags);
	rb = scmi_raw_buffer_dequeue_unlocked(q);
	spin_unlock_irqrestore(&q->msg_q_lock, flags);

	return rb;
}

static void scmi_raw_buffer_queue_flush(struct scmi_raw_queue *q)
{
	struct scmi_raw_buffer *rb;

	do {
		rb = scmi_raw_buffer_dequeue(q);
		if (rb)
			scmi_raw_buffer_put(q, rb);
	} while (rb);
}

static struct scmi_xfer_raw_waiter *
scmi_xfer_raw_waiter_get(struct scmi_raw_mode_info *raw, struct scmi_xfer *xfer,
			 struct scmi_chan_info *cinfo, bool async)
{
	struct scmi_xfer_raw_waiter *rw = NULL;

	mutex_lock(&raw->free_mtx);
	if (!list_empty(&raw->free_waiters)) {
		rw = list_first_entry(&raw->free_waiters,
				      struct scmi_xfer_raw_waiter, node);
		list_del_init(&rw->node);

		if (async) {
			reinit_completion(&rw->async_response);
			xfer->async_done = &rw->async_response;
		}

		rw->cinfo = cinfo;
		rw->xfer = xfer;
	}
	mutex_unlock(&raw->free_mtx);

	return rw;
}

static void scmi_xfer_raw_waiter_put(struct scmi_raw_mode_info *raw,
				     struct scmi_xfer_raw_waiter *rw)
{
	if (rw->xfer) {
		rw->xfer->async_done = NULL;
		rw->xfer = NULL;
	}

	mutex_lock(&raw->free_mtx);
	list_add_tail(&rw->node, &raw->free_waiters);
	mutex_unlock(&raw->free_mtx);
}

static void scmi_xfer_raw_waiter_enqueue(struct scmi_raw_mode_info *raw,
					 struct scmi_xfer_raw_waiter *rw)
{
	/* A timestamp for the deferred worker to know how much this has aged */
	rw->start_jiffies = jiffies;

	trace_scmi_xfer_response_wait(rw->xfer->transfer_id, rw->xfer->hdr.id,
				      rw->xfer->hdr.protocol_id,
				      rw->xfer->hdr.seq,
				      raw->desc->max_rx_timeout_ms,
				      rw->xfer->hdr.poll_completion);

	mutex_lock(&raw->active_mtx);
	list_add_tail(&rw->node, &raw->active_waiters);
	mutex_unlock(&raw->active_mtx);

	/* kick waiter work */
	queue_work(raw->wait_wq, &raw->waiters_work);
}

static struct scmi_xfer_raw_waiter *
scmi_xfer_raw_waiter_dequeue(struct scmi_raw_mode_info *raw)
{
	struct scmi_xfer_raw_waiter *rw = NULL;

	mutex_lock(&raw->active_mtx);
	if (!list_empty(&raw->active_waiters)) {
		rw = list_first_entry(&raw->active_waiters,
				      struct scmi_xfer_raw_waiter, node);
		list_del_init(&rw->node);
	}
	mutex_unlock(&raw->active_mtx);

	return rw;
}

/**
 * scmi_xfer_raw_worker  - Work function to wait for Raw xfers completions
 *
 * @work: A reference to the work.
 *
 * In SCMI Raw mode, once a user-provided injected SCMI message is sent, we
 * cannot wait to receive its response (if any) in the context of the injection
 * routines so as not to leave the userspace write syscall, which delivered the
 * SCMI message to send, pending till eventually a reply is received.
 * Userspace should and will poll/wait instead on the read syscalls which will
 * be in charge of reading a received reply (if any).
 *
 * Even though reply messages are collected and reported into the SCMI Raw layer
 * on the RX path, nonetheless we have to properly wait for their completion as
 * usual (and async_completion too if needed) in order to properly release the
 * xfer structure at the end: to do this out of the context of the write/send
 * these waiting jobs are delegated to this deferred worker.
 *
 * Any sent xfer, to be waited for, is timestamped and queued for later
 * consumption by this worker: queue aging is accounted for while choosing a
 * timeout for the completion, BUT we do not really care here if we end up
 * accidentally waiting for a bit too long.
 */
static void scmi_xfer_raw_worker(struct work_struct *work)
{
	struct scmi_raw_mode_info *raw;
	struct device *dev;
	unsigned long max_tmo;

	raw = container_of(work, struct scmi_raw_mode_info, waiters_work);
	dev = raw->handle->dev;
	max_tmo = msecs_to_jiffies(raw->desc->max_rx_timeout_ms);

	do {
		int ret = 0;
		unsigned int timeout_ms;
		unsigned long aging;
		struct scmi_xfer *xfer;
		struct scmi_xfer_raw_waiter *rw;
		struct scmi_chan_info *cinfo;

		rw = scmi_xfer_raw_waiter_dequeue(raw);
		if (!rw)
			return;

		cinfo = rw->cinfo;
		xfer = rw->xfer;
		/*
		 * Waiters are queued by wait-deadline at the end, so some of
		 * them could have been already expired when processed, BUT we
		 * have to check the completion status anyway just in case a
		 * virtually expired (aged) transaction was indeed completed
		 * fine and we'll have to wait for the asynchronous part (if
		 * any): for this reason a 1 ms timeout is used for already
		 * expired/aged xfers.
		 */
		aging = jiffies - rw->start_jiffies;
		timeout_ms = max_tmo > aging ?
			jiffies_to_msecs(max_tmo - aging) : 1;

		ret = scmi_xfer_raw_wait_for_message_response(cinfo, xfer,
							      timeout_ms);
		if (!ret && xfer->hdr.status)
			ret = scmi_to_linux_errno(xfer->hdr.status);

		if (raw->desc->ops->mark_txdone)
			raw->desc->ops->mark_txdone(rw->cinfo, ret, xfer);

		trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
				    xfer->hdr.protocol_id, xfer->hdr.seq, ret);

		/* Wait also for an async delayed response if needed */
		if (!ret && xfer->async_done) {
			unsigned long tmo = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);

			if (!wait_for_completion_timeout(xfer->async_done, tmo))
				dev_err(dev,
					"timed out in RAW delayed resp - HDR:%08X\n",
					pack_scmi_header(&xfer->hdr));
		}

		/* Release waiter and xfer */
		scmi_xfer_raw_put(raw->handle, xfer);
		scmi_xfer_raw_waiter_put(raw, rw);
	} while (1);
}

static void scmi_xfer_raw_reset(struct scmi_raw_mode_info *raw)
{
	int i;

	dev_info(raw->handle->dev, "Resetting SCMI Raw stack.\n");

	for (i = 0; i < SCMI_RAW_MAX_QUEUE; i++)
		scmi_raw_buffer_queue_flush(raw->q[i]);
}

/**
 * scmi_xfer_raw_get_init  - An helper to build a valid xfer from the provided
 * bare SCMI message.
 *
 * @raw: A reference to the Raw instance.
 * @buf: A buffer containing the whole SCMI message to send (including the
 *	 header) in little-endian binary formmat.
 * @len: Length of the message in @buf.
 * @p: A pointer to return the initialized Raw xfer.
 *
 * After an xfer is picked from the TX pool and filled in with the message
 * content, the xfer is registered as pending with the core in the usual way
 * using the original sequence number provided by the user with the message.
 *
 * Note that, in case the testing user application is NOT using distinct
 * sequence-numbers between successive SCMI messages such registration could
 * fail temporarily if the previous message, using the same sequence number,
 * had still not released; in such a case we just wait and retry.
 *
 * Return: 0 on Success
 */
static int scmi_xfer_raw_get_init(struct scmi_raw_mode_info *raw, void *buf,
				  size_t len, struct scmi_xfer **p)
{
	u32 msg_hdr;
	size_t tx_size;
	struct scmi_xfer *xfer;
	int ret, retry = SCMI_XFER_RAW_MAX_RETRIES;
	struct device *dev = raw->handle->dev;

	if (!buf || len < sizeof(u32))
		return -EINVAL;

	tx_size = len - sizeof(u32);
	/* Ensure we have sane transfer sizes */
	if (tx_size > raw->desc->max_msg_size)
		return -ERANGE;

	xfer = scmi_xfer_raw_get(raw->handle);
	if (IS_ERR(xfer)) {
		dev_warn(dev, "RAW - Cannot get a free RAW xfer !\n");
		return PTR_ERR(xfer);
	}

	/* Build xfer from the provided SCMI bare LE message */
	msg_hdr = le32_to_cpu(*((__le32 *)buf));
	unpack_scmi_header(msg_hdr, &xfer->hdr);
	xfer->hdr.seq = (u16)MSG_XTRACT_TOKEN(msg_hdr);
	/* Polling not supported */
	xfer->hdr.poll_completion = false;
	xfer->hdr.status = SCMI_SUCCESS;
	xfer->tx.len = tx_size;
	xfer->rx.len = raw->desc->max_msg_size;
	/* Clear the whole TX buffer */
	memset(xfer->tx.buf, 0x00, raw->desc->max_msg_size);
	if (xfer->tx.len)
		memcpy(xfer->tx.buf, (u8 *)buf + sizeof(msg_hdr), xfer->tx.len);
	*p = xfer;

	/*
	 * In flight registration can temporarily fail in case of Raw messages
	 * if the user injects messages without using monotonically increasing
	 * sequence numbers since, in Raw mode, the xfer (and the token) is
	 * finally released later by a deferred worker. Just retry for a while.
	 */
	do {
		ret = scmi_xfer_raw_inflight_register(raw->handle, xfer);
		if (ret) {
			dev_dbg(dev,
				"...retrying[%d] inflight registration\n",
				retry);
			msleep(raw->desc->max_rx_timeout_ms /
			       SCMI_XFER_RAW_MAX_RETRIES);
		}
	} while (ret && --retry);

	if (ret) {
		dev_warn(dev,
			 "RAW - Could NOT register xfer %d in-flight HDR:0x%08X\n",
			 xfer->hdr.seq, msg_hdr);
		scmi_xfer_raw_put(raw->handle, xfer);
	}

	return ret;
}

/**
 * scmi_do_xfer_raw_start  - An helper to send a valid raw xfer
 *
 * @raw: A reference to the Raw instance.
 * @xfer: The xfer to send
 * @chan_id: The channel ID to use, if zero the channels is automatically
 *	     selected based on the protocol used.
 * @async: A flag stating if an asynchronous command is required.
 *
 * This function send a previously built raw xfer using an appropriate channel
 * and queues the related waiting work.
 *
 * Note that we need to know explicitly if the required command is meant to be
 * asynchronous in kind since we have to properly setup the waiter.
 * (and deducing this from the payload is weak and do not scale given there is
 *  NOT a common header-flag stating if the command is asynchronous or not)
 *
 * Return: 0 on Success
 */
static int scmi_do_xfer_raw_start(struct scmi_raw_mode_info *raw,
				  struct scmi_xfer *xfer, u8 chan_id,
				  bool async)
{
	int ret;
	struct scmi_chan_info *cinfo;
	struct scmi_xfer_raw_waiter *rw;
	struct device *dev = raw->handle->dev;

	if (!chan_id)
		chan_id = xfer->hdr.protocol_id;
	else
		xfer->flags |= SCMI_XFER_FLAG_CHAN_SET;

	cinfo = scmi_xfer_raw_channel_get(raw->handle, chan_id);
	if (IS_ERR(cinfo))
		return PTR_ERR(cinfo);

	rw = scmi_xfer_raw_waiter_get(raw, xfer, cinfo, async);
	if (!rw) {
		dev_warn(dev, "RAW - Cannot get a free waiter !\n");
		return -ENOMEM;
	}

	/* True ONLY if also supported by transport. */
	if (is_polling_enabled(cinfo, raw->desc))
		xfer->hdr.poll_completion = true;

	reinit_completion(&xfer->done);
	/* Make sure xfer state update is visible before sending */
	smp_store_mb(xfer->state, SCMI_XFER_SENT_OK);

	trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
			      xfer->hdr.protocol_id, xfer->hdr.seq,
			      xfer->hdr.poll_completion);

	ret = raw->desc->ops->send_message(rw->cinfo, xfer);
	if (ret) {
		dev_err(dev, "Failed to send RAW message %d\n", ret);
		scmi_xfer_raw_waiter_put(raw, rw);
		return ret;
	}

	trace_scmi_msg_dump(raw->id, cinfo->id, xfer->hdr.protocol_id,
			    xfer->hdr.id, "cmnd", xfer->hdr.seq,
			    xfer->hdr.status,
			    xfer->tx.buf, xfer->tx.len);

	scmi_xfer_raw_waiter_enqueue(raw, rw);

	return ret;
}

/**
 * scmi_raw_message_send  - An helper to build and send an SCMI command using
 * the provided SCMI bare message buffer
 *
 * @raw: A reference to the Raw instance.
 * @buf: A buffer containing the whole SCMI message to send (including the
 *	 header) in little-endian binary format.
 * @len: Length of the message in @buf.
 * @chan_id: The channel ID to use.
 * @async: A flag stating if an asynchronous command is required.
 *
 * Return: 0 on Success
 */
static int scmi_raw_message_send(struct scmi_raw_mode_info *raw,
				 void *buf, size_t len, u8 chan_id, bool async)
{
	int ret;
	struct scmi_xfer *xfer;

	ret = scmi_xfer_raw_get_init(raw, buf, len, &xfer);
	if (ret)
		return ret;

	ret = scmi_do_xfer_raw_start(raw, xfer, chan_id, async);
	if (ret)
		scmi_xfer_raw_put(raw->handle, xfer);

	return ret;
}

static struct scmi_raw_buffer *
scmi_raw_message_dequeue(struct scmi_raw_queue *q, bool o_nonblock)
{
	unsigned long flags;
	struct scmi_raw_buffer *rb;

	spin_lock_irqsave(&q->msg_q_lock, flags);
	while (list_empty(&q->msg_q)) {
		spin_unlock_irqrestore(&q->msg_q_lock, flags);

		if (o_nonblock)
			return ERR_PTR(-EAGAIN);

		if (wait_event_interruptible(q->wq, !list_empty(&q->msg_q)))
			return ERR_PTR(-ERESTARTSYS);

		spin_lock_irqsave(&q->msg_q_lock, flags);
	}

	rb = scmi_raw_buffer_dequeue_unlocked(q);

	spin_unlock_irqrestore(&q->msg_q_lock, flags);

	return rb;
}

/**
 * scmi_raw_message_receive  - An helper to dequeue and report the next
 * available enqueued raw message payload that has been collected.
 *
 * @raw: A reference to the Raw instance.
 * @buf: A buffer to get hold of the whole SCMI message received and represented
 *	 in little-endian binary format.
 * @len: Length of @buf.
 * @size: The effective size of the message copied into @buf
 * @idx: The index of the queue to pick the next queued message from.
 * @chan_id: The channel ID to use.
 * @o_nonblock: A flag to request a non-blocking message dequeue.
 *
 * Return: 0 on Success
 */
static int scmi_raw_message_receive(struct scmi_raw_mode_info *raw,
				    void *buf, size_t len, size_t *size,
				    unsigned int idx, unsigned int chan_id,
				    bool o_nonblock)
{
	int ret = 0;
	struct scmi_raw_buffer *rb;
	struct scmi_raw_queue *q;

	q = scmi_raw_queue_select(raw, idx, chan_id);
	if (!q)
		return -ENODEV;

	rb = scmi_raw_message_dequeue(q, o_nonblock);
	if (IS_ERR(rb)) {
		dev_dbg(raw->handle->dev, "RAW - No message available!\n");
		return PTR_ERR(rb);
	}

	if (rb->msg.len <= len) {
		memcpy(buf, rb->msg.buf, rb->msg.len);
		*size = rb->msg.len;
	} else {
		ret = -ENOSPC;
	}

	scmi_raw_buffer_put(q, rb);

	return ret;
}

/* SCMI Raw debugfs helpers */

static ssize_t scmi_dbg_raw_mode_common_read(struct file *filp,
					     char __user *buf,
					     size_t count, loff_t *ppos,
					     unsigned int idx)
{
	ssize_t cnt;
	struct scmi_dbg_raw_data *rd = filp->private_data;

	if (!rd->rx_size) {
		int ret;

		ret = scmi_raw_message_receive(rd->raw, rd->rx.buf, rd->rx.len,
					       &rd->rx_size, idx, rd->chan_id,
					       filp->f_flags & O_NONBLOCK);
		if (ret) {
			rd->rx_size = 0;
			return ret;
		}

		/* Reset any previous filepos change, including writes */
		*ppos = 0;
	} else if (*ppos == rd->rx_size) {
		/* Return EOF once all the message has been read-out */
		rd->rx_size = 0;
		return 0;
	}

	cnt = simple_read_from_buffer(buf, count, ppos,
				      rd->rx.buf, rd->rx_size);

	return cnt;
}

static ssize_t scmi_dbg_raw_mode_common_write(struct file *filp,
					      const char __user *buf,
					      size_t count, loff_t *ppos,
					      bool async)
{
	int ret;
	struct scmi_dbg_raw_data *rd = filp->private_data;

	if (count > rd->tx.len - rd->tx_size)
		return -ENOSPC;

	/* On first write attempt @count carries the total full message size. */
	if (!rd->tx_size)
		rd->tx_req_size = count;

	/*
	 * Gather a full message, possibly across multiple interrupted wrrtes,
	 * before sending it with a single RAW xfer.
	 */
	if (rd->tx_size < rd->tx_req_size) {
		ssize_t cnt;

		cnt = simple_write_to_buffer(rd->tx.buf, rd->tx.len, ppos,
					     buf, count);
		if (cnt < 0)
			return cnt;

		rd->tx_size += cnt;
		if (cnt < count)
			return cnt;
	}

	ret = scmi_raw_message_send(rd->raw, rd->tx.buf, rd->tx_size,
				    rd->chan_id, async);

	/* Reset ppos for next message ... */
	rd->tx_size = 0;
	*ppos = 0;

	return ret ?: count;
}

static __poll_t scmi_test_dbg_raw_common_poll(struct file *filp,
					      struct poll_table_struct *wait,
					      unsigned int idx)
{
	unsigned long flags;
	struct scmi_dbg_raw_data *rd = filp->private_data;
	struct scmi_raw_queue *q;
	__poll_t mask = 0;

	q = scmi_raw_queue_select(rd->raw, idx, rd->chan_id);
	if (!q)
		return mask;

	poll_wait(filp, &q->wq, wait);

	spin_lock_irqsave(&q->msg_q_lock, flags);
	if (!list_empty(&q->msg_q))
		mask = EPOLLIN | EPOLLRDNORM;
	spin_unlock_irqrestore(&q->msg_q_lock, flags);

	return mask;
}

static ssize_t scmi_dbg_raw_mode_message_read(struct file *filp,
					      char __user *buf,
					      size_t count, loff_t *ppos)
{
	return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos,
					     SCMI_RAW_REPLY_QUEUE);
}

static ssize_t scmi_dbg_raw_mode_message_write(struct file *filp,
					       const char __user *buf,
					       size_t count, loff_t *ppos)
{
	return scmi_dbg_raw_mode_common_write(filp, buf, count, ppos, false);
}

static __poll_t scmi_dbg_raw_mode_message_poll(struct file *filp,
					       struct poll_table_struct *wait)
{
	return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_REPLY_QUEUE);
}

static int scmi_dbg_raw_mode_open(struct inode *inode, struct file *filp)
{
	u8 id;
	struct scmi_raw_mode_info *raw;
	struct scmi_dbg_raw_data *rd;
	const char *id_str = filp->f_path.dentry->d_parent->d_name.name;

	if (!inode->i_private)
		return -ENODEV;

	raw = inode->i_private;
	rd = kzalloc(sizeof(*rd), GFP_KERNEL);
	if (!rd)
		return -ENOMEM;

	rd->rx.len = raw->desc->max_msg_size + sizeof(u32);
	rd->rx.buf = kzalloc(rd->rx.len, GFP_KERNEL);
	if (!rd->rx.buf) {
		kfree(rd);
		return -ENOMEM;
	}

	rd->tx.len = raw->desc->max_msg_size + sizeof(u32);
	rd->tx.buf = kzalloc(rd->tx.len, GFP_KERNEL);
	if (!rd->tx.buf) {
		kfree(rd->rx.buf);
		kfree(rd);
		return -ENOMEM;
	}

	/* Grab channel ID from debugfs entry naming if any */
	if (!kstrtou8(id_str, 16, &id))
		rd->chan_id = id;

	rd->raw = raw;
	filp->private_data = rd;

	return 0;
}

static int scmi_dbg_raw_mode_release(struct inode *inode, struct file *filp)
{
	struct scmi_dbg_raw_data *rd = filp->private_data;

	kfree(rd->rx.buf);
	kfree(rd->tx.buf);
	kfree(rd);

	return 0;
}

static ssize_t scmi_dbg_raw_mode_reset_write(struct file *filp,
					     const char __user *buf,
					     size_t count, loff_t *ppos)
{
	struct scmi_dbg_raw_data *rd = filp->private_data;

	scmi_xfer_raw_reset(rd->raw);

	return count;
}

static const struct file_operations scmi_dbg_raw_mode_reset_fops = {
	.open = scmi_dbg_raw_mode_open,
	.release = scmi_dbg_raw_mode_release,
	.write = scmi_dbg_raw_mode_reset_write,
	.owner = THIS_MODULE,
};

static const struct file_operations scmi_dbg_raw_mode_message_fops = {
	.open = scmi_dbg_raw_mode_open,
	.release = scmi_dbg_raw_mode_release,
	.read = scmi_dbg_raw_mode_message_read,
	.write = scmi_dbg_raw_mode_message_write,
	.poll = scmi_dbg_raw_mode_message_poll,
	.owner = THIS_MODULE,
};

static ssize_t scmi_dbg_raw_mode_message_async_write(struct file *filp,
						     const char __user *buf,
						     size_t count, loff_t *ppos)
{
	return scmi_dbg_raw_mode_common_write(filp, buf, count, ppos, true);
}

static const struct file_operations scmi_dbg_raw_mode_message_async_fops = {
	.open = scmi_dbg_raw_mode_open,
	.release = scmi_dbg_raw_mode_release,
	.read = scmi_dbg_raw_mode_message_read,
	.write = scmi_dbg_raw_mode_message_async_write,
	.poll = scmi_dbg_raw_mode_message_poll,
	.owner = THIS_MODULE,
};

static ssize_t scmi_test_dbg_raw_mode_notif_read(struct file *filp,
						 char __user *buf,
						 size_t count, loff_t *ppos)
{
	return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos,
					     SCMI_RAW_NOTIF_QUEUE);
}

static __poll_t
scmi_test_dbg_raw_mode_notif_poll(struct file *filp,
				  struct poll_table_struct *wait)
{
	return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_NOTIF_QUEUE);
}

static const struct file_operations scmi_dbg_raw_mode_notification_fops = {
	.open = scmi_dbg_raw_mode_open,
	.release = scmi_dbg_raw_mode_release,
	.read = scmi_test_dbg_raw_mode_notif_read,
	.poll = scmi_test_dbg_raw_mode_notif_poll,
	.owner = THIS_MODULE,
};

static ssize_t scmi_test_dbg_raw_mode_errors_read(struct file *filp,
						  char __user *buf,
						  size_t count, loff_t *ppos)
{
	return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos,
					     SCMI_RAW_ERRS_QUEUE);
}

static __poll_t
scmi_test_dbg_raw_mode_errors_poll(struct file *filp,
				   struct poll_table_struct *wait)
{
	return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_ERRS_QUEUE);
}

static const struct file_operations scmi_dbg_raw_mode_errors_fops = {
	.open = scmi_dbg_raw_mode_open,
	.release = scmi_dbg_raw_mode_release,
	.read = scmi_test_dbg_raw_mode_errors_read,
	.poll = scmi_test_dbg_raw_mode_errors_poll,
	.owner = THIS_MODULE,
};

static struct scmi_raw_queue *
scmi_raw_queue_init(struct scmi_raw_mode_info *raw)
{
	int i;
	struct scmi_raw_buffer *rb;
	struct device *dev = raw->handle->dev;
	struct scmi_raw_queue *q;

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

	rb = devm_kcalloc(dev, raw->tx_max_msg, sizeof(*rb), GFP_KERNEL);
	if (!rb)
		return ERR_PTR(-ENOMEM);

	spin_lock_init(&q->free_bufs_lock);
	INIT_LIST_HEAD(&q->free_bufs);
	for (i = 0; i < raw->tx_max_msg; i++, rb++) {
		rb->max_len = raw->desc->max_msg_size + sizeof(u32);
		rb->msg.buf = devm_kzalloc(dev, rb->max_len, GFP_KERNEL);
		if (!rb->msg.buf)
			return ERR_PTR(-ENOMEM);
		scmi_raw_buffer_put(q, rb);
	}

	spin_lock_init(&q->msg_q_lock);
	INIT_LIST_HEAD(&q->msg_q);
	init_waitqueue_head(&q->wq);

	return q;
}

static int scmi_xfer_raw_worker_init(struct scmi_raw_mode_info *raw)
{
	int i;
	struct scmi_xfer_raw_waiter *rw;
	struct device *dev = raw->handle->dev;

	rw = devm_kcalloc(dev, raw->tx_max_msg, sizeof(*rw), GFP_KERNEL);
	if (!rw)
		return -ENOMEM;

	raw->wait_wq = alloc_workqueue("scmi-raw-wait-wq-%d",
				       WQ_UNBOUND | WQ_FREEZABLE |
				       WQ_HIGHPRI | WQ_SYSFS, 0, raw->id);
	if (!raw->wait_wq)
		return -ENOMEM;

	mutex_init(&raw->free_mtx);
	INIT_LIST_HEAD(&raw->free_waiters);
	mutex_init(&raw->active_mtx);
	INIT_LIST_HEAD(&raw->active_waiters);

	for (i = 0; i < raw->tx_max_msg; i++, rw++) {
		init_completion(&rw->async_response);
		scmi_xfer_raw_waiter_put(raw, rw);
	}
	INIT_WORK(&raw->waiters_work, scmi_xfer_raw_worker);

	return 0;
}

static int scmi_raw_mode_setup(struct scmi_raw_mode_info *raw,
			       u8 *channels, int num_chans)
{
	int ret, idx;
	void *gid;
	struct device *dev = raw->handle->dev;

	gid = devres_open_group(dev, NULL, GFP_KERNEL);
	if (!gid)
		return -ENOMEM;

	for (idx = 0; idx < SCMI_RAW_MAX_QUEUE; idx++) {
		raw->q[idx] = scmi_raw_queue_init(raw);
		if (IS_ERR(raw->q[idx])) {
			ret = PTR_ERR(raw->q[idx]);
			goto err;
		}
	}

	xa_init(&raw->chans_q);
	if (num_chans > 1) {
		int i;

		for (i = 0; i < num_chans; i++) {
			struct scmi_raw_queue *q;

			q = scmi_raw_queue_init(raw);
			if (IS_ERR(q)) {
				ret = PTR_ERR(q);
				goto err_xa;
			}

			ret = xa_insert(&raw->chans_q, channels[i], q,
					GFP_KERNEL);
			if (ret) {
				dev_err(dev,
					"Fail to allocate Raw queue 0x%02X\n",
					channels[i]);
				goto err_xa;
			}
		}
	}

	ret = scmi_xfer_raw_worker_init(raw);
	if (ret)
		goto err_xa;

	devres_close_group(dev, gid);
	raw->gid = gid;

	return 0;

err_xa:
	xa_destroy(&raw->chans_q);
err:
	devres_release_group(dev, gid);
	return ret;
}

/**
 * scmi_raw_mode_init  - Function to initialize the SCMI Raw stack
 *
 * @handle: Pointer to SCMI entity handle
 * @top_dentry: A reference to the top Raw debugfs dentry
 * @instance_id: The ID of the underlying SCMI platform instance represented by
 *		 this Raw instance
 * @channels: The list of the existing channels
 * @num_chans: The number of entries in @channels
 * @desc: Reference to the transport operations
 * @tx_max_msg: Max number of in-flight messages allowed by the transport
 *
 * This function prepare the SCMI Raw stack and creates the debugfs API.
 *
 * Return: An opaque handle to the Raw instance on Success, an ERR_PTR otherwise
 */
void *scmi_raw_mode_init(const struct scmi_handle *handle,
			 struct dentry *top_dentry, int instance_id,
			 u8 *channels, int num_chans,
			 const struct scmi_desc *desc, int tx_max_msg)
{
	int ret;
	struct scmi_raw_mode_info *raw;
	struct device *dev;

	if (!handle || !desc)
		return ERR_PTR(-EINVAL);

	dev = handle->dev;
	raw = devm_kzalloc(dev, sizeof(*raw), GFP_KERNEL);
	if (!raw)
		return ERR_PTR(-ENOMEM);

	raw->handle = handle;
	raw->desc = desc;
	raw->tx_max_msg = tx_max_msg;
	raw->id = instance_id;

	ret = scmi_raw_mode_setup(raw, channels, num_chans);
	if (ret) {
		devm_kfree(dev, raw);
		return ERR_PTR(ret);
	}

	raw->dentry = debugfs_create_dir("raw", top_dentry);

	debugfs_create_file("reset", 0200, raw->dentry, raw,
			    &scmi_dbg_raw_mode_reset_fops);

	debugfs_create_file("message", 0600, raw->dentry, raw,
			    &scmi_dbg_raw_mode_message_fops);

	debugfs_create_file("message_async", 0600, raw->dentry, raw,
			    &scmi_dbg_raw_mode_message_async_fops);

	debugfs_create_file("notification", 0400, raw->dentry, raw,
			    &scmi_dbg_raw_mode_notification_fops);

	debugfs_create_file("errors", 0400, raw->dentry, raw,
			    &scmi_dbg_raw_mode_errors_fops);

	/*
	 * Expose per-channel entries if multiple channels available.
	 * Just ignore errors while setting up these interfaces since we
	 * have anyway already a working core Raw support.
	 */
	if (num_chans > 1) {
		int i;
		struct dentry *top_chans;

		top_chans = debugfs_create_dir("channels", raw->dentry);

		for (i = 0; i < num_chans; i++) {
			char cdir[8];
			struct dentry *chd;

			snprintf(cdir, 8, "0x%02X", channels[i]);
			chd = debugfs_create_dir(cdir, top_chans);

			debugfs_create_file("message", 0600, chd, raw,
					    &scmi_dbg_raw_mode_message_fops);

			debugfs_create_file("message_async", 0600, chd, raw,
					    &scmi_dbg_raw_mode_message_async_fops);
		}
	}

	dev_info(dev, "SCMI RAW Mode initialized for instance %d\n", raw->id);

	return raw;
}

/**
 * scmi_raw_mode_cleanup  - Function to cleanup the SCMI Raw stack
 *
 * @r: An opaque handle to an initialized SCMI Raw instance
 */
void scmi_raw_mode_cleanup(void *r)
{
	struct scmi_raw_mode_info *raw = r;

	if (!raw)
		return;

	debugfs_remove_recursive(raw->dentry);

	cancel_work_sync(&raw->waiters_work);
	destroy_workqueue(raw->wait_wq);
	xa_destroy(&raw->chans_q);
}

static int scmi_xfer_raw_collect(void *msg, size_t *msg_len,
				 struct scmi_xfer *xfer)
{
	__le32 *m;
	size_t msg_size;

	if (!xfer || !msg || !msg_len)
		return -EINVAL;

	/* Account for hdr ...*/
	msg_size = xfer->rx.len + sizeof(u32);
	/* ... and status if needed */
	if (xfer->hdr.type != MSG_TYPE_NOTIFICATION)
		msg_size += sizeof(u32);

	if (msg_size > *msg_len)
		return -ENOSPC;

	m = msg;
	*m = cpu_to_le32(pack_scmi_header(&xfer->hdr));
	if (xfer->hdr.type != MSG_TYPE_NOTIFICATION)
		*++m = cpu_to_le32(xfer->hdr.status);

	memcpy(++m, xfer->rx.buf, xfer->rx.len);

	*msg_len = msg_size;

	return 0;
}

/**
 * scmi_raw_message_report  - Helper to report back valid reponses/notifications
 * to raw message requests.
 *
 * @r: An opaque reference to the raw instance configuration
 * @xfer: The xfer containing the message to be reported
 * @idx: The index of the queue.
 * @chan_id: The channel ID to use.
 *
 * If Raw mode is enabled, this is called from the SCMI core on the regular RX
 * path to save and enqueue the response/notification payload carried by this
 * xfer into a dedicated scmi_raw_buffer for later consumption by the user.
 *
 * This way the caller can free the related xfer immediately afterwards and the
 * user can read back the raw message payload at its own pace (if ever) without
 * holding an xfer for too long.
 */
void scmi_raw_message_report(void *r, struct scmi_xfer *xfer,
			     unsigned int idx, unsigned int chan_id)
{
	int ret;
	unsigned long flags;
	struct scmi_raw_buffer *rb;
	struct device *dev;
	struct scmi_raw_queue *q;
	struct scmi_raw_mode_info *raw = r;

	if (!raw || (idx == SCMI_RAW_REPLY_QUEUE && !SCMI_XFER_IS_RAW(xfer)))
		return;

	dev = raw->handle->dev;
	q = scmi_raw_queue_select(raw, idx,
				  SCMI_XFER_IS_CHAN_SET(xfer) ? chan_id : 0);
	if (!q) {
		dev_warn(dev,
			 "RAW[%d] - NO queue for chan 0x%X. Dropping report.\n",
			 idx, chan_id);
		return;
	}

	/*
	 * Grab the msg_q_lock upfront to avoid a possible race between
	 * realizing the free list was empty and effectively picking the next
	 * buffer to use from the oldest one enqueued and still unread on this
	 * msg_q.
	 *
	 * Note that nowhere else these locks are taken together, so no risk of
	 * deadlocks du eto inversion.
	 */
	spin_lock_irqsave(&q->msg_q_lock, flags);
	rb = scmi_raw_buffer_get(q);
	if (!rb) {
		/*
		 * Immediate and delayed replies to previously injected Raw
		 * commands MUST be read back from userspace to free the buffers:
		 * if this is not happening something is seriously broken and
		 * must be fixed at the application level: complain loudly.
		 */
		if (idx == SCMI_RAW_REPLY_QUEUE) {
			spin_unlock_irqrestore(&q->msg_q_lock, flags);
			dev_warn(dev,
				 "RAW[%d] - Buffers exhausted. Dropping report.\n",
				 idx);
			return;
		}

		/*
		 * Notifications and errors queues are instead handled in a
		 * circular manner: unread old buffers are just overwritten by
		 * newer ones.
		 *
		 * The main reason for this is that notifications originated
		 * by Raw requests cannot be distinguished from normal ones, so
		 * your Raw buffers queues risk to be flooded and depleted by
		 * notifications if you left it mistakenly enabled or when in
		 * coexistence mode.
		 */
		rb = scmi_raw_buffer_dequeue_unlocked(q);
		if (WARN_ON(!rb)) {
			spin_unlock_irqrestore(&q->msg_q_lock, flags);
			return;
		}

		/* Reset to full buffer length */
		rb->msg.len = rb->max_len;

		dev_warn_once(dev,
			      "RAW[%d] - Buffers exhausted. Re-using oldest.\n",
			      idx);
	}
	spin_unlock_irqrestore(&q->msg_q_lock, flags);

	ret = scmi_xfer_raw_collect(rb->msg.buf, &rb->msg.len, xfer);
	if (ret) {
		dev_warn(dev, "RAW - Cannot collect xfer into buffer !\n");
		scmi_raw_buffer_put(q, rb);
		return;
	}

	scmi_raw_buffer_enqueue(q, rb);
}

static void scmi_xfer_raw_fill(struct scmi_raw_mode_info *raw,
			       struct scmi_chan_info *cinfo,
			       struct scmi_xfer *xfer, u32 msg_hdr)
{
	/* Unpack received HDR as it is */
	unpack_scmi_header(msg_hdr, &xfer->hdr);
	xfer->hdr.seq = MSG_XTRACT_TOKEN(msg_hdr);

	memset(xfer->rx.buf, 0x00, xfer->rx.len);

	raw->desc->ops->fetch_response(cinfo, xfer);
}

/**
 * scmi_raw_error_report  - Helper to report back timed-out or generally
 * unexpected replies.
 *
 * @r: An opaque reference to the raw instance configuration
 * @cinfo: A reference to the channel to use to retrieve the broken xfer
 * @msg_hdr: The SCMI message header of the message to fetch and report
 * @priv: Any private data related to the xfer.
 *
 * If Raw mode is enabled, this is called from the SCMI core on the RX path in
 * case of errors to save and enqueue the bad message payload carried by the
 * message that has just been received.
 *
 * Note that we have to manually fetch any available payload into a temporary
 * xfer to be able to save and enqueue the message, since the regular RX error
 * path which had called this would have not fetched the message payload having
 * classified it as an error.
 */
void scmi_raw_error_report(void *r, struct scmi_chan_info *cinfo,
			   u32 msg_hdr, void *priv)
{
	struct scmi_xfer xfer;
	struct scmi_raw_mode_info *raw = r;

	if (!raw)
		return;

	xfer.rx.len = raw->desc->max_msg_size;
	xfer.rx.buf = kzalloc(xfer.rx.len, GFP_ATOMIC);
	if (!xfer.rx.buf) {
		dev_info(raw->handle->dev,
			 "Cannot report Raw error for HDR:0x%X - ENOMEM\n",
			 msg_hdr);
		return;
	}

	/* Any transport-provided priv must be passed back down to transport */
	if (priv)
		/* Ensure priv is visible */
		smp_store_mb(xfer.priv, priv);

	scmi_xfer_raw_fill(raw, cinfo, &xfer, msg_hdr);
	scmi_raw_message_report(raw, &xfer, SCMI_RAW_ERRS_QUEUE, 0);

	kfree(xfer.rx.buf);
}
