// SPDX-License-Identifier: GPL-2.0
//
// Copyright 2018 Google LLC.

#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_device.h>
#include <linux/rpmsg.h>
#include <linux/slab.h>

#include "cros_ec.h"

#define EC_MSG_TIMEOUT_MS	200
#define HOST_COMMAND_MARK	1
#define HOST_EVENT_MARK		2

/**
 * struct cros_ec_rpmsg_response - rpmsg message format from from EC.
 *
 * @type:	The type of message, should be either HOST_COMMAND_MARK or
 *		HOST_EVENT_MARK, representing that the message is a response to
 *		host command, or a host event.
 * @data:	ec_host_response for host command.
 */
struct cros_ec_rpmsg_response {
	u8 type;
	u8 data[] __aligned(4);
};

/**
 * struct cros_ec_rpmsg - information about a EC over rpmsg.
 *
 * @rpdev:	rpmsg device we are connected to
 * @xfer_ack:	completion for host command transfer.
 * @host_event_work:	Work struct for pending host event.
 * @ept: The rpmsg endpoint of this channel.
 * @has_pending_host_event: Boolean used to check if there is a pending event.
 * @probe_done: Flag to indicate that probe is done.
 */
struct cros_ec_rpmsg {
	struct rpmsg_device *rpdev;
	struct completion xfer_ack;
	struct work_struct host_event_work;
	struct rpmsg_endpoint *ept;
	bool has_pending_host_event;
	bool probe_done;
};

/**
 * cros_ec_cmd_xfer_rpmsg - Transfer a message over rpmsg and receive the reply
 *
 * @ec_dev: ChromeOS EC device
 * @ec_msg: Message to transfer
 *
 * This is only used for old EC proto version, and is not supported for this
 * driver.
 *
 * Return: -EINVAL
 */
static int cros_ec_cmd_xfer_rpmsg(struct cros_ec_device *ec_dev,
				  struct cros_ec_command *ec_msg)
{
	return -EINVAL;
}

/**
 * cros_ec_pkt_xfer_rpmsg - Transfer a packet over rpmsg and receive the reply
 *
 * @ec_dev: ChromeOS EC device
 * @ec_msg: Message to transfer
 *
 * Return: number of bytes of the reply on success or negative error code.
 */
static int cros_ec_pkt_xfer_rpmsg(struct cros_ec_device *ec_dev,
				  struct cros_ec_command *ec_msg)
{
	struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv;
	struct ec_host_response *response;
	unsigned long timeout;
	int len;
	int ret;
	u8 sum;
	int i;

	ec_msg->result = 0;
	len = cros_ec_prepare_tx(ec_dev, ec_msg);
	if (len < 0)
		return len;
	dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);

	reinit_completion(&ec_rpmsg->xfer_ack);
	ret = rpmsg_send(ec_rpmsg->ept, ec_dev->dout, len);
	if (ret) {
		dev_err(ec_dev->dev, "rpmsg send failed\n");
		return ret;
	}

	timeout = msecs_to_jiffies(EC_MSG_TIMEOUT_MS);
	ret = wait_for_completion_timeout(&ec_rpmsg->xfer_ack, timeout);
	if (!ret) {
		dev_err(ec_dev->dev, "rpmsg send timeout\n");
		return -EIO;
	}

	/* check response error code */
	response = (struct ec_host_response *)ec_dev->din;
	ec_msg->result = response->result;

	ret = cros_ec_check_result(ec_dev, ec_msg);
	if (ret)
		goto exit;

	if (response->data_len > ec_msg->insize) {
		dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)",
			response->data_len, ec_msg->insize);
		ret = -EMSGSIZE;
		goto exit;
	}

	/* copy response packet payload and compute checksum */
	memcpy(ec_msg->data, ec_dev->din + sizeof(*response),
	       response->data_len);

	sum = 0;
	for (i = 0; i < sizeof(*response) + response->data_len; i++)
		sum += ec_dev->din[i];

	if (sum) {
		dev_err(ec_dev->dev, "bad packet checksum, calculated %x\n",
			sum);
		ret = -EBADMSG;
		goto exit;
	}

	ret = response->data_len;
exit:
	if (ec_msg->command == EC_CMD_REBOOT_EC)
		msleep(EC_REBOOT_DELAY_MS);

	return ret;
}

static void
cros_ec_rpmsg_host_event_function(struct work_struct *host_event_work)
{
	struct cros_ec_rpmsg *ec_rpmsg = container_of(host_event_work,
						      struct cros_ec_rpmsg,
						      host_event_work);

	cros_ec_irq_thread(0, dev_get_drvdata(&ec_rpmsg->rpdev->dev));
}

static int cros_ec_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
				  int len, void *priv, u32 src)
{
	struct cros_ec_device *ec_dev = dev_get_drvdata(&rpdev->dev);
	struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv;
	struct cros_ec_rpmsg_response *resp;

	if (!len) {
		dev_warn(ec_dev->dev, "rpmsg received empty response");
		return -EINVAL;
	}

	resp = data;
	len -= offsetof(struct cros_ec_rpmsg_response, data);
	if (resp->type == HOST_COMMAND_MARK) {
		if (len > ec_dev->din_size) {
			dev_warn(ec_dev->dev,
				 "received length %d > din_size %d, truncating",
				 len, ec_dev->din_size);
			len = ec_dev->din_size;
		}

		memcpy(ec_dev->din, resp->data, len);
		complete(&ec_rpmsg->xfer_ack);
	} else if (resp->type == HOST_EVENT_MARK) {
		/*
		 * If the host event is sent before cros_ec_register is
		 * finished, queue the host event.
		 */
		if (ec_rpmsg->probe_done)
			schedule_work(&ec_rpmsg->host_event_work);
		else
			ec_rpmsg->has_pending_host_event = true;
	} else {
		dev_warn(ec_dev->dev, "rpmsg received invalid type = %d",
			 resp->type);
		return -EINVAL;
	}

	return 0;
}

static struct rpmsg_endpoint *
cros_ec_rpmsg_create_ept(struct rpmsg_device *rpdev)
{
	struct rpmsg_channel_info chinfo = {};

	strscpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
	chinfo.src = rpdev->src;
	chinfo.dst = RPMSG_ADDR_ANY;

	return rpmsg_create_ept(rpdev, cros_ec_rpmsg_callback, NULL, chinfo);
}

static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev)
{
	struct device *dev = &rpdev->dev;
	struct cros_ec_rpmsg *ec_rpmsg;
	struct cros_ec_device *ec_dev;
	int ret;

	ec_dev = cros_ec_device_alloc(dev);
	if (!ec_dev)
		return -ENOMEM;

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

	ec_dev->priv = ec_rpmsg;
	ec_dev->cmd_xfer = cros_ec_cmd_xfer_rpmsg;
	ec_dev->pkt_xfer = cros_ec_pkt_xfer_rpmsg;
	ec_dev->phys_name = dev_name(&rpdev->dev);
	dev_set_drvdata(dev, ec_dev);

	ec_rpmsg->rpdev = rpdev;
	init_completion(&ec_rpmsg->xfer_ack);
	INIT_WORK(&ec_rpmsg->host_event_work,
		  cros_ec_rpmsg_host_event_function);

	ec_rpmsg->ept = cros_ec_rpmsg_create_ept(rpdev);
	if (!ec_rpmsg->ept)
		return -ENOMEM;

	ret = cros_ec_register(ec_dev);
	if (ret < 0) {
		rpmsg_destroy_ept(ec_rpmsg->ept);
		cancel_work_sync(&ec_rpmsg->host_event_work);
		return ret;
	}

	ec_rpmsg->probe_done = true;

	if (ec_rpmsg->has_pending_host_event)
		schedule_work(&ec_rpmsg->host_event_work);

	return 0;
}

static void cros_ec_rpmsg_remove(struct rpmsg_device *rpdev)
{
	struct cros_ec_device *ec_dev = dev_get_drvdata(&rpdev->dev);
	struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv;

	cros_ec_unregister(ec_dev);
	rpmsg_destroy_ept(ec_rpmsg->ept);
	cancel_work_sync(&ec_rpmsg->host_event_work);
}

#ifdef CONFIG_PM_SLEEP
static int cros_ec_rpmsg_suspend(struct device *dev)
{
	struct cros_ec_device *ec_dev = dev_get_drvdata(dev);

	return cros_ec_suspend(ec_dev);
}

static int cros_ec_rpmsg_resume(struct device *dev)
{
	struct cros_ec_device *ec_dev = dev_get_drvdata(dev);

	return cros_ec_resume(ec_dev);
}
#endif

static SIMPLE_DEV_PM_OPS(cros_ec_rpmsg_pm_ops, cros_ec_rpmsg_suspend,
			 cros_ec_rpmsg_resume);

static const struct of_device_id cros_ec_rpmsg_of_match[] = {
	{ .compatible = "google,cros-ec-rpmsg", },
	{ }
};
MODULE_DEVICE_TABLE(of, cros_ec_rpmsg_of_match);

static struct rpmsg_driver cros_ec_driver_rpmsg = {
	.drv = {
		.name   = "cros-ec-rpmsg",
		.of_match_table = cros_ec_rpmsg_of_match,
		.pm	= &cros_ec_rpmsg_pm_ops,
	},
	.probe		= cros_ec_rpmsg_probe,
	.remove		= cros_ec_rpmsg_remove,
};

module_rpmsg_driver(cros_ec_driver_rpmsg);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ChromeOS EC multi function device (rpmsg)");
