/*
 * UART driver for the Greybus "generic" UART module.
 *
 * Copyright 2014 Google Inc.
 * Copyright 2014 Linaro Ltd.
 *
 * Released under the GPLv2 only.
 *
 * Heavily based on drivers/usb/class/cdc-acm.c and
 * drivers/usb/serial/usb-serial.c.
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/mutex.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/idr.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>

#include "greybus.h"

#define GB_NUM_MINORS	16	/* 16 is is more than enough */
#define GB_NAME		"ttyGB"

struct gb_tty_line_coding {
	__le32	rate;
	__u8	format;
	__u8	parity;
	__u8	data_bits;
};

struct gb_tty {
	struct tty_port port;
	void *buffer;
	size_t buffer_payload_max;
	struct gb_connection *connection;
	u16 cport_id;
	unsigned int minor;
	unsigned char clocal;
	bool disconnected;
	spinlock_t read_lock;
	spinlock_t write_lock;
	struct async_icount iocount;
	struct async_icount oldcount;
	wait_queue_head_t wioctl;
	struct mutex mutex;
	u8 ctrlin;	/* input control lines */
	u8 ctrlout;	/* output control lines */
	struct gb_tty_line_coding line_coding;
};

static struct tty_driver *gb_tty_driver;
static DEFINE_IDR(tty_minors);
static DEFINE_MUTEX(table_lock);
static atomic_t reference_count = ATOMIC_INIT(0);

static int gb_uart_receive_data(struct gb_tty *gb_tty,
				struct gb_connection *connection,
				struct gb_uart_recv_data_request *receive_data)
{
	struct tty_port *port = &gb_tty->port;
	u16 recv_data_size;
	int count;
	unsigned long tty_flags = TTY_NORMAL;

	count = gb_tty->buffer_payload_max - sizeof(*receive_data);
	recv_data_size = le16_to_cpu(receive_data->size);
	if (!recv_data_size || recv_data_size > count)
		return -EINVAL;

	if (receive_data->flags) {
		if (receive_data->flags & GB_UART_RECV_FLAG_BREAK)
			tty_flags = TTY_BREAK;
		else if (receive_data->flags & GB_UART_RECV_FLAG_PARITY)
			tty_flags = TTY_PARITY;
		else if (receive_data->flags & GB_UART_RECV_FLAG_FRAMING)
			tty_flags = TTY_FRAME;

		/* overrun is special, not associated with a char */
		if (receive_data->flags & GB_UART_RECV_FLAG_OVERRUN)
			tty_insert_flip_char(port, 0, TTY_OVERRUN);
	}
	count = tty_insert_flip_string_fixed_flag(port, receive_data->data,
						  tty_flags, recv_data_size);
	if (count != recv_data_size) {
		dev_err(&connection->bundle->dev,
			"UART: RX 0x%08x bytes only wrote 0x%08x\n",
			recv_data_size, count);
	}
	if (count)
		tty_flip_buffer_push(port);
	return 0;
}

static int gb_uart_request_recv(u8 type, struct gb_operation *op)
{
	struct gb_connection *connection = op->connection;
	struct gb_tty *gb_tty = connection->private;
	struct gb_message *request = op->request;
	struct gb_uart_serial_state_request *serial_state;
	int ret = 0;

	switch (type) {
	case GB_UART_TYPE_RECEIVE_DATA:
		ret = gb_uart_receive_data(gb_tty, connection,
					   request->payload);
		break;
	case GB_UART_TYPE_SERIAL_STATE:
		serial_state = request->payload;
		gb_tty->ctrlin = serial_state->control;
		break;
	default:
		dev_err(&connection->bundle->dev,
			"unsupported unsolicited request: 0x%02x\n", type);
		ret = -EINVAL;
	}

	return ret;
}

static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
{
	struct gb_uart_send_data_request *request;
	int ret;

	if (!data || !size)
		return 0;

	if (size > tty->buffer_payload_max)
		size = tty->buffer_payload_max;
	request = tty->buffer;
	request->size = cpu_to_le16(size);
	memcpy(&request->data[0], data, size);
	ret = gb_operation_sync(tty->connection, GB_UART_TYPE_SEND_DATA,
				request, sizeof(*request) + size, NULL, 0);
	if (ret)
		return ret;
	else
		return size;
}

static int send_line_coding(struct gb_tty *tty)
{
	struct gb_uart_set_line_coding_request request;

	memcpy(&request, &tty->line_coding,
	       sizeof(tty->line_coding));
	return gb_operation_sync(tty->connection, GB_UART_TYPE_SET_LINE_CODING,
				 &request, sizeof(request), NULL, 0);
}

static int send_control(struct gb_tty *gb_tty, u8 control)
{
	struct gb_uart_set_control_line_state_request request;

	request.control = control;
	return gb_operation_sync(gb_tty->connection,
				 GB_UART_TYPE_SET_CONTROL_LINE_STATE,
				 &request, sizeof(request), NULL, 0);
}

static int send_break(struct gb_tty *gb_tty, u8 state)
{
	struct gb_uart_set_break_request request;

	if ((state != 0) && (state != 1)) {
		dev_err(&gb_tty->connection->bundle->dev,
			"invalid break state of %d\n", state);
		return -EINVAL;
	}

	request.state = state;
	return gb_operation_sync(gb_tty->connection, GB_UART_TYPE_SEND_BREAK,
				 &request, sizeof(request), NULL, 0);
}


static struct gb_tty *get_gb_by_minor(unsigned minor)
{
	struct gb_tty *gb_tty;

	mutex_lock(&table_lock);
	gb_tty = idr_find(&tty_minors, minor);
	if (gb_tty) {
		mutex_lock(&gb_tty->mutex);
		if (gb_tty->disconnected) {
			mutex_unlock(&gb_tty->mutex);
			gb_tty = NULL;
		} else {
			tty_port_get(&gb_tty->port);
			mutex_unlock(&gb_tty->mutex);
		}
	}
	mutex_unlock(&table_lock);
	return gb_tty;
}

static int alloc_minor(struct gb_tty *gb_tty)
{
	int minor;

	mutex_lock(&table_lock);
	minor = idr_alloc(&tty_minors, gb_tty, 0, GB_NUM_MINORS, GFP_KERNEL);
	mutex_unlock(&table_lock);
	if (minor >= 0)
		gb_tty->minor = minor;
	return minor;
}

static void release_minor(struct gb_tty *gb_tty)
{
	int minor = gb_tty->minor;

	gb_tty->minor = 0;	/* Maybe should use an invalid value instead */
	mutex_lock(&table_lock);
	idr_remove(&tty_minors, minor);
	mutex_unlock(&table_lock);
}

static int gb_tty_install(struct tty_driver *driver, struct tty_struct *tty)
{
	struct gb_tty *gb_tty;
	int retval;

	gb_tty = get_gb_by_minor(tty->index);
	if (!gb_tty)
		return -ENODEV;

	retval = tty_standard_install(driver, tty);
	if (retval)
		goto error;

	tty->driver_data = gb_tty;
	return 0;
error:
	tty_port_put(&gb_tty->port);
	return retval;
}

static int gb_tty_open(struct tty_struct *tty, struct file *file)
{
	struct gb_tty *gb_tty = tty->driver_data;

	return tty_port_open(&gb_tty->port, tty, file);
}

static void gb_tty_close(struct tty_struct *tty, struct file *file)
{
	struct gb_tty *gb_tty = tty->driver_data;

	tty_port_close(&gb_tty->port, tty, file);
}

static void gb_tty_cleanup(struct tty_struct *tty)
{
	struct gb_tty *gb_tty = tty->driver_data;

	tty_port_put(&gb_tty->port);
}

static void gb_tty_hangup(struct tty_struct *tty)
{
	struct gb_tty *gb_tty = tty->driver_data;

	tty_port_hangup(&gb_tty->port);
}

static int gb_tty_write(struct tty_struct *tty, const unsigned char *buf,
			int count)
{
	struct gb_tty *gb_tty = tty->driver_data;

	return send_data(gb_tty, count, buf);
}

static int gb_tty_write_room(struct tty_struct *tty)
{
	struct gb_tty *gb_tty = tty->driver_data;

	return gb_tty->buffer_payload_max;
}

static int gb_tty_chars_in_buffer(struct tty_struct *tty)
{
	return 0;
}

static int gb_tty_break_ctl(struct tty_struct *tty, int state)
{
	struct gb_tty *gb_tty = tty->driver_data;

	return send_break(gb_tty, state ? 1 : 0);
}

static void gb_tty_set_termios(struct tty_struct *tty,
			       struct ktermios *termios_old)
{
	struct gb_tty *gb_tty = tty->driver_data;
	struct ktermios *termios = &tty->termios;
	struct gb_tty_line_coding newline;
	u8 newctrl = gb_tty->ctrlout;

	newline.rate = cpu_to_le32(tty_get_baud_rate(tty));
	newline.format = termios->c_cflag & CSTOPB ?
				GB_SERIAL_2_STOP_BITS : GB_SERIAL_1_STOP_BITS;
	newline.parity = termios->c_cflag & PARENB ?
				(termios->c_cflag & PARODD ? 1 : 2) +
				(termios->c_cflag & CMSPAR ? 2 : 0) : 0;

	switch (termios->c_cflag & CSIZE) {
	case CS5:
		newline.data_bits = 5;
		break;
	case CS6:
		newline.data_bits = 6;
		break;
	case CS7:
		newline.data_bits = 7;
		break;
	case CS8:
	default:
		newline.data_bits = 8;
		break;
	}

	/* FIXME: needs to clear unsupported bits in the termios */
	gb_tty->clocal = ((termios->c_cflag & CLOCAL) != 0);

	if (C_BAUD(tty) == B0) {
		newline.rate = gb_tty->line_coding.rate;
		newctrl &= GB_UART_CTRL_DTR;
	} else if (termios_old && (termios_old->c_cflag & CBAUD) == B0) {
		newctrl |= GB_UART_CTRL_DTR;
	}

	if (newctrl != gb_tty->ctrlout) {
		gb_tty->ctrlout = newctrl;
		send_control(gb_tty, newctrl);
	}

	if (memcpy(&gb_tty->line_coding, &newline, sizeof(newline))) {
		memcpy(&gb_tty->line_coding, &newline, sizeof(newline));
		send_line_coding(gb_tty);
	}
}

static int gb_tty_tiocmget(struct tty_struct *tty)
{
	struct gb_tty *gb_tty = tty->driver_data;

	return (gb_tty->ctrlout & GB_UART_CTRL_DTR ? TIOCM_DTR : 0) |
	       (gb_tty->ctrlout & GB_UART_CTRL_RTS ? TIOCM_RTS : 0) |
	       (gb_tty->ctrlin  & GB_UART_CTRL_DSR ? TIOCM_DSR : 0) |
	       (gb_tty->ctrlin  & GB_UART_CTRL_RI  ? TIOCM_RI  : 0) |
	       (gb_tty->ctrlin  & GB_UART_CTRL_DCD ? TIOCM_CD  : 0) |
	       TIOCM_CTS;
}

static int gb_tty_tiocmset(struct tty_struct *tty, unsigned int set,
			   unsigned int clear)
{
	struct gb_tty *gb_tty = tty->driver_data;
	u8 newctrl = gb_tty->ctrlout;

	set = (set & TIOCM_DTR ? GB_UART_CTRL_DTR : 0) |
	      (set & TIOCM_RTS ? GB_UART_CTRL_RTS : 0);
	clear = (clear & TIOCM_DTR ? GB_UART_CTRL_DTR : 0) |
		(clear & TIOCM_RTS ? GB_UART_CTRL_RTS : 0);

	newctrl = (newctrl & ~clear) | set;
	if (gb_tty->ctrlout == newctrl)
		return 0;

	gb_tty->ctrlout = newctrl;
	return send_control(gb_tty, newctrl);
}

static void gb_tty_throttle(struct tty_struct *tty)
{
	struct gb_tty *gb_tty = tty->driver_data;
	unsigned char stop_char;
	int retval;

	if (I_IXOFF(tty)) {
		stop_char = STOP_CHAR(tty);
		retval = gb_tty_write(tty, &stop_char, 1);
		if (retval <= 0)
			return;
	}

	if (tty->termios.c_cflag & CRTSCTS) {
		gb_tty->ctrlout &= ~GB_UART_CTRL_RTS;
		retval = send_control(gb_tty, gb_tty->ctrlout);
	}

}

static void gb_tty_unthrottle(struct tty_struct *tty)
{
	struct gb_tty *gb_tty = tty->driver_data;
	unsigned char start_char;
	int retval;

	if (I_IXOFF(tty)) {
		start_char = START_CHAR(tty);
		retval = gb_tty_write(tty, &start_char, 1);
		if (retval <= 0)
			return;
	}

	if (tty->termios.c_cflag & CRTSCTS) {
		gb_tty->ctrlout |= GB_UART_CTRL_RTS;
		retval = send_control(gb_tty, gb_tty->ctrlout);
	}
}

static int get_serial_info(struct gb_tty *gb_tty,
			   struct serial_struct __user *info)
{
	struct serial_struct tmp;

	if (!info)
		return -EINVAL;

	memset(&tmp, 0, sizeof(tmp));
	tmp.flags = ASYNC_LOW_LATENCY | ASYNC_SKIP_TEST;
	tmp.type = PORT_16550A;
	tmp.line = gb_tty->minor;
	tmp.xmit_fifo_size = 16;
	tmp.baud_base = 9600;
	tmp.close_delay = gb_tty->port.close_delay / 10;
	tmp.closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
				ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10;

	if (copy_to_user(info, &tmp, sizeof(tmp)))
		return -EFAULT;
	return 0;
}

static int set_serial_info(struct gb_tty *gb_tty,
			   struct serial_struct __user *newinfo)
{
	struct serial_struct new_serial;
	unsigned int closing_wait;
	unsigned int close_delay;
	int retval = 0;

	if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
		return -EFAULT;

	close_delay = new_serial.close_delay * 10;
	closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
			ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;

	mutex_lock(&gb_tty->port.mutex);
	if (!capable(CAP_SYS_ADMIN)) {
		if ((close_delay != gb_tty->port.close_delay) ||
		    (closing_wait != gb_tty->port.closing_wait))
			retval = -EPERM;
		else
			retval = -EOPNOTSUPP;
	} else {
		gb_tty->port.close_delay = close_delay;
		gb_tty->port.closing_wait = closing_wait;
	}
	mutex_unlock(&gb_tty->port.mutex);
	return retval;
}

static int wait_serial_change(struct gb_tty *gb_tty, unsigned long arg)
{
	int retval = 0;
	DECLARE_WAITQUEUE(wait, current);
	struct async_icount old;
	struct async_icount new;

	if (!(arg & (TIOCM_DSR | TIOCM_RI | TIOCM_CD)))
		return -EINVAL;

	do {
		spin_lock_irq(&gb_tty->read_lock);
		old = gb_tty->oldcount;
		new = gb_tty->iocount;
		gb_tty->oldcount = new;
		spin_unlock_irq(&gb_tty->read_lock);

		if ((arg & TIOCM_DSR) && (old.dsr != new.dsr))
			break;
		if ((arg & TIOCM_CD) && (old.dcd != new.dcd))
			break;
		if ((arg & TIOCM_RI) && (old.rng != new.rng))
			break;

		add_wait_queue(&gb_tty->wioctl, &wait);
		set_current_state(TASK_INTERRUPTIBLE);
		schedule();
		remove_wait_queue(&gb_tty->wioctl, &wait);
		if (gb_tty->disconnected) {
			if (arg & TIOCM_CD)
				break;
			retval = -ENODEV;
		} else if (signal_pending(current)) {
			retval = -ERESTARTSYS;
		}
	} while (!retval);

	return retval;
}

static int get_serial_usage(struct gb_tty *gb_tty,
			    struct serial_icounter_struct __user *count)
{
	struct serial_icounter_struct icount;
	int retval = 0;

	memset(&icount, 0, sizeof(icount));
	icount.dsr = gb_tty->iocount.dsr;
	icount.rng = gb_tty->iocount.rng;
	icount.dcd = gb_tty->iocount.dcd;
	icount.frame = gb_tty->iocount.frame;
	icount.overrun = gb_tty->iocount.overrun;
	icount.parity = gb_tty->iocount.parity;
	icount.brk = gb_tty->iocount.brk;

	if (copy_to_user(count, &icount, sizeof(icount)) > 0)
		retval = -EFAULT;

	return retval;
}

static int gb_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
			unsigned long arg)
{
	struct gb_tty *gb_tty = tty->driver_data;

	switch (cmd) {
	case TIOCGSERIAL:
		return get_serial_info(gb_tty,
				       (struct serial_struct __user *)arg);
	case TIOCSSERIAL:
		return set_serial_info(gb_tty,
				       (struct serial_struct __user *)arg);
	case TIOCMIWAIT:
		return wait_serial_change(gb_tty, arg);
	case TIOCGICOUNT:
		return get_serial_usage(gb_tty,
					(struct serial_icounter_struct __user *)arg);
	}

	return -ENOIOCTLCMD;
}


static const struct tty_operations gb_ops = {
	.install =		gb_tty_install,
	.open =			gb_tty_open,
	.close =		gb_tty_close,
	.cleanup =		gb_tty_cleanup,
	.hangup =		gb_tty_hangup,
	.write =		gb_tty_write,
	.write_room =		gb_tty_write_room,
	.ioctl =		gb_tty_ioctl,
	.throttle =		gb_tty_throttle,
	.unthrottle =		gb_tty_unthrottle,
	.chars_in_buffer =	gb_tty_chars_in_buffer,
	.break_ctl =		gb_tty_break_ctl,
	.set_termios =		gb_tty_set_termios,
	.tiocmget =		gb_tty_tiocmget,
	.tiocmset =		gb_tty_tiocmset,
};

static struct tty_port_operations null_ops = { };

static int gb_tty_init(void);
static void gb_tty_exit(void);

static int gb_uart_connection_init(struct gb_connection *connection)
{
	struct gb_tty *gb_tty;
	struct device *tty_dev;
	int retval;
	int minor;

	/* First time here, initialize the tty structures */
	if (atomic_inc_return(&reference_count) == 1) {
		retval = gb_tty_init();
		if (retval) {
			atomic_dec(&reference_count);
			return retval;
		}
	}

	gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL);
	if (!gb_tty) {
		retval = -ENOMEM;
		goto error_alloc;
	}

	gb_tty->buffer_payload_max =
		gb_operation_get_payload_size_max(connection) -
			sizeof(struct gb_uart_send_data_request);

	gb_tty->buffer = kzalloc(gb_tty->buffer_payload_max, GFP_KERNEL);
	if (!gb_tty->buffer) {
		retval = -ENOMEM;
		goto error_payload;
	}

	gb_tty->connection = connection;
	connection->private = gb_tty;

	minor = alloc_minor(gb_tty);
	if (minor < 0) {
		if (minor == -ENOSPC) {
			dev_err(&connection->bundle->dev,
				"no more free minor numbers\n");
			retval = -ENODEV;
			goto error_minor;
		}
		retval = minor;
		goto error_minor;
	}

	gb_tty->minor = minor;
	spin_lock_init(&gb_tty->write_lock);
	spin_lock_init(&gb_tty->read_lock);
	init_waitqueue_head(&gb_tty->wioctl);
	mutex_init(&gb_tty->mutex);

	tty_port_init(&gb_tty->port);
	gb_tty->port.ops = &null_ops;

	send_control(gb_tty, gb_tty->ctrlout);

	/* initialize the uart to be 9600n81 */
	gb_tty->line_coding.rate = cpu_to_le32(9600);
	gb_tty->line_coding.format = GB_SERIAL_1_STOP_BITS;
	gb_tty->line_coding.parity = GB_SERIAL_NO_PARITY;
	gb_tty->line_coding.data_bits = 8;
	send_line_coding(gb_tty);

	tty_dev = tty_port_register_device(&gb_tty->port, gb_tty_driver, minor,
					   &connection->bundle->dev);
	if (IS_ERR(tty_dev)) {
		retval = PTR_ERR(tty_dev);
		goto error;
	}

	return 0;
error:
	tty_port_destroy(&gb_tty->port);
	release_minor(gb_tty);
error_minor:
	connection->private = NULL;
	kfree(gb_tty->buffer);
error_payload:
	kfree(gb_tty);
error_alloc:
	if (atomic_dec_return(&reference_count) == 0)
		gb_tty_exit();
	return retval;
}

static void gb_uart_connection_exit(struct gb_connection *connection)
{
	struct gb_tty *gb_tty = connection->private;
	struct tty_struct *tty;

	if (!gb_tty)
		return;

	mutex_lock(&gb_tty->mutex);
	gb_tty->disconnected = true;

	wake_up_all(&gb_tty->wioctl);
	connection->private = NULL;
	mutex_unlock(&gb_tty->mutex);

	tty = tty_port_tty_get(&gb_tty->port);
	if (tty) {
		tty_vhangup(tty);
		tty_kref_put(tty);
	}
	/* FIXME - stop all traffic */

	tty_unregister_device(gb_tty_driver, gb_tty->minor);

	/* FIXME - free transmit / receive buffers */

	tty_port_destroy(&gb_tty->port);
	kfree(gb_tty->buffer);
	kfree(gb_tty);

	/* If last device is gone, tear down the tty structures */
	if (atomic_dec_return(&reference_count) == 0)
		gb_tty_exit();
}

static int gb_tty_init(void)
{
	int retval = 0;

	gb_tty_driver = tty_alloc_driver(GB_NUM_MINORS, 0);
	if (IS_ERR(gb_tty_driver)) {
		pr_err("Can not allocate tty driver\n");
		retval = -ENOMEM;
		goto fail_unregister_dev;
	}

	gb_tty_driver->driver_name = "gb";
	gb_tty_driver->name = GB_NAME;
	gb_tty_driver->major = 0;
	gb_tty_driver->minor_start = 0;
	gb_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
	gb_tty_driver->subtype = SERIAL_TYPE_NORMAL;
	gb_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
	gb_tty_driver->init_termios = tty_std_termios;
	gb_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	tty_set_operations(gb_tty_driver, &gb_ops);

	retval = tty_register_driver(gb_tty_driver);
	if (retval) {
		pr_err("Can not register tty driver: %d\n", retval);
		goto fail_put_gb_tty;
	}

	return 0;

fail_put_gb_tty:
	put_tty_driver(gb_tty_driver);
fail_unregister_dev:
	return retval;
}

static void gb_tty_exit(void)
{
	tty_unregister_driver(gb_tty_driver);
	put_tty_driver(gb_tty_driver);
	idr_destroy(&tty_minors);
}

static struct gb_protocol uart_protocol = {
	.name			= "uart",
	.id			= GREYBUS_PROTOCOL_UART,
	.major			= GB_UART_VERSION_MAJOR,
	.minor			= GB_UART_VERSION_MINOR,
	.connection_init	= gb_uart_connection_init,
	.connection_exit	= gb_uart_connection_exit,
	.request_recv		= gb_uart_request_recv,
};

gb_builtin_protocol_driver(uart_protocol);
