// SPDX-License-Identifier: GPL-2.0
/*
 * Miscellaneous character driver for ChromeOS Embedded Controller
 *
 * Copyright 2014 Google, Inc.
 * Copyright 2019 Google LLC
 *
 * This file is a rework and part of the code is ported from
 * drivers/mfd/cros_ec_dev.c that was originally written by
 * Bill Richardson.
 */

#include <linux/init.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/mfd/cros_ec.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/platform_data/cros_ec_chardev.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_device.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/uaccess.h>

#define DRV_NAME		"cros-ec-chardev"

/* Arbitrary bounded size for the event queue */
#define CROS_MAX_EVENT_LEN	PAGE_SIZE

struct chardev_data {
	struct cros_ec_dev *ec_dev;
	struct miscdevice misc;
};

struct chardev_priv {
	struct cros_ec_dev *ec_dev;
	struct notifier_block notifier;
	wait_queue_head_t wait_event;
	unsigned long event_mask;
	struct list_head events;
	size_t event_len;
};

struct ec_event {
	struct list_head node;
	size_t size;
	u8 event_type;
	u8 data[0];
};

static int ec_get_version(struct cros_ec_dev *ec, char *str, int maxlen)
{
	static const char * const current_image_name[] = {
		"unknown", "read-only", "read-write", "invalid",
	};
	struct ec_response_get_version *resp;
	struct cros_ec_command *msg;
	int ret;

	msg = kzalloc(sizeof(*msg) + sizeof(*resp), GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	msg->command = EC_CMD_GET_VERSION + ec->cmd_offset;
	msg->insize = sizeof(*resp);

	ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
	if (ret < 0) {
		snprintf(str, maxlen,
			 "Unknown EC version, returned error: %d\n",
			 msg->result);
		goto exit;
	}

	resp = (struct ec_response_get_version *)msg->data;
	if (resp->current_image >= ARRAY_SIZE(current_image_name))
		resp->current_image = 3; /* invalid */

	snprintf(str, maxlen, "%s\n%s\n%s\n%s\n", CROS_EC_DEV_VERSION,
		 resp->version_string_ro, resp->version_string_rw,
		 current_image_name[resp->current_image]);

	ret = 0;
exit:
	kfree(msg);
	return ret;
}

static int cros_ec_chardev_mkbp_event(struct notifier_block *nb,
				      unsigned long queued_during_suspend,
				      void *_notify)
{
	struct chardev_priv *priv = container_of(nb, struct chardev_priv,
						 notifier);
	struct cros_ec_device *ec_dev = priv->ec_dev->ec_dev;
	struct ec_event *event;
	unsigned long event_bit = 1 << ec_dev->event_data.event_type;
	int total_size = sizeof(*event) + ec_dev->event_size;

	if (!(event_bit & priv->event_mask) ||
	    (priv->event_len + total_size) > CROS_MAX_EVENT_LEN)
		return NOTIFY_DONE;

	event = kzalloc(total_size, GFP_KERNEL);
	if (!event)
		return NOTIFY_DONE;

	event->size = ec_dev->event_size;
	event->event_type = ec_dev->event_data.event_type;
	memcpy(event->data, &ec_dev->event_data.data, ec_dev->event_size);

	spin_lock(&priv->wait_event.lock);
	list_add_tail(&event->node, &priv->events);
	priv->event_len += total_size;
	wake_up_locked(&priv->wait_event);
	spin_unlock(&priv->wait_event.lock);

	return NOTIFY_OK;
}

static struct ec_event *cros_ec_chardev_fetch_event(struct chardev_priv *priv,
						    bool fetch, bool block)
{
	struct ec_event *event;
	int err;

	spin_lock(&priv->wait_event.lock);
	if (!block && list_empty(&priv->events)) {
		event = ERR_PTR(-EWOULDBLOCK);
		goto out;
	}

	if (!fetch) {
		event = NULL;
		goto out;
	}

	err = wait_event_interruptible_locked(priv->wait_event,
					      !list_empty(&priv->events));
	if (err) {
		event = ERR_PTR(err);
		goto out;
	}

	event = list_first_entry(&priv->events, struct ec_event, node);
	list_del(&event->node);
	priv->event_len -= sizeof(*event) + event->size;

out:
	spin_unlock(&priv->wait_event.lock);
	return event;
}

/*
 * Device file ops
 */
static int cros_ec_chardev_open(struct inode *inode, struct file *filp)
{
	struct miscdevice *mdev = filp->private_data;
	struct cros_ec_dev *ec_dev = dev_get_drvdata(mdev->parent);
	struct chardev_priv *priv;
	int ret;

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

	priv->ec_dev = ec_dev;
	filp->private_data = priv;
	INIT_LIST_HEAD(&priv->events);
	init_waitqueue_head(&priv->wait_event);
	nonseekable_open(inode, filp);

	priv->notifier.notifier_call = cros_ec_chardev_mkbp_event;
	ret = blocking_notifier_chain_register(&ec_dev->ec_dev->event_notifier,
					       &priv->notifier);
	if (ret) {
		dev_err(ec_dev->dev, "failed to register event notifier\n");
		kfree(priv);
	}

	return ret;
}

static __poll_t cros_ec_chardev_poll(struct file *filp, poll_table *wait)
{
	struct chardev_priv *priv = filp->private_data;

	poll_wait(filp, &priv->wait_event, wait);

	if (list_empty(&priv->events))
		return 0;

	return EPOLLIN | EPOLLRDNORM;
}

static ssize_t cros_ec_chardev_read(struct file *filp, char __user *buffer,
				     size_t length, loff_t *offset)
{
	char msg[sizeof(struct ec_response_get_version) +
		 sizeof(CROS_EC_DEV_VERSION)];
	struct chardev_priv *priv = filp->private_data;
	struct cros_ec_dev *ec_dev = priv->ec_dev;
	size_t count;
	int ret;

	if (priv->event_mask) { /* queued MKBP event */
		struct ec_event *event;

		event = cros_ec_chardev_fetch_event(priv, length != 0,
						!(filp->f_flags & O_NONBLOCK));
		if (IS_ERR(event))
			return PTR_ERR(event);
		/*
		 * length == 0 is special - no IO is done but we check
		 * for error conditions.
		 */
		if (length == 0)
			return 0;

		/* The event is 1 byte of type plus the payload */
		count = min(length, event->size + 1);
		ret = copy_to_user(buffer, &event->event_type, count);
		kfree(event);
		if (ret) /* the copy failed */
			return -EFAULT;
		*offset = count;
		return count;
	}

	/*
	 * Legacy behavior if no event mask is defined
	 */
	if (*offset != 0)
		return 0;

	ret = ec_get_version(ec_dev, msg, sizeof(msg));
	if (ret)
		return ret;

	count = min(length, strlen(msg));

	if (copy_to_user(buffer, msg, count))
		return -EFAULT;

	*offset = count;
	return count;
}

static int cros_ec_chardev_release(struct inode *inode, struct file *filp)
{
	struct chardev_priv *priv = filp->private_data;
	struct cros_ec_dev *ec_dev = priv->ec_dev;
	struct ec_event *event, *e;

	blocking_notifier_chain_unregister(&ec_dev->ec_dev->event_notifier,
					   &priv->notifier);

	list_for_each_entry_safe(event, e, &priv->events, node) {
		list_del(&event->node);
		kfree(event);
	}
	kfree(priv);

	return 0;
}

/*
 * Ioctls
 */
static long cros_ec_chardev_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg)
{
	struct cros_ec_command *s_cmd;
	struct cros_ec_command u_cmd;
	long ret;

	if (copy_from_user(&u_cmd, arg, sizeof(u_cmd)))
		return -EFAULT;

	if (u_cmd.outsize > EC_MAX_MSG_BYTES ||
	    u_cmd.insize > EC_MAX_MSG_BYTES)
		return -EINVAL;

	s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize),
			GFP_KERNEL);
	if (!s_cmd)
		return -ENOMEM;

	if (copy_from_user(s_cmd, arg, sizeof(*s_cmd) + u_cmd.outsize)) {
		ret = -EFAULT;
		goto exit;
	}

	if (u_cmd.outsize != s_cmd->outsize ||
	    u_cmd.insize != s_cmd->insize) {
		ret = -EINVAL;
		goto exit;
	}

	s_cmd->command += ec->cmd_offset;
	ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd);
	/* Only copy data to userland if data was received. */
	if (ret < 0)
		goto exit;

	if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize))
		ret = -EFAULT;
exit:
	kfree(s_cmd);
	return ret;
}

static long cros_ec_chardev_ioctl_readmem(struct cros_ec_dev *ec,
					   void __user *arg)
{
	struct cros_ec_device *ec_dev = ec->ec_dev;
	struct cros_ec_readmem s_mem = { };
	long num;

	/* Not every platform supports direct reads */
	if (!ec_dev->cmd_readmem)
		return -ENOTTY;

	if (copy_from_user(&s_mem, arg, sizeof(s_mem)))
		return -EFAULT;

	num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes,
				  s_mem.buffer);
	if (num <= 0)
		return num;

	if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem)))
		return -EFAULT;

	return num;
}

static long cros_ec_chardev_ioctl(struct file *filp, unsigned int cmd,
				   unsigned long arg)
{
	struct chardev_priv *priv = filp->private_data;
	struct cros_ec_dev *ec = priv->ec_dev;

	if (_IOC_TYPE(cmd) != CROS_EC_DEV_IOC)
		return -ENOTTY;

	switch (cmd) {
	case CROS_EC_DEV_IOCXCMD:
		return cros_ec_chardev_ioctl_xcmd(ec, (void __user *)arg);
	case CROS_EC_DEV_IOCRDMEM:
		return cros_ec_chardev_ioctl_readmem(ec, (void __user *)arg);
	case CROS_EC_DEV_IOCEVENTMASK:
		priv->event_mask = arg;
		return 0;
	}

	return -ENOTTY;
}

static const struct file_operations chardev_fops = {
	.open		= cros_ec_chardev_open,
	.poll		= cros_ec_chardev_poll,
	.read		= cros_ec_chardev_read,
	.release	= cros_ec_chardev_release,
	.unlocked_ioctl	= cros_ec_chardev_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= cros_ec_chardev_ioctl,
#endif
};

static int cros_ec_chardev_probe(struct platform_device *pdev)
{
	struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent);
	struct cros_ec_platform *ec_platform = dev_get_platdata(ec_dev->dev);
	struct chardev_data *data;

	/* Create a char device: we want to create it anew */
	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->ec_dev = ec_dev;
	data->misc.minor = MISC_DYNAMIC_MINOR;
	data->misc.fops = &chardev_fops;
	data->misc.name = ec_platform->ec_name;
	data->misc.parent = pdev->dev.parent;

	dev_set_drvdata(&pdev->dev, data);

	return misc_register(&data->misc);
}

static int cros_ec_chardev_remove(struct platform_device *pdev)
{
	struct chardev_data *data = dev_get_drvdata(&pdev->dev);

	misc_deregister(&data->misc);

	return 0;
}

static struct platform_driver cros_ec_chardev_driver = {
	.driver = {
		.name = DRV_NAME,
	},
	.probe = cros_ec_chardev_probe,
	.remove = cros_ec_chardev_remove,
};

module_platform_driver(cros_ec_chardev_driver);

MODULE_ALIAS("platform:" DRV_NAME);
MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>");
MODULE_DESCRIPTION("ChromeOS EC Miscellaneous Character Driver");
MODULE_LICENSE("GPL");
