/*
 * zs.c: Serial port driver for IOASIC DECstations.
 *
 * Derived from drivers/sbus/char/sunserial.c by Paul Mackerras.
 * Derived from drivers/macintosh/macserial.c by Harald Koerfgen.
 *
 * DECstation changes
 * Copyright (C) 1998-2000 Harald Koerfgen
 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007  Maciej W. Rozycki
 *
 * For the rest of the code the original Copyright applies:
 * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
 *
 *
 * Note: for IOASIC systems the wiring is as follows:
 *
 * mouse/keyboard:
 * DIN-7 MJ-4  signal        SCC
 * 2     1     TxD       <-  A.TxD
 * 3     4     RxD       ->  A.RxD
 *
 * EIA-232/EIA-423:
 * DB-25 MMJ-6 signal        SCC
 * 2     2     TxD       <-  B.TxD
 * 3     5     RxD       ->  B.RxD
 * 4           RTS       <- ~A.RTS
 * 5           CTS       -> ~B.CTS
 * 6     6     DSR       -> ~A.SYNC
 * 8           CD        -> ~B.DCD
 * 12          DSRS(DCE) -> ~A.CTS  (*)
 * 15          TxC       ->  B.TxC
 * 17          RxC       ->  B.RxC
 * 20    1     DTR       <- ~A.DTR
 * 22          RI        -> ~A.DCD
 * 23          DSRS(DTE) <- ~B.RTS
 *
 * (*) EIA-232 defines the signal at this pin to be SCD, while DSRS(DCE)
 *     is shared with DSRS(DTE) at pin 23.
 *
 * As you can immediately notice the wiring of the RTS, DTR and DSR signals
 * is a bit odd.  This makes the handling of port B unnecessarily
 * complicated and prevents the use of some automatic modes of operation.
 */

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

#include <linux/bug.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irqflags.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/system.h>

#include <asm/dec/interrupts.h>
#include <asm/dec/ioasic_addrs.h>
#include <asm/dec/system.h>

#include "zs.h"


MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");
MODULE_DESCRIPTION("DECstation Z85C30 serial driver");
MODULE_LICENSE("GPL");


static char zs_name[] __initdata = "DECstation Z85C30 serial driver version ";
static char zs_version[] __initdata = "0.10";

/*
 * It would be nice to dynamically allocate everything that
 * depends on ZS_NUM_SCCS, so we could support any number of
 * Z85C30s, but for now...
 */
#define ZS_NUM_SCCS	2		/* Max # of ZS chips supported.  */
#define ZS_NUM_CHAN	2		/* 2 channels per chip.  */
#define ZS_CHAN_A	0		/* Index of the channel A.  */
#define ZS_CHAN_B	1		/* Index of the channel B.  */
#define ZS_CHAN_IO_SIZE 8		/* IOMEM space size.  */
#define ZS_CHAN_IO_STRIDE 4		/* Register alignment.  */
#define ZS_CHAN_IO_OFFSET 1		/* The SCC resides on the high byte
					   of the 16-bit IOBUS.  */
#define ZS_CLOCK        7372800 	/* Z85C30 PCLK input clock rate.  */

#define to_zport(uport) container_of(uport, struct zs_port, port)

struct zs_parms {
	resource_size_t scc[ZS_NUM_SCCS];
	int irq[ZS_NUM_SCCS];
};

static struct zs_scc zs_sccs[ZS_NUM_SCCS];

static u8 zs_init_regs[ZS_NUM_REGS] __initdata = {
	0,				/* write 0 */
	PAR_SPEC,			/* write 1 */
	0,				/* write 2 */
	0,				/* write 3 */
	X16CLK | SB1,			/* write 4 */
	0,				/* write 5 */
	0, 0, 0,			/* write 6, 7, 8 */
	MIE | DLC | NV,			/* write 9 */
	NRZ,				/* write 10 */
	TCBR | RCBR,			/* write 11 */
	0, 0,				/* BRG time constant, write 12 + 13 */
	BRSRC | BRENABL,		/* write 14 */
	0,				/* write 15 */
};

/*
 * Debugging.
 */
#undef ZS_DEBUG_REGS


/*
 * Reading and writing Z85C30 registers.
 */
static void recovery_delay(void)
{
	udelay(2);
}

static u8 read_zsreg(struct zs_port *zport, int reg)
{
	void __iomem *control = zport->port.membase + ZS_CHAN_IO_OFFSET;
	u8 retval;

	if (reg != 0) {
		writeb(reg & 0xf, control);
		fast_iob();
		recovery_delay();
	}
	retval = readb(control);
	recovery_delay();
	return retval;
}

static void write_zsreg(struct zs_port *zport, int reg, u8 value)
{
	void __iomem *control = zport->port.membase + ZS_CHAN_IO_OFFSET;

	if (reg != 0) {
		writeb(reg & 0xf, control);
		fast_iob(); recovery_delay();
	}
	writeb(value, control);
	fast_iob();
	recovery_delay();
	return;
}

static u8 read_zsdata(struct zs_port *zport)
{
	void __iomem *data = zport->port.membase +
			     ZS_CHAN_IO_STRIDE + ZS_CHAN_IO_OFFSET;
	u8 retval;

	retval = readb(data);
	recovery_delay();
	return retval;
}

static void write_zsdata(struct zs_port *zport, u8 value)
{
	void __iomem *data = zport->port.membase +
			     ZS_CHAN_IO_STRIDE + ZS_CHAN_IO_OFFSET;

	writeb(value, data);
	fast_iob();
	recovery_delay();
	return;
}

#ifdef ZS_DEBUG_REGS
void zs_dump(void)
{
	struct zs_port *zport;
	int i, j;

	for (i = 0; i < ZS_NUM_SCCS * ZS_NUM_CHAN; i++) {
		zport = &zs_sccs[i / ZS_NUM_CHAN].zport[i % ZS_NUM_CHAN];

		if (!zport->scc)
			continue;

		for (j = 0; j < 16; j++)
			printk("W%-2d = 0x%02x\t", j, zport->regs[j]);
		printk("\n");
		for (j = 0; j < 16; j++)
			printk("R%-2d = 0x%02x\t", j, read_zsreg(zport, j));
		printk("\n\n");
	}
}
#endif


static void zs_spin_lock_cond_irq(spinlock_t *lock, int irq)
{
	if (irq)
		spin_lock_irq(lock);
	else
		spin_lock(lock);
}

static void zs_spin_unlock_cond_irq(spinlock_t *lock, int irq)
{
	if (irq)
		spin_unlock_irq(lock);
	else
		spin_unlock(lock);
}

static int zs_receive_drain(struct zs_port *zport)
{
	int loops = 10000;

	while ((read_zsreg(zport, R0) & Rx_CH_AV) && loops--)
		read_zsdata(zport);
	return loops;
}

static int zs_transmit_drain(struct zs_port *zport, int irq)
{
	struct zs_scc *scc = zport->scc;
	int loops = 10000;

	while (!(read_zsreg(zport, R0) & Tx_BUF_EMP) && loops--) {
		zs_spin_unlock_cond_irq(&scc->zlock, irq);
		udelay(2);
		zs_spin_lock_cond_irq(&scc->zlock, irq);
	}
	return loops;
}

static int zs_line_drain(struct zs_port *zport, int irq)
{
	struct zs_scc *scc = zport->scc;
	int loops = 10000;

	while (!(read_zsreg(zport, R1) & ALL_SNT) && loops--) {
		zs_spin_unlock_cond_irq(&scc->zlock, irq);
		udelay(2);
		zs_spin_lock_cond_irq(&scc->zlock, irq);
	}
	return loops;
}


static void load_zsregs(struct zs_port *zport, u8 *regs, int irq)
{
	/* Let the current transmission finish.  */
	zs_line_drain(zport, irq);
	/* Load 'em up.  */
	write_zsreg(zport, R3, regs[3] & ~RxENABLE);
	write_zsreg(zport, R5, regs[5] & ~TxENAB);
	write_zsreg(zport, R4, regs[4]);
	write_zsreg(zport, R9, regs[9]);
	write_zsreg(zport, R1, regs[1]);
	write_zsreg(zport, R2, regs[2]);
	write_zsreg(zport, R10, regs[10]);
	write_zsreg(zport, R14, regs[14] & ~BRENABL);
	write_zsreg(zport, R11, regs[11]);
	write_zsreg(zport, R12, regs[12]);
	write_zsreg(zport, R13, regs[13]);
	write_zsreg(zport, R14, regs[14]);
	write_zsreg(zport, R15, regs[15]);
	if (regs[3] & RxENABLE)
		write_zsreg(zport, R3, regs[3]);
	if (regs[5] & TxENAB)
		write_zsreg(zport, R5, regs[5]);
	return;
}


/*
 * Status handling routines.
 */

/*
 * zs_tx_empty() -- get the transmitter empty status
 *
 * Purpose: Let user call ioctl() to get info when the UART physically
 * 	    is emptied.  On bus types like RS485, the transmitter must
 * 	    release the bus after transmitting.  This must be done when
 * 	    the transmit shift register is empty, not be done when the
 * 	    transmit holding register is empty.  This functionality
 * 	    allows an RS485 driver to be written in user space.
 */
static unsigned int zs_tx_empty(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	unsigned long flags;
	u8 status;

	spin_lock_irqsave(&scc->zlock, flags);
	status = read_zsreg(zport, R1);
	spin_unlock_irqrestore(&scc->zlock, flags);

	return status & ALL_SNT ? TIOCSER_TEMT : 0;
}

static unsigned int zs_raw_get_ab_mctrl(struct zs_port *zport_a,
					struct zs_port *zport_b)
{
	u8 status_a, status_b;
	unsigned int mctrl;

	status_a = read_zsreg(zport_a, R0);
	status_b = read_zsreg(zport_b, R0);

	mctrl = ((status_b & CTS) ? TIOCM_CTS : 0) |
		((status_b & DCD) ? TIOCM_CAR : 0) |
		((status_a & DCD) ? TIOCM_RNG : 0) |
		((status_a & SYNC_HUNT) ? TIOCM_DSR : 0);

	return mctrl;
}

static unsigned int zs_raw_get_mctrl(struct zs_port *zport)
{
	struct zs_port *zport_a = &zport->scc->zport[ZS_CHAN_A];

	return zport != zport_a ? zs_raw_get_ab_mctrl(zport_a, zport) : 0;
}

static unsigned int zs_raw_xor_mctrl(struct zs_port *zport)
{
	struct zs_port *zport_a = &zport->scc->zport[ZS_CHAN_A];
	unsigned int mmask, mctrl, delta;
	u8 mask_a, mask_b;

	if (zport == zport_a)
		return 0;

	mask_a = zport_a->regs[15];
	mask_b = zport->regs[15];

	mmask = ((mask_b & CTSIE) ? TIOCM_CTS : 0) |
		((mask_b & DCDIE) ? TIOCM_CAR : 0) |
		((mask_a & DCDIE) ? TIOCM_RNG : 0) |
		((mask_a & SYNCIE) ? TIOCM_DSR : 0);

	mctrl = zport->mctrl;
	if (mmask) {
		mctrl &= ~mmask;
		mctrl |= zs_raw_get_ab_mctrl(zport_a, zport) & mmask;
	}

	delta = mctrl ^ zport->mctrl;
	if (delta)
		zport->mctrl = mctrl;

	return delta;
}

static unsigned int zs_get_mctrl(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	unsigned int mctrl;

	spin_lock(&scc->zlock);
	mctrl = zs_raw_get_mctrl(zport);
	spin_unlock(&scc->zlock);

	return mctrl;
}

static void zs_set_mctrl(struct uart_port *uport, unsigned int mctrl)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	struct zs_port *zport_a = &scc->zport[ZS_CHAN_A];
	u8 oldloop, newloop;

	spin_lock(&scc->zlock);
	if (zport != zport_a) {
		if (mctrl & TIOCM_DTR)
			zport_a->regs[5] |= DTR;
		else
			zport_a->regs[5] &= ~DTR;
		if (mctrl & TIOCM_RTS)
			zport_a->regs[5] |= RTS;
		else
			zport_a->regs[5] &= ~RTS;
		write_zsreg(zport_a, R5, zport_a->regs[5]);
	}

	/* Rarely modified, so don't poke at hardware unless necessary. */
	oldloop = zport->regs[14];
	newloop = oldloop;
	if (mctrl & TIOCM_LOOP)
		newloop |= LOOPBAK;
	else
		newloop &= ~LOOPBAK;
	if (newloop != oldloop) {
		zport->regs[14] = newloop;
		write_zsreg(zport, R14, zport->regs[14]);
	}
	spin_unlock(&scc->zlock);
}

static void zs_raw_stop_tx(struct zs_port *zport)
{
	write_zsreg(zport, R0, RES_Tx_P);
	zport->tx_stopped = 1;
}

static void zs_stop_tx(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;

	spin_lock(&scc->zlock);
	zs_raw_stop_tx(zport);
	spin_unlock(&scc->zlock);
}

static void zs_raw_transmit_chars(struct zs_port *);

static void zs_start_tx(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;

	spin_lock(&scc->zlock);
	if (zport->tx_stopped) {
		zs_transmit_drain(zport, 0);
		zport->tx_stopped = 0;
		zs_raw_transmit_chars(zport);
	}
	spin_unlock(&scc->zlock);
}

static void zs_stop_rx(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	struct zs_port *zport_a = &scc->zport[ZS_CHAN_A];

	spin_lock(&scc->zlock);
	zport->regs[15] &= ~BRKIE;
	zport->regs[1] &= ~(RxINT_MASK | TxINT_ENAB);
	zport->regs[1] |= RxINT_DISAB;

	if (zport != zport_a) {
		/* A-side DCD tracks RI and SYNC tracks DSR.  */
		zport_a->regs[15] &= ~(DCDIE | SYNCIE);
		write_zsreg(zport_a, R15, zport_a->regs[15]);
		if (!(zport_a->regs[15] & BRKIE)) {
			zport_a->regs[1] &= ~EXT_INT_ENAB;
			write_zsreg(zport_a, R1, zport_a->regs[1]);
		}

		/* This-side DCD tracks DCD and CTS tracks CTS.  */
		zport->regs[15] &= ~(DCDIE | CTSIE);
		zport->regs[1] &= ~EXT_INT_ENAB;
	} else {
		/* DCD tracks RI and SYNC tracks DSR for the B side.  */
		if (!(zport->regs[15] & (DCDIE | SYNCIE)))
			zport->regs[1] &= ~EXT_INT_ENAB;
	}

	write_zsreg(zport, R15, zport->regs[15]);
	write_zsreg(zport, R1, zport->regs[1]);
	spin_unlock(&scc->zlock);
}

static void zs_enable_ms(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	struct zs_port *zport_a = &scc->zport[ZS_CHAN_A];

	if (zport == zport_a)
		return;

	spin_lock(&scc->zlock);

	/* Clear Ext interrupts if not being handled already.  */
	if (!(zport_a->regs[1] & EXT_INT_ENAB))
		write_zsreg(zport_a, R0, RES_EXT_INT);

	/* A-side DCD tracks RI and SYNC tracks DSR.  */
	zport_a->regs[1] |= EXT_INT_ENAB;
	zport_a->regs[15] |= DCDIE | SYNCIE;

	/* This-side DCD tracks DCD and CTS tracks CTS.  */
	zport->regs[15] |= DCDIE | CTSIE;

	zs_raw_xor_mctrl(zport);

	write_zsreg(zport_a, R1, zport_a->regs[1]);
	write_zsreg(zport_a, R15, zport_a->regs[15]);
	write_zsreg(zport, R15, zport->regs[15]);
	spin_unlock(&scc->zlock);
}

static void zs_break_ctl(struct uart_port *uport, int break_state)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	unsigned long flags;

	spin_lock_irqsave(&scc->zlock, flags);
	if (break_state == -1)
		zport->regs[5] |= SND_BRK;
	else
		zport->regs[5] &= ~SND_BRK;
	write_zsreg(zport, R5, zport->regs[5]);
	spin_unlock_irqrestore(&scc->zlock, flags);
}


/*
 * Interrupt handling routines.
 */
#define Rx_BRK 0x0100			/* BREAK event software flag.  */
#define Rx_SYS 0x0200			/* SysRq event software flag.  */

static void zs_receive_chars(struct zs_port *zport)
{
	struct uart_port *uport = &zport->port;
	struct zs_scc *scc = zport->scc;
	struct uart_icount *icount;
	unsigned int avail, status, ch, flag;
	int count;

	for (count = 16; count; count--) {
		spin_lock(&scc->zlock);
		avail = read_zsreg(zport, R0) & Rx_CH_AV;
		spin_unlock(&scc->zlock);
		if (!avail)
			break;

		spin_lock(&scc->zlock);
		status = read_zsreg(zport, R1) & (Rx_OVR | FRM_ERR | PAR_ERR);
		ch = read_zsdata(zport);
		spin_unlock(&scc->zlock);

		flag = TTY_NORMAL;

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

		/* Handle the null char got when BREAK is removed.  */
		if (!ch)
			status |= zport->tty_break;
		if (unlikely(status &
			     (Rx_OVR | FRM_ERR | PAR_ERR | Rx_SYS | Rx_BRK))) {
			zport->tty_break = 0;

			/* Reset the error indication.  */
			if (status & (Rx_OVR | FRM_ERR | PAR_ERR)) {
				spin_lock(&scc->zlock);
				write_zsreg(zport, R0, ERR_RES);
				spin_unlock(&scc->zlock);
			}

			if (status & (Rx_SYS | Rx_BRK)) {
				icount->brk++;
				/* SysRq discards the null char.  */
				if (status & Rx_SYS)
					continue;
			} else if (status & FRM_ERR)
				icount->frame++;
			else if (status & PAR_ERR)
				icount->parity++;
			if (status & Rx_OVR)
				icount->overrun++;

			status &= uport->read_status_mask;
			if (status & Rx_BRK)
				flag = TTY_BREAK;
			else if (status & FRM_ERR)
				flag = TTY_FRAME;
			else if (status & PAR_ERR)
				flag = TTY_PARITY;
		}

		if (uart_handle_sysrq_char(uport, ch))
			continue;

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

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

static void zs_raw_transmit_chars(struct zs_port *zport)
{
	struct circ_buf *xmit = &zport->port.info->xmit;

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

	/* If nothing to do or stopped or hardware stopped.  */
	if (uart_circ_empty(xmit) || uart_tx_stopped(&zport->port)) {
		zs_raw_stop_tx(zport);
		return;
	}

	/* Send char.  */
	write_zsdata(zport, xmit->buf[xmit->tail]);
	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
	zport->port.icount.tx++;

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

	/* Are we are done?  */
	if (uart_circ_empty(xmit))
		zs_raw_stop_tx(zport);
}

static void zs_transmit_chars(struct zs_port *zport)
{
	struct zs_scc *scc = zport->scc;

	spin_lock(&scc->zlock);
	zs_raw_transmit_chars(zport);
	spin_unlock(&scc->zlock);
}

static void zs_status_handle(struct zs_port *zport, struct zs_port *zport_a)
{
	struct uart_port *uport = &zport->port;
	struct zs_scc *scc = zport->scc;
	unsigned int delta;
	u8 status, brk;

	spin_lock(&scc->zlock);

	/* Get status from Read Register 0.  */
	status = read_zsreg(zport, R0);

	if (zport->regs[15] & BRKIE) {
		brk = status & BRK_ABRT;
		if (brk && !zport->brk) {
			spin_unlock(&scc->zlock);
			if (uart_handle_break(uport))
				zport->tty_break = Rx_SYS;
			else
				zport->tty_break = Rx_BRK;
			spin_lock(&scc->zlock);
		}
		zport->brk = brk;
	}

	if (zport != zport_a) {
		delta = zs_raw_xor_mctrl(zport);
		spin_unlock(&scc->zlock);

		if (delta & TIOCM_CTS)
			uart_handle_cts_change(uport,
					       zport->mctrl & TIOCM_CTS);
		if (delta & TIOCM_CAR)
			uart_handle_dcd_change(uport,
					       zport->mctrl & TIOCM_CAR);
		if (delta & TIOCM_RNG)
			uport->icount.dsr++;
		if (delta & TIOCM_DSR)
			uport->icount.rng++;

		if (delta)
			wake_up_interruptible(&uport->info->delta_msr_wait);

		spin_lock(&scc->zlock);
	}

	/* Clear the status condition...  */
	write_zsreg(zport, R0, RES_EXT_INT);

	spin_unlock(&scc->zlock);
}

/*
 * This is the Z85C30 driver's generic interrupt routine.
 */
static irqreturn_t zs_interrupt(int irq, void *dev_id)
{
	struct zs_scc *scc = dev_id;
	struct zs_port *zport_a = &scc->zport[ZS_CHAN_A];
	struct zs_port *zport_b = &scc->zport[ZS_CHAN_B];
	irqreturn_t status = IRQ_NONE;
	u8 zs_intreg;
	int count;

	/*
	 * NOTE: The read register 3, which holds the irq status,
	 *       does so for both channels on each chip.  Although
	 *       the status value itself must be read from the A
	 *       channel and is only valid when read from channel A.
	 *       Yes... broken hardware...
	 */
	for (count = 16; count; count--) {
		spin_lock(&scc->zlock);
		zs_intreg = read_zsreg(zport_a, R3);
		spin_unlock(&scc->zlock);
		if (!zs_intreg)
			break;

		/*
		 * We do not like losing characters, so we prioritise
		 * interrupt sources a little bit differently than
		 * the SCC would, was it allowed to.
		 */
		if (zs_intreg & CHBRxIP)
			zs_receive_chars(zport_b);
		if (zs_intreg & CHARxIP)
			zs_receive_chars(zport_a);
		if (zs_intreg & CHBEXT)
			zs_status_handle(zport_b, zport_a);
		if (zs_intreg & CHAEXT)
			zs_status_handle(zport_a, zport_a);
		if (zs_intreg & CHBTxIP)
			zs_transmit_chars(zport_b);
		if (zs_intreg & CHATxIP)
			zs_transmit_chars(zport_a);

		status = IRQ_HANDLED;
	}

	return status;
}


/*
 * Finally, routines used to initialize the serial port.
 */
static int zs_startup(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	unsigned long flags;
	int irq_guard;
	int ret;

	irq_guard = atomic_add_return(1, &scc->irq_guard);
	if (irq_guard == 1) {
		ret = request_irq(zport->port.irq, zs_interrupt,
				  IRQF_SHARED, "scc", scc);
		if (ret) {
			atomic_add(-1, &scc->irq_guard);
			printk(KERN_ERR "zs: can't get irq %d\n",
			       zport->port.irq);
			return ret;
		}
	}

	spin_lock_irqsave(&scc->zlock, flags);

	/* Clear the receive FIFO.  */
	zs_receive_drain(zport);

	/* Clear the interrupt registers.  */
	write_zsreg(zport, R0, ERR_RES);
	write_zsreg(zport, R0, RES_Tx_P);
	/* But Ext only if not being handled already.  */
	if (!(zport->regs[1] & EXT_INT_ENAB))
		write_zsreg(zport, R0, RES_EXT_INT);

	/* Finally, enable sequencing and interrupts.  */
	zport->regs[1] &= ~RxINT_MASK;
	zport->regs[1] |= RxINT_ALL | TxINT_ENAB | EXT_INT_ENAB;
	zport->regs[3] |= RxENABLE;
	zport->regs[15] |= BRKIE;
	write_zsreg(zport, R1, zport->regs[1]);
	write_zsreg(zport, R3, zport->regs[3]);
	write_zsreg(zport, R5, zport->regs[5]);
	write_zsreg(zport, R15, zport->regs[15]);

	/* Record the current state of RR0.  */
	zport->mctrl = zs_raw_get_mctrl(zport);
	zport->brk = read_zsreg(zport, R0) & BRK_ABRT;

	zport->tx_stopped = 1;

	spin_unlock_irqrestore(&scc->zlock, flags);

	return 0;
}

static void zs_shutdown(struct uart_port *uport)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	unsigned long flags;
	int irq_guard;

	spin_lock_irqsave(&scc->zlock, flags);

	zport->regs[3] &= ~RxENABLE;
	write_zsreg(zport, R5, zport->regs[5]);
	write_zsreg(zport, R3, zport->regs[3]);

	spin_unlock_irqrestore(&scc->zlock, flags);

	irq_guard = atomic_add_return(-1, &scc->irq_guard);
	if (!irq_guard)
		free_irq(zport->port.irq, scc);
}


static void zs_reset(struct zs_port *zport)
{
	struct zs_scc *scc = zport->scc;
	int irq;
	unsigned long flags;

	spin_lock_irqsave(&scc->zlock, flags);
	irq = !irqs_disabled_flags(flags);
	if (!scc->initialised) {
		/* Reset the pointer first, just in case...  */
		read_zsreg(zport, R0);
		/* And let the current transmission finish.  */
		zs_line_drain(zport, irq);
		write_zsreg(zport, R9, FHWRES);
		udelay(10);
		write_zsreg(zport, R9, 0);
		scc->initialised = 1;
	}
	load_zsregs(zport, zport->regs, irq);
	spin_unlock_irqrestore(&scc->zlock, flags);
}

static void zs_set_termios(struct uart_port *uport, struct ktermios *termios,
			   struct ktermios *old_termios)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	struct zs_port *zport_a = &scc->zport[ZS_CHAN_A];
	int irq;
	unsigned int baud, brg;
	unsigned long flags;

	spin_lock_irqsave(&scc->zlock, flags);
	irq = !irqs_disabled_flags(flags);

	/* Byte size.  */
	zport->regs[3] &= ~RxNBITS_MASK;
	zport->regs[5] &= ~TxNBITS_MASK;
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		zport->regs[3] |= Rx5;
		zport->regs[5] |= Tx5;
		break;
	case CS6:
		zport->regs[3] |= Rx6;
		zport->regs[5] |= Tx6;
		break;
	case CS7:
		zport->regs[3] |= Rx7;
		zport->regs[5] |= Tx7;
		break;
	case CS8:
	default:
		zport->regs[3] |= Rx8;
		zport->regs[5] |= Tx8;
		break;
	}

	/* Parity and stop bits.  */
	zport->regs[4] &= ~(XCLK_MASK | SB_MASK | PAR_ENA | PAR_EVEN);
	if (termios->c_cflag & CSTOPB)
		zport->regs[4] |= SB2;
	else
		zport->regs[4] |= SB1;
	if (termios->c_cflag & PARENB)
		zport->regs[4] |= PAR_ENA;
	if (!(termios->c_cflag & PARODD))
		zport->regs[4] |= PAR_EVEN;
	switch (zport->clk_mode) {
	case 64:
		zport->regs[4] |= X64CLK;
		break;
	case 32:
		zport->regs[4] |= X32CLK;
		break;
	case 16:
		zport->regs[4] |= X16CLK;
		break;
	case 1:
		zport->regs[4] |= X1CLK;
		break;
	default:
		BUG();
	}

	baud = uart_get_baud_rate(uport, termios, old_termios, 0,
				  uport->uartclk / zport->clk_mode / 4);

	brg = ZS_BPS_TO_BRG(baud, uport->uartclk / zport->clk_mode);
	zport->regs[12] = brg & 0xff;
	zport->regs[13] = (brg >> 8) & 0xff;

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

	uport->read_status_mask = Rx_OVR;
	if (termios->c_iflag & INPCK)
		uport->read_status_mask |= FRM_ERR | PAR_ERR;
	if (termios->c_iflag & (BRKINT | PARMRK))
		uport->read_status_mask |= Rx_BRK;

	uport->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		uport->ignore_status_mask |= FRM_ERR | PAR_ERR;
	if (termios->c_iflag & IGNBRK) {
		uport->ignore_status_mask |= Rx_BRK;
		if (termios->c_iflag & IGNPAR)
			uport->ignore_status_mask |= Rx_OVR;
	}

	if (termios->c_cflag & CREAD)
		zport->regs[3] |= RxENABLE;
	else
		zport->regs[3] &= ~RxENABLE;

	if (zport != zport_a) {
		if (!(termios->c_cflag & CLOCAL)) {
			zport->regs[15] |= DCDIE;
		} else
			zport->regs[15] &= ~DCDIE;
		if (termios->c_cflag & CRTSCTS) {
			zport->regs[15] |= CTSIE;
		} else
			zport->regs[15] &= ~CTSIE;
		zs_raw_xor_mctrl(zport);
	}

	/* Load up the new values.  */
	load_zsregs(zport, zport->regs, irq);

	spin_unlock_irqrestore(&scc->zlock, flags);
}

/*
 * Hack alert!
 * Required solely so that the initial PROM-based console
 * works undisturbed in parallel with this one.
 */
static void zs_pm(struct uart_port *uport, unsigned int state,
		  unsigned int oldstate)
{
	struct zs_port *zport = to_zport(uport);

	if (state < 3)
		zport->regs[5] |= TxENAB;
	else
		zport->regs[5] &= ~TxENAB;
	write_zsreg(zport, R5, zport->regs[5]);
}


static const char *zs_type(struct uart_port *uport)
{
	return "Z85C30 SCC";
}

static void zs_release_port(struct uart_port *uport)
{
	iounmap(uport->membase);
	uport->membase = 0;
	release_mem_region(uport->mapbase, ZS_CHAN_IO_SIZE);
}

static int zs_map_port(struct uart_port *uport)
{
	if (!uport->membase)
		uport->membase = ioremap_nocache(uport->mapbase,
						 ZS_CHAN_IO_SIZE);
	if (!uport->membase) {
		printk(KERN_ERR "zs: Cannot map MMIO\n");
		return -ENOMEM;
	}
	return 0;
}

static int zs_request_port(struct uart_port *uport)
{
	int ret;

	if (!request_mem_region(uport->mapbase, ZS_CHAN_IO_SIZE, "scc")) {
		printk(KERN_ERR "zs: Unable to reserve MMIO resource\n");
		return -EBUSY;
	}
	ret = zs_map_port(uport);
	if (ret) {
		release_mem_region(uport->mapbase, ZS_CHAN_IO_SIZE);
		return ret;
	}
	return 0;
}

static void zs_config_port(struct uart_port *uport, int flags)
{
	struct zs_port *zport = to_zport(uport);

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

		uport->type = PORT_ZS;

		zs_reset(zport);
	}
}

static int zs_verify_port(struct uart_port *uport, struct serial_struct *ser)
{
	struct zs_port *zport = to_zport(uport);
	int ret = 0;

	if (ser->type != PORT_UNKNOWN && ser->type != PORT_ZS)
		ret = -EINVAL;
	if (ser->irq != uport->irq)
		ret = -EINVAL;
	if (ser->baud_base != uport->uartclk / zport->clk_mode / 4)
		ret = -EINVAL;
	return ret;
}


static struct uart_ops zs_ops = {
	.tx_empty	= zs_tx_empty,
	.set_mctrl	= zs_set_mctrl,
	.get_mctrl	= zs_get_mctrl,
	.stop_tx	= zs_stop_tx,
	.start_tx	= zs_start_tx,
	.stop_rx	= zs_stop_rx,
	.enable_ms	= zs_enable_ms,
	.break_ctl	= zs_break_ctl,
	.startup	= zs_startup,
	.shutdown	= zs_shutdown,
	.set_termios	= zs_set_termios,
	.pm		= zs_pm,
	.type		= zs_type,
	.release_port	= zs_release_port,
	.request_port	= zs_request_port,
	.config_port	= zs_config_port,
	.verify_port	= zs_verify_port,
};

/*
 * Initialize Z85C30 port structures.
 */
static int __init zs_probe_sccs(void)
{
	static int probed;
	struct zs_parms zs_parms;
	int chip, side, irq;
	int n_chips = 0;
	int i;

	if (probed)
		return 0;

	irq = dec_interrupt[DEC_IRQ_SCC0];
	if (irq >= 0) {
		zs_parms.scc[n_chips] = IOASIC_SCC0;
		zs_parms.irq[n_chips] = dec_interrupt[DEC_IRQ_SCC0];
		n_chips++;
	}
	irq = dec_interrupt[DEC_IRQ_SCC1];
	if (irq >= 0) {
		zs_parms.scc[n_chips] = IOASIC_SCC1;
		zs_parms.irq[n_chips] = dec_interrupt[DEC_IRQ_SCC1];
		n_chips++;
	}
	if (!n_chips)
		return -ENXIO;

	probed = 1;

	for (chip = 0; chip < n_chips; chip++) {
		spin_lock_init(&zs_sccs[chip].zlock);
		for (side = 0; side < ZS_NUM_CHAN; side++) {
			struct zs_port *zport = &zs_sccs[chip].zport[side];
			struct uart_port *uport = &zport->port;

			zport->scc	= &zs_sccs[chip];
			zport->clk_mode	= 16;

			uport->irq	= zs_parms.irq[chip];
			uport->uartclk	= ZS_CLOCK;
			uport->fifosize	= 1;
			uport->iotype	= UPIO_MEM;
			uport->flags	= UPF_BOOT_AUTOCONF;
			uport->ops	= &zs_ops;
			uport->line	= chip * ZS_NUM_CHAN + side;
			uport->mapbase	= dec_kn_slot_base +
					  zs_parms.scc[chip] +
					  (side ^ ZS_CHAN_B) * ZS_CHAN_IO_SIZE;

			for (i = 0; i < ZS_NUM_REGS; i++)
				zport->regs[i] = zs_init_regs[i];
		}
	}

	return 0;
}


#ifdef CONFIG_SERIAL_ZS_CONSOLE
static void zs_console_putchar(struct uart_port *uport, int ch)
{
	struct zs_port *zport = to_zport(uport);
	struct zs_scc *scc = zport->scc;
	int irq;
	unsigned long flags;

	spin_lock_irqsave(&scc->zlock, flags);
	irq = !irqs_disabled_flags(flags);
	if (zs_transmit_drain(zport, irq))
		write_zsdata(zport, ch);
	spin_unlock_irqrestore(&scc->zlock, flags);
}

/*
 * Print a string to the serial port trying not to disturb
 * any possible real use of the port...
 */
static void zs_console_write(struct console *co, const char *s,
			     unsigned int count)
{
	int chip = co->index / ZS_NUM_CHAN, side = co->index % ZS_NUM_CHAN;
	struct zs_port *zport = &zs_sccs[chip].zport[side];
	struct zs_scc *scc = zport->scc;
	unsigned long flags;
	u8 txint, txenb;
	int irq;

	/* Disable transmit interrupts and enable the transmitter. */
	spin_lock_irqsave(&scc->zlock, flags);
	txint = zport->regs[1];
	txenb = zport->regs[5];
	if (txint & TxINT_ENAB) {
		zport->regs[1] = txint & ~TxINT_ENAB;
		write_zsreg(zport, R1, zport->regs[1]);
	}
	if (!(txenb & TxENAB)) {
		zport->regs[5] = txenb | TxENAB;
		write_zsreg(zport, R5, zport->regs[5]);
	}
	spin_unlock_irqrestore(&scc->zlock, flags);

	uart_console_write(&zport->port, s, count, zs_console_putchar);

	/* Restore transmit interrupts and the transmitter enable. */
	spin_lock_irqsave(&scc->zlock, flags);
	irq = !irqs_disabled_flags(flags);
	zs_line_drain(zport, irq);
	if (!(txenb & TxENAB)) {
		zport->regs[5] &= ~TxENAB;
		write_zsreg(zport, R5, zport->regs[5]);
	}
	if (txint & TxINT_ENAB) {
		zport->regs[1] |= TxINT_ENAB;
		write_zsreg(zport, R1, zport->regs[1]);
	}
	spin_unlock_irqrestore(&scc->zlock, flags);
}

/*
 * Setup serial console baud/bits/parity.  We do two things here:
 * - construct a cflag setting for the first uart_open()
 * - initialise the serial port
 * Return non-zero if we didn't find a serial port.
 */
static int __init zs_console_setup(struct console *co, char *options)
{
	int chip = co->index / ZS_NUM_CHAN, side = co->index % ZS_NUM_CHAN;
	struct zs_port *zport = &zs_sccs[chip].zport[side];
	struct uart_port *uport = &zport->port;
	int baud = 9600;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;

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

	zs_reset(zport);
	zs_pm(uport, 0, -1);

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

static struct uart_driver zs_reg;
static struct console zs_console = {
	.name	= "ttyS",
	.write	= zs_console_write,
	.device	= uart_console_device,
	.setup	= zs_console_setup,
	.flags	= CON_PRINTBUFFER,
	.index	= -1,
	.data	= &zs_reg,
};

/*
 *	Register console.
 */
static int __init zs_serial_console_init(void)
{
	int ret;

	ret = zs_probe_sccs();
	if (ret)
		return ret;
	register_console(&zs_console);

	return 0;
}

console_initcall(zs_serial_console_init);

#define SERIAL_ZS_CONSOLE	&zs_console
#else
#define SERIAL_ZS_CONSOLE	NULL
#endif /* CONFIG_SERIAL_ZS_CONSOLE */

static struct uart_driver zs_reg = {
	.owner			= THIS_MODULE,
	.driver_name		= "serial",
	.dev_name		= "ttyS",
	.major			= TTY_MAJOR,
	.minor			= 64,
	.nr			= ZS_NUM_SCCS * ZS_NUM_CHAN,
	.cons			= SERIAL_ZS_CONSOLE,
};

/* zs_init inits the driver. */
static int __init zs_init(void)
{
	int i, ret;

	pr_info("%s%s\n", zs_name, zs_version);

	/* Find out how many Z85C30 SCCs we have.  */
	ret = zs_probe_sccs();
	if (ret)
		return ret;

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

	for (i = 0; i < ZS_NUM_SCCS * ZS_NUM_CHAN; i++) {
		struct zs_scc *scc = &zs_sccs[i / ZS_NUM_CHAN];
		struct zs_port *zport = &scc->zport[i % ZS_NUM_CHAN];
		struct uart_port *uport = &zport->port;

		if (zport->scc)
			uart_add_one_port(&zs_reg, uport);
	}

	return 0;
}

static void __exit zs_exit(void)
{
	int i;

	for (i = ZS_NUM_SCCS * ZS_NUM_CHAN - 1; i >= 0; i--) {
		struct zs_scc *scc = &zs_sccs[i / ZS_NUM_CHAN];
		struct zs_port *zport = &scc->zport[i % ZS_NUM_CHAN];
		struct uart_port *uport = &zport->port;

		if (zport->scc)
			uart_remove_one_port(&zs_reg, uport);
	}

	uart_unregister_driver(&zs_reg);
}

module_init(zs_init);
module_exit(zs_exit);
