/*
 * dz.c: Serial port driver for DECStations equiped
 *       with the DZ chipset.
 *
 * Copyright (C) 1998 Olivier A. D. Lebaillif
 *
 * Email: olivier.lebaillif@ifrsys.com
 *
 * [31-AUG-98] triemer
 * Changed IRQ to use Harald's dec internals interrupts.h
 * removed base_addr code - moving address assignment to setup.c
 * Changed name of dz_init to rs_init to be consistent with tc code
 * [13-NOV-98] triemer fixed code to receive characters
 *    after patches by harald to irq code.
 * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
 *            field from "current" - somewhere between 2.1.121 and 2.1.131
 Qua Jun 27 15:02:26 BRT 2001
 * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
 *
 * Parts (C) 1999 David Airlie, airlied@linux.ie
 * [07-SEP-99] Bugfixes
 *
 * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
 * Converted to new serial core
 */

#undef DEBUG_DZ

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>

#include <asm/bootinfo.h>
#include <asm/dec/interrupts.h>
#include <asm/dec/kn01.h>
#include <asm/dec/kn02.h>
#include <asm/dec/machtype.h>
#include <asm/dec/prom.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/uaccess.h>

#define CONSOLE_LINE (3)	/* for definition of struct console */

#include "dz.h"

#define DZ_INTR_DEBUG 1

static char *dz_name = "DECstation DZ serial driver version ";
static char *dz_version = "1.02";

struct dz_port {
	struct uart_port	port;
	unsigned int		cflag;
};

static struct dz_port dz_ports[DZ_NB_PORT];

#ifdef DEBUG_DZ
/*
 * debugging code to send out chars via prom
 */
static void debug_console(const char *s, int count)
{
	unsigned i;

	for (i = 0; i < count; i++) {
		if (*s == 10)
			prom_printf("%c", 13);
		prom_printf("%c", *s++);
	}
}
#endif

/*
 * ------------------------------------------------------------
 * dz_in () and dz_out ()
 *
 * These routines are used to access the registers of the DZ
 * chip, hiding relocation differences between implementation.
 * ------------------------------------------------------------
 */

static inline unsigned short dz_in(struct dz_port *dport, unsigned offset)
{
	volatile unsigned short *addr =
		(volatile unsigned short *) (dport->port.membase + offset);
	return *addr;
}

static inline void dz_out(struct dz_port *dport, unsigned offset,
                          unsigned short value)
{
	volatile unsigned short *addr =
		(volatile unsigned short *) (dport->port.membase + offset);
	*addr = value;
}

/*
 * ------------------------------------------------------------
 * rs_stop () and rs_start ()
 *
 * These routines are called before setting or resetting
 * tty->stopped. They enable or disable transmitter interrupts,
 * as necessary.
 * ------------------------------------------------------------
 */

static void dz_stop_tx(struct uart_port *uport)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned short tmp, mask = 1 << dport->port.line;
	unsigned long flags;

	spin_lock_irqsave(&dport->port.lock, flags);
	tmp = dz_in(dport, DZ_TCR);	/* read the TX flag */
	tmp &= ~mask;			/* clear the TX flag */
	dz_out(dport, DZ_TCR, tmp);
	spin_unlock_irqrestore(&dport->port.lock, flags);
}

static void dz_start_tx(struct uart_port *uport)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned short tmp, mask = 1 << dport->port.line;
	unsigned long flags;

	spin_lock_irqsave(&dport->port.lock, flags);
	tmp = dz_in(dport, DZ_TCR);	/* read the TX flag */
	tmp |= mask;			/* set the TX flag */
	dz_out(dport, DZ_TCR, tmp);
	spin_unlock_irqrestore(&dport->port.lock, flags);
}

static void dz_stop_rx(struct uart_port *uport)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned long flags;

	spin_lock_irqsave(&dport->port.lock, flags);
	dport->cflag &= ~DZ_CREAD;
	dz_out(dport, DZ_LPR, dport->cflag);
	spin_unlock_irqrestore(&dport->port.lock, flags);
}

static void dz_enable_ms(struct uart_port *port)
{
	/* nothing to do */
}

/*
 * ------------------------------------------------------------
 * Here starts the interrupt handling routines.  All of the
 * following subroutines are declared as inline and are folded
 * into dz_interrupt.  They were separated out for readability's
 * sake.
 *
 * Note: rs_interrupt() is a "fast" interrupt, which means that it
 * runs with interrupts turned off.  People who may want to modify
 * rs_interrupt() should try to keep the interrupt handler as fast as
 * possible.  After you are done making modifications, it is not a bad
 * idea to do:
 *
 *	make drivers/serial/dz.s
 *
 * and look at the resulting assemble code in dz.s.
 *
 * ------------------------------------------------------------
 */

/*
 * ------------------------------------------------------------
 * receive_char ()
 *
 * This routine deals with inputs from any lines.
 * ------------------------------------------------------------
 */
static inline void dz_receive_chars(struct dz_port *dport)
{
	struct tty_struct *tty = NULL;
	struct uart_icount *icount;
	int ignore = 0;
	unsigned short status, tmp;
	unsigned char ch, flag;

	/* this code is going to be a problem...
	   the call to tty_flip_buffer is going to need
	   to be rethought...
	 */
	do {
		status = dz_in(dport, DZ_RBUF);

		/* punt so we don't get duplicate characters */
		if (!(status & DZ_DVAL))
			goto ignore_char;


		ch = UCHAR(status);	/* grab the char */
		flag = TTY_NORMAL;

#if 0
		if (info->is_console) {
			if (ch == 0)
				return;		/* it's a break ... */
		}
#endif

		tty = dport->port.info->tty;/* now tty points to the proper dev */
		icount = &dport->port.icount;

		if (!tty)
			break;

		icount->rx++;

		/* keep track of the statistics */
		if (status & (DZ_OERR | DZ_FERR | DZ_PERR)) {
			if (status & DZ_PERR)	/* parity error */
				icount->parity++;
			else if (status & DZ_FERR)	/* frame error */
				icount->frame++;
			if (status & DZ_OERR)	/* overrun error */
				icount->overrun++;

			/*  check to see if we should ignore the character
			   and mask off conditions that should be ignored
			 */

			if (status & dport->port.ignore_status_mask) {
				if (++ignore > 100)
					break;
				goto ignore_char;
			}
			/* mask off the error conditions we want to ignore */
			tmp = status & dport->port.read_status_mask;

			if (tmp & DZ_PERR) {
				flag = TTY_PARITY;
#ifdef DEBUG_DZ
				debug_console("PERR\n", 5);
#endif
			} else if (tmp & DZ_FERR) {
				flag = TTY_FRAME;
#ifdef DEBUG_DZ
				debug_console("FERR\n", 5);
#endif
			}
			if (tmp & DZ_OERR) {
#ifdef DEBUG_DZ
				debug_console("OERR\n", 5);
#endif
				tty_insert_flip_char(tty, ch, flag);
				ch = 0;
				flag = TTY_OVERRUN;
			}
		}
		tty_insert_flip_char(tty, ch, flag);
	      ignore_char:
			;
	} while (status & DZ_DVAL);

	if (tty)
		tty_flip_buffer_push(tty);
}

/*
 * ------------------------------------------------------------
 * transmit_char ()
 *
 * This routine deals with outputs to any lines.
 * ------------------------------------------------------------
 */
static inline void dz_transmit_chars(struct dz_port *dport)
{
	struct circ_buf *xmit = &dport->port.info->xmit;
	unsigned char tmp;

	if (dport->port.x_char) {	/* XON/XOFF chars */
		dz_out(dport, DZ_TDR, dport->port.x_char);
		dport->port.icount.tx++;
		dport->port.x_char = 0;
		return;
	}
	/* if nothing to do or stopped or hardware stopped */
	if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
		dz_stop_tx(&dport->port);
		return;
	}

	/*
	 * if something to do ... (rember the dz has no output fifo so we go
	 * one char at a time :-<
	 */
	tmp = xmit->buf[xmit->tail];
	xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
	dz_out(dport, DZ_TDR, tmp);
	dport->port.icount.tx++;

	if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
		uart_write_wakeup(&dport->port);

	/* Are we done */
	if (uart_circ_empty(xmit))
		dz_stop_tx(&dport->port);
}

/*
 * ------------------------------------------------------------
 * check_modem_status ()
 *
 * Only valid for the MODEM line duh !
 * ------------------------------------------------------------
 */
static inline void check_modem_status(struct dz_port *dport)
{
	unsigned short status;

	/* if not ne modem line just return */
	if (dport->port.line != DZ_MODEM)
		return;

	status = dz_in(dport, DZ_MSR);

	/* it's easy, since DSR2 is the only bit in the register */
	if (status)
		dport->port.icount.dsr++;
}

/*
 * ------------------------------------------------------------
 * dz_interrupt ()
 *
 * this is the main interrupt routine for the DZ chip.
 * It deals with the multiple ports.
 * ------------------------------------------------------------
 */
static irqreturn_t dz_interrupt(int irq, void *dev)
{
	struct dz_port *dport;
	unsigned short status;

	/* get the reason why we just got an irq */
	status = dz_in((struct dz_port *)dev, DZ_CSR);
	dport = &dz_ports[LINE(status)];

	if (status & DZ_RDONE)
		dz_receive_chars(dport);

	if (status & DZ_TRDY)
		dz_transmit_chars(dport);

	/* FIXME: what about check modem status??? --rmk */

	return IRQ_HANDLED;
}

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

static unsigned int dz_get_mctrl(struct uart_port *uport)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;

	if (dport->port.line == DZ_MODEM) {
		/*
		 * CHECKME: This is a guess from the other code... --rmk
		 */
		if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
			mctrl &= ~TIOCM_DSR;
	}

	return mctrl;
}

static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned short tmp;

	if (dport->port.line == DZ_MODEM) {
		tmp = dz_in(dport, DZ_TCR);
		if (mctrl & TIOCM_DTR)
			tmp &= ~DZ_MODEM_DTR;
		else
			tmp |= DZ_MODEM_DTR;
		dz_out(dport, DZ_TCR, tmp);
	}
}

/*
 * -------------------------------------------------------------------
 * startup ()
 *
 * various initialization tasks
 * -------------------------------------------------------------------
 */
static int dz_startup(struct uart_port *uport)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned long flags;
	unsigned short tmp;

	/* The dz lines for the mouse/keyboard must be
	 * opened using their respective drivers.
	 */
	if ((dport->port.line == DZ_KEYBOARD) ||
	    (dport->port.line == DZ_MOUSE))
		return -ENODEV;

	spin_lock_irqsave(&dport->port.lock, flags);

	/* enable the interrupt and the scanning */
	tmp = dz_in(dport, DZ_CSR);
	tmp |= DZ_RIE | DZ_TIE | DZ_MSE;
	dz_out(dport, DZ_CSR, tmp);

	spin_unlock_irqrestore(&dport->port.lock, flags);

	return 0;
}

/*
 * -------------------------------------------------------------------
 * shutdown ()
 *
 * 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 dz_shutdown(struct uart_port *uport)
{
	dz_stop_tx(uport);
}

/*
 * get_lsr_info - get line status register info
 *
 * Purpose: Let user call ioctl() to get info when the UART physically
 *          is emptied.  On bus types like RS485, the transmitter must
 *          release the bus after transmitting. This must be done when
 *          the transmit shift register is empty, not be done when the
 *          transmit holding register is empty.  This functionality
 *          allows an RS485 driver to be written in user space.
 */
static unsigned int dz_tx_empty(struct uart_port *uport)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned short status = dz_in(dport, DZ_LPR);

	/* FIXME: this appears to be obviously broken --rmk. */
	return status ? TIOCSER_TEMT : 0;
}

static void dz_break_ctl(struct uart_port *uport, int break_state)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned long flags;
	unsigned short tmp, mask = 1 << uport->line;

	spin_lock_irqsave(&uport->lock, flags);
	tmp = dz_in(dport, DZ_TCR);
	if (break_state)
		tmp |= mask;
	else
		tmp &= ~mask;
	dz_out(dport, DZ_TCR, tmp);
	spin_unlock_irqrestore(&uport->lock, flags);
}

static void dz_set_termios(struct uart_port *uport, struct termios *termios,
			   struct termios *old_termios)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned long flags;
	unsigned int cflag, baud;

	cflag = dport->port.line;

	switch (termios->c_cflag & CSIZE) {
	case CS5:
		cflag |= DZ_CS5;
		break;
	case CS6:
		cflag |= DZ_CS6;
		break;
	case CS7:
		cflag |= DZ_CS7;
		break;
	case CS8:
	default:
		cflag |= DZ_CS8;
	}

	if (termios->c_cflag & CSTOPB)
		cflag |= DZ_CSTOPB;
	if (termios->c_cflag & PARENB)
		cflag |= DZ_PARENB;
	if (termios->c_cflag & PARODD)
		cflag |= DZ_PARODD;

	baud = uart_get_baud_rate(uport, termios, old_termios, 50, 9600);
	switch (baud) {
	case 50:
		cflag |= DZ_B50;
		break;
	case 75:
		cflag |= DZ_B75;
		break;
	case 110:
		cflag |= DZ_B110;
		break;
	case 134:
		cflag |= DZ_B134;
		break;
	case 150:
		cflag |= DZ_B150;
		break;
	case 300:
		cflag |= DZ_B300;
		break;
	case 600:
		cflag |= DZ_B600;
		break;
	case 1200:
		cflag |= DZ_B1200;
		break;
	case 1800:
		cflag |= DZ_B1800;
		break;
	case 2000:
		cflag |= DZ_B2000;
		break;
	case 2400:
		cflag |= DZ_B2400;
		break;
	case 3600:
		cflag |= DZ_B3600;
		break;
	case 4800:
		cflag |= DZ_B4800;
		break;
	case 7200:
		cflag |= DZ_B7200;
		break;
	case 9600:
	default:
		cflag |= DZ_B9600;
	}

	if (termios->c_cflag & CREAD)
		cflag |= DZ_RXENAB;

	spin_lock_irqsave(&dport->port.lock, flags);

	dz_out(dport, DZ_LPR, cflag);
	dport->cflag = cflag;

	/* setup accept flag */
	dport->port.read_status_mask = DZ_OERR;
	if (termios->c_iflag & INPCK)
		dport->port.read_status_mask |= DZ_FERR | DZ_PERR;

	/* characters to ignore */
	uport->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		dport->port.ignore_status_mask |= DZ_FERR | DZ_PERR;

	spin_unlock_irqrestore(&dport->port.lock, flags);
}

static const char *dz_type(struct uart_port *port)
{
	return "DZ";
}

static void dz_release_port(struct uart_port *port)
{
	/* nothing to do */
}

static int dz_request_port(struct uart_port *port)
{
	return 0;
}

static void dz_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE)
		port->type = PORT_DZ;
}

/*
 * verify the new serial_struct (for TIOCSSERIAL).
 */
static int dz_verify_port(struct uart_port *port, struct serial_struct *ser)
{
	int ret = 0;
	if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ)
		ret = -EINVAL;
	if (ser->irq != port->irq)
		ret = -EINVAL;
	return ret;
}

static struct uart_ops dz_ops = {
	.tx_empty	= dz_tx_empty,
	.get_mctrl	= dz_get_mctrl,
	.set_mctrl	= dz_set_mctrl,
	.stop_tx	= dz_stop_tx,
	.start_tx	= dz_start_tx,
	.stop_rx	= dz_stop_rx,
	.enable_ms	= dz_enable_ms,
	.break_ctl	= dz_break_ctl,
	.startup	= dz_startup,
	.shutdown	= dz_shutdown,
	.set_termios	= dz_set_termios,
	.type		= dz_type,
	.release_port	= dz_release_port,
	.request_port	= dz_request_port,
	.config_port	= dz_config_port,
	.verify_port	= dz_verify_port,
};

static void __init dz_init_ports(void)
{
	static int first = 1;
	struct dz_port *dport;
	unsigned long base;
	int i;

	if (!first)
		return;
	first = 0;

	if (mips_machtype == MACH_DS23100 ||
	    mips_machtype == MACH_DS5100)
		base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11);
	else
		base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11);

	for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
		spin_lock_init(&dport->port.lock);
		dport->port.membase	= (char *) base;
		dport->port.iotype	= UPIO_PORT;
		dport->port.irq		= dec_interrupt[DEC_IRQ_DZ11];
		dport->port.line	= i;
		dport->port.fifosize	= 1;
		dport->port.ops		= &dz_ops;
		dport->port.flags	= UPF_BOOT_AUTOCONF;
	}
}

static void dz_reset(struct dz_port *dport)
{
	dz_out(dport, DZ_CSR, DZ_CLR);

	while (dz_in(dport, DZ_CSR) & DZ_CLR);
		/* FIXME: cpu_relax? */

	iob();

	/* enable scanning */
	dz_out(dport, DZ_CSR, DZ_MSE);
}

#ifdef CONFIG_SERIAL_DZ_CONSOLE
static void dz_console_putchar(struct uart_port *uport, int ch)
{
	struct dz_port *dport = (struct dz_port *)uport;
	unsigned long flags;
	int loops = 2500;
	unsigned short tmp = (unsigned char)ch;
	/* this code sends stuff out to serial device - spinning its
	   wheels and waiting. */

	spin_lock_irqsave(&dport->port.lock, flags);

	/* spin our wheels */
	while (((dz_in(dport, DZ_CSR) & DZ_TRDY) != DZ_TRDY) && loops--)
		/* FIXME: cpu_relax, udelay? --rmk */
		;

	/* Actually transmit the character. */
	dz_out(dport, DZ_TDR, tmp);

	spin_unlock_irqrestore(&dport->port.lock, flags);
}

/*
 * -------------------------------------------------------------------
 * dz_console_print ()
 *
 * dz_console_print is registered for printk.
 * The console must be locked when we get here.
 * -------------------------------------------------------------------
 */
static void dz_console_print(struct console *cons,
			     const char *str,
			     unsigned int count)
{
	struct dz_port *dport = &dz_ports[CONSOLE_LINE];
#ifdef DEBUG_DZ
	prom_printf((char *) str);
#endif
	uart_console_write(&dport->port, str, count, dz_console_putchar);
}

static int __init dz_console_setup(struct console *co, char *options)
{
	struct dz_port *dport = &dz_ports[CONSOLE_LINE];
	int baud = 9600;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;
	unsigned short mask, tmp;

	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);

	dz_reset(dport);

	ret = uart_set_options(&dport->port, co, baud, parity, bits, flow);
	if (ret == 0) {
		mask = 1 << dport->port.line;
		tmp = dz_in(dport, DZ_TCR);	/* read the TX flag */
		if (!(tmp & mask)) {
			tmp |= mask;		/* set the TX flag */
			dz_out(dport, DZ_TCR, tmp);
		}
	}

	return ret;
}

static struct console dz_sercons =
{
	.name	= "ttyS",
	.write	= dz_console_print,
	.device	= uart_console_device,
	.setup	= dz_console_setup,
	.flags	= CON_CONSDEV | CON_PRINTBUFFER,
	.index	= CONSOLE_LINE,
};

void __init dz_serial_console_init(void)
{
	dz_init_ports();

	register_console(&dz_sercons);
}

#define SERIAL_DZ_CONSOLE	&dz_sercons
#else
#define SERIAL_DZ_CONSOLE	NULL
#endif /* CONFIG_SERIAL_DZ_CONSOLE */

static struct uart_driver dz_reg = {
	.owner			= THIS_MODULE,
	.driver_name		= "serial",
	.dev_name		= "ttyS%d",
	.major			= TTY_MAJOR,
	.minor			= 64,
	.nr			= DZ_NB_PORT,
	.cons			= SERIAL_DZ_CONSOLE,
};

int __init dz_init(void)
{
	unsigned long flags;
	int ret, i;

	printk("%s%s\n", dz_name, dz_version);

	dz_init_ports();

	save_flags(flags);
	cli();

#ifndef CONFIG_SERIAL_DZ_CONSOLE
	/* reset the chip */
	dz_reset(&dz_ports[0]);
#endif

	/* order matters here... the trick is that flags
	   is updated... in request_irq - to immediatedly obliterate
	   it is unwise. */
	restore_flags(flags);

	if (request_irq(dz_ports[0].port.irq, dz_interrupt,
			IRQF_DISABLED, "DZ", &dz_ports[0]))
		panic("Unable to register DZ interrupt");

	ret = uart_register_driver(&dz_reg);
	if (ret != 0)
		return ret;

	for (i = 0; i < DZ_NB_PORT; i++)
		uart_add_one_port(&dz_reg, &dz_ports[i].port);

	return ret;
}

MODULE_DESCRIPTION("DECstation DZ serial driver");
MODULE_LICENSE("GPL");
