/*
 * 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->state->port.tty);
}

static void zs_raw_transmit_chars(struct zs_port *zport)
{
	struct circ_buf *xmit = &zport->port.state->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->state->port.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);
