/*
 *  Serial Port driver for a NWP uart device
 *
 *    Copyright (C) 2008 IBM Corp., Benjamin Krill <ben@codiert.org>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version
 *  2 of the License, or (at your option) any later version.
 *
 */
#include <linux/init.h>
#include <linux/export.h>
#include <linux/console.h>
#include <linux/serial.h>
#include <linux/serial_reg.h>
#include <linux/serial_core.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/irqreturn.h>
#include <linux/mutex.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/nwpserial.h>
#include <asm/prom.h>
#include <asm/dcr.h>

#define NWPSERIAL_NR               2

#define NWPSERIAL_STATUS_RXVALID 0x1
#define NWPSERIAL_STATUS_TXFULL  0x2

struct nwpserial_port {
	struct uart_port port;
	dcr_host_t dcr_host;
	unsigned int ier;
	unsigned int mcr;
};

static DEFINE_MUTEX(nwpserial_mutex);
static struct nwpserial_port nwpserial_ports[NWPSERIAL_NR];

static void wait_for_bits(struct nwpserial_port *up, int bits)
{
	unsigned int status, tmout = 10000;

	/* Wait up to 10ms for the character(s) to be sent. */
	do {
		status = dcr_read(up->dcr_host, UART_LSR);

		if (--tmout == 0)
			break;
		udelay(1);
	} while ((status & bits) != bits);
}

#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE
static void nwpserial_console_putchar(struct uart_port *port, int c)
{
	struct nwpserial_port *up;
	up = container_of(port, struct nwpserial_port, port);
	/* check if tx buffer is full */
	wait_for_bits(up, UART_LSR_THRE);
	dcr_write(up->dcr_host, UART_TX, c);
	up->port.icount.tx++;
}

static void
nwpserial_console_write(struct console *co, const char *s, unsigned int count)
{
	struct nwpserial_port *up = &nwpserial_ports[co->index];
	unsigned long flags;
	int locked = 1;

	if (oops_in_progress)
		locked = spin_trylock_irqsave(&up->port.lock, flags);
	else
		spin_lock_irqsave(&up->port.lock, flags);

	/* save and disable interrupt */
	up->ier = dcr_read(up->dcr_host, UART_IER);
	dcr_write(up->dcr_host, UART_IER, up->ier & ~UART_IER_RDI);

	uart_console_write(&up->port, s, count, nwpserial_console_putchar);

	/* wait for transmitter to become empty */
	while ((dcr_read(up->dcr_host, UART_LSR) & UART_LSR_THRE) == 0)
		cpu_relax();

	/* restore interrupt state */
	dcr_write(up->dcr_host, UART_IER, up->ier);

	if (locked)
		spin_unlock_irqrestore(&up->port.lock, flags);
}

static struct uart_driver nwpserial_reg;
static struct console nwpserial_console = {
	.name		= "ttySQ",
	.write		= nwpserial_console_write,
	.device		= uart_console_device,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &nwpserial_reg,
};
#define NWPSERIAL_CONSOLE	(&nwpserial_console)
#else
#define NWPSERIAL_CONSOLE	NULL
#endif /* CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE */

/**************************************************************************/

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

static void nwpserial_release_port(struct uart_port *port)
{
	/* N/A */
}

static void nwpserial_config_port(struct uart_port *port, int flags)
{
	port->type = PORT_NWPSERIAL;
}

static irqreturn_t nwpserial_interrupt(int irq, void *dev_id)
{
	struct nwpserial_port *up = dev_id;
	struct tty_port *port = &up->port.state->port;
	irqreturn_t ret;
	unsigned int iir;
	unsigned char ch;

	spin_lock(&up->port.lock);

	/* check if the uart was the interrupt source. */
	iir = dcr_read(up->dcr_host, UART_IIR);
	if (!iir) {
		ret = IRQ_NONE;
		goto out;
	}

	do {
		up->port.icount.rx++;
		ch = dcr_read(up->dcr_host, UART_RX);
		if (up->port.ignore_status_mask != NWPSERIAL_STATUS_RXVALID)
			tty_insert_flip_char(port, ch, TTY_NORMAL);
	} while (dcr_read(up->dcr_host, UART_LSR) & UART_LSR_DR);

	tty_flip_buffer_push(port);
	ret = IRQ_HANDLED;

	/* clear interrupt */
	dcr_write(up->dcr_host, UART_IIR, 1);
out:
	spin_unlock(&up->port.lock);
	return ret;
}

static int nwpserial_startup(struct uart_port *port)
{
	struct nwpserial_port *up;
	int err;

	up = container_of(port, struct nwpserial_port, port);

	/* disable flow control by default */
	up->mcr = dcr_read(up->dcr_host, UART_MCR) & ~UART_MCR_AFE;
	dcr_write(up->dcr_host, UART_MCR, up->mcr);

	/* register interrupt handler */
	err = request_irq(up->port.irq, nwpserial_interrupt,
			IRQF_SHARED, "nwpserial", up);
	if (err)
		return err;

	/* enable interrupts */
	up->ier = UART_IER_RDI;
	dcr_write(up->dcr_host, UART_IER, up->ier);

	/* enable receiving */
	up->port.ignore_status_mask &= ~NWPSERIAL_STATUS_RXVALID;

	return 0;
}

static void nwpserial_shutdown(struct uart_port *port)
{
	struct nwpserial_port *up;
	up = container_of(port, struct nwpserial_port, port);

	/* disable receiving */
	up->port.ignore_status_mask |= NWPSERIAL_STATUS_RXVALID;

	/* disable interrupts from this port */
	up->ier = 0;
	dcr_write(up->dcr_host, UART_IER, up->ier);

	/* free irq */
	free_irq(up->port.irq, up);
}

static int nwpserial_verify_port(struct uart_port *port,
			struct serial_struct *ser)
{
	return -EINVAL;
}

static const char *nwpserial_type(struct uart_port *port)
{
	return port->type == PORT_NWPSERIAL ? "nwpserial" : NULL;
}

static void nwpserial_set_termios(struct uart_port *port,
			struct ktermios *termios, struct ktermios *old)
{
	struct nwpserial_port *up;
	up = container_of(port, struct nwpserial_port, port);

	up->port.read_status_mask = NWPSERIAL_STATUS_RXVALID
				| NWPSERIAL_STATUS_TXFULL;

	up->port.ignore_status_mask = 0;
	/* ignore all characters if CREAD is not set */
	if ((termios->c_cflag & CREAD) == 0)
		up->port.ignore_status_mask |= NWPSERIAL_STATUS_RXVALID;

	/* Copy back the old hardware settings */
	if (old)
		tty_termios_copy_hw(termios, old);
}

static void nwpserial_break_ctl(struct uart_port *port, int ctl)
{
	/* N/A */
}

static void nwpserial_enable_ms(struct uart_port *port)
{
	/* N/A */
}

static void nwpserial_stop_rx(struct uart_port *port)
{
	struct nwpserial_port *up;
	up = container_of(port, struct nwpserial_port, port);
	/* don't forward any more data (like !CREAD) */
	up->port.ignore_status_mask = NWPSERIAL_STATUS_RXVALID;
}

static void nwpserial_putchar(struct nwpserial_port *up, unsigned char c)
{
	/* check if tx buffer is full */
	wait_for_bits(up, UART_LSR_THRE);
	dcr_write(up->dcr_host, UART_TX, c);
	up->port.icount.tx++;
}

static void nwpserial_start_tx(struct uart_port *port)
{
	struct nwpserial_port *up;
	struct circ_buf *xmit;
	up = container_of(port, struct nwpserial_port, port);
	xmit  = &up->port.state->xmit;

	if (port->x_char) {
		nwpserial_putchar(up, up->port.x_char);
		port->x_char = 0;
	}

	while (!(uart_circ_empty(xmit) || uart_tx_stopped(&up->port))) {
		nwpserial_putchar(up, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
	}
}

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

static void nwpserial_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	/* N/A */
}

static void nwpserial_stop_tx(struct uart_port *port)
{
	/* N/A */
}

static unsigned int nwpserial_tx_empty(struct uart_port *port)
{
	struct nwpserial_port *up;
	unsigned long flags;
	int ret;
	up = container_of(port, struct nwpserial_port, port);

	spin_lock_irqsave(&up->port.lock, flags);
	ret = dcr_read(up->dcr_host, UART_LSR);
	spin_unlock_irqrestore(&up->port.lock, flags);

	return ret & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
}

static struct uart_ops nwpserial_pops = {
	.tx_empty     = nwpserial_tx_empty,
	.set_mctrl    = nwpserial_set_mctrl,
	.get_mctrl    = nwpserial_get_mctrl,
	.stop_tx      = nwpserial_stop_tx,
	.start_tx     = nwpserial_start_tx,
	.stop_rx      = nwpserial_stop_rx,
	.enable_ms    = nwpserial_enable_ms,
	.break_ctl    = nwpserial_break_ctl,
	.startup      = nwpserial_startup,
	.shutdown     = nwpserial_shutdown,
	.set_termios  = nwpserial_set_termios,
	.type         = nwpserial_type,
	.release_port = nwpserial_release_port,
	.request_port = nwpserial_request_port,
	.config_port  = nwpserial_config_port,
	.verify_port  = nwpserial_verify_port,
};

static struct uart_driver nwpserial_reg = {
	.owner       = THIS_MODULE,
	.driver_name = "nwpserial",
	.dev_name    = "ttySQ",
	.major       = TTY_MAJOR,
	.minor       = 68,
	.nr          = NWPSERIAL_NR,
	.cons        = NWPSERIAL_CONSOLE,
};

int nwpserial_register_port(struct uart_port *port)
{
	struct nwpserial_port *up = NULL;
	int ret = -1;
	int i;
	static int first = 1;
	int dcr_len;
	int dcr_base;
	struct device_node *dn;

	mutex_lock(&nwpserial_mutex);

	dn = port->dev->of_node;
	if (dn == NULL)
		goto out;

	/* get dcr base. */
	dcr_base = dcr_resource_start(dn, 0);

	/* find matching entry */
	for (i = 0; i < NWPSERIAL_NR; i++)
		if (nwpserial_ports[i].port.iobase == dcr_base) {
			up = &nwpserial_ports[i];
			break;
		}

	/* we didn't find a mtching entry, search for a free port */
	if (up == NULL)
		for (i = 0; i < NWPSERIAL_NR; i++)
			if (nwpserial_ports[i].port.type == PORT_UNKNOWN &&
				nwpserial_ports[i].port.iobase == 0) {
				up = &nwpserial_ports[i];
				break;
			}

	if (up == NULL) {
		ret = -EBUSY;
		goto out;
	}

	if (first)
		uart_register_driver(&nwpserial_reg);
	first = 0;

	up->port.membase      = port->membase;
	up->port.irq          = port->irq;
	up->port.uartclk      = port->uartclk;
	up->port.fifosize     = port->fifosize;
	up->port.regshift     = port->regshift;
	up->port.iotype       = port->iotype;
	up->port.flags        = port->flags;
	up->port.mapbase      = port->mapbase;
	up->port.private_data = port->private_data;

	if (port->dev)
		up->port.dev = port->dev;

	if (up->port.iobase != dcr_base) {
		up->port.ops          = &nwpserial_pops;
		up->port.fifosize     = 16;

		spin_lock_init(&up->port.lock);

		up->port.iobase = dcr_base;
		dcr_len = dcr_resource_len(dn, 0);

		up->dcr_host = dcr_map(dn, dcr_base, dcr_len);
		if (!DCR_MAP_OK(up->dcr_host)) {
			printk(KERN_ERR "Cannot map DCR resources for NWPSERIAL");
			goto out;
		}
	}

	ret = uart_add_one_port(&nwpserial_reg, &up->port);
	if (ret == 0)
		ret = up->port.line;

out:
	mutex_unlock(&nwpserial_mutex);

	return ret;
}
EXPORT_SYMBOL(nwpserial_register_port);

void nwpserial_unregister_port(int line)
{
	struct nwpserial_port *up = &nwpserial_ports[line];
	mutex_lock(&nwpserial_mutex);
	uart_remove_one_port(&nwpserial_reg, &up->port);

	up->port.type = PORT_UNKNOWN;

	mutex_unlock(&nwpserial_mutex);
}
EXPORT_SYMBOL(nwpserial_unregister_port);

#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE
static int __init nwpserial_console_init(void)
{
	struct nwpserial_port *up = NULL;
	struct device_node *dn;
	const char *name;
	int dcr_base;
	int dcr_len;
	int i;

	/* search for a free port */
	for (i = 0; i < NWPSERIAL_NR; i++)
		if (nwpserial_ports[i].port.type == PORT_UNKNOWN) {
			up = &nwpserial_ports[i];
			break;
		}

	if (up == NULL)
		return -1;

	name = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (name == NULL)
		return -1;

	dn = of_find_node_by_path(name);
	if (!dn)
		return -1;

	spin_lock_init(&up->port.lock);
	up->port.ops = &nwpserial_pops;
	up->port.type = PORT_NWPSERIAL;
	up->port.fifosize = 16;

	dcr_base = dcr_resource_start(dn, 0);
	dcr_len = dcr_resource_len(dn, 0);
	up->port.iobase = dcr_base;

	up->dcr_host = dcr_map(dn, dcr_base, dcr_len);
	if (!DCR_MAP_OK(up->dcr_host)) {
		printk("Cannot map DCR resources for SERIAL");
		return -1;
	}
	register_console(&nwpserial_console);
	return 0;
}
console_initcall(nwpserial_console_init);
#endif /* CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL_CONSOLE */
