/*
 * ACPI AML interfacing support
 *
 * Copyright (C) 2015, Intel Corporation
 * Authors: Lv Zheng <lv.zheng@intel.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/* #define DEBUG */
#define pr_fmt(fmt) "ACPI : AML: " fmt

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/proc_fs.h>
#include <linux/debugfs.h>
#include <linux/circ_buf.h>
#include <linux/acpi.h>
#include "internal.h"

#define ACPI_AML_BUF_ALIGN	(sizeof (acpi_size))
#define ACPI_AML_BUF_SIZE	PAGE_SIZE

#define circ_count(circ) \
	(CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_count_to_end(circ) \
	(CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_space(circ) \
	(CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))
#define circ_space_to_end(circ) \
	(CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE))

#define ACPI_AML_OPENED		0x0001
#define ACPI_AML_CLOSED		0x0002
#define ACPI_AML_IN_USER	0x0004 /* user space is writing cmd */
#define ACPI_AML_IN_KERN	0x0008 /* kernel space is reading cmd */
#define ACPI_AML_OUT_USER	0x0010 /* user space is reading log */
#define ACPI_AML_OUT_KERN	0x0020 /* kernel space is writing log */
#define ACPI_AML_USER		(ACPI_AML_IN_USER | ACPI_AML_OUT_USER)
#define ACPI_AML_KERN		(ACPI_AML_IN_KERN | ACPI_AML_OUT_KERN)
#define ACPI_AML_BUSY		(ACPI_AML_USER | ACPI_AML_KERN)
#define ACPI_AML_OPEN		(ACPI_AML_OPENED | ACPI_AML_CLOSED)

struct acpi_aml_io {
	wait_queue_head_t wait;
	unsigned long flags;
	unsigned long users;
	struct mutex lock;
	struct task_struct *thread;
	char out_buf[ACPI_AML_BUF_SIZE] __aligned(ACPI_AML_BUF_ALIGN);
	struct circ_buf out_crc;
	char in_buf[ACPI_AML_BUF_SIZE] __aligned(ACPI_AML_BUF_ALIGN);
	struct circ_buf in_crc;
	acpi_osd_exec_callback function;
	void *context;
	unsigned long usages;
};

static struct acpi_aml_io acpi_aml_io;
static bool acpi_aml_initialized;
static struct file *acpi_aml_active_reader;
static struct dentry *acpi_aml_dentry;

static inline bool __acpi_aml_running(void)
{
	return acpi_aml_io.thread ? true : false;
}

static inline bool __acpi_aml_access_ok(unsigned long flag)
{
	/*
	 * The debugger interface is in opened state (OPENED && !CLOSED),
	 * then it is allowed to access the debugger buffers from either
	 * user space or the kernel space.
	 * In addition, for the kernel space, only the debugger thread
	 * (thread ID matched) is allowed to access.
	 */
	if (!(acpi_aml_io.flags & ACPI_AML_OPENED) ||
	    (acpi_aml_io.flags & ACPI_AML_CLOSED) ||
	    !__acpi_aml_running())
		return false;
	if ((flag & ACPI_AML_KERN) &&
	    current != acpi_aml_io.thread)
		return false;
	return true;
}

static inline bool __acpi_aml_readable(struct circ_buf *circ, unsigned long flag)
{
	/*
	 * Another read is not in progress and there is data in buffer
	 * available for read.
	 */
	if (!(acpi_aml_io.flags & flag) && circ_count(circ))
		return true;
	return false;
}

static inline bool __acpi_aml_writable(struct circ_buf *circ, unsigned long flag)
{
	/*
	 * Another write is not in progress and there is buffer space
	 * available for write.
	 */
	if (!(acpi_aml_io.flags & flag) && circ_space(circ))
		return true;
	return false;
}

static inline bool __acpi_aml_busy(void)
{
	if (acpi_aml_io.flags & ACPI_AML_BUSY)
		return true;
	return false;
}

static inline bool __acpi_aml_opened(void)
{
	if (acpi_aml_io.flags & ACPI_AML_OPEN)
		return true;
	return false;
}

static inline bool __acpi_aml_used(void)
{
	return acpi_aml_io.usages ? true : false;
}

static inline bool acpi_aml_running(void)
{
	bool ret;

	mutex_lock(&acpi_aml_io.lock);
	ret = __acpi_aml_running();
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static bool acpi_aml_busy(void)
{
	bool ret;

	mutex_lock(&acpi_aml_io.lock);
	ret = __acpi_aml_busy();
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static bool acpi_aml_used(void)
{
	bool ret;

	/*
	 * The usage count is prepared to avoid race conditions between the
	 * starts and the stops of the debugger thread.
	 */
	mutex_lock(&acpi_aml_io.lock);
	ret = __acpi_aml_used();
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static bool acpi_aml_kern_readable(void)
{
	bool ret;

	mutex_lock(&acpi_aml_io.lock);
	ret = !__acpi_aml_access_ok(ACPI_AML_IN_KERN) ||
	      __acpi_aml_readable(&acpi_aml_io.in_crc, ACPI_AML_IN_KERN);
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static bool acpi_aml_kern_writable(void)
{
	bool ret;

	mutex_lock(&acpi_aml_io.lock);
	ret = !__acpi_aml_access_ok(ACPI_AML_OUT_KERN) ||
	      __acpi_aml_writable(&acpi_aml_io.out_crc, ACPI_AML_OUT_KERN);
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static bool acpi_aml_user_readable(void)
{
	bool ret;

	mutex_lock(&acpi_aml_io.lock);
	ret = !__acpi_aml_access_ok(ACPI_AML_OUT_USER) ||
	      __acpi_aml_readable(&acpi_aml_io.out_crc, ACPI_AML_OUT_USER);
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static bool acpi_aml_user_writable(void)
{
	bool ret;

	mutex_lock(&acpi_aml_io.lock);
	ret = !__acpi_aml_access_ok(ACPI_AML_IN_USER) ||
	      __acpi_aml_writable(&acpi_aml_io.in_crc, ACPI_AML_IN_USER);
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static int acpi_aml_lock_write(struct circ_buf *circ, unsigned long flag)
{
	int ret = 0;

	mutex_lock(&acpi_aml_io.lock);
	if (!__acpi_aml_access_ok(flag)) {
		ret = -EFAULT;
		goto out;
	}
	if (!__acpi_aml_writable(circ, flag)) {
		ret = -EAGAIN;
		goto out;
	}
	acpi_aml_io.flags |= flag;
out:
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static int acpi_aml_lock_read(struct circ_buf *circ, unsigned long flag)
{
	int ret = 0;

	mutex_lock(&acpi_aml_io.lock);
	if (!__acpi_aml_access_ok(flag)) {
		ret = -EFAULT;
		goto out;
	}
	if (!__acpi_aml_readable(circ, flag)) {
		ret = -EAGAIN;
		goto out;
	}
	acpi_aml_io.flags |= flag;
out:
	mutex_unlock(&acpi_aml_io.lock);
	return ret;
}

static void acpi_aml_unlock_fifo(unsigned long flag, bool wakeup)
{
	mutex_lock(&acpi_aml_io.lock);
	acpi_aml_io.flags &= ~flag;
	if (wakeup)
		wake_up_interruptible(&acpi_aml_io.wait);
	mutex_unlock(&acpi_aml_io.lock);
}

static int acpi_aml_write_kern(const char *buf, int len)
{
	int ret;
	struct circ_buf *crc = &acpi_aml_io.out_crc;
	int n;
	char *p;

	ret = acpi_aml_lock_write(crc, ACPI_AML_OUT_KERN);
	if (ret < 0)
		return ret;
	/* sync tail before inserting logs */
	smp_mb();
	p = &crc->buf[crc->head];
	n = min(len, circ_space_to_end(crc));
	memcpy(p, buf, n);
	/* sync head after inserting logs */
	smp_wmb();
	crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
	acpi_aml_unlock_fifo(ACPI_AML_OUT_KERN, true);
	return n;
}

static int acpi_aml_readb_kern(void)
{
	int ret;
	struct circ_buf *crc = &acpi_aml_io.in_crc;
	char *p;

	ret = acpi_aml_lock_read(crc, ACPI_AML_IN_KERN);
	if (ret < 0)
		return ret;
	/* sync head before removing cmds */
	smp_rmb();
	p = &crc->buf[crc->tail];
	ret = (int)*p;
	/* sync tail before inserting cmds */
	smp_mb();
	crc->tail = (crc->tail + 1) & (ACPI_AML_BUF_SIZE - 1);
	acpi_aml_unlock_fifo(ACPI_AML_IN_KERN, true);
	return ret;
}

/*
 * acpi_aml_write_log() - Capture debugger output
 * @msg: the debugger output
 *
 * This function should be used to implement acpi_os_printf() to filter out
 * the debugger output and store the output into the debugger interface
 * buffer. Return the size of stored logs or errno.
 */
static ssize_t acpi_aml_write_log(const char *msg)
{
	int ret = 0;
	int count = 0, size = 0;

	if (!acpi_aml_initialized)
		return -ENODEV;
	if (msg)
		count = strlen(msg);
	while (count > 0) {
again:
		ret = acpi_aml_write_kern(msg + size, count);
		if (ret == -EAGAIN) {
			ret = wait_event_interruptible(acpi_aml_io.wait,
				acpi_aml_kern_writable());
			/*
			 * We need to retry when the condition
			 * becomes true.
			 */
			if (ret == 0)
				goto again;
			break;
		}
		if (ret < 0)
			break;
		size += ret;
		count -= ret;
	}
	return size > 0 ? size : ret;
}

/*
 * acpi_aml_read_cmd() - Capture debugger input
 * @msg: the debugger input
 * @size: the size of the debugger input
 *
 * This function should be used to implement acpi_os_get_line() to capture
 * the debugger input commands and store the input commands into the
 * debugger interface buffer. Return the size of stored commands or errno.
 */
static ssize_t acpi_aml_read_cmd(char *msg, size_t count)
{
	int ret = 0;
	int size = 0;

	/*
	 * This is ensured by the running fact of the debugger thread
	 * unless a bug is introduced.
	 */
	BUG_ON(!acpi_aml_initialized);
	while (count > 0) {
again:
		/*
		 * Check each input byte to find the end of the command.
		 */
		ret = acpi_aml_readb_kern();
		if (ret == -EAGAIN) {
			ret = wait_event_interruptible(acpi_aml_io.wait,
				acpi_aml_kern_readable());
			/*
			 * We need to retry when the condition becomes
			 * true.
			 */
			if (ret == 0)
				goto again;
		}
		if (ret < 0)
			break;
		*(msg + size) = (char)ret;
		size++;
		count--;
		if (ret == '\n') {
			/*
			 * acpi_os_get_line() requires a zero terminated command
			 * string.
			 */
			*(msg + size - 1) = '\0';
			break;
		}
	}
	return size > 0 ? size : ret;
}

static int acpi_aml_thread(void *unsed)
{
	acpi_osd_exec_callback function = NULL;
	void *context;

	mutex_lock(&acpi_aml_io.lock);
	if (acpi_aml_io.function) {
		acpi_aml_io.usages++;
		function = acpi_aml_io.function;
		context = acpi_aml_io.context;
	}
	mutex_unlock(&acpi_aml_io.lock);

	if (function)
		function(context);

	mutex_lock(&acpi_aml_io.lock);
	acpi_aml_io.usages--;
	if (!__acpi_aml_used()) {
		acpi_aml_io.thread = NULL;
		wake_up(&acpi_aml_io.wait);
	}
	mutex_unlock(&acpi_aml_io.lock);

	return 0;
}

/*
 * acpi_aml_create_thread() - Create AML debugger thread
 * @function: the debugger thread callback
 * @context: the context to be passed to the debugger thread
 *
 * This function should be used to implement acpi_os_execute() which is
 * used by the ACPICA debugger to create the debugger thread.
 */
static int acpi_aml_create_thread(acpi_osd_exec_callback function, void *context)
{
	struct task_struct *t;

	mutex_lock(&acpi_aml_io.lock);
	acpi_aml_io.function = function;
	acpi_aml_io.context = context;
	mutex_unlock(&acpi_aml_io.lock);

	t = kthread_create(acpi_aml_thread, NULL, "aml");
	if (IS_ERR(t)) {
		pr_err("Failed to create AML debugger thread.\n");
		return PTR_ERR(t);
	}

	mutex_lock(&acpi_aml_io.lock);
	acpi_aml_io.thread = t;
	acpi_set_debugger_thread_id((acpi_thread_id)(unsigned long)t);
	wake_up_process(t);
	mutex_unlock(&acpi_aml_io.lock);
	return 0;
}

static int acpi_aml_wait_command_ready(bool single_step,
				       char *buffer, size_t length)
{
	acpi_status status;

	if (single_step)
		acpi_os_printf("\n%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
	else
		acpi_os_printf("\n%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);

	status = acpi_os_get_line(buffer, length, NULL);
	if (ACPI_FAILURE(status))
		return -EINVAL;
	return 0;
}

static int acpi_aml_notify_command_complete(void)
{
	return 0;
}

static int acpi_aml_open(struct inode *inode, struct file *file)
{
	int ret = 0;
	acpi_status status;

	mutex_lock(&acpi_aml_io.lock);
	/*
	 * The debugger interface is being closed, no new user is allowed
	 * during this period.
	 */
	if (acpi_aml_io.flags & ACPI_AML_CLOSED) {
		ret = -EBUSY;
		goto err_lock;
	}
	if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
		/*
		 * Only one reader is allowed to initiate the debugger
		 * thread.
		 */
		if (acpi_aml_active_reader) {
			ret = -EBUSY;
			goto err_lock;
		} else {
			pr_debug("Opening debugger reader.\n");
			acpi_aml_active_reader = file;
		}
	} else {
		/*
		 * No writer is allowed unless the debugger thread is
		 * ready.
		 */
		if (!(acpi_aml_io.flags & ACPI_AML_OPENED)) {
			ret = -ENODEV;
			goto err_lock;
		}
	}
	if (acpi_aml_active_reader == file) {
		pr_debug("Opening debugger interface.\n");
		mutex_unlock(&acpi_aml_io.lock);

		pr_debug("Initializing debugger thread.\n");
		status = acpi_initialize_debugger();
		if (ACPI_FAILURE(status)) {
			pr_err("Failed to initialize debugger.\n");
			ret = -EINVAL;
			goto err_exit;
		}
		pr_debug("Debugger thread initialized.\n");

		mutex_lock(&acpi_aml_io.lock);
		acpi_aml_io.flags |= ACPI_AML_OPENED;
		acpi_aml_io.out_crc.head = acpi_aml_io.out_crc.tail = 0;
		acpi_aml_io.in_crc.head = acpi_aml_io.in_crc.tail = 0;
		pr_debug("Debugger interface opened.\n");
	}
	acpi_aml_io.users++;
err_lock:
	if (ret < 0) {
		if (acpi_aml_active_reader == file)
			acpi_aml_active_reader = NULL;
	}
	mutex_unlock(&acpi_aml_io.lock);
err_exit:
	return ret;
}

static int acpi_aml_release(struct inode *inode, struct file *file)
{
	mutex_lock(&acpi_aml_io.lock);
	acpi_aml_io.users--;
	if (file == acpi_aml_active_reader) {
		pr_debug("Closing debugger reader.\n");
		acpi_aml_active_reader = NULL;

		pr_debug("Closing debugger interface.\n");
		acpi_aml_io.flags |= ACPI_AML_CLOSED;

		/*
		 * Wake up all user space/kernel space blocked
		 * readers/writers.
		 */
		wake_up_interruptible(&acpi_aml_io.wait);
		mutex_unlock(&acpi_aml_io.lock);
		/*
		 * Wait all user space/kernel space readers/writers to
		 * stop so that ACPICA command loop of the debugger thread
		 * should fail all its command line reads after this point.
		 */
		wait_event(acpi_aml_io.wait, !acpi_aml_busy());

		/*
		 * Then we try to terminate the debugger thread if it is
		 * not terminated.
		 */
		pr_debug("Terminating debugger thread.\n");
		acpi_terminate_debugger();
		wait_event(acpi_aml_io.wait, !acpi_aml_used());
		pr_debug("Debugger thread terminated.\n");

		mutex_lock(&acpi_aml_io.lock);
		acpi_aml_io.flags &= ~ACPI_AML_OPENED;
	}
	if (acpi_aml_io.users == 0) {
		pr_debug("Debugger interface closed.\n");
		acpi_aml_io.flags &= ~ACPI_AML_CLOSED;
	}
	mutex_unlock(&acpi_aml_io.lock);
	return 0;
}

static int acpi_aml_read_user(char __user *buf, int len)
{
	int ret;
	struct circ_buf *crc = &acpi_aml_io.out_crc;
	int n;
	char *p;

	ret = acpi_aml_lock_read(crc, ACPI_AML_OUT_USER);
	if (ret < 0)
		return ret;
	/* sync head before removing logs */
	smp_rmb();
	p = &crc->buf[crc->tail];
	n = min(len, circ_count_to_end(crc));
	if (copy_to_user(buf, p, n)) {
		ret = -EFAULT;
		goto out;
	}
	/* sync tail after removing logs */
	smp_mb();
	crc->tail = (crc->tail + n) & (ACPI_AML_BUF_SIZE - 1);
	ret = n;
out:
	acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, ret >= 0);
	return ret;
}

static ssize_t acpi_aml_read(struct file *file, char __user *buf,
			     size_t count, loff_t *ppos)
{
	int ret = 0;
	int size = 0;

	if (!count)
		return 0;
	if (!access_ok(VERIFY_WRITE, buf, count))
		return -EFAULT;

	while (count > 0) {
again:
		ret = acpi_aml_read_user(buf + size, count);
		if (ret == -EAGAIN) {
			if (file->f_flags & O_NONBLOCK)
				break;
			else {
				ret = wait_event_interruptible(acpi_aml_io.wait,
					acpi_aml_user_readable());
				/*
				 * We need to retry when the condition
				 * becomes true.
				 */
				if (ret == 0)
					goto again;
			}
		}
		if (ret < 0) {
			if (!acpi_aml_running())
				ret = 0;
			break;
		}
		if (ret) {
			size += ret;
			count -= ret;
			*ppos += ret;
			break;
		}
	}
	return size > 0 ? size : ret;
}

static int acpi_aml_write_user(const char __user *buf, int len)
{
	int ret;
	struct circ_buf *crc = &acpi_aml_io.in_crc;
	int n;
	char *p;

	ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER);
	if (ret < 0)
		return ret;
	/* sync tail before inserting cmds */
	smp_mb();
	p = &crc->buf[crc->head];
	n = min(len, circ_space_to_end(crc));
	if (copy_from_user(p, buf, n)) {
		ret = -EFAULT;
		goto out;
	}
	/* sync head after inserting cmds */
	smp_wmb();
	crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
	ret = n;
out:
	acpi_aml_unlock_fifo(ACPI_AML_IN_USER, ret >= 0);
	return n;
}

static ssize_t acpi_aml_write(struct file *file, const char __user *buf,
			      size_t count, loff_t *ppos)
{
	int ret = 0;
	int size = 0;

	if (!count)
		return 0;
	if (!access_ok(VERIFY_READ, buf, count))
		return -EFAULT;

	while (count > 0) {
again:
		ret = acpi_aml_write_user(buf + size, count);
		if (ret == -EAGAIN) {
			if (file->f_flags & O_NONBLOCK)
				break;
			else {
				ret = wait_event_interruptible(acpi_aml_io.wait,
					acpi_aml_user_writable());
				/*
				 * We need to retry when the condition
				 * becomes true.
				 */
				if (ret == 0)
					goto again;
			}
		}
		if (ret < 0) {
			if (!acpi_aml_running())
				ret = 0;
			break;
		}
		if (ret) {
			size += ret;
			count -= ret;
			*ppos += ret;
		}
	}
	return size > 0 ? size : ret;
}

static unsigned int acpi_aml_poll(struct file *file, poll_table *wait)
{
	int masks = 0;

	poll_wait(file, &acpi_aml_io.wait, wait);
	if (acpi_aml_user_readable())
		masks |= POLLIN | POLLRDNORM;
	if (acpi_aml_user_writable())
		masks |= POLLOUT | POLLWRNORM;

	return masks;
}

static const struct file_operations acpi_aml_operations = {
	.read		= acpi_aml_read,
	.write		= acpi_aml_write,
	.poll		= acpi_aml_poll,
	.open		= acpi_aml_open,
	.release	= acpi_aml_release,
	.llseek		= generic_file_llseek,
};

static const struct acpi_debugger_ops acpi_aml_debugger = {
	.create_thread		 = acpi_aml_create_thread,
	.read_cmd		 = acpi_aml_read_cmd,
	.write_log		 = acpi_aml_write_log,
	.wait_command_ready	 = acpi_aml_wait_command_ready,
	.notify_command_complete = acpi_aml_notify_command_complete,
};

int __init acpi_aml_init(void)
{
	int ret = 0;

	if (!acpi_debugfs_dir) {
		ret = -ENOENT;
		goto err_exit;
	}

	/* Initialize AML IO interface */
	mutex_init(&acpi_aml_io.lock);
	init_waitqueue_head(&acpi_aml_io.wait);
	acpi_aml_io.out_crc.buf = acpi_aml_io.out_buf;
	acpi_aml_io.in_crc.buf = acpi_aml_io.in_buf;
	acpi_aml_dentry = debugfs_create_file("acpidbg",
					      S_IFREG | S_IRUGO | S_IWUSR,
					      acpi_debugfs_dir, NULL,
					      &acpi_aml_operations);
	if (acpi_aml_dentry == NULL) {
		ret = -ENODEV;
		goto err_exit;
	}
	ret = acpi_register_debugger(THIS_MODULE, &acpi_aml_debugger);
	if (ret)
		goto err_fs;
	acpi_aml_initialized = true;

err_fs:
	if (ret) {
		debugfs_remove(acpi_aml_dentry);
		acpi_aml_dentry = NULL;
	}
err_exit:
	return ret;
}

void __exit acpi_aml_exit(void)
{
	if (acpi_aml_initialized) {
		acpi_unregister_debugger(&acpi_aml_debugger);
		if (acpi_aml_dentry) {
			debugfs_remove(acpi_aml_dentry);
			acpi_aml_dentry = NULL;
		}
		acpi_aml_initialized = false;
	}
}

module_init(acpi_aml_init);
module_exit(acpi_aml_exit);

MODULE_AUTHOR("Lv Zheng");
MODULE_DESCRIPTION("ACPI debugger userspace IO driver");
MODULE_LICENSE("GPL");
