/*
 * timbuart.c timberdale FPGA UART driver
 * Copyright (c) 2009 Intel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* Supports:
 * Timberdale FPGA UART
 */

#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/serial_core.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <linux/slab.h>

#include "timbuart.h"

struct timbuart_port {
	struct uart_port	port;
	struct tasklet_struct	tasklet;
	int			usedma;
	u32			last_ier;
	struct platform_device  *dev;
};

static int baudrates[] = {9600, 19200, 38400, 57600, 115200, 230400, 460800,
	921600, 1843200, 3250000};

static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier);

static irqreturn_t timbuart_handleinterrupt(int irq, void *devid);

static void timbuart_stop_rx(struct uart_port *port)
{
	/* spin lock held by upper layer, disable all RX interrupts */
	u32 ier = ioread32(port->membase + TIMBUART_IER) & ~RXFLAGS;
	iowrite32(ier, port->membase + TIMBUART_IER);
}

static void timbuart_stop_tx(struct uart_port *port)
{
	/* spinlock held by upper layer, disable TX interrupt */
	u32 ier = ioread32(port->membase + TIMBUART_IER) & ~TXBAE;
	iowrite32(ier, port->membase + TIMBUART_IER);
}

static void timbuart_start_tx(struct uart_port *port)
{
	struct timbuart_port *uart =
		container_of(port, struct timbuart_port, port);

	/* do not transfer anything here -> fire off the tasklet */
	tasklet_schedule(&uart->tasklet);
}

static unsigned int timbuart_tx_empty(struct uart_port *port)
{
	u32 isr = ioread32(port->membase + TIMBUART_ISR);

	return (isr & TXBE) ? TIOCSER_TEMT : 0;
}

static void timbuart_flush_buffer(struct uart_port *port)
{
	if (!timbuart_tx_empty(port)) {
		u8 ctl = ioread8(port->membase + TIMBUART_CTRL) |
			TIMBUART_CTRL_FLSHTX;

		iowrite8(ctl, port->membase + TIMBUART_CTRL);
		iowrite32(TXBF, port->membase + TIMBUART_ISR);
	}
}

static void timbuart_rx_chars(struct uart_port *port)
{
	struct tty_struct *tty = port->state->port.tty;

	while (ioread32(port->membase + TIMBUART_ISR) & RXDP) {
		u8 ch = ioread8(port->membase + TIMBUART_RXFIFO);
		port->icount.rx++;
		tty_insert_flip_char(tty, ch, TTY_NORMAL);
	}

	spin_unlock(&port->lock);
	tty_flip_buffer_push(port->state->port.tty);
	spin_lock(&port->lock);

	dev_dbg(port->dev, "%s - total read %d bytes\n",
		__func__, port->icount.rx);
}

static void timbuart_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;

	while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) &&
		!uart_circ_empty(xmit)) {
		iowrite8(xmit->buf[xmit->tail],
			port->membase + TIMBUART_TXFIFO);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}

	dev_dbg(port->dev,
		"%s - total written %d bytes, CTL: %x, RTS: %x, baud: %x\n",
		 __func__,
		port->icount.tx,
		ioread8(port->membase + TIMBUART_CTRL),
		port->mctrl & TIOCM_RTS,
		ioread8(port->membase + TIMBUART_BAUDRATE));
}

static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier)
{
	struct timbuart_port *uart =
		container_of(port, struct timbuart_port, port);
	struct circ_buf *xmit = &port->state->xmit;

	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
		return;

	if (port->x_char)
		return;

	if (isr & TXFLAGS) {
		timbuart_tx_chars(port);
		/* clear all TX interrupts */
		iowrite32(TXFLAGS, port->membase + TIMBUART_ISR);

		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
			uart_write_wakeup(port);
	} else
		/* Re-enable any tx interrupt */
		*ier |= uart->last_ier & TXFLAGS;

	/* enable interrupts if there are chars in the transmit buffer,
	 * Or if we delivered some bytes and want the almost empty interrupt
	 * we wake up the upper layer later when we got the interrupt
	 * to give it some time to go out...
	 */
	if (!uart_circ_empty(xmit))
		*ier |= TXBAE;

	dev_dbg(port->dev, "%s - leaving\n", __func__);
}

void timbuart_handle_rx_port(struct uart_port *port, u32 isr, u32 *ier)
{
	if (isr & RXFLAGS) {
		/* Some RX status is set */
		if (isr & RXBF) {
			u8 ctl = ioread8(port->membase + TIMBUART_CTRL) |
				TIMBUART_CTRL_FLSHRX;
			iowrite8(ctl, port->membase + TIMBUART_CTRL);
			port->icount.overrun++;
		} else if (isr & (RXDP))
			timbuart_rx_chars(port);

		/* ack all RX interrupts */
		iowrite32(RXFLAGS, port->membase + TIMBUART_ISR);
	}

	/* always have the RX interrupts enabled */
	*ier |= RXBAF | RXBF | RXTT;

	dev_dbg(port->dev, "%s - leaving\n", __func__);
}

void timbuart_tasklet(unsigned long arg)
{
	struct timbuart_port *uart = (struct timbuart_port *)arg;
	u32 isr, ier = 0;

	spin_lock(&uart->port.lock);

	isr = ioread32(uart->port.membase + TIMBUART_ISR);
	dev_dbg(uart->port.dev, "%s ISR: %x\n", __func__, isr);

	if (!uart->usedma)
		timbuart_handle_tx_port(&uart->port, isr, &ier);

	timbuart_mctrl_check(&uart->port, isr, &ier);

	if (!uart->usedma)
		timbuart_handle_rx_port(&uart->port, isr, &ier);

	iowrite32(ier, uart->port.membase + TIMBUART_IER);

	spin_unlock(&uart->port.lock);
	dev_dbg(uart->port.dev, "%s leaving\n", __func__);
}

static unsigned int timbuart_get_mctrl(struct uart_port *port)
{
	u8 cts = ioread8(port->membase + TIMBUART_CTRL);
	dev_dbg(port->dev, "%s - cts %x\n", __func__, cts);

	if (cts & TIMBUART_CTRL_CTS)
		return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
	else
		return TIOCM_DSR | TIOCM_CAR;
}

static void timbuart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	dev_dbg(port->dev, "%s - %x\n", __func__, mctrl);

	if (mctrl & TIOCM_RTS)
		iowrite8(TIMBUART_CTRL_RTS, port->membase + TIMBUART_CTRL);
	else
		iowrite8(0, port->membase + TIMBUART_CTRL);
}

static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier)
{
	unsigned int cts;

	if (isr & CTS_DELTA) {
		/* ack */
		iowrite32(CTS_DELTA, port->membase + TIMBUART_ISR);
		cts = timbuart_get_mctrl(port);
		uart_handle_cts_change(port, cts & TIOCM_CTS);
		wake_up_interruptible(&port->state->port.delta_msr_wait);
	}

	*ier |= CTS_DELTA;
}

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

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

static int timbuart_startup(struct uart_port *port)
{
	struct timbuart_port *uart =
		container_of(port, struct timbuart_port, port);

	dev_dbg(port->dev, "%s\n", __func__);

	iowrite8(TIMBUART_CTRL_FLSHRX, port->membase + TIMBUART_CTRL);
	iowrite32(0x1ff, port->membase + TIMBUART_ISR);
	/* Enable all but TX interrupts */
	iowrite32(RXBAF | RXBF | RXTT | CTS_DELTA,
		port->membase + TIMBUART_IER);

	return request_irq(port->irq, timbuart_handleinterrupt, IRQF_SHARED,
		"timb-uart", uart);
}

static void timbuart_shutdown(struct uart_port *port)
{
	struct timbuart_port *uart =
		container_of(port, struct timbuart_port, port);
	dev_dbg(port->dev, "%s\n", __func__);
	free_irq(port->irq, uart);
	iowrite32(0, port->membase + TIMBUART_IER);
}

static int get_bindex(int baud)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(baudrates); i++)
		if (baud <= baudrates[i])
			return i;

	return -1;
}

static void timbuart_set_termios(struct uart_port *port,
	struct ktermios *termios,
	struct ktermios *old)
{
	unsigned int baud;
	short bindex;
	unsigned long flags;

	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
	bindex = get_bindex(baud);
	dev_dbg(port->dev, "%s - bindex %d\n", __func__, bindex);

	if (bindex < 0)
		bindex = 0;
	baud = baudrates[bindex];

	/* The serial layer calls into this once with old = NULL when setting
	   up initially */
	if (old)
		tty_termios_copy_hw(termios, old);
	tty_termios_encode_baud_rate(termios, baud, baud);

	spin_lock_irqsave(&port->lock, flags);
	iowrite8((u8)bindex, port->membase + TIMBUART_BAUDRATE);
	uart_update_timeout(port, termios->c_cflag, baud);
	spin_unlock_irqrestore(&port->lock, flags);
}

static const char *timbuart_type(struct uart_port *port)
{
	return port->type == PORT_UNKNOWN ? "timbuart" : NULL;
}

/* We do not request/release mappings of the registers here,
 * currently it's done in the proble function.
 */
static void timbuart_release_port(struct uart_port *port)
{
	struct platform_device *pdev = to_platform_device(port->dev);
	int size =
		resource_size(platform_get_resource(pdev, IORESOURCE_MEM, 0));

	if (port->flags & UPF_IOREMAP) {
		iounmap(port->membase);
		port->membase = NULL;
	}

	release_mem_region(port->mapbase, size);
}

static int timbuart_request_port(struct uart_port *port)
{
	struct platform_device *pdev = to_platform_device(port->dev);
	int size =
		resource_size(platform_get_resource(pdev, IORESOURCE_MEM, 0));

	if (!request_mem_region(port->mapbase, size, "timb-uart"))
		return -EBUSY;

	if (port->flags & UPF_IOREMAP) {
		port->membase = ioremap(port->mapbase, size);
		if (port->membase == NULL) {
			release_mem_region(port->mapbase, size);
			return -ENOMEM;
		}
	}

	return 0;
}

static irqreturn_t timbuart_handleinterrupt(int irq, void *devid)
{
	struct timbuart_port *uart = (struct timbuart_port *)devid;

	if (ioread8(uart->port.membase + TIMBUART_IPR)) {
		uart->last_ier = ioread32(uart->port.membase + TIMBUART_IER);

		/* disable interrupts, the tasklet enables them again */
		iowrite32(0, uart->port.membase + TIMBUART_IER);

		/* fire off bottom half */
		tasklet_schedule(&uart->tasklet);

		return IRQ_HANDLED;
	} else
		return IRQ_NONE;
}

/*
 * Configure/autoconfigure the port.
 */
static void timbuart_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE) {
		port->type = PORT_TIMBUART;
		timbuart_request_port(port);
	}
}

static int timbuart_verify_port(struct uart_port *port,
	struct serial_struct *ser)
{
	/* we don't want the core code to modify any port params */
	return -EINVAL;
}

static struct uart_ops timbuart_ops = {
	.tx_empty = timbuart_tx_empty,
	.set_mctrl = timbuart_set_mctrl,
	.get_mctrl = timbuart_get_mctrl,
	.stop_tx = timbuart_stop_tx,
	.start_tx = timbuart_start_tx,
	.flush_buffer = timbuart_flush_buffer,
	.stop_rx = timbuart_stop_rx,
	.enable_ms = timbuart_enable_ms,
	.break_ctl = timbuart_break_ctl,
	.startup = timbuart_startup,
	.shutdown = timbuart_shutdown,
	.set_termios = timbuart_set_termios,
	.type = timbuart_type,
	.release_port = timbuart_release_port,
	.request_port = timbuart_request_port,
	.config_port = timbuart_config_port,
	.verify_port = timbuart_verify_port
};

static struct uart_driver timbuart_driver = {
	.owner = THIS_MODULE,
	.driver_name = "timberdale_uart",
	.dev_name = "ttyTU",
	.major = TIMBUART_MAJOR,
	.minor = TIMBUART_MINOR,
	.nr = 1
};

static int timbuart_probe(struct platform_device *dev)
{
	int err, irq;
	struct timbuart_port *uart;
	struct resource *iomem;

	dev_dbg(&dev->dev, "%s\n", __func__);

	uart = kzalloc(sizeof(*uart), GFP_KERNEL);
	if (!uart) {
		err = -EINVAL;
		goto err_mem;
	}

	uart->usedma = 0;

	uart->port.uartclk = 3250000 * 16;
	uart->port.fifosize  = TIMBUART_FIFO_SIZE;
	uart->port.regshift  = 2;
	uart->port.iotype  = UPIO_MEM;
	uart->port.ops = &timbuart_ops;
	uart->port.irq = 0;
	uart->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
	uart->port.line  = 0;
	uart->port.dev	= &dev->dev;

	iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!iomem) {
		err = -ENOMEM;
		goto err_register;
	}
	uart->port.mapbase = iomem->start;
	uart->port.membase = NULL;

	irq = platform_get_irq(dev, 0);
	if (irq < 0) {
		err = -EINVAL;
		goto err_register;
	}
	uart->port.irq = irq;

	tasklet_init(&uart->tasklet, timbuart_tasklet, (unsigned long)uart);

	err = uart_register_driver(&timbuart_driver);
	if (err)
		goto err_register;

	err = uart_add_one_port(&timbuart_driver, &uart->port);
	if (err)
		goto err_add_port;

	platform_set_drvdata(dev, uart);

	return 0;

err_add_port:
	uart_unregister_driver(&timbuart_driver);
err_register:
	kfree(uart);
err_mem:
	printk(KERN_ERR "timberdale: Failed to register Timberdale UART: %d\n",
		err);

	return err;
}

static int timbuart_remove(struct platform_device *dev)
{
	struct timbuart_port *uart = platform_get_drvdata(dev);

	tasklet_kill(&uart->tasklet);
	uart_remove_one_port(&timbuart_driver, &uart->port);
	uart_unregister_driver(&timbuart_driver);
	kfree(uart);

	return 0;
}

static struct platform_driver timbuart_platform_driver = {
	.driver = {
		.name	= "timb-uart",
		.owner	= THIS_MODULE,
	},
	.probe		= timbuart_probe,
	.remove		= timbuart_remove,
};

/*--------------------------------------------------------------------------*/

static int __init timbuart_init(void)
{
	return platform_driver_register(&timbuart_platform_driver);
}

static void __exit timbuart_exit(void)
{
	platform_driver_unregister(&timbuart_platform_driver);
}

module_init(timbuart_init);
module_exit(timbuart_exit);

MODULE_DESCRIPTION("Timberdale UART driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:timb-uart");

