/*
 * 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,
			   SA_INTERRUPT, "v850e_uart", port);
	if (err)
		return err;

	/* Alloc TX irq.  */
	err = request_irq (V850E_UART_TX_IRQ (port->line), v850e_uart_tx_irq,
			   SA_INTERRUPT, "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",
	.devfs_name		= "tts/",
	.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");
