/*
 *	drivers/serial/sb1250-duart.c
 *
 *	Support for the asynchronous serial interface (DUART) included
 *	in the BCM1250 and derived System-On-a-Chip (SOC) devices.
 *
 *	Copyright (c) 2007  Maciej W. Rozycki
 *
 *	Derived from drivers/char/sb1250_duart.c for which the following
 *	copyright applies:
 *
 *	Copyright (c) 2000, 2001, 2002, 2003, 2004  Broadcom Corporation
 *
 *	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.
 *
 *	References:
 *
 *	"BCM1250/BCM1125/BCM1125H User Manual", Broadcom Corporation
 */

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

#include <linux/compiler.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/spinlock.h>
#include <linux/sysrq.h>
#include <linux/tty.h>
#include <linux/types.h>

#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/war.h>

#include <asm/sibyte/sb1250.h>
#include <asm/sibyte/sb1250_uart.h>
#include <asm/sibyte/swarm.h>


#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
#include <asm/sibyte/bcm1480_regs.h>
#include <asm/sibyte/bcm1480_int.h>

#define SBD_CHANREGS(line)	A_BCM1480_DUART_CHANREG((line), 0)
#define SBD_CTRLREGS(line)	A_BCM1480_DUART_CTRLREG((line), 0)
#define SBD_INT(line)		(K_BCM1480_INT_UART_0 + (line))

#define DUART_CHANREG_SPACING	BCM1480_DUART_CHANREG_SPACING

#define R_DUART_IMRREG(line)	R_BCM1480_DUART_IMRREG(line)
#define R_DUART_INCHREG(line)	R_BCM1480_DUART_INCHREG(line)
#define R_DUART_ISRREG(line)	R_BCM1480_DUART_ISRREG(line)

#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_int.h>

#define SBD_CHANREGS(line)	A_DUART_CHANREG((line), 0)
#define SBD_CTRLREGS(line)	A_DUART_CTRLREG(0)
#define SBD_INT(line)		(K_INT_UART_0 + (line))

#else
#error invalid SB1250 UART configuration

#endif


MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");
MODULE_DESCRIPTION("BCM1xxx on-chip DUART serial driver");
MODULE_LICENSE("GPL");


#define DUART_MAX_CHIP 2
#define DUART_MAX_SIDE 2

/*
 * Per-port state.
 */
struct sbd_port {
	struct sbd_duart	*duart;
	struct uart_port	port;
	unsigned char __iomem	*memctrl;
	int			tx_stopped;
	int			initialised;
};

/*
 * Per-DUART state for the shared register space.
 */
struct sbd_duart {
	struct sbd_port		sport[2];
	unsigned long		mapctrl;
	atomic_t		map_guard;
};

#define to_sport(uport) container_of(uport, struct sbd_port, port)

static struct sbd_duart sbd_duarts[DUART_MAX_CHIP];


/*
 * Reading and writing SB1250 DUART registers.
 *
 * There are three register spaces: two per-channel ones and
 * a shared one.  We have to define accessors appropriately.
 * All registers are 64-bit and all but the Baud Rate Clock
 * registers only define 8 least significant bits.  There is
 * also a workaround to take into account.  Raw accessors use
 * the full register width, but cooked ones truncate it
 * intentionally so that the rest of the driver does not care.
 */
static u64 __read_sbdchn(struct sbd_port *sport, int reg)
{
	void __iomem *csr = sport->port.membase + reg;

	return __raw_readq(csr);
}

static u64 __read_sbdshr(struct sbd_port *sport, int reg)
{
	void __iomem *csr = sport->memctrl + reg;

	return __raw_readq(csr);
}

static void __write_sbdchn(struct sbd_port *sport, int reg, u64 value)
{
	void __iomem *csr = sport->port.membase + reg;

	__raw_writeq(value, csr);
}

static void __write_sbdshr(struct sbd_port *sport, int reg, u64 value)
{
	void __iomem *csr = sport->memctrl + reg;

	__raw_writeq(value, csr);
}

/*
 * In bug 1956, we get glitches that can mess up uart registers.  This
 * "read-mode-reg after any register access" is an accepted workaround.
 */
static void __war_sbd1956(struct sbd_port *sport)
{
	__read_sbdchn(sport, R_DUART_MODE_REG_1);
	__read_sbdchn(sport, R_DUART_MODE_REG_2);
}

static unsigned char read_sbdchn(struct sbd_port *sport, int reg)
{
	unsigned char retval;

	retval = __read_sbdchn(sport, reg);
	if (SIBYTE_1956_WAR)
		__war_sbd1956(sport);
	return retval;
}

static unsigned char read_sbdshr(struct sbd_port *sport, int reg)
{
	unsigned char retval;

	retval = __read_sbdshr(sport, reg);
	if (SIBYTE_1956_WAR)
		__war_sbd1956(sport);
	return retval;
}

static void write_sbdchn(struct sbd_port *sport, int reg, unsigned int value)
{
	__write_sbdchn(sport, reg, value);
	if (SIBYTE_1956_WAR)
		__war_sbd1956(sport);
}

static void write_sbdshr(struct sbd_port *sport, int reg, unsigned int value)
{
	__write_sbdshr(sport, reg, value);
	if (SIBYTE_1956_WAR)
		__war_sbd1956(sport);
}


static int sbd_receive_ready(struct sbd_port *sport)
{
	return read_sbdchn(sport, R_DUART_STATUS) & M_DUART_RX_RDY;
}

static int sbd_receive_drain(struct sbd_port *sport)
{
	int loops = 10000;

	while (sbd_receive_ready(sport) && loops--)
		read_sbdchn(sport, R_DUART_RX_HOLD);
	return loops;
}

static int __maybe_unused sbd_transmit_ready(struct sbd_port *sport)
{
	return read_sbdchn(sport, R_DUART_STATUS) & M_DUART_TX_RDY;
}

static int __maybe_unused sbd_transmit_drain(struct sbd_port *sport)
{
	int loops = 10000;

	while (!sbd_transmit_ready(sport) && loops--)
		udelay(2);
	return loops;
}

static int sbd_transmit_empty(struct sbd_port *sport)
{
	return read_sbdchn(sport, R_DUART_STATUS) & M_DUART_TX_EMT;
}

static int sbd_line_drain(struct sbd_port *sport)
{
	int loops = 10000;

	while (!sbd_transmit_empty(sport) && loops--)
		udelay(2);
	return loops;
}


static unsigned int sbd_tx_empty(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);

	return sbd_transmit_empty(sport) ? TIOCSER_TEMT : 0;
}

static unsigned int sbd_get_mctrl(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int mctrl, status;

	status = read_sbdshr(sport, R_DUART_IN_PORT);
	status >>= (uport->line) % 2;
	mctrl = (!(status & M_DUART_IN_PIN0_VAL) ? TIOCM_CTS : 0) |
		(!(status & M_DUART_IN_PIN4_VAL) ? TIOCM_CAR : 0) |
		(!(status & M_DUART_RIN0_PIN) ? TIOCM_RNG : 0) |
		(!(status & M_DUART_IN_PIN2_VAL) ? TIOCM_DSR : 0);
	return mctrl;
}

static void sbd_set_mctrl(struct uart_port *uport, unsigned int mctrl)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int clr = 0, set = 0, mode2;

	if (mctrl & TIOCM_DTR)
		set |= M_DUART_SET_OPR2;
	else
		clr |= M_DUART_CLR_OPR2;
	if (mctrl & TIOCM_RTS)
		set |= M_DUART_SET_OPR0;
	else
		clr |= M_DUART_CLR_OPR0;
	clr <<= (uport->line) % 2;
	set <<= (uport->line) % 2;

	mode2 = read_sbdchn(sport, R_DUART_MODE_REG_2);
	mode2 &= ~M_DUART_CHAN_MODE;
	if (mctrl & TIOCM_LOOP)
		mode2 |= V_DUART_CHAN_MODE_LCL_LOOP;
	else
		mode2 |= V_DUART_CHAN_MODE_NORMAL;

	write_sbdshr(sport, R_DUART_CLEAR_OPR, clr);
	write_sbdshr(sport, R_DUART_SET_OPR, set);
	write_sbdchn(sport, R_DUART_MODE_REG_2, mode2);
}

static void sbd_stop_tx(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);

	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS);
	sport->tx_stopped = 1;
};

static void sbd_start_tx(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int mask;

	/* Enable tx interrupts.  */
	mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
	mask |= M_DUART_IMR_TX;
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);

	/* Go!, go!, go!...  */
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN);
	sport->tx_stopped = 0;
};

static void sbd_stop_rx(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);

	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), 0);
};

static void sbd_enable_ms(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);

	write_sbdchn(sport, R_DUART_AUXCTL_X,
		     M_DUART_CIN_CHNG_ENA | M_DUART_CTS_CHNG_ENA);
}

static void sbd_break_ctl(struct uart_port *uport, int break_state)
{
	struct sbd_port *sport = to_sport(uport);

	if (break_state == -1)
		write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_START_BREAK);
	else
		write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_STOP_BREAK);
}


static void sbd_receive_chars(struct sbd_port *sport)
{
	struct uart_port *uport = &sport->port;
	struct uart_icount *icount;
	unsigned int status, ch, flag;
	int count;

	for (count = 16; count; count--) {
		status = read_sbdchn(sport, R_DUART_STATUS);
		if (!(status & M_DUART_RX_RDY))
			break;

		ch = read_sbdchn(sport, R_DUART_RX_HOLD);

		flag = TTY_NORMAL;

		icount = &uport->icount;
		icount->rx++;

		if (unlikely(status &
			     (M_DUART_RCVD_BRK | M_DUART_FRM_ERR |
			      M_DUART_PARITY_ERR | M_DUART_OVRUN_ERR))) {
			if (status & M_DUART_RCVD_BRK) {
				icount->brk++;
				if (uart_handle_break(uport))
					continue;
			} else if (status & M_DUART_FRM_ERR)
				icount->frame++;
			else if (status & M_DUART_PARITY_ERR)
				icount->parity++;
			if (status & M_DUART_OVRUN_ERR)
				icount->overrun++;

			status &= uport->read_status_mask;
			if (status & M_DUART_RCVD_BRK)
				flag = TTY_BREAK;
			else if (status & M_DUART_FRM_ERR)
				flag = TTY_FRAME;
			else if (status & M_DUART_PARITY_ERR)
				flag = TTY_PARITY;
		}

		if (uart_handle_sysrq_char(uport, ch))
			continue;

		uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag);
	}

	tty_flip_buffer_push(uport->info->tty);
}

static void sbd_transmit_chars(struct sbd_port *sport)
{
	struct uart_port *uport = &sport->port;
	struct circ_buf *xmit = &sport->port.info->xmit;
	unsigned int mask;
	int stop_tx;

	/* XON/XOFF chars.  */
	if (sport->port.x_char) {
		write_sbdchn(sport, R_DUART_TX_HOLD, sport->port.x_char);
		sport->port.icount.tx++;
		sport->port.x_char = 0;
		return;
	}

	/* If nothing to do or stopped or hardware stopped.  */
	stop_tx = (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port));

	/* Send char.  */
	if (!stop_tx) {
		write_sbdchn(sport, R_DUART_TX_HOLD, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		sport->port.icount.tx++;

		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
			uart_write_wakeup(&sport->port);
	}

	/* Are we are done?  */
	if (stop_tx || uart_circ_empty(xmit)) {
		/* Disable tx interrupts.  */
		mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
		mask &= ~M_DUART_IMR_TX;
		write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);
	}
}

static void sbd_status_handle(struct sbd_port *sport)
{
	struct uart_port *uport = &sport->port;
	unsigned int delta;

	delta = read_sbdshr(sport, R_DUART_INCHREG((uport->line) % 2));
	delta >>= (uport->line) % 2;

	if (delta & (M_DUART_IN_PIN0_VAL << S_DUART_IN_PIN_CHNG))
		uart_handle_cts_change(uport, !(delta & M_DUART_IN_PIN0_VAL));

	if (delta & (M_DUART_IN_PIN2_VAL << S_DUART_IN_PIN_CHNG))
		uport->icount.dsr++;

	if (delta & ((M_DUART_IN_PIN2_VAL | M_DUART_IN_PIN0_VAL) <<
		     S_DUART_IN_PIN_CHNG))
		wake_up_interruptible(&uport->info->delta_msr_wait);
}

static irqreturn_t sbd_interrupt(int irq, void *dev_id)
{
	struct sbd_port *sport = dev_id;
	struct uart_port *uport = &sport->port;
	irqreturn_t status = IRQ_NONE;
	unsigned int intstat;
	int count;

	for (count = 16; count; count--) {
		intstat = read_sbdshr(sport,
				      R_DUART_ISRREG((uport->line) % 2));
		intstat &= read_sbdshr(sport,
				       R_DUART_IMRREG((uport->line) % 2));
		intstat &= M_DUART_ISR_ALL;
		if (!intstat)
			break;

		if (intstat & M_DUART_ISR_RX)
			sbd_receive_chars(sport);
		if (intstat & M_DUART_ISR_IN)
			sbd_status_handle(sport);
		if (intstat & M_DUART_ISR_TX)
			sbd_transmit_chars(sport);

		status = IRQ_HANDLED;
	}

	return status;
}


static int sbd_startup(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int mode1;
	int ret;

	ret = request_irq(sport->port.irq, sbd_interrupt,
			  IRQF_SHARED, "sb1250-duart", sport);
	if (ret)
		return ret;

	/* Clear the receive FIFO.  */
	sbd_receive_drain(sport);

	/* Clear the interrupt registers.  */
	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT);
	read_sbdshr(sport, R_DUART_INCHREG((uport->line) % 2));

	/* Set rx/tx interrupt to FIFO available.  */
	mode1 = read_sbdchn(sport, R_DUART_MODE_REG_1);
	mode1 &= ~(M_DUART_RX_IRQ_SEL_RXFULL | M_DUART_TX_IRQ_SEL_TXEMPT);
	write_sbdchn(sport, R_DUART_MODE_REG_1, mode1);

	/* Disable tx, enable rx.  */
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_EN);
	sport->tx_stopped = 1;

	/* Enable interrupts.  */
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2),
		     M_DUART_IMR_IN | M_DUART_IMR_RX);

	return 0;
}

static void sbd_shutdown(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);

	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_DIS);
	sport->tx_stopped = 1;
	free_irq(sport->port.irq, sport);
}


static void sbd_init_port(struct sbd_port *sport)
{
	struct uart_port *uport = &sport->port;

	if (sport->initialised)
		return;

	/* There is no DUART reset feature, so just set some sane defaults.  */
	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_TX);
	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_RX);
	write_sbdchn(sport, R_DUART_MODE_REG_1, V_DUART_BITS_PER_CHAR_8);
	write_sbdchn(sport, R_DUART_MODE_REG_2, 0);
	write_sbdchn(sport, R_DUART_FULL_CTL,
		     V_DUART_INT_TIME(0) | V_DUART_SIG_FULL(15));
	write_sbdchn(sport, R_DUART_OPCR_X, 0);
	write_sbdchn(sport, R_DUART_AUXCTL_X, 0);
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), 0);

	sport->initialised = 1;
}

static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios,
			    struct ktermios *old_termios)
{
	struct sbd_port *sport = to_sport(uport);
	unsigned int mode1 = 0, mode2 = 0, aux = 0;
	unsigned int mode1mask = 0, mode2mask = 0, auxmask = 0;
	unsigned int oldmode1, oldmode2, oldaux;
	unsigned int baud, brg;
	unsigned int command;

	mode1mask |= ~(M_DUART_PARITY_MODE | M_DUART_PARITY_TYPE_ODD |
		       M_DUART_BITS_PER_CHAR);
	mode2mask |= ~M_DUART_STOP_BIT_LEN_2;
	auxmask |= ~M_DUART_CTS_CHNG_ENA;

	/* Byte size.  */
	switch (termios->c_cflag & CSIZE) {
	case CS5:
	case CS6:
		/* Unsupported, leave unchanged.  */
		mode1mask |= M_DUART_PARITY_MODE;
		break;
	case CS7:
		mode1 |= V_DUART_BITS_PER_CHAR_7;
		break;
	case CS8:
	default:
		mode1 |= V_DUART_BITS_PER_CHAR_8;
		break;
	}

	/* Parity and stop bits.  */
	if (termios->c_cflag & CSTOPB)
		mode2 |= M_DUART_STOP_BIT_LEN_2;
	else
		mode2 |= M_DUART_STOP_BIT_LEN_1;
	if (termios->c_cflag & PARENB)
		mode1 |= V_DUART_PARITY_MODE_ADD;
	else
		mode1 |= V_DUART_PARITY_MODE_NONE;
	if (termios->c_cflag & PARODD)
		mode1 |= M_DUART_PARITY_TYPE_ODD;
	else
		mode1 |= M_DUART_PARITY_TYPE_EVEN;

	baud = uart_get_baud_rate(uport, termios, old_termios, 1200, 5000000);
	brg = V_DUART_BAUD_RATE(baud);
	/* The actual lower bound is 1221bps, so compensate.  */
	if (brg > M_DUART_CLK_COUNTER)
		brg = M_DUART_CLK_COUNTER;

	uart_update_timeout(uport, termios->c_cflag, baud);

	uport->read_status_mask = M_DUART_OVRUN_ERR;
	if (termios->c_iflag & INPCK)
		uport->read_status_mask |= M_DUART_FRM_ERR |
					   M_DUART_PARITY_ERR;
	if (termios->c_iflag & (BRKINT | PARMRK))
		uport->read_status_mask |= M_DUART_RCVD_BRK;

	uport->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		uport->ignore_status_mask |= M_DUART_FRM_ERR |
					     M_DUART_PARITY_ERR;
	if (termios->c_iflag & IGNBRK) {
		uport->ignore_status_mask |= M_DUART_RCVD_BRK;
		if (termios->c_iflag & IGNPAR)
			uport->ignore_status_mask |= M_DUART_OVRUN_ERR;
	}

	if (termios->c_cflag & CREAD)
		command = M_DUART_RX_EN;
	else
		command = M_DUART_RX_DIS;

	if (termios->c_cflag & CRTSCTS)
		aux |= M_DUART_CTS_CHNG_ENA;
	else
		aux &= ~M_DUART_CTS_CHNG_ENA;

	spin_lock(&uport->lock);

	if (sport->tx_stopped)
		command |= M_DUART_TX_DIS;
	else
		command |= M_DUART_TX_EN;

	oldmode1 = read_sbdchn(sport, R_DUART_MODE_REG_1) & mode1mask;
	oldmode2 = read_sbdchn(sport, R_DUART_MODE_REG_2) & mode2mask;
	oldaux = read_sbdchn(sport, R_DUART_AUXCTL_X) & auxmask;

	if (!sport->tx_stopped)
		sbd_line_drain(sport);
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_DIS);

	write_sbdchn(sport, R_DUART_MODE_REG_1, mode1 | oldmode1);
	write_sbdchn(sport, R_DUART_MODE_REG_2, mode2 | oldmode2);
	write_sbdchn(sport, R_DUART_CLK_SEL, brg);
	write_sbdchn(sport, R_DUART_AUXCTL_X, aux | oldaux);

	write_sbdchn(sport, R_DUART_CMD, command);

	spin_unlock(&uport->lock);
}


static const char *sbd_type(struct uart_port *uport)
{
	return "SB1250 DUART";
}

static void sbd_release_port(struct uart_port *uport)
{
	struct sbd_port *sport = to_sport(uport);
	struct sbd_duart *duart = sport->duart;
	int map_guard;

	iounmap(sport->memctrl);
	sport->memctrl = NULL;
	iounmap(uport->membase);
	uport->membase = NULL;

	map_guard = atomic_add_return(-1, &duart->map_guard);
	if (!map_guard)
		release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING);
	release_mem_region(uport->mapbase, DUART_CHANREG_SPACING);
}

static int sbd_map_port(struct uart_port *uport)
{
	const char *err = KERN_ERR "sbd: Cannot map MMIO\n";
	struct sbd_port *sport = to_sport(uport);
	struct sbd_duart *duart = sport->duart;

	if (!uport->membase)
		uport->membase = ioremap_nocache(uport->mapbase,
						 DUART_CHANREG_SPACING);
	if (!uport->membase) {
		printk(err);
		return -ENOMEM;
	}

	if (!sport->memctrl)
		sport->memctrl = ioremap_nocache(duart->mapctrl,
						 DUART_CHANREG_SPACING);
	if (!sport->memctrl) {
		printk(err);
		iounmap(uport->membase);
		uport->membase = NULL;
		return -ENOMEM;
	}

	return 0;
}

static int sbd_request_port(struct uart_port *uport)
{
	const char *err = KERN_ERR "sbd: Unable to reserve MMIO resource\n";
	struct sbd_duart *duart = to_sport(uport)->duart;
	int map_guard;
	int ret = 0;

	if (!request_mem_region(uport->mapbase, DUART_CHANREG_SPACING,
				"sb1250-duart")) {
		printk(err);
		return -EBUSY;
	}
	map_guard = atomic_add_return(1, &duart->map_guard);
	if (map_guard == 1) {
		if (!request_mem_region(duart->mapctrl, DUART_CHANREG_SPACING,
					"sb1250-duart")) {
			atomic_add(-1, &duart->map_guard);
			printk(err);
			ret = -EBUSY;
		}
	}
	if (!ret) {
		ret = sbd_map_port(uport);
		if (ret) {
			map_guard = atomic_add_return(-1, &duart->map_guard);
			if (!map_guard)
				release_mem_region(duart->mapctrl,
						   DUART_CHANREG_SPACING);
		}
	}
	if (ret) {
		release_mem_region(uport->mapbase, DUART_CHANREG_SPACING);
		return ret;
	}
	return 0;
}

static void sbd_config_port(struct uart_port *uport, int flags)
{
	struct sbd_port *sport = to_sport(uport);

	if (flags & UART_CONFIG_TYPE) {
		if (sbd_request_port(uport))
			return;

		uport->type = PORT_SB1250_DUART;

		sbd_init_port(sport);
	}
}

static int sbd_verify_port(struct uart_port *uport, struct serial_struct *ser)
{
	int ret = 0;

	if (ser->type != PORT_UNKNOWN && ser->type != PORT_SB1250_DUART)
		ret = -EINVAL;
	if (ser->irq != uport->irq)
		ret = -EINVAL;
	if (ser->baud_base != uport->uartclk / 16)
		ret = -EINVAL;
	return ret;
}


static const struct uart_ops sbd_ops = {
	.tx_empty	= sbd_tx_empty,
	.set_mctrl	= sbd_set_mctrl,
	.get_mctrl	= sbd_get_mctrl,
	.stop_tx	= sbd_stop_tx,
	.start_tx	= sbd_start_tx,
	.stop_rx	= sbd_stop_rx,
	.enable_ms	= sbd_enable_ms,
	.break_ctl	= sbd_break_ctl,
	.startup	= sbd_startup,
	.shutdown	= sbd_shutdown,
	.set_termios	= sbd_set_termios,
	.type		= sbd_type,
	.release_port	= sbd_release_port,
	.request_port	= sbd_request_port,
	.config_port	= sbd_config_port,
	.verify_port	= sbd_verify_port,
};

/* Initialize SB1250 DUART port structures.  */
static void __init sbd_probe_duarts(void)
{
	static int probed;
	int chip, side;
	int max_lines, line;

	if (probed)
		return;

	/* Set the number of available units based on the SOC type.  */
	switch (soc_type) {
	case K_SYS_SOC_TYPE_BCM1x55:
	case K_SYS_SOC_TYPE_BCM1x80:
		max_lines = 4;
		break;
	default:
		/* Assume at least two serial ports at the normal address.  */
		max_lines = 2;
		break;
	}

	probed = 1;

	for (chip = 0, line = 0; chip < DUART_MAX_CHIP && line < max_lines;
	     chip++) {
		sbd_duarts[chip].mapctrl = SBD_CTRLREGS(line);

		for (side = 0; side < DUART_MAX_SIDE && line < max_lines;
		     side++, line++) {
			struct sbd_port *sport = &sbd_duarts[chip].sport[side];
			struct uart_port *uport = &sport->port;

			sport->duart	= &sbd_duarts[chip];

			uport->irq	= SBD_INT(line);
			uport->uartclk	= 100000000 / 20 * 16;
			uport->fifosize	= 16;
			uport->iotype	= UPIO_MEM;
			uport->flags	= UPF_BOOT_AUTOCONF;
			uport->ops	= &sbd_ops;
			uport->line	= line;
			uport->mapbase	= SBD_CHANREGS(line);
		}
	}
}


#ifdef CONFIG_SERIAL_SB1250_DUART_CONSOLE
/*
 * Serial console stuff.  Very basic, polling driver for doing serial
 * console output.  The console_sem is held by the caller, so we
 * shouldn't be interrupted for more console activity.
 */
static void sbd_console_putchar(struct uart_port *uport, int ch)
{
	struct sbd_port *sport = to_sport(uport);

	sbd_transmit_drain(sport);
	write_sbdchn(sport, R_DUART_TX_HOLD, ch);
}

static void sbd_console_write(struct console *co, const char *s,
			      unsigned int count)
{
	int chip = co->index / DUART_MAX_SIDE;
	int side = co->index % DUART_MAX_SIDE;
	struct sbd_port *sport = &sbd_duarts[chip].sport[side];
	struct uart_port *uport = &sport->port;
	unsigned long flags;
	unsigned int mask;

	/* Disable transmit interrupts and enable the transmitter. */
	spin_lock_irqsave(&uport->lock, flags);
	mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2),
		     mask & ~M_DUART_IMR_TX);
	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN);
	spin_unlock_irqrestore(&uport->lock, flags);

	uart_console_write(&sport->port, s, count, sbd_console_putchar);

	/* Restore transmit interrupts and the transmitter enable. */
	spin_lock_irqsave(&uport->lock, flags);
	sbd_line_drain(sport);
	if (sport->tx_stopped)
		write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS);
	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);
	spin_unlock_irqrestore(&uport->lock, flags);
}

static int __init sbd_console_setup(struct console *co, char *options)
{
	int chip = co->index / DUART_MAX_SIDE;
	int side = co->index % DUART_MAX_SIDE;
	struct sbd_port *sport = &sbd_duarts[chip].sport[side];
	struct uart_port *uport = &sport->port;
	int baud = 115200;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;

	if (!sport->duart)
		return -ENXIO;

	ret = sbd_map_port(uport);
	if (ret)
		return ret;

	sbd_init_port(sport);

	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);
	return uart_set_options(uport, co, baud, parity, bits, flow);
}

static struct uart_driver sbd_reg;
static struct console sbd_console = {
	.name	= "duart",
	.write	= sbd_console_write,
	.device	= uart_console_device,
	.setup	= sbd_console_setup,
	.flags	= CON_PRINTBUFFER,
	.index	= -1,
	.data	= &sbd_reg
};

static int __init sbd_serial_console_init(void)
{
	sbd_probe_duarts();
	register_console(&sbd_console);

	return 0;
}

console_initcall(sbd_serial_console_init);

#define SERIAL_SB1250_DUART_CONSOLE	&sbd_console
#else
#define SERIAL_SB1250_DUART_CONSOLE	NULL
#endif /* CONFIG_SERIAL_SB1250_DUART_CONSOLE */


static struct uart_driver sbd_reg = {
	.owner		= THIS_MODULE,
	.driver_name	= "serial",
	.dev_name	= "duart",
	.major		= TTY_MAJOR,
	.minor		= SB1250_DUART_MINOR_BASE,
	.nr		= DUART_MAX_CHIP * DUART_MAX_SIDE,
	.cons		= SERIAL_SB1250_DUART_CONSOLE,
};

/* Set up the driver and register it.  */
static int __init sbd_init(void)
{
	int i, ret;

	sbd_probe_duarts();

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

	for (i = 0; i < DUART_MAX_CHIP * DUART_MAX_SIDE; i++) {
		struct sbd_duart *duart = &sbd_duarts[i / DUART_MAX_SIDE];
		struct sbd_port *sport = &duart->sport[i % DUART_MAX_SIDE];
		struct uart_port *uport = &sport->port;

		if (sport->duart)
			uart_add_one_port(&sbd_reg, uport);
	}

	return 0;
}

/* Unload the driver.  Unregister stuff, get ready to go away.  */
static void __exit sbd_exit(void)
{
	int i;

	for (i = DUART_MAX_CHIP * DUART_MAX_SIDE - 1; i >= 0; i--) {
		struct sbd_duart *duart = &sbd_duarts[i / DUART_MAX_SIDE];
		struct sbd_port *sport = &duart->sport[i % DUART_MAX_SIDE];
		struct uart_port *uport = &sport->port;

		if (sport->duart)
			uart_remove_one_port(&sbd_reg, uport);
	}

	uart_unregister_driver(&sbd_reg);
}

module_init(sbd_init);
module_exit(sbd_exit);
