// SPDX-License-Identifier: GPL-2.0
/*
 * Simulated Serial Driver (fake serial)
 *
 * This driver is mostly used for bringup purposes and will go away.
 * It has a strong dependency on the system console. All outputs
 * are rerouted to the same facility as the one used by printk which, in our
 * case means sys_sim.c console (goes via the simulator).
 *
 * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
 *	Stephane Eranian <eranian@hpl.hp.com>
 *	David Mosberger-Tang <davidm@hpl.hp.com>
 */

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/major.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/capability.h>
#include <linux/circ_buf.h>
#include <linux/console.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/serial.h>
#include <linux/sysrq.h>
#include <linux/uaccess.h>

#include <asm/hpsim.h>

#include "hpsim_ssc.h"

#undef SIMSERIAL_DEBUG	/* define this to get some debug information */

#define KEYBOARD_INTR	3	/* must match with simulator! */

#define NR_PORTS	1	/* only one port for now */

struct serial_state {
	struct tty_port port;
	struct circ_buf xmit;
	int irq;
	int x_char;
};

static struct serial_state rs_table[NR_PORTS];

struct tty_driver *hp_simserial_driver;

static struct console *console;

static void receive_chars(struct tty_port *port)
{
	unsigned char ch;
	static unsigned char seen_esc = 0;

	while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
		if (ch == 27 && seen_esc == 0) {
			seen_esc = 1;
			continue;
		} else if (seen_esc == 1 && ch == 'O') {
			seen_esc = 2;
			continue;
		} else if (seen_esc == 2) {
			if (ch == 'P') /* F1 */
				show_state();
#ifdef CONFIG_MAGIC_SYSRQ
			if (ch == 'S') { /* F4 */
				do {
					ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR);
				} while (!ch);
				handle_sysrq(ch);
			}
#endif
			seen_esc = 0;
			continue;
		}
		seen_esc = 0;

		if (tty_insert_flip_char(port, ch, TTY_NORMAL) == 0)
			break;
	}
	tty_flip_buffer_push(port);
}

/*
 * This is the serial driver's interrupt routine for a single port
 */
static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
{
	struct serial_state *info = dev_id;

	receive_chars(&info->port);

	return IRQ_HANDLED;
}

/*
 * -------------------------------------------------------------------
 * Here ends the serial interrupt routines.
 * -------------------------------------------------------------------
 */

static int rs_put_char(struct tty_struct *tty, unsigned char ch)
{
	struct serial_state *info = tty->driver_data;
	unsigned long flags;

	if (!info->xmit.buf)
		return 0;

	local_irq_save(flags);
	if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
		local_irq_restore(flags);
		return 0;
	}
	info->xmit.buf[info->xmit.head] = ch;
	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
	local_irq_restore(flags);
	return 1;
}

static void transmit_chars(struct tty_struct *tty, struct serial_state *info,
		int *intr_done)
{
	int count;
	unsigned long flags;

	local_irq_save(flags);

	if (info->x_char) {
		char c = info->x_char;

		console->write(console, &c, 1);

		info->x_char = 0;

		goto out;
	}

	if (info->xmit.head == info->xmit.tail || tty->stopped) {
#ifdef SIMSERIAL_DEBUG
		printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
		       info->xmit.head, info->xmit.tail, tty->stopped);
#endif
		goto out;
	}
	/*
	 * We removed the loop and try to do it in to chunks. We need
	 * 2 operations maximum because it's a ring buffer.
	 *
	 * First from current to tail if possible.
	 * Then from the beginning of the buffer until necessary
	 */

	count = min(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
		    SERIAL_XMIT_SIZE - info->xmit.tail);
	console->write(console, info->xmit.buf+info->xmit.tail, count);

	info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);

	/*
	 * We have more at the beginning of the buffer
	 */
	count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
	if (count) {
		console->write(console, info->xmit.buf, count);
		info->xmit.tail += count;
	}
out:
	local_irq_restore(flags);
}

static void rs_flush_chars(struct tty_struct *tty)
{
	struct serial_state *info = tty->driver_data;

	if (info->xmit.head == info->xmit.tail || tty->stopped ||
			!info->xmit.buf)
		return;

	transmit_chars(tty, info, NULL);
}

static int rs_write(struct tty_struct * tty,
		    const unsigned char *buf, int count)
{
	struct serial_state *info = tty->driver_data;
	int	c, ret = 0;
	unsigned long flags;

	if (!info->xmit.buf)
		return 0;

	local_irq_save(flags);
	while (1) {
		c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
		if (count < c)
			c = count;
		if (c <= 0) {
			break;
		}
		memcpy(info->xmit.buf + info->xmit.head, buf, c);
		info->xmit.head = ((info->xmit.head + c) &
				   (SERIAL_XMIT_SIZE-1));
		buf += c;
		count -= c;
		ret += c;
	}
	local_irq_restore(flags);
	/*
	 * Hey, we transmit directly from here in our case
	 */
	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) &&
			!tty->stopped)
		transmit_chars(tty, info, NULL);

	return ret;
}

static int rs_write_room(struct tty_struct *tty)
{
	struct serial_state *info = tty->driver_data;

	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
}

static int rs_chars_in_buffer(struct tty_struct *tty)
{
	struct serial_state *info = tty->driver_data;

	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
}

static void rs_flush_buffer(struct tty_struct *tty)
{
	struct serial_state *info = tty->driver_data;
	unsigned long flags;

	local_irq_save(flags);
	info->xmit.head = info->xmit.tail = 0;
	local_irq_restore(flags);

	tty_wakeup(tty);
}

/*
 * This function is used to send a high-priority XON/XOFF character to
 * the device
 */
static void rs_send_xchar(struct tty_struct *tty, char ch)
{
	struct serial_state *info = tty->driver_data;

	info->x_char = ch;
	if (ch) {
		/*
		 * I guess we could call console->write() directly but
		 * let's do that for now.
		 */
		transmit_chars(tty, info, NULL);
	}
}

/*
 * ------------------------------------------------------------
 * rs_throttle()
 *
 * This routine is called by the upper-layer tty layer to signal that
 * incoming characters should be throttled.
 * ------------------------------------------------------------
 */
static void rs_throttle(struct tty_struct * tty)
{
	if (I_IXOFF(tty))
		rs_send_xchar(tty, STOP_CHAR(tty));

	printk(KERN_INFO "simrs_throttle called\n");
}

static void rs_unthrottle(struct tty_struct * tty)
{
	struct serial_state *info = tty->driver_data;

	if (I_IXOFF(tty)) {
		if (info->x_char)
			info->x_char = 0;
		else
			rs_send_xchar(tty, START_CHAR(tty));
	}
	printk(KERN_INFO "simrs_unthrottle called\n");
}

static int rs_setserial(struct tty_struct *tty, struct serial_struct *ss)
{
	return 0;
}

static int rs_getserial(struct tty_struct *tty, struct serial_struct *ss)
{
	return 0;
}

static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
{
	if ((cmd != TIOCSERCONFIG) && (cmd != TIOCMIWAIT)) {
		if (tty_io_error(tty))
		    return -EIO;
	}

	switch (cmd) {
	case TIOCMIWAIT:
		return 0;
	case TIOCSERCONFIG:
	case TIOCSERGETLSR: /* Get line status register */
		return -EINVAL;
	}
	return -ENOIOCTLCMD;
}

#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))

/*
 * This routine will shutdown a serial port; interrupts are disabled, and
 * DTR is dropped if the hangup on close termio flag is on.
 */
static void shutdown(struct tty_port *port)
{
	struct serial_state *info = container_of(port, struct serial_state,
			port);
	unsigned long flags;

	local_irq_save(flags);
	if (info->irq)
		free_irq(info->irq, info);

	if (info->xmit.buf) {
		free_page((unsigned long) info->xmit.buf);
		info->xmit.buf = NULL;
	}
	local_irq_restore(flags);
}

static void rs_close(struct tty_struct *tty, struct file * filp)
{
	struct serial_state *info = tty->driver_data;

	tty_port_close(&info->port, tty, filp);
}

static void rs_hangup(struct tty_struct *tty)
{
	struct serial_state *info = tty->driver_data;

	rs_flush_buffer(tty);
	tty_port_hangup(&info->port);
}

static int activate(struct tty_port *port, struct tty_struct *tty)
{
	struct serial_state *state = container_of(port, struct serial_state,
			port);
	unsigned long flags, page;
	int retval = 0;

	page = get_zeroed_page(GFP_KERNEL);
	if (!page)
		return -ENOMEM;

	local_irq_save(flags);

	if (state->xmit.buf)
		free_page(page);
	else
		state->xmit.buf = (unsigned char *) page;

	if (state->irq) {
		retval = request_irq(state->irq, rs_interrupt_single, 0,
				"simserial", state);
		if (retval)
			goto errout;
	}

	state->xmit.head = state->xmit.tail = 0;
errout:
	local_irq_restore(flags);
	return retval;
}


/*
 * This routine is called whenever a serial port is opened.  It
 * enables interrupts for a serial port, linking in its async structure into
 * the IRQ chain.   It also performs the serial-specific
 * initialization for the tty structure.
 */
static int rs_open(struct tty_struct *tty, struct file * filp)
{
	struct serial_state *info = rs_table + tty->index;
	struct tty_port *port = &info->port;

	tty->driver_data = info;
	port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;

	/*
	 * figure out which console to use (should be one already)
	 */
	console = console_drivers;
	while (console) {
		if ((console->flags & CON_ENABLED) && console->write) break;
		console = console->next;
	}

	return tty_port_open(port, tty, filp);
}

/*
 * /proc fs routines....
 */

static int rs_proc_show(struct seq_file *m, void *v)
{
	int i;

	seq_printf(m, "simserinfo:1.0\n");
	for (i = 0; i < NR_PORTS; i++)
		seq_printf(m, "%d: uart:16550 port:3F8 irq:%d\n",
		       i, rs_table[i].irq);
	return 0;
}

static const struct tty_operations hp_ops = {
	.open = rs_open,
	.close = rs_close,
	.write = rs_write,
	.put_char = rs_put_char,
	.flush_chars = rs_flush_chars,
	.write_room = rs_write_room,
	.chars_in_buffer = rs_chars_in_buffer,
	.flush_buffer = rs_flush_buffer,
	.ioctl = rs_ioctl,
	.throttle = rs_throttle,
	.unthrottle = rs_unthrottle,
	.send_xchar = rs_send_xchar,
	.set_serial = rs_setserial,
	.get_serial = rs_getserial,
	.hangup = rs_hangup,
	.proc_show = rs_proc_show,
};

static const struct tty_port_operations hp_port_ops = {
	.activate = activate,
	.shutdown = shutdown,
};

static int __init simrs_init(void)
{
	struct serial_state *state;
	int retval;

	if (!ia64_platform_is("hpsim"))
		return -ENODEV;

	hp_simserial_driver = alloc_tty_driver(NR_PORTS);
	if (!hp_simserial_driver)
		return -ENOMEM;

	printk(KERN_INFO "SimSerial driver with no serial options enabled\n");

	/* Initialize the tty_driver structure */

	hp_simserial_driver->driver_name = "simserial";
	hp_simserial_driver->name = "ttyS";
	hp_simserial_driver->major = TTY_MAJOR;
	hp_simserial_driver->minor_start = 64;
	hp_simserial_driver->type = TTY_DRIVER_TYPE_SERIAL;
	hp_simserial_driver->subtype = SERIAL_TYPE_NORMAL;
	hp_simserial_driver->init_termios = tty_std_termios;
	hp_simserial_driver->init_termios.c_cflag =
		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW;
	tty_set_operations(hp_simserial_driver, &hp_ops);

	state = rs_table;
	tty_port_init(&state->port);
	state->port.ops = &hp_port_ops;
	state->port.close_delay = 0; /* XXX really 0? */

	retval = hpsim_get_irq(KEYBOARD_INTR);
	if (retval < 0) {
		printk(KERN_ERR "%s: out of interrupt vectors!\n",
				__func__);
		goto err_free_tty;
	}

	state->irq = retval;

	/* the port is imaginary */
	printk(KERN_INFO "ttyS0 at 0x03f8 (irq = %d) is a 16550\n", state->irq);

	tty_port_link_device(&state->port, hp_simserial_driver, 0);
	retval = tty_register_driver(hp_simserial_driver);
	if (retval) {
		printk(KERN_ERR "Couldn't register simserial driver\n");
		goto err_free_tty;
	}

	return 0;
err_free_tty:
	put_tty_driver(hp_simserial_driver);
	tty_port_destroy(&state->port);
	return retval;
}

#ifndef MODULE
__initcall(simrs_init);
#endif
