// SPDX-License-Identifier: GPL-2.0-only
/*
 * GCIP Mailbox Interface.
 *
 * Copyright (C) 2022 Google LLC
 */

#include <linux/device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h> /* memcpy */
#include <linux/wait.h>

#include <gcip/gcip-mailbox.h>

#if IS_ENABLED(CONFIG_GCIP_TEST)
#include "unittests/helper/gcip-mailbox-controller.h"

#define TEST_TRIGGER_TIMEOUT_RACE(awaiter) gcip_mailbox_controller_trigger_timeout_race(awaiter)
#else
#define TEST_TRIGGER_TIMEOUT_RACE(...)
#endif

#define GET_CMD_QUEUE_HEAD() mailbox->ops->get_cmd_queue_head(mailbox)
#define GET_CMD_QUEUE_TAIL() mailbox->ops->get_cmd_queue_tail(mailbox)
#define INC_CMD_QUEUE_TAIL(inc) mailbox->ops->inc_cmd_queue_tail(mailbox, inc)
#define ACQUIRE_CMD_QUEUE_LOCK(try, atomic)                                                        \
	mailbox->ops->acquire_cmd_queue_lock(mailbox, try, atomic)
#define RELEASE_CMD_QUEUE_LOCK() mailbox->ops->release_cmd_queue_lock(mailbox)

#define GET_CMD_ELEM_SEQ(cmd) mailbox->ops->get_cmd_elem_seq(mailbox, cmd)
#define SET_CMD_ELEM_SEQ(cmd, seq) mailbox->ops->set_cmd_elem_seq(mailbox, cmd, seq)
#define GET_CMD_ELEM_CODE(cmd) mailbox->ops->get_cmd_elem_code(mailbox, cmd)

#define GET_RESP_QUEUE_SIZE() mailbox->ops->get_resp_queue_size(mailbox)
#define GET_RESP_QUEUE_HEAD() mailbox->ops->get_resp_queue_head(mailbox)
#define INC_RESP_QUEUE_HEAD(inc) mailbox->ops->inc_resp_queue_head(mailbox, inc)
#define GET_RESP_QUEUE_TAIL() mailbox->ops->get_resp_queue_tail(mailbox)
#define ACQUIRE_RESP_QUEUE_LOCK(try, atomic)                                                       \
	mailbox->ops->acquire_resp_queue_lock(mailbox, try, atomic)
#define RELEASE_RESP_QUEUE_LOCK() mailbox->ops->release_resp_queue_lock(mailbox)

#define GET_RESP_ELEM_SEQ(resp) mailbox->ops->get_resp_elem_seq(mailbox, resp)
#define SET_RESP_ELEM_SEQ(resp, seq) mailbox->ops->set_resp_elem_seq(mailbox, resp, seq)

#define ACQUIRE_WAIT_LIST_LOCK(irqsave, flags)                                                     \
	mailbox->ops->acquire_wait_list_lock(mailbox, irqsave, flags)
#define RELEASE_WAIT_LIST_LOCK(irqrestore, flags)                                                  \
	mailbox->ops->release_wait_list_lock(mailbox, irqrestore, flags)

#define IS_BLOCK_OFF() (mailbox->ops->is_block_off ? mailbox->ops->is_block_off(mailbox) : false)

struct gcip_mailbox_wait_list_elem {
	struct list_head list;
	struct gcip_mailbox_async_resp *async_resp;
	struct gcip_mailbox_resp_awaiter *awaiter;
};

static void gcip_mailbox_awaiter_release(struct gcip_mailbox_resp_awaiter *awaiter)
{
	if (awaiter->release_data)
		awaiter->release_data(awaiter->data);
	kfree(awaiter);
}

static void gcip_mailbox_awaiter_dec_refs(struct gcip_mailbox_resp_awaiter *awaiter)
{
	if (refcount_dec_and_test(&awaiter->refs))
		gcip_mailbox_awaiter_release(awaiter);
}

/*
 * Removes the response previously pushed with gcip_mailbox_push_wait_resp().
 *
 * This is used when the kernel gives up waiting for the response.
 */
static void gcip_mailbox_del_wait_resp(struct gcip_mailbox *mailbox,
				       struct gcip_mailbox_async_resp *async_resp)
{
	struct gcip_mailbox_wait_list_elem *cur;
	unsigned long flags;
	u64 cur_seq, seq = GET_RESP_ELEM_SEQ(async_resp->resp);

	ACQUIRE_WAIT_LIST_LOCK(true, &flags);

	list_for_each_entry (cur, &mailbox->wait_list, list) {
		cur_seq = GET_RESP_ELEM_SEQ(cur->async_resp->resp);
		if (cur_seq == seq) {
			list_del(&cur->list);
			if (cur->awaiter) {
				/* Remove the reference of the arrived handler. */
				gcip_mailbox_awaiter_dec_refs(cur->awaiter);
			}
			kfree(cur);
			break;
		}
	}

	RELEASE_WAIT_LIST_LOCK(true, flags);
}

/*
 * Adds @resp to @mailbox->wait_list. If @awaiter is not NULL, the @resp is asynchronous.
 * Otherwise, the @resp is synchronous.
 *
 * wait_list is a FIFO queue, with sequence number in increasing order.
 *
 * Returns 0 on success, or -ENOMEM if failed on allocation.
 */
static int gcip_mailbox_push_wait_resp(struct gcip_mailbox *mailbox,
				       struct gcip_mailbox_async_resp *async_resp,
				       struct gcip_mailbox_resp_awaiter *awaiter, bool atomic)
{
	struct gcip_mailbox_wait_list_elem *entry;
	unsigned long flags;
	int ret;

	entry = kzalloc(sizeof(*entry), atomic ? GFP_ATOMIC : GFP_KERNEL);
	if (!entry)
		return -ENOMEM;

	if (mailbox->ops->before_enqueue_wait_list) {
		ret = mailbox->ops->before_enqueue_wait_list(mailbox, async_resp->resp, awaiter);
		if (ret) {
			kfree(entry);
			return ret;
		}
	}

	/* Increase a reference of arrived handler. */
	if (awaiter)
		refcount_inc(&awaiter->refs);

	entry->async_resp = async_resp;
	entry->awaiter = awaiter;
	ACQUIRE_WAIT_LIST_LOCK(true, &flags);
	list_add_tail(&entry->list, &mailbox->wait_list);
	RELEASE_WAIT_LIST_LOCK(true, flags);

	return 0;
}

/* The locked version of gcip_mailbox_inc_seq_num */
static uint gcip_mailbox_inc_seq_num_locked(struct gcip_mailbox *mailbox, uint n)
{
	uint ret = mailbox->cur_seq;

	mailbox->cur_seq += n;

	return ret;
}

/*
 * Pushes @cmd to the command queue of mailbox and returns. @resp should be passed if the request
 * is synchronous and want to get the response. If @resp is NULL even though the request is
 * synchronous, the @cmd will be put into the queue, but the caller may not wait the response and
 * ignore it. If the request is async, @awaiter should be passed too.
 */
static int gcip_mailbox_enqueue_cmd(struct gcip_mailbox *mailbox, void *cmd,
				    struct gcip_mailbox_async_resp *async_resp,
				    struct gcip_mailbox_resp_awaiter *awaiter,
				    gcip_mailbox_cmd_flags_t flags)
{
	int ret = 0;
	u32 tail;
	bool atomic = false;

	ACQUIRE_CMD_QUEUE_LOCK(false, &atomic);

	if (!(flags & GCIP_MAILBOX_CMD_FLAGS_SKIP_ASSIGN_SEQ))
		SET_CMD_ELEM_SEQ(cmd, mailbox->cur_seq);
	/*
	 * The lock ensures mailbox cmd_queue_tail cannot be changed by other processes (this
	 * method should be the only one to modify the value of tail), therefore we can remember
	 * its value here and use it in the condition of wait_event() call.
	 */
	tail = GET_CMD_QUEUE_TAIL();

	if (mailbox->ops->wait_for_cmd_queue_not_full) {
		/* Wait until the cmd queue has a space for putting cmd. */
		ret = mailbox->ops->wait_for_cmd_queue_not_full(mailbox);
		if (ret)
			goto out;
	} else if (GET_CMD_QUEUE_HEAD() == (tail ^ mailbox->queue_wrap_bit)) {
		/*
		 * Default logic of checking the fullness of cmd_queue. If the cmd_queue is full,
		 * it's up to the caller to retry.
		 */
		ret = -EAGAIN;
		goto out;
	}

	if (async_resp->resp) {
		/* Adds @resp to the wait_list only if the cmd can be pushed successfully. */
		SET_RESP_ELEM_SEQ(async_resp->resp, GET_CMD_ELEM_SEQ(cmd));
		async_resp->status = GCIP_MAILBOX_STATUS_WAITING_RESPONSE;
		ret = gcip_mailbox_push_wait_resp(mailbox, async_resp, awaiter, atomic);
		if (ret)
			goto out;
	}
	/* Size of cmd_queue is a multiple of mailbox->cmd_elem_size. */
	memcpy(mailbox->cmd_queue + mailbox->cmd_elem_size *
					    CIRC_QUEUE_REAL_INDEX(tail, mailbox->queue_wrap_bit),
	       cmd, mailbox->cmd_elem_size);
	INC_CMD_QUEUE_TAIL(1);
	if (mailbox->ops->after_enqueue_cmd) {
		ret = mailbox->ops->after_enqueue_cmd(mailbox, cmd);
		if (ret) {
			/*
			 * Currently, as both DSP and EdgeTPU never return errors, do nothing
			 * here. We can decide later how to rollback the status such as
			 * `cmd_queue_tail` when the possibility of returning an error is raised.
			 */
			dev_warn(mailbox->dev,
				 "after_enqueue_cmd returned an error, but not handled: ret=%d\n",
				 ret);
			goto out;
		}
	}

	if (!(flags & GCIP_MAILBOX_CMD_FLAGS_SKIP_ASSIGN_SEQ))
		gcip_mailbox_inc_seq_num_locked(mailbox, 1);

out:
	RELEASE_CMD_QUEUE_LOCK();
	if (ret)
		dev_dbg(mailbox->dev, "%s: ret=%d", __func__, ret);

	return ret;
}

/*
 * Handler of a response.
 * Pops the wait_list until the sequence number of @resp is found, and copies @resp to the found
 * entry.
 */
static void gcip_mailbox_handle_response(struct gcip_mailbox *mailbox, void *resp)
{
	struct gcip_mailbox_wait_list_elem *cur, *nxt;
	struct gcip_mailbox_resp_awaiter *awaiter = NULL;
	unsigned long flags;
	u64 cur_seq, seq = GET_RESP_ELEM_SEQ(resp);

	/* If before_handle_resp is defined and it returns false, don't handle the response */
	if (mailbox->ops->before_handle_resp && !mailbox->ops->before_handle_resp(mailbox, resp))
		return;

	ACQUIRE_WAIT_LIST_LOCK(true, &flags);

	list_for_each_entry_safe (cur, nxt, &mailbox->wait_list, list) {
		cur_seq = GET_RESP_ELEM_SEQ(cur->async_resp->resp);
		if (cur_seq != seq)
			continue;
		cur->async_resp->status = GCIP_MAILBOX_STATUS_OK;
		memcpy(cur->async_resp->resp, resp, mailbox->resp_elem_size);
		list_del(&cur->list);
		awaiter = cur->awaiter;
		if (awaiter) {
			/*
			 * The timedout handler will be fired, but pended by waiting for acquiring
			 * the wait_list_lock.
			 */
			TEST_TRIGGER_TIMEOUT_RACE(awaiter);
		}
		kfree(cur);
		break;
	}

	RELEASE_WAIT_LIST_LOCK(true, flags);

	if (!awaiter)
		return;

	/*
	 * If canceling timeout_work succeeded, we have to decrease the reference count here because
	 * the timeout handler will not be called. Otherwise, the timeout handler is already
	 * canceled or pending by race. If it is canceled, the count must be decreased already, and
	 * if it is pending, the timeout handler will decrease the awaiter reference.
	 */
	if (cancel_delayed_work(&awaiter->timeout_work))
		gcip_mailbox_awaiter_dec_refs(awaiter);
	if (mailbox->ops->handle_awaiter_arrived)
		mailbox->ops->handle_awaiter_arrived(mailbox, awaiter);
	/* Remove the reference of the arrived handler. */
	gcip_mailbox_awaiter_dec_refs(awaiter);
}

/*
 * Fetches elements in the response queue.
 *
 * Returns the pointer of fetched response elements.
 * @total_ptr will be the number of elements fetched.
 *
 * Returns -ENOMEM if failed on memory allocation.
 * Returns NULL if the response queue is empty or there is another worker fetching responses.
 */
static void *gcip_mailbox_fetch_responses(struct gcip_mailbox *mailbox, u32 *total_ptr)
{
	u32 head;
	u32 tail;
	u32 count;
	u32 i;
	u32 j;
	u32 total = 0;
	const u32 wrap_bit = mailbox->queue_wrap_bit;
	const u32 size = GET_RESP_QUEUE_SIZE();
	const u32 elem_size = mailbox->resp_elem_size;
	void *ret = NULL; /* Array of responses. */
	void *prev_ptr = NULL; /* Temporary pointer to realloc ret. */
	bool atomic = false;

	/* The block is off or someone is working on consuming - we can leave early. */
	if (IS_BLOCK_OFF() || !ACQUIRE_RESP_QUEUE_LOCK(true, &atomic))
		goto out;

	head = GET_RESP_QUEUE_HEAD();
	/* Loops until our head equals to CSR tail. */
	while (1) {
		tail = GET_RESP_QUEUE_TAIL();
		/*
		 * Make sure the CSR is read and reported properly by checking if any bit higher
		 * than wrap_bit is set and if the tail exceeds resp_queue size.
		 */
		if (unlikely(tail & ~CIRC_QUEUE_VALID_MASK(wrap_bit) ||
			     CIRC_QUEUE_REAL_INDEX(tail, wrap_bit) >= size)) {
			dev_err_ratelimited(mailbox->dev, "Invalid response queue tail: %#x\n",
					    tail);
			break;
		}

		count = gcip_circ_queue_cnt(head, tail, size, wrap_bit);
		if (count == 0)
			break;

		prev_ptr = ret;
		ret = krealloc(prev_ptr, (total + count) * elem_size,
			       atomic ? GFP_ATOMIC : GFP_KERNEL);
		/*
		 * Out-of-memory, we can return the previously fetched responses if any, or ENOMEM
		 * otherwise.
		 */
		if (!ret) {
			if (!prev_ptr)
				ret = ERR_PTR(-ENOMEM);
			else
				ret = prev_ptr;
			break;
		}
		/* Copies responses. */
		j = CIRC_QUEUE_REAL_INDEX(head, wrap_bit);
		for (i = 0; i < count; i++) {
			memcpy(ret + elem_size * total, mailbox->resp_queue + elem_size * j,
			       elem_size);
			j = (j + 1) % size;
			total++;
		}
		head = gcip_circ_queue_inc(head, count, size, wrap_bit);
	}
	INC_RESP_QUEUE_HEAD(total);

	RELEASE_RESP_QUEUE_LOCK();

	if (mailbox->ops->after_fetch_resps)
		mailbox->ops->after_fetch_resps(mailbox, total);
out:
	*total_ptr = total;
	return ret;
}

/* Fetches one response from the response queue. */
static int gcip_mailbox_fetch_one_response(struct gcip_mailbox *mailbox, void *resp)
{
	u32 head;
	u32 tail;
	bool atomic;

	if (IS_BLOCK_OFF() || !ACQUIRE_RESP_QUEUE_LOCK(true, &atomic))
		return 0;

	head = GET_RESP_QUEUE_HEAD();
	tail = GET_RESP_QUEUE_TAIL();
	/* Queue empty. */
	if (head == tail) {
		RELEASE_RESP_QUEUE_LOCK();
		return 0;
	}

	memcpy(resp,
	       mailbox->resp_queue + CIRC_QUEUE_REAL_INDEX(head, mailbox->queue_wrap_bit) *
					     mailbox->resp_elem_size,
	       mailbox->resp_elem_size);
	INC_RESP_QUEUE_HEAD(1);

	RELEASE_RESP_QUEUE_LOCK();

	if (mailbox->ops->after_fetch_resps)
		mailbox->ops->after_fetch_resps(mailbox, 1);

	return 1;
}

/* Handles the timed out asynchronous commands. */
static void gcip_mailbox_async_cmd_timeout_work(struct work_struct *work)
{
	struct gcip_mailbox_resp_awaiter *awaiter =
		container_of(work, struct gcip_mailbox_resp_awaiter, timeout_work.work);
	struct gcip_mailbox *mailbox = awaiter->mailbox;

	/*
	 * This function will acquire the mailbox wait_list_lock. This means if
	 * response processing is in progress, it will complete before this
	 * response can be removed from the wait list.
	 *
	 * Once this function has the wait_list_lock, no future response
	 * processing will begin until this response has been removed.
	 */
	gcip_mailbox_del_wait_resp(mailbox, &awaiter->async_resp);

	/*
	 * Handle timed out awaiter. If `handle_awaiter_timedout` is defined, @awaiter
	 * will be released from the implementation side. Otherwise, it should be freed from here.
	 */
	if (mailbox->ops->handle_awaiter_timedout)
		mailbox->ops->handle_awaiter_timedout(mailbox, awaiter);

	/* Remove the reference of the timedout handler. */
	gcip_mailbox_awaiter_dec_refs(awaiter);
}

/* Cleans up all the asynchronous responses which are not responded yet. */
static void gcip_mailbox_flush_awaiter(struct gcip_mailbox *mailbox)
{
	struct gcip_mailbox_wait_list_elem *cur, *nxt;
	struct gcip_mailbox_resp_awaiter *awaiter;
	struct list_head resps_to_flush;
	unsigned long flags;

	/* If mailbox->ops is NULL, the mailbox is already released. */
	if (!mailbox->ops)
		return;

	/*
	 * At this point only async responses should be pending. Flush them all
	 * from the `wait_list` at once so any remaining timeout workers
	 * waiting on `wait_list_lock` will know their responses have been
	 * handled already.
	 */
	INIT_LIST_HEAD(&resps_to_flush);
	ACQUIRE_WAIT_LIST_LOCK(true, &flags);
	list_for_each_entry_safe (cur, nxt, &mailbox->wait_list, list) {
		list_del(&cur->list);
		if (cur->awaiter) {
			list_add_tail(&cur->list, &resps_to_flush);
			/*
			 * Clear the response's destination queue so that if the
			 * timeout worker is running, it won't try to process
			 * this response after `wait_list_lock` is released.
			 */
			awaiter = cur->awaiter;
			if (mailbox->ops->flush_awaiter)
				mailbox->ops->flush_awaiter(mailbox, awaiter);
			/* Remove the reference of the arrived handler. */
			gcip_mailbox_awaiter_dec_refs(cur->awaiter);
		} else {
			dev_warn(mailbox->dev,
				 "Unexpected synchronous command pending on mailbox release\n");
			kfree(cur);
		}
	}
	RELEASE_WAIT_LIST_LOCK(true, flags);

	/*
	 * Cancel the timeout timer of and free any responses that were still in
	 * the `wait_list` above.
	 */
	list_for_each_entry_safe (cur, nxt, &resps_to_flush, list) {
		list_del(&cur->list);
		awaiter = cur->awaiter;
		/* Cancel the timeout work and remove the reference of the timedout handler. */
		gcip_mailbox_cancel_awaiter_timeout(awaiter);
		/* Remove the reference of the caller. */
		gcip_mailbox_awaiter_dec_refs(cur->awaiter);
		kfree(cur);
	}
}

/* Verifies and sets the mailbox operators. */
static int gcip_mailbox_set_ops(struct gcip_mailbox *mailbox, const struct gcip_mailbox_ops *ops)
{
	if (!ops) {
		mailbox->ops = NULL;
		return 0;
	}

	if (!ops->get_cmd_queue_head || !ops->get_cmd_queue_tail || !ops->inc_cmd_queue_tail ||
	    !ops->acquire_cmd_queue_lock || !ops->release_cmd_queue_lock ||
	    !ops->get_cmd_elem_seq || !ops->set_cmd_elem_seq || !ops->get_cmd_elem_code) {
		dev_err(mailbox->dev, "Incomplete mailbox CMD queue ops.\n");
		return -EINVAL;
	}

	if (!ops->get_resp_queue_size || !ops->get_resp_queue_head || !ops->get_resp_queue_tail ||
	    !ops->inc_resp_queue_head || !ops->acquire_resp_queue_lock ||
	    !ops->release_resp_queue_lock || !ops->get_resp_elem_seq || !ops->set_resp_elem_seq) {
		dev_err(mailbox->dev, "Incomplete mailbox RESP queue ops.\n");
		return -EINVAL;
	}

	if (!ops->acquire_wait_list_lock || !ops->release_wait_list_lock) {
		dev_err(mailbox->dev, "Incomplete mailbox wait_list ops.\n");
		return -EINVAL;
	}

	mailbox->ops = ops;

	return 0;
}

/* Sets the mailbox private data. */
static inline void gcip_mailbox_set_data(struct gcip_mailbox *mailbox, void *data)
{
	mailbox->data = data;
}

int gcip_mailbox_init(struct gcip_mailbox *mailbox, const struct gcip_mailbox_args *args)
{
	int ret;

	mailbox->dev = args->dev;
	mailbox->queue_wrap_bit = args->queue_wrap_bit;
	mailbox->cmd_queue = args->cmd_queue;
	mailbox->cmd_elem_size = args->cmd_elem_size;
	mailbox->resp_queue = args->resp_queue;
	mailbox->resp_elem_size = args->resp_elem_size;
	mailbox->timeout = args->timeout;
	mailbox->cur_seq = 0;
	gcip_mailbox_set_data(mailbox, args->data);

	ret = gcip_mailbox_set_ops(mailbox, args->ops);
	if (ret)
		goto err_unset_data;

	INIT_LIST_HEAD(&mailbox->wait_list);
	init_waitqueue_head(&mailbox->wait_list_waitq);

	return 0;

err_unset_data:
	gcip_mailbox_set_data(mailbox, NULL);

	return ret;
}

void gcip_mailbox_release(struct gcip_mailbox *mailbox)
{
	gcip_mailbox_flush_awaiter(mailbox);
	gcip_mailbox_set_ops(mailbox, NULL);
	gcip_mailbox_set_data(mailbox, NULL);
}

void gcip_mailbox_consume_responses_work(struct gcip_mailbox *mailbox)
{
	void *responses;
	u32 i;
	u32 count = 0;

	/* Fetches responses and bumps resp_queue head. */
	responses = gcip_mailbox_fetch_responses(mailbox, &count);
	if (count == 0)
		return;
	if (IS_ERR(responses)) {
		dev_err(mailbox->dev, "GCIP mailbox failed on fetching responses: %ld",
			PTR_ERR(responses));
		return;
	}

	for (i = 0; i < count; i++)
		gcip_mailbox_handle_response(mailbox, responses + mailbox->resp_elem_size * i);
	/* Responses handled, wake up threads that are waiting for a response. */
	wake_up(&mailbox->wait_list_waitq);
	kfree(responses);
}

int gcip_mailbox_send_cmd(struct gcip_mailbox *mailbox, void *cmd, void *resp,
			  gcip_mailbox_cmd_flags_t flags)
{
	struct gcip_mailbox_async_resp async_resp = {
		.resp = resp,
	};
	int ret;

	ret = gcip_mailbox_enqueue_cmd(mailbox, cmd, &async_resp, NULL, flags);
	if (ret)
		goto err;

	/*
	 * If @resp is NULL, it will not enqueue the response into the waiting list. Therefore, it
	 * is fine to release @async_resp.
	 */
	if (!resp)
		return 0;

	ret = wait_event_timeout(mailbox->wait_list_waitq,
				 async_resp.status != GCIP_MAILBOX_STATUS_WAITING_RESPONSE,
				 msecs_to_jiffies(mailbox->timeout));
	if (!ret) {
		dev_dbg(mailbox->dev, "event wait timeout");
		gcip_mailbox_del_wait_resp(mailbox, &async_resp);
		ret = -ETIMEDOUT;
		goto err;
	}
	if (async_resp.status != GCIP_MAILBOX_STATUS_OK) {
		dev_err(mailbox->dev, "Mailbox cmd %u response status %u", GET_CMD_ELEM_CODE(cmd),
			async_resp.status);
		ret = -ENOMSG;
		goto err;
	}

	return 0;

err:
	if (mailbox->ops->on_error)
		mailbox->ops->on_error(mailbox, ret);

	return ret;
}

struct gcip_mailbox_resp_awaiter *gcip_mailbox_put_cmd_flags(struct gcip_mailbox *mailbox,
							     void *cmd, void *resp, void *data,
							     gcip_mailbox_cmd_flags_t flags)
{
	struct gcip_mailbox_resp_awaiter *awaiter;
	int ret;
	u32 timeout = mailbox->timeout;

	awaiter = kzalloc(sizeof(*awaiter), GFP_KERNEL);
	if (!awaiter)
		return ERR_PTR(-ENOMEM);

	if (mailbox->ops->get_cmd_timeout)
		timeout = mailbox->ops->get_cmd_timeout(mailbox, cmd, resp, data);

	awaiter->async_resp.resp = resp;
	awaiter->mailbox = mailbox;
	awaiter->data = data;
	awaiter->release_data = mailbox->ops->release_awaiter_data;
	/* 2 refs: caller (vd) and timedout handler. */
	refcount_set(&awaiter->refs, 2);

	INIT_DELAYED_WORK(&awaiter->timeout_work, gcip_mailbox_async_cmd_timeout_work);
	schedule_delayed_work(&awaiter->timeout_work, msecs_to_jiffies(timeout));

	ret = gcip_mailbox_enqueue_cmd(mailbox, cmd, &awaiter->async_resp, awaiter, flags);
	if (ret)
		goto err_free_resp;

	return awaiter;

err_free_resp:
	gcip_mailbox_cancel_awaiter_timeout(awaiter);
	kfree(awaiter);
	return ERR_PTR(ret);
}

struct gcip_mailbox_resp_awaiter *gcip_mailbox_put_cmd(struct gcip_mailbox *mailbox, void *cmd,
						       void *resp, void *data)
{
	return gcip_mailbox_put_cmd_flags(mailbox, cmd, resp, data, 0);
}

void gcip_mailbox_cancel_awaiter(struct gcip_mailbox_resp_awaiter *awaiter)
{
	gcip_mailbox_del_wait_resp(awaiter->mailbox, &awaiter->async_resp);
	gcip_mailbox_cancel_awaiter_timeout(awaiter);
}

void gcip_mailbox_cancel_awaiter_timeout(struct gcip_mailbox_resp_awaiter *awaiter)
{
	if (cancel_delayed_work_sync(&awaiter->timeout_work))
		gcip_mailbox_awaiter_dec_refs(awaiter);
}

void gcip_mailbox_release_awaiter(struct gcip_mailbox_resp_awaiter *awaiter)
{
	gcip_mailbox_awaiter_dec_refs(awaiter);
}

void gcip_mailbox_consume_one_response(struct gcip_mailbox *mailbox, void *resp)
{
	int ret;

	/* Fetches (at most) one response. */
	ret = gcip_mailbox_fetch_one_response(mailbox, resp);
	if (!ret)
		return;

	gcip_mailbox_handle_response(mailbox, resp);

	/* Responses handled, wakes up threads that are waiting for a response. */
	wake_up(&mailbox->wait_list_waitq);
}

uint gcip_mailbox_inc_seq_num(struct gcip_mailbox *mailbox, uint n)
{
	bool atomic = false;
	uint ret;

	ACQUIRE_CMD_QUEUE_LOCK(false, &atomic);

	ret = gcip_mailbox_inc_seq_num_locked(mailbox, n);

	RELEASE_CMD_QUEUE_LOCK();

	return ret;
}
