// 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 = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
	if (!ec_dev)
		return -ENOMEM;

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

	ec_dev->dev = dev;
	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);
	ec_dev->din_size = sizeof(struct ec_host_response) +
			   sizeof(struct ec_response_get_protocol_info);
	ec_dev->dout_size = sizeof(struct ec_host_request);
	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)");
