/*
 * drivers/serial/v850e_uart.c -- Serial I/O using V850E on-chip UART or UARTB
 *
 *  Copyright (C) 2001,02,03  NEC Electronics Corporation
 *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License.  See the file COPYING in the main directory of this
 * archive for more details.
 *
 * Written by Miles Bader <miles@gnu.org>
 */

/* This driver supports both the original V850E UART interface (called
   merely `UART' in the docs) and the newer `UARTB' interface, which is
   roughly a superset of the first one.  The selection is made at
   configure time -- if CONFIG_V850E_UARTB is defined, then UARTB is
   presumed, otherwise the old UART -- as these are on-CPU UARTS, a system
   can never have both.

   The UARTB interface also has a 16-entry FIFO mode, which is not
   yet supported by this driver.  */

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

#include <asm/v850e_uart.h>

/* Initial UART state.  This may be overridden by machine-dependent headers. */
#ifndef V850E_UART_INIT_BAUD
#define V850E_UART_INIT_BAUD	115200
#endif
#ifndef V850E_UART_INIT_CFLAGS
#define V850E_UART_INIT_CFLAGS	(B115200 | CS8 | CREAD)
#endif

/* A string used for prefixing printed descriptions; since the same UART
   macro is actually used on other chips than the V850E.  This must be a
   constant string.  */
#ifndef V850E_UART_CHIP_NAME
#define V850E_UART_CHIP_NAME	"V850E"
#endif

#define V850E_UART_MINOR_BASE	64	   /* First tty minor number */


/* Low-level UART functions.  */

/* Configure and turn on uart channel CHAN, using the termios `control
   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
{
	int flags;
	v850e_uart_speed_t old_speed;
	v850e_uart_config_t old_config;
	v850e_uart_speed_t new_speed = v850e_uart_calc_speed (baud);
	v850e_uart_config_t new_config = v850e_uart_calc_config (cflags);

	/* Disable interrupts while we're twiddling the hardware.  */
	local_irq_save (flags);

#ifdef V850E_UART_PRE_CONFIGURE
	V850E_UART_PRE_CONFIGURE (chan, cflags, baud);
#endif

	old_config = V850E_UART_CONFIG (chan);
	old_speed = v850e_uart_speed (chan);

	if (! v850e_uart_speed_eq (old_speed, new_speed)) {
		/* The baud rate has changed.  First, disable the UART.  */
		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_FINI;
		old_config = 0;	/* Force the uart to be re-initialized. */

		/* Reprogram the baud-rate generator.  */
		v850e_uart_set_speed (chan, new_speed);
	}

	if (! (old_config & V850E_UART_CONFIG_ENABLED)) {
		/* If we are using the uart for the first time, start by
		   enabling it, which must be done before turning on any
		   other bits.  */
		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_INIT;
		/* See the initial state.  */
		old_config = V850E_UART_CONFIG (chan);
	}

	if (new_config != old_config) {
		/* Which of the TXE/RXE bits we'll temporarily turn off
		   before changing other control bits.  */
		unsigned temp_disable = 0;
		/* Which of the TXE/RXE bits will be enabled.  */
		unsigned enable = 0;
		unsigned changed_bits = new_config ^ old_config;

		/* Which of RX/TX will be enabled in the new configuration.  */
		if (new_config & V850E_UART_CONFIG_RX_BITS)
			enable |= (new_config & V850E_UART_CONFIG_RX_ENABLE);
		if (new_config & V850E_UART_CONFIG_TX_BITS)
			enable |= (new_config & V850E_UART_CONFIG_TX_ENABLE);

		/* Figure out which of RX/TX needs to be disabled; note
		   that this will only happen if they're not already
		   disabled.  */
		if (changed_bits & V850E_UART_CONFIG_RX_BITS)
			temp_disable
				|= (old_config & V850E_UART_CONFIG_RX_ENABLE);
		if (changed_bits & V850E_UART_CONFIG_TX_BITS)
			temp_disable
				|= (old_config & V850E_UART_CONFIG_TX_ENABLE);

		/* We have to turn off RX and/or TX mode before changing
		   any associated control bits.  */
		if (temp_disable)
			V850E_UART_CONFIG (chan) = old_config & ~temp_disable;

		/* Write the new control bits, while RX/TX are disabled. */ 
		if (changed_bits & ~enable)
			V850E_UART_CONFIG (chan) = new_config & ~enable;

		v850e_uart_config_delay (new_config, new_speed);

		/* Write the final version, with enable bits turned on.  */
		V850E_UART_CONFIG (chan) = new_config;
	}

	local_irq_restore (flags);
}


/*  Low-level console. */

#ifdef CONFIG_V850E_UART_CONSOLE

static void v850e_uart_cons_write (struct console *co,
				   const char *s, unsigned count)
{
	if (count > 0) {
		unsigned chan = co->index;
		unsigned irq = V850E_UART_TX_IRQ (chan);
		int irq_was_enabled, irq_was_pending, flags;

		/* We don't want to get `transmission completed'
		   interrupts, since we're busy-waiting, so we disable them
		   while sending (we don't disable interrupts entirely
		   because sending over a serial line is really slow).  We
		   save the status of the tx interrupt and restore it when
		   we're done so that using printk doesn't interfere with
		   normal serial transmission (other than interleaving the
		   output, of course!).  This should work correctly even if
		   this function is interrupted and the interrupt printks
		   something.  */

		/* Disable interrupts while fiddling with tx interrupt.  */
		local_irq_save (flags);
		/* Get current tx interrupt status.  */
		irq_was_enabled = v850e_intc_irq_enabled (irq);
		irq_was_pending = v850e_intc_irq_pending (irq);
		/* Disable tx interrupt if necessary.  */
		if (irq_was_enabled)
			v850e_intc_disable_irq (irq);
		/* Turn interrupts back on.  */
		local_irq_restore (flags);

		/* Send characters.  */
		while (count > 0) {
			int ch = *s++;

			if (ch == '\n') {
				/* We don't have the benefit of a tty
				   driver, so translate NL into CR LF.  */
				v850e_uart_wait_for_xmit_ok (chan);
				v850e_uart_putc (chan, '\r');
			}

			v850e_uart_wait_for_xmit_ok (chan);
			v850e_uart_putc (chan, ch);

			count--;
		}

		/* Restore saved tx interrupt status.  */
		if (irq_was_enabled) {
			/* Wait for the last character we sent to be
			   completely transmitted (as we'll get an
			   interrupt interrupt at that point).  */
			v850e_uart_wait_for_xmit_done (chan);
			/* Clear pending interrupts received due
			   to our transmission, unless there was already
			   one pending, in which case we want the
			   handler to be called.  */
			if (! irq_was_pending)
				v850e_intc_clear_pending_irq (irq);
			/* ... and then turn back on handling.  */
			v850e_intc_enable_irq (irq);
		}
	}
}

extern struct uart_driver v850e_uart_driver;
static struct console v850e_uart_cons =
{
    .name	= "ttyS",
    .write	= v850e_uart_cons_write,
    .device	= uart_console_device,
    .flags	= CON_PRINTBUFFER,
    .cflag	= V850E_UART_INIT_CFLAGS,
    .index	= -1,
    .data	= &v850e_uart_driver,
};

void v850e_uart_cons_init (unsigned chan)
{
	v850e_uart_configure (chan, V850E_UART_INIT_CFLAGS,
			      V850E_UART_INIT_BAUD);
	v850e_uart_cons.index = chan;
	register_console (&v850e_uart_cons);
	printk ("Console: %s on-chip UART channel %d\n",
		V850E_UART_CHIP_NAME, chan);
}

/* This is what the init code actually calls.  */
static int v850e_uart_console_init (void)
{
	v850e_uart_cons_init (V850E_UART_CONSOLE_CHANNEL);
	return 0;
}
console_initcall(v850e_uart_console_init);

#define V850E_UART_CONSOLE &v850e_uart_cons

#else /* !CONFIG_V850E_UART_CONSOLE */
#define V850E_UART_CONSOLE 0
#endif /* CONFIG_V850E_UART_CONSOLE */

/* TX/RX interrupt handlers.  */

static void v850e_uart_stop_tx (struct uart_port *port);

void v850e_uart_tx (struct uart_port *port)
{
	struct circ_buf *xmit = &port->info->xmit;
	int stopped = uart_tx_stopped (port);

	if (v850e_uart_xmit_ok (port->line)) {
		int tx_ch;

		if (port->x_char) {
			tx_ch = port->x_char;
			port->x_char = 0;
		} else if (!uart_circ_empty (xmit) && !stopped) {
			tx_ch = xmit->buf[xmit->tail];
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		} else
			goto no_xmit;

		v850e_uart_putc (port->line, tx_ch);
		port->icount.tx++;

		if (uart_circ_chars_pending (xmit) < WAKEUP_CHARS)
			uart_write_wakeup (port);
	}

 no_xmit:
	if (uart_circ_empty (xmit) || stopped)
		v850e_uart_stop_tx (port, stopped);
}

static irqreturn_t v850e_uart_tx_irq(int irq, void *data, struct pt_regs *regs)
{
	struct uart_port *port = data;
	v850e_uart_tx (port);
	return IRQ_HANDLED;
}

static irqreturn_t v850e_uart_rx_irq(int irq, void *data, struct pt_regs *regs)
{
	struct uart_port *port = data;
	unsigned ch_stat = TTY_NORMAL;
	unsigned ch = v850e_uart_getc (port->line);
	unsigned err = v850e_uart_err (port->line);

	if (err) {
		if (err & V850E_UART_ERR_OVERRUN) {
			ch_stat = TTY_OVERRUN;
			port->icount.overrun++;
		} else if (err & V850E_UART_ERR_FRAME) {
			ch_stat = TTY_FRAME;
			port->icount.frame++;
		} else if (err & V850E_UART_ERR_PARITY) {
			ch_stat = TTY_PARITY;
			port->icount.parity++;
		}
	}

	port->icount.rx++;

	tty_insert_flip_char (port->info->tty, ch, ch_stat);
	tty_schedule_flip (port->info->tty);

	return IRQ_HANDLED;
}


/* Control functions for the serial framework.  */

static void v850e_uart_nop (struct uart_port *port) { }
static int v850e_uart_success (struct uart_port *port) { return 0; }

static unsigned v850e_uart_tx_empty (struct uart_port *port)
{
	return TIOCSER_TEMT;	/* Can't detect.  */
}

static void v850e_uart_set_mctrl (struct uart_port *port, unsigned mctrl)
{
#ifdef V850E_UART_SET_RTS
	V850E_UART_SET_RTS (port->line, (mctrl & TIOCM_RTS));
#endif
}

static unsigned v850e_uart_get_mctrl (struct uart_port *port)
{
	/* We don't support DCD or DSR, so consider them permanently active. */
	int mctrl = TIOCM_CAR | TIOCM_DSR;

	/* We may support CTS.  */
#ifdef V850E_UART_CTS
	mctrl |= V850E_UART_CTS(port->line) ? TIOCM_CTS : 0;
#else
	mctrl |= TIOCM_CTS;
#endif

	return mctrl;
}

static void v850e_uart_start_tx (struct uart_port *port)
{
	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
	v850e_uart_tx (port);
	v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line));
}

static void v850e_uart_stop_tx (struct uart_port *port)
{
	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
}

static void v850e_uart_start_rx (struct uart_port *port)
{
	v850e_intc_enable_irq (V850E_UART_RX_IRQ (port->line));
}

static void v850e_uart_stop_rx (struct uart_port *port)
{
	v850e_intc_disable_irq (V850E_UART_RX_IRQ (port->line));
}

static void v850e_uart_break_ctl (struct uart_port *port, int break_ctl)
{
	/* Umm, do this later.  */
}

static int v850e_uart_startup (struct uart_port *port)
{
	int err;

	/* Alloc RX irq.  */
	err = request_irq (V850E_UART_RX_IRQ (port->line), v850e_uart_rx_irq,
			   IRQF_DISABLED, "v850e_uart", port);
	if (err)
		return err;

	/* Alloc TX irq.  */
	err = request_irq (V850E_UART_TX_IRQ (port->line), v850e_uart_tx_irq,
			   IRQF_DISABLED, "v850e_uart", port);
	if (err) {
		free_irq (V850E_UART_RX_IRQ (port->line), port);
		return err;
	}

	v850e_uart_start_rx (port);

	return 0;
}

static void v850e_uart_shutdown (struct uart_port *port)
{
	/* Disable port interrupts.  */
	free_irq (V850E_UART_TX_IRQ (port->line), port);
	free_irq (V850E_UART_RX_IRQ (port->line), port);

	/* Turn off xmit/recv enable bits.  */
	V850E_UART_CONFIG (port->line)
		&= ~(V850E_UART_CONFIG_TX_ENABLE
		     | V850E_UART_CONFIG_RX_ENABLE);
	/* Then reset the channel.  */
	V850E_UART_CONFIG (port->line) = 0;
}

static void
v850e_uart_set_termios (struct uart_port *port, struct termios *termios,
		        struct termios *old)
{
	unsigned cflags = termios->c_cflag;

	/* Restrict flags to legal values.  */
	if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
		/* The new value of CSIZE is invalid, use the old value.  */
		cflags = (cflags & ~CSIZE)
			| (old ? (old->c_cflag & CSIZE) : CS8);

	termios->c_cflag = cflags;

	v850e_uart_configure (port->line, cflags,
			      uart_get_baud_rate (port, termios, old,
						  v850e_uart_min_baud(),
						  v850e_uart_max_baud()));
}

static const char *v850e_uart_type (struct uart_port *port)
{
	return port->type == PORT_V850E_UART ? "v850e_uart" : 0;
}

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

static int
v850e_uart_verify_port (struct uart_port *port, struct serial_struct *ser)
{
	if (ser->type != PORT_UNKNOWN && ser->type != PORT_V850E_UART)
		return -EINVAL;
	if (ser->irq != V850E_UART_TX_IRQ (port->line))
		return -EINVAL;
	return 0;
}

static struct uart_ops v850e_uart_ops = {
	.tx_empty	= v850e_uart_tx_empty,
	.get_mctrl	= v850e_uart_get_mctrl,
	.set_mctrl	= v850e_uart_set_mctrl,
	.start_tx	= v850e_uart_start_tx,
	.stop_tx	= v850e_uart_stop_tx,
	.stop_rx	= v850e_uart_stop_rx,
	.enable_ms	= v850e_uart_nop,
	.break_ctl	= v850e_uart_break_ctl,
	.startup	= v850e_uart_startup,
	.shutdown	= v850e_uart_shutdown,
	.set_termios	= v850e_uart_set_termios,
	.type		= v850e_uart_type,
	.release_port	= v850e_uart_nop,
	.request_port	= v850e_uart_success,
	.config_port	= v850e_uart_config_port,
	.verify_port	= v850e_uart_verify_port,
};

/* Initialization and cleanup.  */

static struct uart_driver v850e_uart_driver = {
	.owner			= THIS_MODULE,
	.driver_name		= "v850e_uart",
	.dev_name		= "ttyS",
	.major			= TTY_MAJOR,
	.minor			= V850E_UART_MINOR_BASE,
	.nr			= V850E_UART_NUM_CHANNELS,
	.cons			= V850E_UART_CONSOLE,
};


static struct uart_port v850e_uart_ports[V850E_UART_NUM_CHANNELS];

static int __init v850e_uart_init (void)
{
	int rval;

	printk (KERN_INFO "%s on-chip UART\n", V850E_UART_CHIP_NAME);

	rval = uart_register_driver (&v850e_uart_driver);
	if (rval == 0) {
		unsigned chan;

		for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++) {
			struct uart_port *port = &v850e_uart_ports[chan];
			
			memset (port, 0, sizeof *port);

			port->ops = &v850e_uart_ops;
			port->line = chan;
			port->iotype = UPIO_MEM;
			port->flags = UPF_BOOT_AUTOCONF;

			/* We actually use multiple IRQs, but the serial
			   framework seems to mainly use this for
			   informational purposes anyway.  Here we use the TX
			   irq.  */
			port->irq = V850E_UART_TX_IRQ (chan);

			/* The serial framework doesn't really use these
			   membase/mapbase fields for anything useful, but
			   it requires that they be something non-zero to
			   consider the port `valid', and also uses them
			   for informational purposes.  */
			port->membase = (void *)V850E_UART_BASE_ADDR (chan);
			port->mapbase = V850E_UART_BASE_ADDR (chan);

			/* The framework insists on knowing the uart's master
			   clock freq, though it doesn't seem to do anything
			   useful for us with it.  We must make it at least
			   higher than (the maximum baud rate * 16), otherwise
			   the framework will puke during its internal
			   calculations, and force the baud rate to be 9600.
			   To be accurate though, just repeat the calculation
			   we use when actually setting the speed.  */
			port->uartclk = v850e_uart_max_clock() * 16;

			uart_add_one_port (&v850e_uart_driver, port);
		}
	}

	return rval;
}

static void __exit v850e_uart_exit (void)
{
	unsigned chan;

	for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++)
		uart_remove_one_port (&v850e_uart_driver,
				      &v850e_uart_ports[chan]);

	uart_unregister_driver (&v850e_uart_driver);
}

module_init (v850e_uart_init);
module_exit (v850e_uart_exit);

MODULE_AUTHOR ("Miles Bader");
MODULE_DESCRIPTION ("NEC " V850E_UART_CHIP_NAME " on-chip UART");
MODULE_LICENSE ("GPL");
