/*
 * 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.
 *
 * Derived from many drivers using generic_serial interface.
 *
 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
 *
 *  Serial driver for BCM63xx integrated UART.
 *
 * Hardware flow control was _not_ tested since I only have RX/TX on
 * my board.
 */

#if defined(CONFIG_SERIAL_BCM63XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#endif

#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/console.h>
#include <linux/clk.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/sysrq.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/serial_bcm63xx.h>
#include <linux/io.h>
#include <linux/of.h>

#define BCM63XX_NR_UARTS	2

static struct uart_port ports[BCM63XX_NR_UARTS];

/*
 * rx interrupt mask / stat
 *
 * mask:
 *  - rx fifo full
 *  - rx fifo above threshold
 *  - rx fifo not empty for too long
 */
#define UART_RX_INT_MASK	(UART_IR_MASK(UART_IR_RXOVER) |		\
				UART_IR_MASK(UART_IR_RXTHRESH) |	\
				UART_IR_MASK(UART_IR_RXTIMEOUT))

#define UART_RX_INT_STAT	(UART_IR_STAT(UART_IR_RXOVER) |		\
				UART_IR_STAT(UART_IR_RXTHRESH) |	\
				UART_IR_STAT(UART_IR_RXTIMEOUT))

/*
 * tx interrupt mask / stat
 *
 * mask:
 * - tx fifo empty
 * - tx fifo below threshold
 */
#define UART_TX_INT_MASK	(UART_IR_MASK(UART_IR_TXEMPTY) |	\
				UART_IR_MASK(UART_IR_TXTRESH))

#define UART_TX_INT_STAT	(UART_IR_STAT(UART_IR_TXEMPTY) |	\
				UART_IR_STAT(UART_IR_TXTRESH))

/*
 * external input interrupt
 *
 * mask: any edge on CTS, DCD
 */
#define UART_EXTINP_INT_MASK	(UART_EXTINP_IRMASK(UART_EXTINP_IR_CTS) | \
				 UART_EXTINP_IRMASK(UART_EXTINP_IR_DCD))

/*
 * handy uart register accessor
 */
static inline unsigned int bcm_uart_readl(struct uart_port *port,
					 unsigned int offset)
{
	return __raw_readl(port->membase + offset);
}

static inline void bcm_uart_writel(struct uart_port *port,
				  unsigned int value, unsigned int offset)
{
	__raw_writel(value, port->membase + offset);
}

/*
 * serial core request to check if uart tx fifo is empty
 */
static unsigned int bcm_uart_tx_empty(struct uart_port *port)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_IR_REG);
	return (val & UART_IR_STAT(UART_IR_TXEMPTY)) ? 1 : 0;
}

/*
 * serial core request to set RTS and DTR pin state and loopback mode
 */
static void bcm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_MCTL_REG);
	val &= ~(UART_MCTL_DTR_MASK | UART_MCTL_RTS_MASK);
	/* invert of written value is reflected on the pin */
	if (!(mctrl & TIOCM_DTR))
		val |= UART_MCTL_DTR_MASK;
	if (!(mctrl & TIOCM_RTS))
		val |= UART_MCTL_RTS_MASK;
	bcm_uart_writel(port, val, UART_MCTL_REG);

	val = bcm_uart_readl(port, UART_CTL_REG);
	if (mctrl & TIOCM_LOOP)
		val |= UART_CTL_LOOPBACK_MASK;
	else
		val &= ~UART_CTL_LOOPBACK_MASK;
	bcm_uart_writel(port, val, UART_CTL_REG);
}

/*
 * serial core request to return RI, CTS, DCD and DSR pin state
 */
static unsigned int bcm_uart_get_mctrl(struct uart_port *port)
{
	unsigned int val, mctrl;

	mctrl = 0;
	val = bcm_uart_readl(port, UART_EXTINP_REG);
	if (val & UART_EXTINP_RI_MASK)
		mctrl |= TIOCM_RI;
	if (val & UART_EXTINP_CTS_MASK)
		mctrl |= TIOCM_CTS;
	if (val & UART_EXTINP_DCD_MASK)
		mctrl |= TIOCM_CD;
	if (val & UART_EXTINP_DSR_MASK)
		mctrl |= TIOCM_DSR;
	return mctrl;
}

/*
 * serial core request to disable tx ASAP (used for flow control)
 */
static void bcm_uart_stop_tx(struct uart_port *port)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_CTL_REG);
	val &= ~(UART_CTL_TXEN_MASK);
	bcm_uart_writel(port, val, UART_CTL_REG);

	val = bcm_uart_readl(port, UART_IR_REG);
	val &= ~UART_TX_INT_MASK;
	bcm_uart_writel(port, val, UART_IR_REG);
}

/*
 * serial core request to (re)enable tx
 */
static void bcm_uart_start_tx(struct uart_port *port)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_IR_REG);
	val |= UART_TX_INT_MASK;
	bcm_uart_writel(port, val, UART_IR_REG);

	val = bcm_uart_readl(port, UART_CTL_REG);
	val |= UART_CTL_TXEN_MASK;
	bcm_uart_writel(port, val, UART_CTL_REG);
}

/*
 * serial core request to stop rx, called before port shutdown
 */
static void bcm_uart_stop_rx(struct uart_port *port)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_IR_REG);
	val &= ~UART_RX_INT_MASK;
	bcm_uart_writel(port, val, UART_IR_REG);
}

/*
 * serial core request to enable modem status interrupt reporting
 */
static void bcm_uart_enable_ms(struct uart_port *port)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_IR_REG);
	val |= UART_IR_MASK(UART_IR_EXTIP);
	bcm_uart_writel(port, val, UART_IR_REG);
}

/*
 * serial core request to start/stop emitting break char
 */
static void bcm_uart_break_ctl(struct uart_port *port, int ctl)
{
	unsigned long flags;
	unsigned int val;

	spin_lock_irqsave(&port->lock, flags);

	val = bcm_uart_readl(port, UART_CTL_REG);
	if (ctl)
		val |= UART_CTL_XMITBRK_MASK;
	else
		val &= ~UART_CTL_XMITBRK_MASK;
	bcm_uart_writel(port, val, UART_CTL_REG);

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

/*
 * return port type in string format
 */
static const char *bcm_uart_type(struct uart_port *port)
{
	return (port->type == PORT_BCM63XX) ? "bcm63xx_uart" : NULL;
}

/*
 * read all chars in rx fifo and send them to core
 */
static void bcm_uart_do_rx(struct uart_port *port)
{
	struct tty_port *tty_port = &port->state->port;
	unsigned int max_count;

	/* limit number of char read in interrupt, should not be
	 * higher than fifo size anyway since we're much faster than
	 * serial port */
	max_count = 32;
	do {
		unsigned int iestat, c, cstat;
		char flag;

		/* get overrun/fifo empty information from ier
		 * register */
		iestat = bcm_uart_readl(port, UART_IR_REG);

		if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
			unsigned int val;

			/* fifo reset is required to clear
			 * interrupt */
			val = bcm_uart_readl(port, UART_CTL_REG);
			val |= UART_CTL_RSTRXFIFO_MASK;
			bcm_uart_writel(port, val, UART_CTL_REG);

			port->icount.overrun++;
			tty_insert_flip_char(tty_port, 0, TTY_OVERRUN);
		}

		if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
			break;

		cstat = c = bcm_uart_readl(port, UART_FIFO_REG);
		port->icount.rx++;
		flag = TTY_NORMAL;
		c &= 0xff;

		if (unlikely((cstat & UART_FIFO_ANYERR_MASK))) {
			/* do stats first */
			if (cstat & UART_FIFO_BRKDET_MASK) {
				port->icount.brk++;
				if (uart_handle_break(port))
					continue;
			}

			if (cstat & UART_FIFO_PARERR_MASK)
				port->icount.parity++;
			if (cstat & UART_FIFO_FRAMEERR_MASK)
				port->icount.frame++;

			/* update flag wrt read_status_mask */
			cstat &= port->read_status_mask;
			if (cstat & UART_FIFO_BRKDET_MASK)
				flag = TTY_BREAK;
			if (cstat & UART_FIFO_FRAMEERR_MASK)
				flag = TTY_FRAME;
			if (cstat & UART_FIFO_PARERR_MASK)
				flag = TTY_PARITY;
		}

		if (uart_handle_sysrq_char(port, c))
			continue;


		if ((cstat & port->ignore_status_mask) == 0)
			tty_insert_flip_char(tty_port, c, flag);

	} while (--max_count);

	spin_unlock(&port->lock);
	tty_flip_buffer_push(tty_port);
	spin_lock(&port->lock);
}

/*
 * fill tx fifo with chars to send, stop when fifo is about to be full
 * or when all chars have been sent.
 */
static void bcm_uart_do_tx(struct uart_port *port)
{
	struct circ_buf *xmit;
	unsigned int val, max_count;

	if (port->x_char) {
		bcm_uart_writel(port, port->x_char, UART_FIFO_REG);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	if (uart_tx_stopped(port)) {
		bcm_uart_stop_tx(port);
		return;
	}

	xmit = &port->state->xmit;
	if (uart_circ_empty(xmit))
		goto txq_empty;

	val = bcm_uart_readl(port, UART_MCTL_REG);
	val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT;
	max_count = port->fifosize - val;

	while (max_count--) {
		unsigned int c;

		c = xmit->buf[xmit->tail];
		bcm_uart_writel(port, c, UART_FIFO_REG);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if (uart_circ_empty(xmit))
			break;
	}

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

	if (uart_circ_empty(xmit))
		goto txq_empty;
	return;

txq_empty:
	/* nothing to send, disable transmit interrupt */
	val = bcm_uart_readl(port, UART_IR_REG);
	val &= ~UART_TX_INT_MASK;
	bcm_uart_writel(port, val, UART_IR_REG);
	return;
}

/*
 * process uart interrupt
 */
static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id)
{
	struct uart_port *port;
	unsigned int irqstat;

	port = dev_id;
	spin_lock(&port->lock);

	irqstat = bcm_uart_readl(port, UART_IR_REG);
	if (irqstat & UART_RX_INT_STAT)
		bcm_uart_do_rx(port);

	if (irqstat & UART_TX_INT_STAT)
		bcm_uart_do_tx(port);

	if (irqstat & UART_IR_MASK(UART_IR_EXTIP)) {
		unsigned int estat;

		estat = bcm_uart_readl(port, UART_EXTINP_REG);
		if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_CTS))
			uart_handle_cts_change(port,
					       estat & UART_EXTINP_CTS_MASK);
		if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_DCD))
			uart_handle_dcd_change(port,
					       estat & UART_EXTINP_DCD_MASK);
	}

	spin_unlock(&port->lock);
	return IRQ_HANDLED;
}

/*
 * enable rx & tx operation on uart
 */
static void bcm_uart_enable(struct uart_port *port)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_CTL_REG);
	val |= (UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
	bcm_uart_writel(port, val, UART_CTL_REG);
}

/*
 * disable rx & tx operation on uart
 */
static void bcm_uart_disable(struct uart_port *port)
{
	unsigned int val;

	val = bcm_uart_readl(port, UART_CTL_REG);
	val &= ~(UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK |
		 UART_CTL_RXEN_MASK);
	bcm_uart_writel(port, val, UART_CTL_REG);
}

/*
 * clear all unread data in rx fifo and unsent data in tx fifo
 */
static void bcm_uart_flush(struct uart_port *port)
{
	unsigned int val;

	/* empty rx and tx fifo */
	val = bcm_uart_readl(port, UART_CTL_REG);
	val |= UART_CTL_RSTRXFIFO_MASK | UART_CTL_RSTTXFIFO_MASK;
	bcm_uart_writel(port, val, UART_CTL_REG);

	/* read any pending char to make sure all irq status are
	 * cleared */
	(void)bcm_uart_readl(port, UART_FIFO_REG);
}

/*
 * serial core request to initialize uart and start rx operation
 */
static int bcm_uart_startup(struct uart_port *port)
{
	unsigned int val;
	int ret;

	/* mask all irq and flush port */
	bcm_uart_disable(port);
	bcm_uart_writel(port, 0, UART_IR_REG);
	bcm_uart_flush(port);

	/* clear any pending external input interrupt */
	(void)bcm_uart_readl(port, UART_EXTINP_REG);

	/* set rx/tx fifo thresh to fifo half size */
	val = bcm_uart_readl(port, UART_MCTL_REG);
	val &= ~(UART_MCTL_RXFIFOTHRESH_MASK | UART_MCTL_TXFIFOTHRESH_MASK);
	val |= (port->fifosize / 2) << UART_MCTL_RXFIFOTHRESH_SHIFT;
	val |= (port->fifosize / 2) << UART_MCTL_TXFIFOTHRESH_SHIFT;
	bcm_uart_writel(port, val, UART_MCTL_REG);

	/* set rx fifo timeout to 1 char time */
	val = bcm_uart_readl(port, UART_CTL_REG);
	val &= ~UART_CTL_RXTMOUTCNT_MASK;
	val |= 1 << UART_CTL_RXTMOUTCNT_SHIFT;
	bcm_uart_writel(port, val, UART_CTL_REG);

	/* report any edge on dcd and cts */
	val = UART_EXTINP_INT_MASK;
	val |= UART_EXTINP_DCD_NOSENSE_MASK;
	val |= UART_EXTINP_CTS_NOSENSE_MASK;
	bcm_uart_writel(port, val, UART_EXTINP_REG);

	/* register irq and enable rx interrupts */
	ret = request_irq(port->irq, bcm_uart_interrupt, 0,
			  dev_name(port->dev), port);
	if (ret)
		return ret;
	bcm_uart_writel(port, UART_RX_INT_MASK, UART_IR_REG);
	bcm_uart_enable(port);
	return 0;
}

/*
 * serial core request to flush & disable uart
 */
static void bcm_uart_shutdown(struct uart_port *port)
{
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);
	bcm_uart_writel(port, 0, UART_IR_REG);
	spin_unlock_irqrestore(&port->lock, flags);

	bcm_uart_disable(port);
	bcm_uart_flush(port);
	free_irq(port->irq, port);
}

/*
 * serial core request to change current uart setting
 */
static void bcm_uart_set_termios(struct uart_port *port,
				 struct ktermios *new,
				 struct ktermios *old)
{
	unsigned int ctl, baud, quot, ier;
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);

	/* disable uart while changing speed */
	bcm_uart_disable(port);
	bcm_uart_flush(port);

	/* update Control register */
	ctl = bcm_uart_readl(port, UART_CTL_REG);
	ctl &= ~UART_CTL_BITSPERSYM_MASK;

	switch (new->c_cflag & CSIZE) {
	case CS5:
		ctl |= (0 << UART_CTL_BITSPERSYM_SHIFT);
		break;
	case CS6:
		ctl |= (1 << UART_CTL_BITSPERSYM_SHIFT);
		break;
	case CS7:
		ctl |= (2 << UART_CTL_BITSPERSYM_SHIFT);
		break;
	default:
		ctl |= (3 << UART_CTL_BITSPERSYM_SHIFT);
		break;
	}

	ctl &= ~UART_CTL_STOPBITS_MASK;
	if (new->c_cflag & CSTOPB)
		ctl |= UART_CTL_STOPBITS_2;
	else
		ctl |= UART_CTL_STOPBITS_1;

	ctl &= ~(UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
	if (new->c_cflag & PARENB)
		ctl |= (UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
	ctl &= ~(UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
	if (new->c_cflag & PARODD)
		ctl |= (UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
	bcm_uart_writel(port, ctl, UART_CTL_REG);

	/* update Baudword register */
	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
	quot = uart_get_divisor(port, baud) - 1;
	bcm_uart_writel(port, quot, UART_BAUD_REG);

	/* update Interrupt register */
	ier = bcm_uart_readl(port, UART_IR_REG);

	ier &= ~UART_IR_MASK(UART_IR_EXTIP);
	if (UART_ENABLE_MS(port, new->c_cflag))
		ier |= UART_IR_MASK(UART_IR_EXTIP);

	bcm_uart_writel(port, ier, UART_IR_REG);

	/* update read/ignore mask */
	port->read_status_mask = UART_FIFO_VALID_MASK;
	if (new->c_iflag & INPCK) {
		port->read_status_mask |= UART_FIFO_FRAMEERR_MASK;
		port->read_status_mask |= UART_FIFO_PARERR_MASK;
	}
	if (new->c_iflag & (IGNBRK | BRKINT))
		port->read_status_mask |= UART_FIFO_BRKDET_MASK;

	port->ignore_status_mask = 0;
	if (new->c_iflag & IGNPAR)
		port->ignore_status_mask |= UART_FIFO_PARERR_MASK;
	if (new->c_iflag & IGNBRK)
		port->ignore_status_mask |= UART_FIFO_BRKDET_MASK;
	if (!(new->c_cflag & CREAD))
		port->ignore_status_mask |= UART_FIFO_VALID_MASK;

	uart_update_timeout(port, new->c_cflag, baud);
	bcm_uart_enable(port);
	spin_unlock_irqrestore(&port->lock, flags);
}

/*
 * serial core request to claim uart iomem
 */
static int bcm_uart_request_port(struct uart_port *port)
{
	/* UARTs always present */
	return 0;
}

/*
 * serial core request to release uart iomem
 */
static void bcm_uart_release_port(struct uart_port *port)
{
	/* Nothing to release ... */
}

/*
 * serial core request to do any port required autoconfiguration
 */
static void bcm_uart_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE) {
		if (bcm_uart_request_port(port))
			return;
		port->type = PORT_BCM63XX;
	}
}

/*
 * serial core request to check that port information in serinfo are
 * suitable
 */
static int bcm_uart_verify_port(struct uart_port *port,
				struct serial_struct *serinfo)
{
	if (port->type != PORT_BCM63XX)
		return -EINVAL;
	if (port->irq != serinfo->irq)
		return -EINVAL;
	if (port->iotype != serinfo->io_type)
		return -EINVAL;
	if (port->mapbase != (unsigned long)serinfo->iomem_base)
		return -EINVAL;
	return 0;
}

/* serial core callbacks */
static struct uart_ops bcm_uart_ops = {
	.tx_empty	= bcm_uart_tx_empty,
	.get_mctrl	= bcm_uart_get_mctrl,
	.set_mctrl	= bcm_uart_set_mctrl,
	.start_tx	= bcm_uart_start_tx,
	.stop_tx	= bcm_uart_stop_tx,
	.stop_rx	= bcm_uart_stop_rx,
	.enable_ms	= bcm_uart_enable_ms,
	.break_ctl	= bcm_uart_break_ctl,
	.startup	= bcm_uart_startup,
	.shutdown	= bcm_uart_shutdown,
	.set_termios	= bcm_uart_set_termios,
	.type		= bcm_uart_type,
	.release_port	= bcm_uart_release_port,
	.request_port	= bcm_uart_request_port,
	.config_port	= bcm_uart_config_port,
	.verify_port	= bcm_uart_verify_port,
};



#ifdef CONFIG_SERIAL_BCM63XX_CONSOLE
static inline void wait_for_xmitr(struct uart_port *port)
{
	unsigned int tmout;

	/* Wait up to 10ms for the character(s) to be sent. */
	tmout = 10000;
	while (--tmout) {
		unsigned int val;

		val = bcm_uart_readl(port, UART_IR_REG);
		if (val & UART_IR_STAT(UART_IR_TXEMPTY))
			break;
		udelay(1);
	}

	/* Wait up to 1s for flow control if necessary */
	if (port->flags & UPF_CONS_FLOW) {
		tmout = 1000000;
		while (--tmout) {
			unsigned int val;

			val = bcm_uart_readl(port, UART_EXTINP_REG);
			if (val & UART_EXTINP_CTS_MASK)
				break;
			udelay(1);
		}
	}
}

/*
 * output given char
 */
static void bcm_console_putchar(struct uart_port *port, int ch)
{
	wait_for_xmitr(port);
	bcm_uart_writel(port, ch, UART_FIFO_REG);
}

/*
 * console core request to output given string
 */
static void bcm_console_write(struct console *co, const char *s,
			      unsigned int count)
{
	struct uart_port *port;
	unsigned long flags;
	int locked;

	port = &ports[co->index];

	local_irq_save(flags);
	if (port->sysrq) {
		/* bcm_uart_interrupt() already took the lock */
		locked = 0;
	} else if (oops_in_progress) {
		locked = spin_trylock(&port->lock);
	} else {
		spin_lock(&port->lock);
		locked = 1;
	}

	/* call helper to deal with \r\n */
	uart_console_write(port, s, count, bcm_console_putchar);

	/* and wait for char to be transmitted */
	wait_for_xmitr(port);

	if (locked)
		spin_unlock(&port->lock);
	local_irq_restore(flags);
}

/*
 * console core request to setup given console, find matching uart
 * port and setup it.
 */
static int bcm_console_setup(struct console *co, char *options)
{
	struct uart_port *port;
	int baud = 9600;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';

	if (co->index < 0 || co->index >= BCM63XX_NR_UARTS)
		return -EINVAL;
	port = &ports[co->index];
	if (!port->membase)
		return -ENODEV;
	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);

	return uart_set_options(port, co, baud, parity, bits, flow);
}

static struct uart_driver bcm_uart_driver;

static struct console bcm63xx_console = {
	.name		= "ttyS",
	.write		= bcm_console_write,
	.device		= uart_console_device,
	.setup		= bcm_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &bcm_uart_driver,
};

static int __init bcm63xx_console_init(void)
{
	register_console(&bcm63xx_console);
	return 0;
}

console_initcall(bcm63xx_console_init);

static void bcm_early_write(struct console *con, const char *s, unsigned n)
{
	struct earlycon_device *dev = con->data;

	uart_console_write(&dev->port, s, n, bcm_console_putchar);
	wait_for_xmitr(&dev->port);
}

static int __init bcm_early_console_setup(struct earlycon_device *device,
					  const char *opt)
{
	if (!device->port.membase)
		return -ENODEV;

	device->con->write = bcm_early_write;
	return 0;
}

OF_EARLYCON_DECLARE(bcm63xx_uart, "brcm,bcm6345-uart", bcm_early_console_setup);

#define BCM63XX_CONSOLE	(&bcm63xx_console)
#else
#define BCM63XX_CONSOLE	NULL
#endif /* CONFIG_SERIAL_BCM63XX_CONSOLE */

static struct uart_driver bcm_uart_driver = {
	.owner		= THIS_MODULE,
	.driver_name	= "bcm63xx_uart",
	.dev_name	= "ttyS",
	.major		= TTY_MAJOR,
	.minor		= 64,
	.nr		= BCM63XX_NR_UARTS,
	.cons		= BCM63XX_CONSOLE,
};

/*
 * platform driver probe/remove callback
 */
static int bcm_uart_probe(struct platform_device *pdev)
{
	struct resource *res_mem, *res_irq;
	struct uart_port *port;
	struct clk *clk;
	int ret;

	if (pdev->dev.of_node)
		pdev->id = of_alias_get_id(pdev->dev.of_node, "uart");

	if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS)
		return -EINVAL;

	port = &ports[pdev->id];
	if (port->membase)
		return -EBUSY;
	memset(port, 0, sizeof(*port));

	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res_mem)
		return -ENODEV;

	port->mapbase = res_mem->start;
	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
	if (IS_ERR(port->membase))
		return PTR_ERR(port->membase);

	res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res_irq)
		return -ENODEV;

	clk = pdev->dev.of_node ? of_clk_get(pdev->dev.of_node, 0) :
				  clk_get(&pdev->dev, "periph");
	if (IS_ERR(clk))
		return -ENODEV;

	port->iotype = UPIO_MEM;
	port->irq = res_irq->start;
	port->ops = &bcm_uart_ops;
	port->flags = UPF_BOOT_AUTOCONF;
	port->dev = &pdev->dev;
	port->fifosize = 16;
	port->uartclk = clk_get_rate(clk) / 2;
	port->line = pdev->id;
	clk_put(clk);

	ret = uart_add_one_port(&bcm_uart_driver, port);
	if (ret) {
		ports[pdev->id].membase = NULL;
		return ret;
	}
	platform_set_drvdata(pdev, port);
	return 0;
}

static int bcm_uart_remove(struct platform_device *pdev)
{
	struct uart_port *port;

	port = platform_get_drvdata(pdev);
	uart_remove_one_port(&bcm_uart_driver, port);
	/* mark port as free */
	ports[pdev->id].membase = NULL;
	return 0;
}

static const struct of_device_id bcm63xx_of_match[] = {
	{ .compatible = "brcm,bcm6345-uart" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, bcm63xx_of_match);

/*
 * platform driver stuff
 */
static struct platform_driver bcm_uart_platform_driver = {
	.probe	= bcm_uart_probe,
	.remove	= bcm_uart_remove,
	.driver	= {
		.name  = "bcm63xx_uart",
		.of_match_table = bcm63xx_of_match,
	},
};

static int __init bcm_uart_init(void)
{
	int ret;

	ret = uart_register_driver(&bcm_uart_driver);
	if (ret)
		return ret;

	ret = platform_driver_register(&bcm_uart_platform_driver);
	if (ret)
		uart_unregister_driver(&bcm_uart_driver);

	return ret;
}

static void __exit bcm_uart_exit(void)
{
	platform_driver_unregister(&bcm_uart_platform_driver);
	uart_unregister_driver(&bcm_uart_driver);
}

module_init(bcm_uart_init);
module_exit(bcm_uart_exit);

MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
MODULE_DESCRIPTION("Broadcom 63xx integrated uart driver");
MODULE_LICENSE("GPL");
