// 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 };
	u16 status;
	u8 ch, flag;
	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 tty_port *tport;
	unsigned char tmp;
	u16 status;

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

	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_tx_stopped(&dport->port) ||
			!uart_fifo_get(&dport->port, &tmp)) {
		uart_port_lock(&dport->port);
		dz_stop_tx(&dport->port);
		uart_port_unlock(&dport->port);
		return;
	}

	/*
	 * If something to do... (remember the dz has no output fifo,
	 * so we go one char at a time) :-<
	 */
	dz_out(dport, DZ_TDR, tmp);

	if (kfifo_len(&tport->xmit_fifo) < DZ_WAKEUP_CHARS)
		uart_write_wakeup(&dport->port);

	/* Are we are done. */
	if (kfifo_is_empty(&tport->xmit_fifo)) {
		uart_port_lock(&dport->port);
		dz_stop_tx(&dport->port);
		uart_port_unlock(&dport->port);
	}
}

/*
 * ------------------------------------------------------------
 * 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;
	}

	uart_port_lock_irqsave(&dport->port, &flags);

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

	uart_port_unlock_irqrestore(&dport->port, 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;

	uart_port_lock_irqsave(&dport->port, &flags);
	dz_stop_tx(&dport->port);
	uart_port_unlock_irqrestore(&dport->port, 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;

	uart_port_lock_irqsave(uport, &flags);
	tmp = dz_in(dport, DZ_TCR);
	if (break_state)
		tmp |= mask;
	else
		tmp &= ~mask;
	dz_out(dport, DZ_TCR, tmp);
	uart_port_unlock_irqrestore(uport, 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,
			   const 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)	{
		if (old_termios) {
			/* Keep unchanged. */
			baud = tty_termios_baud_rate(old_termios);
			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;

	uart_port_lock_irqsave(&dport->port, &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;

	uart_port_unlock_irqrestore(&dport->port, 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;

	uart_port_lock_irqsave(&dport->port, &flags);
	if (state < 3)
		dz_start_tx(&dport->port);
	else
		dz_stop_tx(&dport->port);
	uart_port_unlock_irqrestore(&dport->port, 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, unsigned char ch)
{
	struct dz_port *dport = to_dport(uport);
	unsigned long flags;
	unsigned short csr, tcr, trdy, mask;
	int loops = 10000;

	uart_port_lock_irqsave(&dport->port, &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();
	uart_port_unlock_irqrestore(&dport->port, 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);
