// SPDX-License-Identifier: GPL-2.0
/*
 * System Control and Management Interface (SCMI) Message Mailbox Transport
 * driver.
 *
 * Copyright (C) 2019-2024 ARM Ltd.
 */

#include <linux/err.h>
#include <linux/device.h>
#include <linux/mailbox_client.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "../common.h"

/**
 * struct scmi_mailbox - Structure representing a SCMI mailbox transport
 *
 * @cl: Mailbox Client
 * @chan: Transmit/Receive mailbox uni/bi-directional channel
 * @chan_receiver: Optional Receiver mailbox unidirectional channel
 * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel
 * @cinfo: SCMI channel info
 * @shmem: Transmit/Receive shared memory area
 */
struct scmi_mailbox {
	struct mbox_client cl;
	struct mbox_chan *chan;
	struct mbox_chan *chan_receiver;
	struct mbox_chan *chan_platform_receiver;
	struct scmi_chan_info *cinfo;
	struct scmi_shared_mem __iomem *shmem;
};

#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)

static struct scmi_transport_core_operations *core;

static void tx_prepare(struct mbox_client *cl, void *m)
{
	struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);

	core->shmem->tx_prepare(smbox->shmem, m, smbox->cinfo);
}

static void rx_callback(struct mbox_client *cl, void *m)
{
	struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);

	/*
	 * An A2P IRQ is NOT valid when received while the platform still has
	 * the ownership of the channel, because the platform at first releases
	 * the SMT channel and then sends the completion interrupt.
	 *
	 * This addresses a possible race condition in which a spurious IRQ from
	 * a previous timed-out reply which arrived late could be wrongly
	 * associated with the next pending transaction.
	 */
	if (cl->knows_txdone &&
	    !core->shmem->channel_free(smbox->shmem)) {
		dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n");
		core->bad_message_trace(smbox->cinfo,
			     core->shmem->read_header(smbox->shmem),
							     MSG_MBOX_SPURIOUS);
		return;
	}

	core->rx_callback(smbox->cinfo,
		      core->shmem->read_header(smbox->shmem), NULL);
}

static bool mailbox_chan_available(struct device_node *of_node, int idx)
{
	int num_mb;

	/*
	 * Just check if bidirrectional channels are involved, and check the
	 * index accordingly; proper full validation will be made later
	 * in mailbox_chan_setup().
	 */
	num_mb = of_count_phandle_with_args(of_node, "mboxes", "#mbox-cells");
	if (num_mb == 3 && idx == 1)
		idx = 2;

	return !of_parse_phandle_with_args(of_node, "mboxes",
					   "#mbox-cells", idx, NULL);
}

/**
 * mailbox_chan_validate  - Validate transport configuration and map channels
 *
 * @cdev: Reference to the underlying transport device carrying the
 *	  of_node descriptor to analyze.
 * @a2p_rx_chan: A reference to an optional unidirectional channel to use
 *		 for replies on the a2p channel. Set as zero if not present.
 * @p2a_chan: A reference to the optional p2a channel.
 *	      Set as zero if not present.
 * @p2a_rx_chan: A reference to the optional p2a completion channel.
 *	      Set as zero if not present.
 *
 * At first, validate the transport configuration as described in terms of
 * 'mboxes' and 'shmem', then determin which mailbox channel indexes are
 * appropriate to be use in the current configuration.
 *
 * Return: 0 on Success or error
 */
static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan,
				 int *p2a_chan, int *p2a_rx_chan)
{
	int num_mb, num_sh, ret = 0;
	struct device_node *np = cdev->of_node;

	num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
	num_sh = of_count_phandle_with_args(np, "shmem", NULL);
	dev_dbg(cdev, "Found %d mboxes and %d shmems !\n", num_mb, num_sh);

	/* Bail out if mboxes and shmem descriptors are inconsistent */
	if (num_mb <= 0 || num_sh <= 0 || num_sh > 2 || num_mb > 4 ||
	    (num_mb == 1 && num_sh != 1) || (num_mb == 3 && num_sh != 2) ||
	    (num_mb == 4 && num_sh != 2)) {
		dev_warn(cdev,
			 "Invalid channel descriptor for '%s' - mbs:%d  shm:%d\n",
			 of_node_full_name(np), num_mb, num_sh);
		return -EINVAL;
	}

	/* Bail out if provided shmem descriptors do not refer distinct areas  */
	if (num_sh > 1) {
		struct device_node *np_tx __free(device_node) =
					of_parse_phandle(np, "shmem", 0);
		struct device_node *np_rx __free(device_node) =
					of_parse_phandle(np, "shmem", 1);

		if (!np_tx || !np_rx || np_tx == np_rx) {
			dev_warn(cdev, "Invalid shmem descriptor for '%s'\n",
				 of_node_full_name(np));
			ret = -EINVAL;
		}
	}

	/* Calculate channels IDs to use depending on mboxes/shmem layout */
	if (!ret) {
		switch (num_mb) {
		case 1:
			*a2p_rx_chan = 0;
			*p2a_chan = 0;
			*p2a_rx_chan = 0;
			break;
		case 2:
			if (num_sh == 2) {
				*a2p_rx_chan = 0;
				*p2a_chan = 1;
			} else {
				*a2p_rx_chan = 1;
				*p2a_chan = 0;
			}
			*p2a_rx_chan = 0;
			break;
		case 3:
			*a2p_rx_chan = 1;
			*p2a_chan = 2;
			*p2a_rx_chan = 0;
			break;
		case 4:
			*a2p_rx_chan = 1;
			*p2a_chan = 2;
			*p2a_rx_chan = 3;
			break;
		}
	}

	return ret;
}

static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
			      bool tx)
{
	const char *desc = tx ? "Tx" : "Rx";
	struct device *cdev = cinfo->dev;
	struct scmi_mailbox *smbox;
	int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan;
	struct mbox_client *cl;

	ret = mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan, &p2a_rx_chan);
	if (ret)
		return ret;

	if (!tx && !p2a_chan)
		return -ENODEV;

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

	smbox->shmem = core->shmem->setup_iomap(cinfo, dev, tx, NULL);
	if (IS_ERR(smbox->shmem))
		return PTR_ERR(smbox->shmem);

	cl = &smbox->cl;
	cl->dev = cdev;
	cl->tx_prepare = tx ? tx_prepare : NULL;
	cl->rx_callback = rx_callback;
	cl->tx_block = false;
	cl->knows_txdone = tx;

	smbox->chan = mbox_request_channel(cl, tx ? 0 : p2a_chan);
	if (IS_ERR(smbox->chan)) {
		ret = PTR_ERR(smbox->chan);
		if (ret != -EPROBE_DEFER)
			dev_err(cdev,
				"failed to request SCMI %s mailbox\n", desc);
		return ret;
	}

	/* Additional unidirectional channel for TX if needed */
	if (tx && a2p_rx_chan) {
		smbox->chan_receiver = mbox_request_channel(cl, a2p_rx_chan);
		if (IS_ERR(smbox->chan_receiver)) {
			ret = PTR_ERR(smbox->chan_receiver);
			if (ret != -EPROBE_DEFER)
				dev_err(cdev, "failed to request SCMI Tx Receiver mailbox\n");
			return ret;
		}
	}

	if (!tx && p2a_rx_chan) {
		smbox->chan_platform_receiver = mbox_request_channel(cl, p2a_rx_chan);
		if (IS_ERR(smbox->chan_platform_receiver)) {
			ret = PTR_ERR(smbox->chan_platform_receiver);
			if (ret != -EPROBE_DEFER)
				dev_err(cdev, "failed to request SCMI P2A Receiver mailbox\n");
			return ret;
		}
	}

	cinfo->transport_info = smbox;
	smbox->cinfo = cinfo;

	return 0;
}

static int mailbox_chan_free(int id, void *p, void *data)
{
	struct scmi_chan_info *cinfo = p;
	struct scmi_mailbox *smbox = cinfo->transport_info;

	if (smbox && !IS_ERR(smbox->chan)) {
		mbox_free_channel(smbox->chan);
		mbox_free_channel(smbox->chan_receiver);
		mbox_free_channel(smbox->chan_platform_receiver);
		cinfo->transport_info = NULL;
		smbox->chan = NULL;
		smbox->chan_receiver = NULL;
		smbox->chan_platform_receiver = NULL;
		smbox->cinfo = NULL;
	}

	return 0;
}

static int mailbox_send_message(struct scmi_chan_info *cinfo,
				struct scmi_xfer *xfer)
{
	struct scmi_mailbox *smbox = cinfo->transport_info;
	int ret;

	ret = mbox_send_message(smbox->chan, xfer);

	/* mbox_send_message returns non-negative value on success, so reset */
	if (ret > 0)
		ret = 0;

	return ret;
}

static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
				struct scmi_xfer *__unused)
{
	struct scmi_mailbox *smbox = cinfo->transport_info;

	/*
	 * NOTE: we might prefer not to need the mailbox ticker to manage the
	 * transfer queueing since the protocol layer queues things by itself.
	 * Unfortunately, we have to kick the mailbox framework after we have
	 * received our message.
	 */
	mbox_client_txdone(smbox->chan, ret);
}

static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
				   struct scmi_xfer *xfer)
{
	struct scmi_mailbox *smbox = cinfo->transport_info;

	core->shmem->fetch_response(smbox->shmem, xfer);
}

static void mailbox_fetch_notification(struct scmi_chan_info *cinfo,
				       size_t max_len, struct scmi_xfer *xfer)
{
	struct scmi_mailbox *smbox = cinfo->transport_info;

	core->shmem->fetch_notification(smbox->shmem, max_len, xfer);
}

static void mailbox_clear_channel(struct scmi_chan_info *cinfo)
{
	struct scmi_mailbox *smbox = cinfo->transport_info;
	struct mbox_chan *intr_chan;
	int ret;

	core->shmem->clear_channel(smbox->shmem);

	if (!core->shmem->channel_intr_enabled(smbox->shmem))
		return;

	if (smbox->chan_platform_receiver)
		intr_chan = smbox->chan_platform_receiver;
	else if (smbox->chan)
		intr_chan = smbox->chan;
	else
		return;

	ret = mbox_send_message(intr_chan, NULL);
	/* mbox_send_message returns non-negative value on success, so reset */
	if (ret > 0)
		ret = 0;

	mbox_client_txdone(intr_chan, ret);
}

static bool
mailbox_poll_done(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
{
	struct scmi_mailbox *smbox = cinfo->transport_info;

	return core->shmem->poll_done(smbox->shmem, xfer);
}

static const struct scmi_transport_ops scmi_mailbox_ops = {
	.chan_available = mailbox_chan_available,
	.chan_setup = mailbox_chan_setup,
	.chan_free = mailbox_chan_free,
	.send_message = mailbox_send_message,
	.mark_txdone = mailbox_mark_txdone,
	.fetch_response = mailbox_fetch_response,
	.fetch_notification = mailbox_fetch_notification,
	.clear_channel = mailbox_clear_channel,
	.poll_done = mailbox_poll_done,
};

static struct scmi_desc scmi_mailbox_desc = {
	.ops = &scmi_mailbox_ops,
	.max_rx_timeout_ms = 30, /* We may increase this if required */
	.max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */
	.max_msg_size = 128,
};

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

DEFINE_SCMI_TRANSPORT_DRIVER(scmi_mailbox, scmi_mailbox_driver,
			     scmi_mailbox_desc, scmi_of_match, core);
module_platform_driver(scmi_mailbox_driver);

MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
MODULE_DESCRIPTION("SCMI Mailbox Transport driver");
MODULE_LICENSE("GPL");
