// SPDX-License-Identifier: GPL-2.0
/*
 * dz.c: Serial port driver for DECstations equipped
 *       with the DZ chipset.
 *
 * Copyright (C) 1998 Olivier A. D. Lebaillif
 *
 * Email: olivier.lebaillif@ifrsys.com
 *
 * Copyright (C) 2004, 2006, 2007  Maciej W. Rozycki
 *
 * [31-AUG-98] triemer
 * Changed IRQ to use Harald's dec internals interrupts.h
 * removed base_addr code - moving address assignment to setup.c
 * Changed name of dz_init to rs_init to be consistent with tc code
 * [13-NOV-98] triemer fixed code to receive characters
 *    after patches by harald to irq code.
 * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
 *            field from "current" - somewhere between 2.1.121 and 2.1.131
 Qua Jun 27 15:02:26 BRT 2001
 * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
 *
 * Parts (C) 1999 David Airlie, airlied@linux.ie
 * [07-SEP-99] Bugfixes
 *
 * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
 * Converted to new serial core
 */

#undef DEBUG_DZ

#include <linux/bitops.h>
#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/module.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/sysrq.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>

#include <linux/atomic.h>
#include <linux/io.h>
#include <asm/bootinfo.h>

#include <asm/dec/interrupts.h>
#include <asm/dec/kn01.h>
#include <asm/dec/kn02.h>
#include <asm/dec/machtype.h>
#include <asm/dec/prom.h>
#include <asm/dec/system.h>

#include "dz.h"


MODULE_DESCRIPTION("DECstation DZ serial driver");
MODULE_LICENSE("GPL");


static char dz_name[] __initdata = "DECstation DZ serial driver version ";
static char dz_version[] __initdata = "1.04";

struct dz_port {
	struct dz_mux		*mux;
	struct uart_port	port;
	unsigned int		cflag;
};

struct dz_mux {
	struct dz_port		dport[DZ_NB_PORT];
	atomic_t		map_guard;
	atomic_t		irq_guard;
	int			initialised;
};

static struct dz_mux dz_mux;

static inline struct dz_port *to_dport(struct uart_port *uport)
{
	return container_of(uport, struct dz_port, port);
}

/*
 * ------------------------------------------------------------
 * dz_in () and dz_out ()
 *
 * These routines are used to access the registers of the DZ
 * chip, hiding relocation differences between implementation.
 * ------------------------------------------------------------
 */

static u16 dz_in(struct dz_port *dport, unsigned offset)
{
	void __iomem *addr = dport->port.membase + offset;

	return readw(addr);
}

static void dz_out(struct dz_port *dport, unsigned offset, u16 value)
{
	void __iomem *addr = dport->port.membase + offset;

	writew(value, addr);
}

/*
 * ------------------------------------------------------------
 * rs_stop () and rs_start ()
 *
 * These routines are called before setting or resetting
 * tty->flow.stopped. They enable or disable transmitter interrupts,
 * as necessary.
 * ------------------------------------------------------------
 */

static void dz_stop_tx(struct uart_port *uport)
{
	struct dz_port *dport = to_dport(uport);
	u16 tmp, mask = 1 << dport->port.line;

	tmp = dz_in(dport, DZ_TCR);	/* read the TX flag */
	tmp &= ~mask;			/* clear the TX flag */
	dz_out(dport, DZ_TCR, tmp);
}

static void dz_start_tx(struct uart_port *uport)
{
	struct dz_port *dport = to_dport(uport);
	u16 tmp, mask = 1 << dport->port.line;

	tmp = dz_in(dport, DZ_TCR);	/* read the TX flag */
	tmp |= mask;			/* set the TX flag */
	dz_out(dport, DZ_TCR, tmp);
}

static void dz_stop_rx(struct uart_port *uport)
{
	struct dz_port *dport = to_dport(uport);

	dport->cflag &= ~DZ_RXENAB;
	dz_out(dport, DZ_LPR, dport->cflag);
}

/*
 * ------------------------------------------------------------
 *
 * Here start the interrupt handling routines.  All of the following
 * subroutines are declared as inline and are folded into
 * dz_interrupt.  They were separated out for readability's sake.
 *
 * Note: dz_interrupt() is a "fast" interrupt, which means that it
 * runs with interrupts turned off.  People who may want to modify
 * dz_interrupt() should try to keep the interrupt handler as fast as
 * possible.  After you are done making modifications, it is not a bad
 * idea to do:
 *
 *	make drivers/serial/dz.s
 *
 * and look at the resulting assemble code in dz.s.
 *
 * ------------------------------------------------------------
 */

/*
 * ------------------------------------------------------------
 * receive_char ()
 *
 * This routine deals with inputs from any lines.
 * ------------------------------------------------------------
 */
static inline void dz_receive_chars(struct dz_mux *mux)
{
	struct uart_port *uport;
	struct dz_port *dport = &mux->dport[0];
	struct uart_icount *icount;
	int lines_rx[DZ_NB_PORT] = { [0 ... DZ_NB_PORT - 1] = 0 };
	unsigned char ch, flag;
	u16 status;
	int i;

	while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
		dport = &mux->dport[LINE(status)];
		uport = &dport->port;

		ch = UCHAR(status);		/* grab the char */
		flag = TTY_NORMAL;

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

		if (unlikely(status & (DZ_OERR | DZ_FERR | DZ_PERR))) {

			/*
			 * There is no separate BREAK status bit, so treat
			 * null characters with framing errors as BREAKs;
			 * normally, otherwise.  For this move the Framing
			 * Error bit to a simulated BREAK bit.
			 */
			if (!ch) {
				status |= (status & DZ_FERR) >>
					  (ffs(DZ_FERR) - ffs(DZ_BREAK));
				status &= ~DZ_FERR;
			}

			/* Handle SysRq/SAK & keep track of the statistics. */
			if (status & DZ_BREAK) {
				icount->brk++;
				if (uart_handle_break(uport))
					continue;
			} else if (status & DZ_FERR)
				icount->frame++;
			else if (status & DZ_PERR)
				icount->parity++;
			if (status & DZ_OERR)
				icount->overrun++;

			status &= uport->read_status_mask;
			if (status & DZ_BREAK)
				flag = TTY_BREAK;
			else if (status & DZ_FERR)
				flag = TTY_FRAME;
			else if (status & DZ_PERR)
				flag = TTY_PARITY;

		}

		if (uart_handle_sysrq_char(uport, ch))
			continue;

		uart_insert_char(uport, status, DZ_OERR, ch, flag);
		lines_rx[LINE(status)] = 1;
	}
	for (i = 0; i < DZ_NB_PORT; i++)
		if (lines_rx[i])
			tty_flip_buffer_push(&mux->dport[i].port.state->port);
}

/*
 * ------------------------------------------------------------
 * transmit_char ()
 *
 * This routine deals with outputs to any lines.
 * ------------------------------------------------------------
 */
static inline void dz_transmit_chars(struct dz_mux *mux)
{
	struct dz_port *dport = &mux->dport[0];
	struct circ_buf *xmit;
	unsigned char tmp;
	u16 status;

	status = dz_in(dport, DZ_CSR);
	dport = &mux->dport[LINE(status)];
	xmit = &dport->port.state->xmit;

	if (dport->port.x_char) {		/* XON/XOFF chars */
		dz_out(dport, DZ_TDR, dport->port.x_char);
		dport->port.icount.tx++;
		dport->port.x_char = 0;
		return;
	}
	/* If nothing to do or stopped or hardware stopped. */
	if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) {
		spin_lock(&dport->port.lock);
		dz_stop_tx(&dport->port);
		spin_unlock(&dport->port.lock);
		return;
	}

	/*
	 * If something to do... (remember the dz has no output fifo,
	 * so we go one char at a time) :-<
	 */
	tmp = xmit->buf[xmit->tail];
	xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1);
	dz_out(dport, DZ_TDR, tmp);
	dport->port.icount.tx++;

	if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS)
		uart_write_wakeup(&dport->port);

	/* Are we are done. */
	if (uart_circ_empty(xmit)) {
		spin_lock(&dport->port.lock);
		dz_stop_tx(&dport->port);
		spin_unlock(&dport->port.lock);
	}
}

/*
 * ------------------------------------------------------------
 * check_modem_status()
 *
 * DS 3100 & 5100: Only valid for the MODEM line, duh!
 * DS 5000/200: Valid for the MODEM and PRINTER line.
 * ------------------------------------------------------------
 */
static inline void check_modem_status(struct dz_port *dport)
{
	/*
	 * FIXME:
	 * 1. No status change interrupt; use a timer.
	 * 2. Handle the 3100/5000 as appropriate. --macro
	 */
	u16 status;

	/* If not the modem line just return.  */
	if (dport->port.line != DZ_MODEM)
		return;

	status = dz_in(dport, DZ_MSR);

	/* it's easy, since DSR2 is the only bit in the register */
	if (status)
		dport->port.icount.dsr++;
}

/*
 * ------------------------------------------------------------
 * dz_interrupt ()
 *
 * this is the main interrupt routine for the DZ chip.
 * It deals with the multiple ports.
 * ------------------------------------------------------------
 */
static irqreturn_t dz_interrupt(int irq, void *dev_id)
{
	struct dz_mux *mux = dev_id;
	struct dz_port *dport = &mux->dport[0];
	u16 status;

	/* get the reason why we just got an irq */
	status = dz_in(dport, DZ_CSR);

	if ((status & (DZ_RDONE | DZ_RIE)) == (DZ_RDONE | DZ_RIE))
		dz_receive_chars(mux);

	if ((status & (DZ_TRDY | DZ_TIE)) == (DZ_TRDY | DZ_TIE))
		dz_transmit_chars(mux);

	return IRQ_HANDLED;
}

/*
 * -------------------------------------------------------------------
 * Here ends the DZ interrupt routines.
 * -------------------------------------------------------------------
 */

static unsigned int dz_get_mctrl(struct uart_port *uport)
{
	/*
	 * FIXME: Handle the 3100/5000 as appropriate. --macro
	 */
	struct dz_port *dport = to_dport(uport);
	unsigned int mctrl = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;

	if (dport->port.line == DZ_MODEM) {
		if (dz_in(dport, DZ_MSR) & DZ_MODEM_DSR)
			mctrl &= ~TIOCM_DSR;
	}

	return mctrl;
}

static void dz_set_mctrl(struct uart_port *uport, unsigned int mctrl)
{
	/*
	 * FIXME: Handle the 3100/5000 as appropriate. --macro
	 */
	struct dz_port *dport = to_dport(uport);
	u16 tmp;

	if (dport->port.line == DZ_MODEM) {
		tmp = dz_in(dport, DZ_TCR);
		if (mctrl & TIOCM_DTR)
			tmp &= ~DZ_MODEM_DTR;
		else
			tmp |= DZ_MODEM_DTR;
		dz_out(dport, DZ_TCR, tmp);
	}
}

/*
 * -------------------------------------------------------------------
 * startup ()
 *
 * various initialization tasks
 * -------------------------------------------------------------------
 */
static int dz_startup(struct uart_port *uport)
{
	struct dz_port *dport = to_dport(uport);
	struct dz_mux *mux = dport->mux;
	unsigned long flags;
	int irq_guard;
	int ret;
	u16 tmp;

	irq_guard = atomic_add_return(1, &mux->irq_guard);
	if (irq_guard != 1)
		return 0;

	ret = request_irq(dport->port.irq, dz_interrupt,
			  IRQF_SHARED, "dz", mux);
	if (ret) {
		atomic_add(-1, &mux->irq_guard);
		printk(KERN_ERR "dz: Cannot get IRQ %d!\n", dport->port.irq);
		return ret;
	}

	spin_lock_irqsave(&dport->port.lock, flags);

	/* Enable interrupts.  */
	tmp = dz_in(dport, DZ_CSR);
	tmp |= DZ_RIE | DZ_TIE;
	dz_out(dport, DZ_CSR, tmp);

	spin_unlock_irqrestore(&dport->port.lock, flags);

	return 0;
}

/*
 * -------------------------------------------------------------------
 * shutdown ()
 *
 * This routine will shutdown a serial port; interrupts are disabled, and
 * DTR is dropped if the hangup on close termio flag is on.
 * -------------------------------------------------------------------
 */
static void dz_shutdown(struct uart_port *uport)
{
	struct dz_port *dport = to_dport(uport);
	struct dz_mux *mux = dport->mux;
	unsigned long flags;
	int irq_guard;
	u16 tmp;

	spin_lock_irqsave(&dport->port.lock, flags);
	dz_stop_tx(&dport->port);
	spin_unlock_irqrestore(&dport->port.lock, flags);

	irq_guard = atomic_add_return(-1, &mux->irq_guard);
	if (!irq_guard) {
		/* Disable interrupts.  */
		tmp = dz_in(dport, DZ_CSR);
		tmp &= ~(DZ_RIE | DZ_TIE);
		dz_out(dport, DZ_CSR, tmp);

		free_irq(dport->port.irq, mux);
	}
}

/*
 * -------------------------------------------------------------------
 * dz_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 dz_tx_empty(struct uart_port *uport)
{
	struct dz_port *dport = to_dport(uport);
	unsigned short tmp, mask = 1 << dport->port.line;

	tmp = dz_in(dport, DZ_TCR);
	tmp &= mask;

	return tmp ? 0 : TIOCSER_TEMT;
}

static void dz_break_ctl(struct uart_port *uport, int break_state)
{
	/*
	 * FIXME: Can't access BREAK bits in TDR easily;
	 * reuse the code for polled TX. --macro
	 */
	struct dz_port *dport = to_dport(uport);
	unsigned long flags;
	unsigned short tmp, mask = 1 << dport->port.line;

	spin_lock_irqsave(&uport->lock, flags);
	tmp = dz_in(dport, DZ_TCR);
	if (break_state)
		tmp |= mask;
	else
		tmp &= ~mask;
	dz_out(dport, DZ_TCR, tmp);
	spin_unlock_irqrestore(&uport->lock, flags);
}

static int dz_encode_baud_rate(unsigned int baud)
{
	switch (baud) {
	case 50:
		return DZ_B50;
	case 75:
		return DZ_B75;
	case 110:
		return DZ_B110;
	case 134:
		return DZ_B134;
	case 150:
		return DZ_B150;
	case 300:
		return DZ_B300;
	case 600:
		return DZ_B600;
	case 1200:
		return DZ_B1200;
	case 1800:
		return DZ_B1800;
	case 2000:
		return DZ_B2000;
	case 2400:
		return DZ_B2400;
	case 3600:
		return DZ_B3600;
	case 4800:
		return DZ_B4800;
	case 7200:
		return DZ_B7200;
	case 9600:
		return DZ_B9600;
	default:
		return -1;
	}
}


static void dz_reset(struct dz_port *dport)
{
	struct dz_mux *mux = dport->mux;

	if (mux->initialised)
		return;

	dz_out(dport, DZ_CSR, DZ_CLR);
	while (dz_in(dport, DZ_CSR) & DZ_CLR);
	iob();

	/* Enable scanning.  */
	dz_out(dport, DZ_CSR, DZ_MSE);

	mux->initialised = 1;
}

static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
			   struct ktermios *old_termios)
{
	struct dz_port *dport = to_dport(uport);
	unsigned long flags;
	unsigned int cflag, baud;
	int bflag;

	cflag = dport->port.line;

	switch (termios->c_cflag & CSIZE) {
	case CS5:
		cflag |= DZ_CS5;
		break;
	case CS6:
		cflag |= DZ_CS6;
		break;
	case CS7:
		cflag |= DZ_CS7;
		break;
	case CS8:
	default:
		cflag |= DZ_CS8;
	}

	if (termios->c_cflag & CSTOPB)
		cflag |= DZ_CSTOPB;
	if (termios->c_cflag & PARENB)
		cflag |= DZ_PARENB;
	if (termios->c_cflag & PARODD)
		cflag |= DZ_PARODD;

	baud = uart_get_baud_rate(uport, termios, old_termios, 50, 9600);
	bflag = dz_encode_baud_rate(baud);
	if (bflag < 0)	{			/* Try to keep unchanged.  */
		baud = uart_get_baud_rate(uport, old_termios, NULL, 50, 9600);
		bflag = dz_encode_baud_rate(baud);
		if (bflag < 0)	{		/* Resort to 9600.  */
			baud = 9600;
			bflag = DZ_B9600;
		}
		tty_termios_encode_baud_rate(termios, baud, baud);
	}
	cflag |= bflag;

	if (termios->c_cflag & CREAD)
		cflag |= DZ_RXENAB;

	spin_lock_irqsave(&dport->port.lock, flags);

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

	dz_out(dport, DZ_LPR, cflag);
	dport->cflag = cflag;

	/* setup accept flag */
	dport->port.read_status_mask = DZ_OERR;
	if (termios->c_iflag & INPCK)
		dport->port.read_status_mask |= DZ_FERR | DZ_PERR;
	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
		dport->port.read_status_mask |= DZ_BREAK;

	/* characters to ignore */
	uport->ignore_status_mask = 0;
	if ((termios->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
		dport->port.ignore_status_mask |= DZ_OERR;
	if (termios->c_iflag & IGNPAR)
		dport->port.ignore_status_mask |= DZ_FERR | DZ_PERR;
	if (termios->c_iflag & IGNBRK)
		dport->port.ignore_status_mask |= DZ_BREAK;

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

/*
 * Hack alert!
 * Required solely so that the initial PROM-based console
 * works undisturbed in parallel with this one.
 */
static void dz_pm(struct uart_port *uport, unsigned int state,
		  unsigned int oldstate)
{
	struct dz_port *dport = to_dport(uport);
	unsigned long flags;

	spin_lock_irqsave(&dport->port.lock, flags);
	if (state < 3)
		dz_start_tx(&dport->port);
	else
		dz_stop_tx(&dport->port);
	spin_unlock_irqrestore(&dport->port.lock, flags);
}


static const char *dz_type(struct uart_port *uport)
{
	return "DZ";
}

static void dz_release_port(struct uart_port *uport)
{
	struct dz_mux *mux = to_dport(uport)->mux;
	int map_guard;

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

	map_guard = atomic_add_return(-1, &mux->map_guard);
	if (!map_guard)
		release_mem_region(uport->mapbase, dec_kn_slot_size);
}

static int dz_map_port(struct uart_port *uport)
{
	if (!uport->membase)
		uport->membase = ioremap(uport->mapbase,
						 dec_kn_slot_size);
	if (!uport->membase) {
		printk(KERN_ERR "dz: Cannot map MMIO\n");
		return -ENOMEM;
	}
	return 0;
}

static int dz_request_port(struct uart_port *uport)
{
	struct dz_mux *mux = to_dport(uport)->mux;
	int map_guard;
	int ret;

	map_guard = atomic_add_return(1, &mux->map_guard);
	if (map_guard == 1) {
		if (!request_mem_region(uport->mapbase, dec_kn_slot_size,
					"dz")) {
			atomic_add(-1, &mux->map_guard);
			printk(KERN_ERR
			       "dz: Unable to reserve MMIO resource\n");
			return -EBUSY;
		}
	}
	ret = dz_map_port(uport);
	if (ret) {
		map_guard = atomic_add_return(-1, &mux->map_guard);
		if (!map_guard)
			release_mem_region(uport->mapbase, dec_kn_slot_size);
		return ret;
	}
	return 0;
}

static void dz_config_port(struct uart_port *uport, int flags)
{
	struct dz_port *dport = to_dport(uport);

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

		uport->type = PORT_DZ;

		dz_reset(dport);
	}
}

/*
 * Verify the new serial_struct (for TIOCSSERIAL).
 */
static int dz_verify_port(struct uart_port *uport, struct serial_struct *ser)
{
	int ret = 0;

	if (ser->type != PORT_UNKNOWN && ser->type != PORT_DZ)
		ret = -EINVAL;
	if (ser->irq != uport->irq)
		ret = -EINVAL;
	return ret;
}

static const struct uart_ops dz_ops = {
	.tx_empty	= dz_tx_empty,
	.get_mctrl	= dz_get_mctrl,
	.set_mctrl	= dz_set_mctrl,
	.stop_tx	= dz_stop_tx,
	.start_tx	= dz_start_tx,
	.stop_rx	= dz_stop_rx,
	.break_ctl	= dz_break_ctl,
	.startup	= dz_startup,
	.shutdown	= dz_shutdown,
	.set_termios	= dz_set_termios,
	.pm		= dz_pm,
	.type		= dz_type,
	.release_port	= dz_release_port,
	.request_port	= dz_request_port,
	.config_port	= dz_config_port,
	.verify_port	= dz_verify_port,
};

static void __init dz_init_ports(void)
{
	static int first = 1;
	unsigned long base;
	int line;

	if (!first)
		return;
	first = 0;

	if (mips_machtype == MACH_DS23100 || mips_machtype == MACH_DS5100)
		base = dec_kn_slot_base + KN01_DZ11;
	else
		base = dec_kn_slot_base + KN02_DZ11;

	for (line = 0; line < DZ_NB_PORT; line++) {
		struct dz_port *dport = &dz_mux.dport[line];
		struct uart_port *uport = &dport->port;

		dport->mux	= &dz_mux;

		uport->irq	= dec_interrupt[DEC_IRQ_DZ11];
		uport->fifosize	= 1;
		uport->iotype	= UPIO_MEM;
		uport->flags	= UPF_BOOT_AUTOCONF;
		uport->ops	= &dz_ops;
		uport->line	= line;
		uport->mapbase	= base;
		uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_DZ_CONSOLE);
	}
}

#ifdef CONFIG_SERIAL_DZ_CONSOLE
/*
 * -------------------------------------------------------------------
 * dz_console_putchar() -- transmit a character
 *
 * Polled transmission.  This is tricky.  We need to mask transmit
 * interrupts so that they do not interfere, enable the transmitter
 * for the line requested and then wait till the transmit scanner
 * requests data for this line.  But it may request data for another
 * line first, in which case we have to disable its transmitter and
 * repeat waiting till our line pops up.  Only then the character may
 * be transmitted.  Finally, the state of the transmitter mask is
 * restored.  Welcome to the world of PDP-11!
 * -------------------------------------------------------------------
 */
static void dz_console_putchar(struct uart_port *uport, int ch)
{
	struct dz_port *dport = to_dport(uport);
	unsigned long flags;
	unsigned short csr, tcr, trdy, mask;
	int loops = 10000;

	spin_lock_irqsave(&dport->port.lock, flags);
	csr = dz_in(dport, DZ_CSR);
	dz_out(dport, DZ_CSR, csr & ~DZ_TIE);
	tcr = dz_in(dport, DZ_TCR);
	tcr |= 1 << dport->port.line;
	mask = tcr;
	dz_out(dport, DZ_TCR, mask);
	iob();
	spin_unlock_irqrestore(&dport->port.lock, flags);

	do {
		trdy = dz_in(dport, DZ_CSR);
		if (!(trdy & DZ_TRDY))
			continue;
		trdy = (trdy & DZ_TLINE) >> 8;
		if (trdy == dport->port.line)
			break;
		mask &= ~(1 << trdy);
		dz_out(dport, DZ_TCR, mask);
		iob();
		udelay(2);
	} while (--loops);

	if (loops)				/* Cannot send otherwise. */
		dz_out(dport, DZ_TDR, ch);

	dz_out(dport, DZ_TCR, tcr);
	dz_out(dport, DZ_CSR, csr);
}

/*
 * -------------------------------------------------------------------
 * dz_console_print ()
 *
 * dz_console_print is registered for printk.
 * The console must be locked when we get here.
 * -------------------------------------------------------------------
 */
static void dz_console_print(struct console *co,
			     const char *str,
			     unsigned int count)
{
	struct dz_port *dport = &dz_mux.dport[co->index];
#ifdef DEBUG_DZ
	prom_printf((char *) str);
#endif
	uart_console_write(&dport->port, str, count, dz_console_putchar);
}

static int __init dz_console_setup(struct console *co, char *options)
{
	struct dz_port *dport = &dz_mux.dport[co->index];
	struct uart_port *uport = &dport->port;
	int baud = 9600;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';
	int ret;

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

	spin_lock_init(&dport->port.lock);	/* For dz_pm().  */

	dz_reset(dport);
	dz_pm(uport, 0, -1);

	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);

	return uart_set_options(&dport->port, co, baud, parity, bits, flow);
}

static struct uart_driver dz_reg;
static struct console dz_console = {
	.name	= "ttyS",
	.write	= dz_console_print,
	.device	= uart_console_device,
	.setup	= dz_console_setup,
	.flags	= CON_PRINTBUFFER,
	.index	= -1,
	.data	= &dz_reg,
};

static int __init dz_serial_console_init(void)
{
	if (!IOASIC) {
		dz_init_ports();
		register_console(&dz_console);
		return 0;
	} else
		return -ENXIO;
}

console_initcall(dz_serial_console_init);

#define SERIAL_DZ_CONSOLE	&dz_console
#else
#define SERIAL_DZ_CONSOLE	NULL
#endif /* CONFIG_SERIAL_DZ_CONSOLE */

static struct uart_driver dz_reg = {
	.owner			= THIS_MODULE,
	.driver_name		= "serial",
	.dev_name		= "ttyS",
	.major			= TTY_MAJOR,
	.minor			= 64,
	.nr			= DZ_NB_PORT,
	.cons			= SERIAL_DZ_CONSOLE,
};

static int __init dz_init(void)
{
	int ret, i;

	if (IOASIC)
		return -ENXIO;

	printk("%s%s\n", dz_name, dz_version);

	dz_init_ports();

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

	for (i = 0; i < DZ_NB_PORT; i++)
		uart_add_one_port(&dz_reg, &dz_mux.dport[i].port);

	return 0;
}

module_init(dz_init);
