/*
 * Generic driver for the OLPC Embedded Controller.
 *
 * Copyright (C) 2011-2012 One Laptop per Child Foundation.
 *
 * Licensed under the GPL v2 or later.
 */
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/olpc-ec.h>
#include <asm/olpc.h>

struct ec_cmd_desc {
	u8 cmd;
	u8 *inbuf, *outbuf;
	size_t inlen, outlen;

	int err;
	struct completion finished;
	struct list_head node;

	void *priv;
};

struct olpc_ec_priv {
	struct olpc_ec_driver *drv;
	struct work_struct worker;
	struct mutex cmd_lock;

	/* Pending EC commands */
	struct list_head cmd_q;
	spinlock_t cmd_q_lock;

	struct dentry *dbgfs_dir;

	/*
	 * Running an EC command while suspending means we don't always finish
	 * the command before the machine suspends.  This means that the EC
	 * is expecting the command protocol to finish, but we after a period
	 * of time (while the OS is asleep) the EC times out and restarts its
	 * idle loop.  Meanwhile, the OS wakes up, thinks it's still in the
	 * middle of the command protocol, starts throwing random things at
	 * the EC... and everyone's uphappy.
	 */
	bool suspended;
};

static struct olpc_ec_driver *ec_driver;
static struct olpc_ec_priv *ec_priv;
static void *ec_cb_arg;

void olpc_ec_driver_register(struct olpc_ec_driver *drv, void *arg)
{
	ec_driver = drv;
	ec_cb_arg = arg;
}
EXPORT_SYMBOL_GPL(olpc_ec_driver_register);

static void olpc_ec_worker(struct work_struct *w)
{
	struct olpc_ec_priv *ec = container_of(w, struct olpc_ec_priv, worker);
	struct ec_cmd_desc *desc = NULL;
	unsigned long flags;

	/* Grab the first pending command from the queue */
	spin_lock_irqsave(&ec->cmd_q_lock, flags);
	if (!list_empty(&ec->cmd_q)) {
		desc = list_first_entry(&ec->cmd_q, struct ec_cmd_desc, node);
		list_del(&desc->node);
	}
	spin_unlock_irqrestore(&ec->cmd_q_lock, flags);

	/* Do we actually have anything to do? */
	if (!desc)
		return;

	/* Protect the EC hw with a mutex; only run one cmd at a time */
	mutex_lock(&ec->cmd_lock);
	desc->err = ec_driver->ec_cmd(desc->cmd, desc->inbuf, desc->inlen,
			desc->outbuf, desc->outlen, ec_cb_arg);
	mutex_unlock(&ec->cmd_lock);

	/* Finished, wake up olpc_ec_cmd() */
	complete(&desc->finished);

	/* Run the worker thread again in case there are more cmds pending */
	schedule_work(&ec->worker);
}

/*
 * Throw a cmd descripter onto the list.  We now have SMP OLPC machines, so
 * locking is pretty critical.
 */
static void queue_ec_descriptor(struct ec_cmd_desc *desc,
		struct olpc_ec_priv *ec)
{
	unsigned long flags;

	INIT_LIST_HEAD(&desc->node);

	spin_lock_irqsave(&ec->cmd_q_lock, flags);
	list_add_tail(&desc->node, &ec->cmd_q);
	spin_unlock_irqrestore(&ec->cmd_q_lock, flags);

	schedule_work(&ec->worker);
}

int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, size_t outlen)
{
	struct olpc_ec_priv *ec = ec_priv;
	struct ec_cmd_desc desc;

	/* Ensure a driver and ec hook have been registered */
	if (WARN_ON(!ec_driver || !ec_driver->ec_cmd))
		return -ENODEV;

	if (!ec)
		return -ENOMEM;

	/* Suspending in the middle of a command hoses things really badly */
	if (WARN_ON(ec->suspended))
		return -EBUSY;

	might_sleep();

	desc.cmd = cmd;
	desc.inbuf = inbuf;
	desc.outbuf = outbuf;
	desc.inlen = inlen;
	desc.outlen = outlen;
	desc.err = 0;
	init_completion(&desc.finished);

	queue_ec_descriptor(&desc, ec);

	/* Timeouts must be handled in the platform-specific EC hook */
	wait_for_completion(&desc.finished);

	/* The worker thread dequeues the cmd; no need to do anything here */
	return desc.err;
}
EXPORT_SYMBOL_GPL(olpc_ec_cmd);

#ifdef CONFIG_DEBUG_FS

/*
 * debugfs support for "generic commands", to allow sending
 * arbitrary EC commands from userspace.
 */

#define EC_MAX_CMD_ARGS (5 + 1)		/* cmd byte + 5 args */
#define EC_MAX_CMD_REPLY (8)

static DEFINE_MUTEX(ec_dbgfs_lock);
static unsigned char ec_dbgfs_resp[EC_MAX_CMD_REPLY];
static unsigned int ec_dbgfs_resp_bytes;

static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf,
		size_t size, loff_t *ppos)
{
	int i, m;
	unsigned char ec_cmd[EC_MAX_CMD_ARGS];
	unsigned int ec_cmd_int[EC_MAX_CMD_ARGS];
	char cmdbuf[64];
	int ec_cmd_bytes;

	mutex_lock(&ec_dbgfs_lock);

	size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size);

	m = sscanf(cmdbuf, "%x:%u %x %x %x %x %x", &ec_cmd_int[0],
			&ec_dbgfs_resp_bytes, &ec_cmd_int[1], &ec_cmd_int[2],
			&ec_cmd_int[3], &ec_cmd_int[4], &ec_cmd_int[5]);
	if (m < 2 || ec_dbgfs_resp_bytes > EC_MAX_CMD_REPLY) {
		/* reset to prevent overflow on read */
		ec_dbgfs_resp_bytes = 0;

		pr_debug("olpc-ec: bad ec cmd:  cmd:response-count [arg1 [arg2 ...]]\n");
		size = -EINVAL;
		goto out;
	}

	/* convert scanf'd ints to char */
	ec_cmd_bytes = m - 2;
	for (i = 0; i <= ec_cmd_bytes; i++)
		ec_cmd[i] = ec_cmd_int[i];

	pr_debug("olpc-ec: debugfs cmd 0x%02x with %d args %5ph, want %d returns\n",
			ec_cmd[0], ec_cmd_bytes, ec_cmd + 1,
			ec_dbgfs_resp_bytes);

	olpc_ec_cmd(ec_cmd[0], (ec_cmd_bytes == 0) ? NULL : &ec_cmd[1],
			ec_cmd_bytes, ec_dbgfs_resp, ec_dbgfs_resp_bytes);

	pr_debug("olpc-ec: response %8ph (%d bytes expected)\n",
			ec_dbgfs_resp, ec_dbgfs_resp_bytes);

out:
	mutex_unlock(&ec_dbgfs_lock);
	return size;
}

static ssize_t ec_dbgfs_cmd_read(struct file *file, char __user *buf,
		size_t size, loff_t *ppos)
{
	unsigned int i, r;
	char *rp;
	char respbuf[64];

	mutex_lock(&ec_dbgfs_lock);
	rp = respbuf;
	rp += sprintf(rp, "%02x", ec_dbgfs_resp[0]);
	for (i = 1; i < ec_dbgfs_resp_bytes; i++)
		rp += sprintf(rp, ", %02x", ec_dbgfs_resp[i]);
	mutex_unlock(&ec_dbgfs_lock);
	rp += sprintf(rp, "\n");

	r = rp - respbuf;
	return simple_read_from_buffer(buf, size, ppos, respbuf, r);
}

static const struct file_operations ec_dbgfs_ops = {
	.write = ec_dbgfs_cmd_write,
	.read = ec_dbgfs_cmd_read,
};

static struct dentry *olpc_ec_setup_debugfs(void)
{
	struct dentry *dbgfs_dir;

	dbgfs_dir = debugfs_create_dir("olpc-ec", NULL);
	if (IS_ERR_OR_NULL(dbgfs_dir))
		return NULL;

	debugfs_create_file("cmd", 0600, dbgfs_dir, NULL, &ec_dbgfs_ops);

	return dbgfs_dir;
}

#else

static struct dentry *olpc_ec_setup_debugfs(void)
{
	return NULL;
}

#endif /* CONFIG_DEBUG_FS */

static int olpc_ec_probe(struct platform_device *pdev)
{
	struct olpc_ec_priv *ec;
	int err;

	if (!ec_driver)
		return -ENODEV;

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

	ec->drv = ec_driver;
	INIT_WORK(&ec->worker, olpc_ec_worker);
	mutex_init(&ec->cmd_lock);

	INIT_LIST_HEAD(&ec->cmd_q);
	spin_lock_init(&ec->cmd_q_lock);

	ec_priv = ec;
	platform_set_drvdata(pdev, ec);

	err = ec_driver->probe ? ec_driver->probe(pdev) : 0;
	if (err) {
		ec_priv = NULL;
		kfree(ec);
	} else {
		ec->dbgfs_dir = olpc_ec_setup_debugfs();
	}

	return err;
}

static int olpc_ec_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct olpc_ec_priv *ec = platform_get_drvdata(pdev);
	int err = 0;

	if (ec_driver->suspend)
		err = ec_driver->suspend(pdev);
	if (!err)
		ec->suspended = true;

	return err;
}

static int olpc_ec_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct olpc_ec_priv *ec = platform_get_drvdata(pdev);

	ec->suspended = false;
	return ec_driver->resume ? ec_driver->resume(pdev) : 0;
}

static const struct dev_pm_ops olpc_ec_pm_ops = {
	.suspend_late = olpc_ec_suspend,
	.resume_early = olpc_ec_resume,
};

static struct platform_driver olpc_ec_plat_driver = {
	.probe = olpc_ec_probe,
	.driver = {
		.name = "olpc-ec",
		.pm = &olpc_ec_pm_ops,
	},
};

static int __init olpc_ec_init_module(void)
{
	return platform_driver_register(&olpc_ec_plat_driver);
}

arch_initcall(olpc_ec_init_module);

MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
MODULE_LICENSE("GPL");
