/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
 */

/*
 * This file contains a module version of the ioc3 serial driver. This
 * includes all the support functions needed (support functions, etc.)
 * and the serial driver itself.
 */
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/circ_buf.h>
#include <linux/serial_reg.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/serial_core.h>
#include <linux/ioc3.h>

/*
 * Interesting things about the ioc3
 */

#define LOGICAL_PORTS		2	/* rs232(0) and rs422(1) */
#define PORTS_PER_CARD		2
#define LOGICAL_PORTS_PER_CARD (PORTS_PER_CARD * LOGICAL_PORTS)
#define MAX_CARDS		8
#define MAX_LOGICAL_PORTS	(LOGICAL_PORTS_PER_CARD * MAX_CARDS)

/* determine given the sio_ir what port it applies to */
#define GET_PORT_FROM_SIO_IR(_x)	(_x & SIO_IR_SA) ? 0 : 1


/*
 * we have 2 logical ports (rs232, rs422) for each physical port
 * evens are rs232, odds are rs422
 */
#define GET_PHYSICAL_PORT(_x)	((_x) >> 1)
#define GET_LOGICAL_PORT(_x)	((_x) & 1)
#define IS_PHYSICAL_PORT(_x)	!((_x) & 1)
#define IS_RS232(_x)		!((_x) & 1)

static unsigned int Num_of_ioc3_cards;
static unsigned int Submodule_slot;

/* defining this will get you LOTS of great debug info */
//#define DEBUG_INTERRUPTS
#define DPRINT_CONFIG(_x...)	;
//#define DPRINT_CONFIG(_x...)  printk _x
#define NOT_PROGRESS()	;
//#define NOT_PROGRESS()	printk("%s : fails %d\n", __func__, __LINE__)

/* number of characters we want to transmit to the lower level at a time */
#define MAX_CHARS		256
#define FIFO_SIZE		(MAX_CHARS-1)	/* it's a uchar */

/* Device name we're using */
#define DEVICE_NAME		"ttySIOC"
#define DEVICE_MAJOR		204
#define DEVICE_MINOR		116

/* flags for next_char_state */
#define NCS_BREAK		0x1
#define NCS_PARITY		0x2
#define NCS_FRAMING		0x4
#define NCS_OVERRUN		0x8

/* cause we need SOME parameters ... */
#define MIN_BAUD_SUPPORTED	1200
#define MAX_BAUD_SUPPORTED	115200

/* protocol types supported */
#define PROTO_RS232		0
#define PROTO_RS422		1

/* Notification types */
#define N_DATA_READY		0x01
#define N_OUTPUT_LOWAT		0x02
#define N_BREAK			0x04
#define N_PARITY_ERROR		0x08
#define N_FRAMING_ERROR		0x10
#define N_OVERRUN_ERROR		0x20
#define N_DDCD			0x40
#define N_DCTS			0x80

#define N_ALL_INPUT		(N_DATA_READY | N_BREAK			   \
					| N_PARITY_ERROR | N_FRAMING_ERROR \
					| N_OVERRUN_ERROR | N_DDCD | N_DCTS)

#define N_ALL_OUTPUT		N_OUTPUT_LOWAT

#define N_ALL_ERRORS		(N_PARITY_ERROR | N_FRAMING_ERROR \
						| N_OVERRUN_ERROR)

#define N_ALL			(N_DATA_READY | N_OUTPUT_LOWAT | N_BREAK    \
					| N_PARITY_ERROR | N_FRAMING_ERROR  \
					| N_OVERRUN_ERROR | N_DDCD | N_DCTS)

#define SER_CLK_SPEED(prediv)	((22000000 << 1) / prediv)
#define SER_DIVISOR(x, clk)	(((clk) + (x) * 8) / ((x) * 16))
#define DIVISOR_TO_BAUD(div, clk) ((clk) / 16 / (div))

/* Some masks */
#define LCR_MASK_BITS_CHAR	(UART_LCR_WLEN5 | UART_LCR_WLEN6 \
					| UART_LCR_WLEN7 | UART_LCR_WLEN8)
#define LCR_MASK_STOP_BITS	(UART_LCR_STOP)

#define PENDING(_a, _p)		(readl(&(_p)->vma->sio_ir) & (_a)->ic_enable)

#define RING_BUF_SIZE		4096
#define BUF_SIZE_BIT		SBBR_L_SIZE
#define PROD_CONS_MASK		PROD_CONS_PTR_4K

#define TOTAL_RING_BUF_SIZE	(RING_BUF_SIZE * 4)

/* driver specific - one per card */
struct ioc3_card {
	struct {
		/* uart ports are allocated here */
		struct uart_port icp_uart_port[LOGICAL_PORTS];
		/* the ioc3_port used for this port */
		struct ioc3_port *icp_port;
	} ic_port[PORTS_PER_CARD];
	/* currently enabled interrupts */
	uint32_t ic_enable;
};

/* Local port info for each IOC3 serial port */
struct ioc3_port {
	/* handy reference material */
	struct uart_port *ip_port;
	struct ioc3_card *ip_card;
	struct ioc3_driver_data *ip_idd;
	struct ioc3_submodule *ip_is;

	/* pci mem addresses for this port */
	struct ioc3_serialregs __iomem *ip_serial_regs;
	struct ioc3_uartregs __iomem *ip_uart_regs;

	/* Ring buffer page for this port */
	dma_addr_t ip_dma_ringbuf;
	/* vaddr of ring buffer */
	struct ring_buffer *ip_cpu_ringbuf;

	/* Rings for this port */
	struct ring *ip_inring;
	struct ring *ip_outring;

	/* Hook to port specific values */
	struct port_hooks *ip_hooks;

	spinlock_t ip_lock;

	/* Various rx/tx parameters */
	int ip_baud;
	int ip_tx_lowat;
	int ip_rx_timeout;

	/* Copy of notification bits */
	int ip_notify;

	/* Shadow copies of various registers so we don't need to PIO
	 * read them constantly
	 */
	uint32_t ip_sscr;
	uint32_t ip_tx_prod;
	uint32_t ip_rx_cons;
	unsigned char ip_flags;
};

/* tx low water mark.  We need to notify the driver whenever tx is getting
 * close to empty so it can refill the tx buffer and keep things going.
 * Let's assume that if we interrupt 1 ms before the tx goes idle, we'll
 * have no trouble getting in more chars in time (I certainly hope so).
 */
#define TX_LOWAT_LATENCY      1000
#define TX_LOWAT_HZ          (1000000 / TX_LOWAT_LATENCY)
#define TX_LOWAT_CHARS(baud) (baud / 10 / TX_LOWAT_HZ)

/* Flags per port */
#define INPUT_HIGH		0x01
	/* used to signify that we have turned off the rx_high
	 * temporarily - we need to drain the fifo and don't
	 * want to get blasted with interrupts.
	 */
#define DCD_ON			0x02
	/* DCD state is on */
#define LOWAT_WRITTEN		0x04
#define READ_ABORTED		0x08
	/* the read was aborted - used to avaoid infinate looping
	 * in the interrupt handler
	 */
#define INPUT_ENABLE		0x10

/* Since each port has different register offsets and bitmasks
 * for everything, we'll store those that we need in tables so we
 * don't have to be constantly checking the port we are dealing with.
 */
struct port_hooks {
	uint32_t intr_delta_dcd;
	uint32_t intr_delta_cts;
	uint32_t intr_tx_mt;
	uint32_t intr_rx_timer;
	uint32_t intr_rx_high;
	uint32_t intr_tx_explicit;
	uint32_t intr_clear;
	uint32_t intr_all;
	char rs422_select_pin;
};

static struct port_hooks hooks_array[PORTS_PER_CARD] = {
	/* values for port A */
	{
	.intr_delta_dcd = SIO_IR_SA_DELTA_DCD,
	.intr_delta_cts = SIO_IR_SA_DELTA_CTS,
	.intr_tx_mt = SIO_IR_SA_TX_MT,
	.intr_rx_timer = SIO_IR_SA_RX_TIMER,
	.intr_rx_high = SIO_IR_SA_RX_HIGH,
	.intr_tx_explicit = SIO_IR_SA_TX_EXPLICIT,
	.intr_clear = (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL
				| SIO_IR_SA_RX_HIGH
				| SIO_IR_SA_RX_TIMER
				| SIO_IR_SA_DELTA_DCD
				| SIO_IR_SA_DELTA_CTS
				| SIO_IR_SA_INT
				| SIO_IR_SA_TX_EXPLICIT
				| SIO_IR_SA_MEMERR),
	.intr_all =  SIO_IR_SA,
	.rs422_select_pin = GPPR_UARTA_MODESEL_PIN,
	 },

	/* values for port B */
	{
	.intr_delta_dcd = SIO_IR_SB_DELTA_DCD,
	.intr_delta_cts = SIO_IR_SB_DELTA_CTS,
	.intr_tx_mt = SIO_IR_SB_TX_MT,
	.intr_rx_timer = SIO_IR_SB_RX_TIMER,
	.intr_rx_high = SIO_IR_SB_RX_HIGH,
	.intr_tx_explicit = SIO_IR_SB_TX_EXPLICIT,
	.intr_clear = (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL
				| SIO_IR_SB_RX_HIGH
				| SIO_IR_SB_RX_TIMER
				| SIO_IR_SB_DELTA_DCD
				| SIO_IR_SB_DELTA_CTS
				| SIO_IR_SB_INT
				| SIO_IR_SB_TX_EXPLICIT
				| SIO_IR_SB_MEMERR),
	.intr_all = SIO_IR_SB,
	.rs422_select_pin = GPPR_UARTB_MODESEL_PIN,
	 }
};

struct ring_entry {
	union {
		struct {
			uint32_t alldata;
			uint32_t allsc;
		} all;
		struct {
			char data[4];	/* data bytes */
			char sc[4];	/* status/control */
		} s;
	} u;
};

/* Test the valid bits in any of the 4 sc chars using "allsc" member */
#define RING_ANY_VALID \
	((uint32_t)(RXSB_MODEM_VALID | RXSB_DATA_VALID) * 0x01010101)

#define ring_sc		u.s.sc
#define ring_data	u.s.data
#define ring_allsc	u.all.allsc

/* Number of entries per ring buffer. */
#define ENTRIES_PER_RING (RING_BUF_SIZE / (int) sizeof(struct ring_entry))

/* An individual ring */
struct ring {
	struct ring_entry entries[ENTRIES_PER_RING];
};

/* The whole enchilada */
struct ring_buffer {
	struct ring TX_A;
	struct ring RX_A;
	struct ring TX_B;
	struct ring RX_B;
};

/* Get a ring from a port struct */
#define RING(_p, _wh)	&(((struct ring_buffer *)((_p)->ip_cpu_ringbuf))->_wh)

/* for Infinite loop detection  */
#define MAXITER		10000000


/**
 * set_baud - Baud rate setting code
 * @port: port to set
 * @baud: baud rate to use
 */
static int set_baud(struct ioc3_port *port, int baud)
{
	int divisor;
	int actual_baud;
	int diff;
	int lcr, prediv;
	struct ioc3_uartregs __iomem *uart;

	for (prediv = 6; prediv < 64; prediv++) {
		divisor = SER_DIVISOR(baud, SER_CLK_SPEED(prediv));
		if (!divisor)
			continue;	/* invalid divisor */
		actual_baud = DIVISOR_TO_BAUD(divisor, SER_CLK_SPEED(prediv));

		diff = actual_baud - baud;
		if (diff < 0)
			diff = -diff;

		/* if we're within 1% we've found a match */
		if (diff * 100 <= actual_baud)
			break;
	}

	/* if the above loop completed, we didn't match
	 * the baud rate.  give up.
	 */
	if (prediv == 64) {
		NOT_PROGRESS();
		return 1;
	}

	uart = port->ip_uart_regs;
	lcr = readb(&uart->iu_lcr);

	writeb(lcr | UART_LCR_DLAB, &uart->iu_lcr);
	writeb((unsigned char)divisor, &uart->iu_dll);
	writeb((unsigned char)(divisor >> 8), &uart->iu_dlm);
	writeb((unsigned char)prediv, &uart->iu_scr);
	writeb((unsigned char)lcr, &uart->iu_lcr);

	return 0;
}

/**
 * get_ioc3_port - given a uart port, return the control structure
 * @the_port: uart port to find
 */
static struct ioc3_port *get_ioc3_port(struct uart_port *the_port)
{
	struct ioc3_driver_data *idd = dev_get_drvdata(the_port->dev);
	struct ioc3_card *card_ptr = idd->data[Submodule_slot];
	int ii, jj;

	if (!card_ptr) {
		NOT_PROGRESS();
		return NULL;
	}
	for (ii = 0; ii < PORTS_PER_CARD; ii++) {
		for (jj = 0; jj < LOGICAL_PORTS; jj++) {
			if (the_port == &card_ptr->ic_port[ii].icp_uart_port[jj])
				return card_ptr->ic_port[ii].icp_port;
		}
	}
	NOT_PROGRESS();
	return NULL;
}

/**
 * port_init - Initialize the sio and ioc3 hardware for a given port
 *			called per port from attach...
 * @port: port to initialize
 */
static int inline port_init(struct ioc3_port *port)
{
	uint32_t sio_cr;
	struct port_hooks *hooks = port->ip_hooks;
	struct ioc3_uartregs __iomem *uart;
	int reset_loop_counter = 0xfffff;
	struct ioc3_driver_data *idd = port->ip_idd;

	/* Idle the IOC3 serial interface */
	writel(SSCR_RESET, &port->ip_serial_regs->sscr);

	/* Wait until any pending bus activity for this port has ceased */
	do {
		sio_cr = readl(&idd->vma->sio_cr);
		if (reset_loop_counter-- <= 0) {
			printk(KERN_WARNING
			       "IOC3 unable to come out of reset"
				" scr 0x%x\n", sio_cr);
			return -1;
		}
	} while (!(sio_cr & SIO_CR_ARB_DIAG_IDLE) &&
	       (((sio_cr &= SIO_CR_ARB_DIAG) == SIO_CR_ARB_DIAG_TXA)
		|| sio_cr == SIO_CR_ARB_DIAG_TXB
		|| sio_cr == SIO_CR_ARB_DIAG_RXA
		|| sio_cr == SIO_CR_ARB_DIAG_RXB));

	/* Finish reset sequence */
	writel(0, &port->ip_serial_regs->sscr);

	/* Once RESET is done, reload cached tx_prod and rx_cons values
	 * and set rings to empty by making prod == cons
	 */
	port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
	writel(port->ip_tx_prod, &port->ip_serial_regs->stpir);
	port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
	writel(port->ip_rx_cons | SRCIR_ARM, &port->ip_serial_regs->srcir);

	/* Disable interrupts for this 16550 */
	uart = port->ip_uart_regs;
	writeb(0, &uart->iu_lcr);
	writeb(0, &uart->iu_ier);

	/* Set the default baud */
	set_baud(port, port->ip_baud);

	/* Set line control to 8 bits no parity */
	writeb(UART_LCR_WLEN8 | 0, &uart->iu_lcr);
	/* UART_LCR_STOP == 1 stop */

	/* Enable the FIFOs */
	writeb(UART_FCR_ENABLE_FIFO, &uart->iu_fcr);
	/* then reset 16550 FIFOs */
	writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
	       &uart->iu_fcr);

	/* Clear modem control register */
	writeb(0, &uart->iu_mcr);

	/* Clear deltas in modem status register */
	writel(0, &port->ip_serial_regs->shadow);

	/* Only do this once per port pair */
	if (port->ip_hooks == &hooks_array[0]) {
		unsigned long ring_pci_addr;
		uint32_t __iomem *sbbr_l, *sbbr_h;

		sbbr_l = &idd->vma->sbbr_l;
		sbbr_h = &idd->vma->sbbr_h;
		ring_pci_addr = (unsigned long __iomem)port->ip_dma_ringbuf;
		DPRINT_CONFIG(("%s: ring_pci_addr 0x%p\n",
			       __func__, (void *)ring_pci_addr));

		writel((unsigned int)((uint64_t) ring_pci_addr >> 32), sbbr_h);
		writel((unsigned int)ring_pci_addr | BUF_SIZE_BIT, sbbr_l);
	}

	/* Set the receive timeout value to 10 msec */
	writel(SRTR_HZ / 100, &port->ip_serial_regs->srtr);

	/* Set rx threshold, enable DMA */
	/* Set high water mark at 3/4 of full ring */
	port->ip_sscr = (ENTRIES_PER_RING * 3 / 4);

	/* uart experiences pauses at high baud rate reducing actual
	 * throughput by 10% or so unless we enable high speed polling
	 * XXX when this hardware bug is resolved we should revert to
	 * normal polling speed
	 */
	port->ip_sscr |= SSCR_HIGH_SPD;

	writel(port->ip_sscr, &port->ip_serial_regs->sscr);

	/* Disable and clear all serial related interrupt bits */
	port->ip_card->ic_enable &= ~hooks->intr_clear;
	ioc3_disable(port->ip_is, idd, hooks->intr_clear);
	ioc3_ack(port->ip_is, idd, hooks->intr_clear);
	return 0;
}

/**
 * enable_intrs - enable interrupts
 * @port: port to enable
 * @mask: mask to use
 */
static void enable_intrs(struct ioc3_port *port, uint32_t mask)
{
	if ((port->ip_card->ic_enable & mask) != mask) {
		port->ip_card->ic_enable |= mask;
		ioc3_enable(port->ip_is, port->ip_idd, mask);
	}
}

/**
 * local_open - local open a port
 * @port: port to open
 */
static inline int local_open(struct ioc3_port *port)
{
	int spiniter = 0;

	port->ip_flags = INPUT_ENABLE;

	/* Pause the DMA interface if necessary */
	if (port->ip_sscr & SSCR_DMA_EN) {
		writel(port->ip_sscr | SSCR_DMA_PAUSE,
		       &port->ip_serial_regs->sscr);
		while ((readl(&port->ip_serial_regs->sscr)
			& SSCR_PAUSE_STATE) == 0) {
			spiniter++;
			if (spiniter > MAXITER) {
				NOT_PROGRESS();
				return -1;
			}
		}
	}

	/* Reset the input fifo.  If the uart received chars while the port
	 * was closed and DMA is not enabled, the uart may have a bunch of
	 * chars hanging around in its rx fifo which will not be discarded
	 * by rclr in the upper layer. We must get rid of them here.
	 */
	writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR,
	       &port->ip_uart_regs->iu_fcr);

	writeb(UART_LCR_WLEN8, &port->ip_uart_regs->iu_lcr);
	/* UART_LCR_STOP == 1 stop */

	/* Re-enable DMA, set default threshold to intr whenever there is
	 * data available.
	 */
	port->ip_sscr &= ~SSCR_RX_THRESHOLD;
	port->ip_sscr |= 1;	/* default threshold */

	/* Plug in the new sscr.  This implicitly clears the DMA_PAUSE
	 * flag if it was set above
	 */
	writel(port->ip_sscr, &port->ip_serial_regs->sscr);
	port->ip_tx_lowat = 1;
	return 0;
}

/**
 * set_rx_timeout - Set rx timeout and threshold values.
 * @port: port to use
 * @timeout: timeout value in ticks
 */
static inline int set_rx_timeout(struct ioc3_port *port, int timeout)
{
	int threshold;

	port->ip_rx_timeout = timeout;

	/* Timeout is in ticks.  Let's figure out how many chars we
	 * can receive at the current baud rate in that interval
	 * and set the rx threshold to that amount.  There are 4 chars
	 * per ring entry, so we'll divide the number of chars that will
	 * arrive in timeout by 4.
	 * So .... timeout * baud / 10 / HZ / 4, with HZ = 100.
	 */
	threshold = timeout * port->ip_baud / 4000;
	if (threshold == 0)
		threshold = 1;	/* otherwise we'll intr all the time! */

	if ((unsigned)threshold > (unsigned)SSCR_RX_THRESHOLD)
		return 1;

	port->ip_sscr &= ~SSCR_RX_THRESHOLD;
	port->ip_sscr |= threshold;
	writel(port->ip_sscr, &port->ip_serial_regs->sscr);

	/* Now set the rx timeout to the given value
	 * again timeout * SRTR_HZ / HZ
	 */
	timeout = timeout * SRTR_HZ / 100;
	if (timeout > SRTR_CNT)
		timeout = SRTR_CNT;
	writel(timeout, &port->ip_serial_regs->srtr);
	return 0;
}

/**
 * config_port - config the hardware
 * @port: port to config
 * @baud: baud rate for the port
 * @byte_size: data size
 * @stop_bits: number of stop bits
 * @parenb: parity enable ?
 * @parodd: odd parity ?
 */
static inline int
config_port(struct ioc3_port *port,
	    int baud, int byte_size, int stop_bits, int parenb, int parodd)
{
	char lcr, sizebits;
	int spiniter = 0;

	DPRINT_CONFIG(("%s: line %d baud %d byte_size %d stop %d parenb %d "
			"parodd %d\n",
		       __func__, ((struct uart_port *)port->ip_port)->line,
			baud, byte_size, stop_bits, parenb, parodd));

	if (set_baud(port, baud))
		return 1;

	switch (byte_size) {
	case 5:
		sizebits = UART_LCR_WLEN5;
		break;
	case 6:
		sizebits = UART_LCR_WLEN6;
		break;
	case 7:
		sizebits = UART_LCR_WLEN7;
		break;
	case 8:
		sizebits = UART_LCR_WLEN8;
		break;
	default:
		return 1;
	}

	/* Pause the DMA interface if necessary */
	if (port->ip_sscr & SSCR_DMA_EN) {
		writel(port->ip_sscr | SSCR_DMA_PAUSE,
		       &port->ip_serial_regs->sscr);
		while ((readl(&port->ip_serial_regs->sscr)
			& SSCR_PAUSE_STATE) == 0) {
			spiniter++;
			if (spiniter > MAXITER)
				return -1;
		}
	}

	/* Clear relevant fields in lcr */
	lcr = readb(&port->ip_uart_regs->iu_lcr);
	lcr &= ~(LCR_MASK_BITS_CHAR | UART_LCR_EPAR |
		 UART_LCR_PARITY | LCR_MASK_STOP_BITS);

	/* Set byte size in lcr */
	lcr |= sizebits;

	/* Set parity */
	if (parenb) {
		lcr |= UART_LCR_PARITY;
		if (!parodd)
			lcr |= UART_LCR_EPAR;
	}

	/* Set stop bits */
	if (stop_bits)
		lcr |= UART_LCR_STOP /* 2 stop bits */ ;

	writeb(lcr, &port->ip_uart_regs->iu_lcr);

	/* Re-enable the DMA interface if necessary */
	if (port->ip_sscr & SSCR_DMA_EN) {
		writel(port->ip_sscr, &port->ip_serial_regs->sscr);
	}
	port->ip_baud = baud;

	/* When we get within this number of ring entries of filling the
	 * entire ring on tx, place an EXPLICIT intr to generate a lowat
	 * notification when output has drained.
	 */
	port->ip_tx_lowat = (TX_LOWAT_CHARS(baud) + 3) / 4;
	if (port->ip_tx_lowat == 0)
		port->ip_tx_lowat = 1;

	set_rx_timeout(port, 2);
	return 0;
}

/**
 * do_write - Write bytes to the port.  Returns the number of bytes
 *			actually written. Called from transmit_chars
 * @port: port to use
 * @buf: the stuff to write
 * @len: how many bytes in 'buf'
 */
static inline int do_write(struct ioc3_port *port, char *buf, int len)
{
	int prod_ptr, cons_ptr, total = 0;
	struct ring *outring;
	struct ring_entry *entry;
	struct port_hooks *hooks = port->ip_hooks;

	BUG_ON(!(len >= 0));

	prod_ptr = port->ip_tx_prod;
	cons_ptr = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
	outring = port->ip_outring;

	/* Maintain a 1-entry red-zone.  The ring buffer is full when
	 * (cons - prod) % ring_size is 1.  Rather than do this subtraction
	 * in the body of the loop, I'll do it now.
	 */
	cons_ptr = (cons_ptr - (int)sizeof(struct ring_entry)) & PROD_CONS_MASK;

	/* Stuff the bytes into the output */
	while ((prod_ptr != cons_ptr) && (len > 0)) {
		int xx;

		/* Get 4 bytes (one ring entry) at a time */
		entry = (struct ring_entry *)((caddr_t) outring + prod_ptr);

		/* Invalidate all entries */
		entry->ring_allsc = 0;

		/* Copy in some bytes */
		for (xx = 0; (xx < 4) && (len > 0); xx++) {
			entry->ring_data[xx] = *buf++;
			entry->ring_sc[xx] = TXCB_VALID;
			len--;
			total++;
		}

		/* If we are within some small threshold of filling up the
		 * entire ring buffer, we must place an EXPLICIT intr here
		 * to generate a lowat interrupt in case we subsequently
		 * really do fill up the ring and the caller goes to sleep.
		 * No need to place more than one though.
		 */
		if (!(port->ip_flags & LOWAT_WRITTEN) &&
		    ((cons_ptr - prod_ptr) & PROD_CONS_MASK)
		    <= port->ip_tx_lowat * (int)sizeof(struct ring_entry)) {
			port->ip_flags |= LOWAT_WRITTEN;
			entry->ring_sc[0] |= TXCB_INT_WHEN_DONE;
		}

		/* Go on to next entry */
		prod_ptr += sizeof(struct ring_entry);
		prod_ptr &= PROD_CONS_MASK;
	}

	/* If we sent something, start DMA if necessary */
	if (total > 0 && !(port->ip_sscr & SSCR_DMA_EN)) {
		port->ip_sscr |= SSCR_DMA_EN;
		writel(port->ip_sscr, &port->ip_serial_regs->sscr);
	}

	/* Store the new producer pointer.  If tx is disabled, we stuff the
	 * data into the ring buffer, but we don't actually start tx.
	 */
	if (!uart_tx_stopped(port->ip_port)) {
		writel(prod_ptr, &port->ip_serial_regs->stpir);

		/* If we are now transmitting, enable tx_mt interrupt so we
		 * can disable DMA if necessary when the tx finishes.
		 */
		if (total > 0)
			enable_intrs(port, hooks->intr_tx_mt);
	}
	port->ip_tx_prod = prod_ptr;

	return total;
}

/**
 * disable_intrs - disable interrupts
 * @port: port to enable
 * @mask: mask to use
 */
static inline void disable_intrs(struct ioc3_port *port, uint32_t mask)
{
	if (port->ip_card->ic_enable & mask) {
		ioc3_disable(port->ip_is, port->ip_idd, mask);
		port->ip_card->ic_enable &= ~mask;
	}
}

/**
 * set_notification - Modify event notification
 * @port: port to use
 * @mask: events mask
 * @set_on: set ?
 */
static int set_notification(struct ioc3_port *port, int mask, int set_on)
{
	struct port_hooks *hooks = port->ip_hooks;
	uint32_t intrbits, sscrbits;

	BUG_ON(!mask);

	intrbits = sscrbits = 0;

	if (mask & N_DATA_READY)
		intrbits |= (hooks->intr_rx_timer | hooks->intr_rx_high);
	if (mask & N_OUTPUT_LOWAT)
		intrbits |= hooks->intr_tx_explicit;
	if (mask & N_DDCD) {
		intrbits |= hooks->intr_delta_dcd;
		sscrbits |= SSCR_RX_RING_DCD;
	}
	if (mask & N_DCTS)
		intrbits |= hooks->intr_delta_cts;

	if (set_on) {
		enable_intrs(port, intrbits);
		port->ip_notify |= mask;
		port->ip_sscr |= sscrbits;
	} else {
		disable_intrs(port, intrbits);
		port->ip_notify &= ~mask;
		port->ip_sscr &= ~sscrbits;
	}

	/* We require DMA if either DATA_READY or DDCD notification is
	 * currently requested. If neither of these is requested and
	 * there is currently no tx in progress, DMA may be disabled.
	 */
	if (port->ip_notify & (N_DATA_READY | N_DDCD))
		port->ip_sscr |= SSCR_DMA_EN;
	else if (!(port->ip_card->ic_enable & hooks->intr_tx_mt))
		port->ip_sscr &= ~SSCR_DMA_EN;

	writel(port->ip_sscr, &port->ip_serial_regs->sscr);
	return 0;
}

/**
 * set_mcr - set the master control reg
 * @the_port: port to use
 * @mask1: mcr mask
 * @mask2: shadow mask
 */
static inline int set_mcr(struct uart_port *the_port,
			  int mask1, int mask2)
{
	struct ioc3_port *port = get_ioc3_port(the_port);
	uint32_t shadow;
	int spiniter = 0;
	char mcr;

	if (!port)
		return -1;

	/* Pause the DMA interface if necessary */
	if (port->ip_sscr & SSCR_DMA_EN) {
		writel(port->ip_sscr | SSCR_DMA_PAUSE,
		       &port->ip_serial_regs->sscr);
		while ((readl(&port->ip_serial_regs->sscr)
			& SSCR_PAUSE_STATE) == 0) {
			spiniter++;
			if (spiniter > MAXITER)
				return -1;
		}
	}
	shadow = readl(&port->ip_serial_regs->shadow);
	mcr = (shadow & 0xff000000) >> 24;

	/* Set new value */
	mcr |= mask1;
	shadow |= mask2;
	writeb(mcr, &port->ip_uart_regs->iu_mcr);
	writel(shadow, &port->ip_serial_regs->shadow);

	/* Re-enable the DMA interface if necessary */
	if (port->ip_sscr & SSCR_DMA_EN) {
		writel(port->ip_sscr, &port->ip_serial_regs->sscr);
	}
	return 0;
}

/**
 * ioc3_set_proto - set the protocol for the port
 * @port: port to use
 * @proto: protocol to use
 */
static int ioc3_set_proto(struct ioc3_port *port, int proto)
{
	struct port_hooks *hooks = port->ip_hooks;

	switch (proto) {
	default:
	case PROTO_RS232:
		/* Clear the appropriate GIO pin */
		DPRINT_CONFIG(("%s: rs232\n", __func__));
		writel(0, (&port->ip_idd->vma->gppr[0]
					+ hooks->rs422_select_pin));
		break;

	case PROTO_RS422:
		/* Set the appropriate GIO pin */
		DPRINT_CONFIG(("%s: rs422\n", __func__));
		writel(1, (&port->ip_idd->vma->gppr[0]
					+ hooks->rs422_select_pin));
		break;
	}
	return 0;
}

/**
 * transmit_chars - upper level write, called with the_port->lock
 * @the_port: port to write
 */
static void transmit_chars(struct uart_port *the_port)
{
	int xmit_count, tail, head;
	int result;
	char *start;
	struct tty_struct *tty;
	struct ioc3_port *port = get_ioc3_port(the_port);
	struct uart_info *info;

	if (!the_port)
		return;
	if (!port)
		return;

	info = the_port->info;
	tty = info->port.tty;

	if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
		/* Nothing to do or hw stopped */
		set_notification(port, N_ALL_OUTPUT, 0);
		return;
	}

	head = info->xmit.head;
	tail = info->xmit.tail;
	start = (char *)&info->xmit.buf[tail];

	/* write out all the data or until the end of the buffer */
	xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
	if (xmit_count > 0) {
		result = do_write(port, start, xmit_count);
		if (result > 0) {
			/* booking */
			xmit_count -= result;
			the_port->icount.tx += result;
			/* advance the pointers */
			tail += result;
			tail &= UART_XMIT_SIZE - 1;
			info->xmit.tail = tail;
			start = (char *)&info->xmit.buf[tail];
		}
	}
	if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS)
		uart_write_wakeup(the_port);

	if (uart_circ_empty(&info->xmit)) {
		set_notification(port, N_OUTPUT_LOWAT, 0);
	} else {
		set_notification(port, N_OUTPUT_LOWAT, 1);
	}
}

/**
 * ioc3_change_speed - change the speed of the port
 * @the_port: port to change
 * @new_termios: new termios settings
 * @old_termios: old termios settings
 */
static void
ioc3_change_speed(struct uart_port *the_port,
		  struct ktermios *new_termios, struct ktermios *old_termios)
{
	struct ioc3_port *port = get_ioc3_port(the_port);
	unsigned int cflag;
	int baud;
	int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
	struct uart_info *info = the_port->info;

	cflag = new_termios->c_cflag;

	switch (cflag & CSIZE) {
	case CS5:
		new_data = 5;
		break;
	case CS6:
		new_data = 6;
		break;
	case CS7:
		new_data = 7;
		break;
	case CS8:
		new_data = 8;
		break;
	default:
		/* cuz we always need a default ... */
		new_data = 5;
		break;
	}
	if (cflag & CSTOPB) {
		new_stop = 1;
	}
	if (cflag & PARENB) {
		new_parity_enable = 1;
		if (cflag & PARODD)
			new_parity = 1;
	}
	baud = uart_get_baud_rate(the_port, new_termios, old_termios,
				  MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED);
	DPRINT_CONFIG(("%s: returned baud %d for line %d\n", __func__, baud,
				the_port->line));

	if (!the_port->fifosize)
		the_port->fifosize = FIFO_SIZE;
	uart_update_timeout(the_port, cflag, baud);

	the_port->ignore_status_mask = N_ALL_INPUT;

	info->port.tty->low_latency = 1;

	if (I_IGNPAR(info->port.tty))
		the_port->ignore_status_mask &= ~(N_PARITY_ERROR
						  | N_FRAMING_ERROR);
	if (I_IGNBRK(info->port.tty)) {
		the_port->ignore_status_mask &= ~N_BREAK;
		if (I_IGNPAR(info->port.tty))
			the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
	}
	if (!(cflag & CREAD)) {
		/* ignore everything */
		the_port->ignore_status_mask &= ~N_DATA_READY;
	}

	if (cflag & CRTSCTS) {
		/* enable hardware flow control */
		port->ip_sscr |= SSCR_HFC_EN;
	}
	else {
		/* disable hardware flow control */
		port->ip_sscr &= ~SSCR_HFC_EN;
	}
	writel(port->ip_sscr, &port->ip_serial_regs->sscr);

	/* Set the configuration and proper notification call */
	DPRINT_CONFIG(("%s : port 0x%p line %d cflag 0%o "
		       "config_port(baud %d data %d stop %d penable %d "
			" parity %d), notification 0x%x\n",
		       __func__, (void *)port, the_port->line, cflag, baud,
		       new_data, new_stop, new_parity_enable, new_parity,
		       the_port->ignore_status_mask));

	if ((config_port(port, baud,	/* baud */
			 new_data,	/* byte size */
			 new_stop,	/* stop bits */
			 new_parity_enable,	/* set parity */
			 new_parity)) >= 0) {	/* parity 1==odd */
		set_notification(port, the_port->ignore_status_mask, 1);
	}
}

/**
 * ic3_startup_local - Start up the serial port - returns >= 0 if no errors
 * @the_port: Port to operate on
 */
static inline int ic3_startup_local(struct uart_port *the_port)
{
	struct ioc3_port *port;

	if (!the_port) {
		NOT_PROGRESS();
		return -1;
	}

	port = get_ioc3_port(the_port);
	if (!port) {
		NOT_PROGRESS();
		return -1;
	}

	local_open(port);

	/* set the protocol */
	ioc3_set_proto(port, IS_RS232(the_port->line) ? PROTO_RS232 :
							PROTO_RS422);
	return 0;
}

/*
 * ioc3_cb_output_lowat - called when the output low water mark is hit
 * @port: port to output
 */
static void ioc3_cb_output_lowat(struct ioc3_port *port)
{
	unsigned long pflags;

	/* the_port->lock is set on the call here */
	if (port->ip_port) {
		spin_lock_irqsave(&port->ip_port->lock, pflags);
		transmit_chars(port->ip_port);
		spin_unlock_irqrestore(&port->ip_port->lock, pflags);
	}
}

/*
 * ioc3_cb_post_ncs - called for some basic errors
 * @port: port to use
 * @ncs: event
 */
static void ioc3_cb_post_ncs(struct uart_port *the_port, int ncs)
{
	struct uart_icount *icount;

	icount = &the_port->icount;

	if (ncs & NCS_BREAK)
		icount->brk++;
	if (ncs & NCS_FRAMING)
		icount->frame++;
	if (ncs & NCS_OVERRUN)
		icount->overrun++;
	if (ncs & NCS_PARITY)
		icount->parity++;
}

/**
 * do_read - Read in bytes from the port.  Return the number of bytes
 *			actually read.
 * @the_port: port to use
 * @buf: place to put the stuff we read
 * @len: how big 'buf' is
 */

static inline int do_read(struct uart_port *the_port, char *buf, int len)
{
	int prod_ptr, cons_ptr, total;
	struct ioc3_port *port = get_ioc3_port(the_port);
	struct ring *inring;
	struct ring_entry *entry;
	struct port_hooks *hooks = port->ip_hooks;
	int byte_num;
	char *sc;
	int loop_counter;

	BUG_ON(!(len >= 0));
	BUG_ON(!port);

	/* There is a nasty timing issue in the IOC3. When the rx_timer
	 * expires or the rx_high condition arises, we take an interrupt.
	 * At some point while servicing the interrupt, we read bytes from
	 * the ring buffer and re-arm the rx_timer.  However the rx_timer is
	 * not started until the first byte is received *after* it is armed,
	 * and any bytes pending in the rx construction buffers are not drained
	 * to memory until either there are 4 bytes available or the rx_timer
	 * expires.  This leads to a potential situation where data is left
	 * in the construction buffers forever - 1 to 3 bytes were received
	 * after the interrupt was generated but before the rx_timer was
	 * re-armed. At that point as long as no subsequent bytes are received
	 * the timer will never be started and the bytes will remain in the
	 * construction buffer forever.  The solution is to execute a DRAIN
	 * command after rearming the timer.  This way any bytes received before
	 * the DRAIN will be drained to memory, and any bytes received after
	 * the DRAIN will start the TIMER and be drained when it expires.
	 * Luckily, this only needs to be done when the DMA buffer is empty
	 * since there is no requirement that this function return all
	 * available data as long as it returns some.
	 */
	/* Re-arm the timer */

	writel(port->ip_rx_cons | SRCIR_ARM, &port->ip_serial_regs->srcir);

	prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
	cons_ptr = port->ip_rx_cons;

	if (prod_ptr == cons_ptr) {
		int reset_dma = 0;

		/* Input buffer appears empty, do a flush. */

		/* DMA must be enabled for this to work. */
		if (!(port->ip_sscr & SSCR_DMA_EN)) {
			port->ip_sscr |= SSCR_DMA_EN;
			reset_dma = 1;
		}

		/* Potential race condition: we must reload the srpir after
		 * issuing the drain command, otherwise we could think the rx
		 * buffer is empty, then take a very long interrupt, and when
		 * we come back it's full and we wait forever for the drain to
		 * complete.
		 */
		writel(port->ip_sscr | SSCR_RX_DRAIN,
		       &port->ip_serial_regs->sscr);
		prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;

		/* We must not wait for the DRAIN to complete unless there are
		 * at least 8 bytes (2 ring entries) available to receive the
		 * data otherwise the DRAIN will never complete and we'll
		 * deadlock here.
		 * In fact, to make things easier, I'll just ignore the flush if
		 * there is any data at all now available.
		 */
		if (prod_ptr == cons_ptr) {
			loop_counter = 0;
			while (readl(&port->ip_serial_regs->sscr) &
			       SSCR_RX_DRAIN) {
				loop_counter++;
				if (loop_counter > MAXITER)
					return -1;
			}

			/* SIGH. We have to reload the prod_ptr *again* since
			 * the drain may have caused it to change
			 */
			prod_ptr = readl(&port->ip_serial_regs->srpir)
			    & PROD_CONS_MASK;
		}
		if (reset_dma) {
			port->ip_sscr &= ~SSCR_DMA_EN;
			writel(port->ip_sscr, &port->ip_serial_regs->sscr);
		}
	}
	inring = port->ip_inring;
	port->ip_flags &= ~READ_ABORTED;

	total = 0;
	loop_counter = 0xfffff;	/* to avoid hangs */

	/* Grab bytes from the hardware */
	while ((prod_ptr != cons_ptr) && (len > 0)) {
		entry = (struct ring_entry *)((caddr_t) inring + cons_ptr);

		if (loop_counter-- <= 0) {
			printk(KERN_WARNING "IOC3 serial: "
			       "possible hang condition/"
			       "port stuck on read (line %d).\n",
				the_port->line);
			break;
		}

		/* According to the producer pointer, this ring entry
		 * must contain some data.  But if the PIO happened faster
		 * than the DMA, the data may not be available yet, so let's
		 * wait until it arrives.
		 */
		if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
			/* Indicate the read is aborted so we don't disable
			 * the interrupt thinking that the consumer is
			 * congested.
			 */
			port->ip_flags |= READ_ABORTED;
			len = 0;
			break;
		}

		/* Load the bytes/status out of the ring entry */
		for (byte_num = 0; byte_num < 4 && len > 0; byte_num++) {
			sc = &(entry->ring_sc[byte_num]);

			/* Check for change in modem state or overrun */
			if ((*sc & RXSB_MODEM_VALID)
			    && (port->ip_notify & N_DDCD)) {
				/* Notify upper layer if DCD dropped */
				if ((port->ip_flags & DCD_ON)
				    && !(*sc & RXSB_DCD)) {
					/* If we have already copied some data,
					 * return it.  We'll pick up the carrier
					 * drop on the next pass.  That way we
					 * don't throw away the data that has
					 * already been copied back to
					 * the caller's buffer.
					 */
					if (total > 0) {
						len = 0;
						break;
					}
					port->ip_flags &= ~DCD_ON;

					/* Turn off this notification so the
					 * carrier drop protocol won't see it
					 * again when it does a read.
					 */
					*sc &= ~RXSB_MODEM_VALID;

					/* To keep things consistent, we need
					 * to update the consumer pointer so
					 * the next reader won't come in and
					 * try to read the same ring entries
					 * again. This must be done here before
					 * the dcd change.
					 */

					if ((entry->ring_allsc & RING_ANY_VALID)
					    == 0) {
						cons_ptr += (int)sizeof
						    (struct ring_entry);
						cons_ptr &= PROD_CONS_MASK;
					}
					writel(cons_ptr,
					       &port->ip_serial_regs->srcir);
					port->ip_rx_cons = cons_ptr;

					/* Notify upper layer of carrier drop */
					if ((port->ip_notify & N_DDCD)
					    && port->ip_port) {
						uart_handle_dcd_change
							(port->ip_port, 0);
						wake_up_interruptible
						    (&the_port->info->
						     delta_msr_wait);
					}

					/* If we had any data to return, we
					 * would have returned it above.
					 */
					return 0;
				}
			}
			if (*sc & RXSB_MODEM_VALID) {
				/* Notify that an input overrun occurred */
				if ((*sc & RXSB_OVERRUN)
				    && (port->ip_notify & N_OVERRUN_ERROR)) {
					ioc3_cb_post_ncs(the_port, NCS_OVERRUN);
				}
				/* Don't look at this byte again */
				*sc &= ~RXSB_MODEM_VALID;
			}

			/* Check for valid data or RX errors */
			if ((*sc & RXSB_DATA_VALID) &&
			    ((*sc & (RXSB_PAR_ERR
				     | RXSB_FRAME_ERR | RXSB_BREAK))
			     && (port->ip_notify & (N_PARITY_ERROR
						    | N_FRAMING_ERROR
						    | N_BREAK)))) {
				/* There is an error condition on the next byte.
				 * If we have already transferred some bytes,
				 * we'll stop here. Otherwise if this is the
				 * first byte to be read, we'll just transfer
				 * it alone after notifying the
				 * upper layer of its status.
				 */
				if (total > 0) {
					len = 0;
					break;
				} else {
					if ((*sc & RXSB_PAR_ERR) &&
					    (port->
					     ip_notify & N_PARITY_ERROR)) {
						ioc3_cb_post_ncs(the_port,
								 NCS_PARITY);
					}
					if ((*sc & RXSB_FRAME_ERR) &&
					    (port->
					     ip_notify & N_FRAMING_ERROR)) {
						ioc3_cb_post_ncs(the_port,
								 NCS_FRAMING);
					}
					if ((*sc & RXSB_BREAK)
					    && (port->ip_notify & N_BREAK)) {
						ioc3_cb_post_ncs
						    (the_port, NCS_BREAK);
					}
					len = 1;
				}
			}
			if (*sc & RXSB_DATA_VALID) {
				*sc &= ~RXSB_DATA_VALID;
				*buf = entry->ring_data[byte_num];
				buf++;
				len--;
				total++;
			}
		}

		/* If we used up this entry entirely, go on to the next one,
		 * otherwise we must have run out of buffer space, so
		 * leave the consumer pointer here for the next read in case
		 * there are still unread bytes in this entry.
		 */
		if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
			cons_ptr += (int)sizeof(struct ring_entry);
			cons_ptr &= PROD_CONS_MASK;
		}
	}

	/* Update consumer pointer and re-arm rx timer interrupt */
	writel(cons_ptr, &port->ip_serial_regs->srcir);
	port->ip_rx_cons = cons_ptr;

	/* If we have now dipped below the rx high water mark and we have
	 * rx_high interrupt turned off, we can now turn it back on again.
	 */
	if ((port->ip_flags & INPUT_HIGH) && (((prod_ptr - cons_ptr)
					       & PROD_CONS_MASK) <
					      ((port->
						ip_sscr &
						SSCR_RX_THRESHOLD)
					       << PROD_CONS_PTR_OFF))) {
		port->ip_flags &= ~INPUT_HIGH;
		enable_intrs(port, hooks->intr_rx_high);
	}
	return total;
}

/**
 * receive_chars - upper level read.
 * @the_port: port to read from
 */
static int receive_chars(struct uart_port *the_port)
{
	struct tty_struct *tty;
	unsigned char ch[MAX_CHARS];
	int read_count = 0, read_room, flip = 0;
	struct uart_info *info = the_port->info;
	struct ioc3_port *port = get_ioc3_port(the_port);
	unsigned long pflags;

	/* Make sure all the pointers are "good" ones */
	if (!info)
		return 0;
	if (!info->port.tty)
		return 0;

	if (!(port->ip_flags & INPUT_ENABLE))
		return 0;

	spin_lock_irqsave(&the_port->lock, pflags);
	tty = info->port.tty;

	read_count = do_read(the_port, ch, MAX_CHARS);
	if (read_count > 0) {
		flip = 1;
		read_room = tty_buffer_request_room(tty, read_count);
		tty_insert_flip_string(tty, ch, read_room);
		the_port->icount.rx += read_count;
	}
	spin_unlock_irqrestore(&the_port->lock, pflags);

	if (flip)
		tty_flip_buffer_push(tty);

	return read_count;
}

/**
 * ioc3uart_intr_one - lowest level (per port) interrupt handler.
 * @is : submodule
 * @idd: driver data
 * @pending: interrupts to handle
 */

static int inline
ioc3uart_intr_one(struct ioc3_submodule *is,
			struct ioc3_driver_data *idd,
			unsigned int pending)
{
	int port_num = GET_PORT_FROM_SIO_IR(pending);
	struct port_hooks *hooks;
	unsigned int rx_high_rd_aborted = 0;
	unsigned long flags;
	struct uart_port *the_port;
	struct ioc3_port *port;
	int loop_counter;
	struct ioc3_card *card_ptr;
	unsigned int sio_ir;

	card_ptr = idd->data[is->id];
	port = card_ptr->ic_port[port_num].icp_port;
	hooks = port->ip_hooks;

	/* Possible race condition here: The tx_mt interrupt bit may be
	 * cleared without the intervention of the interrupt handler,
	 * e.g. by a write.  If the top level interrupt handler reads a
	 * tx_mt, then some other processor does a write, starting up
	 * output, then we come in here, see the tx_mt and stop DMA, the
	 * output started by the other processor will hang.  Thus we can
	 * only rely on tx_mt being legitimate if it is read while the
	 * port lock is held.  Therefore this bit must be ignored in the
	 * passed in interrupt mask which was read by the top level
	 * interrupt handler since the port lock was not held at the time
	 * it was read.  We can only rely on this bit being accurate if it
	 * is read while the port lock is held.  So we'll clear it for now,
	 * and reload it later once we have the port lock.
	 */

	sio_ir = pending & ~(hooks->intr_tx_mt);
	spin_lock_irqsave(&port->ip_lock, flags);

	loop_counter = MAXITER;	/* to avoid hangs */

	do {
		uint32_t shadow;

		if (loop_counter-- <= 0) {
			printk(KERN_WARNING "IOC3 serial: "
			       "possible hang condition/"
			       "port stuck on interrupt (line %d).\n",
				((struct uart_port *)port->ip_port)->line);
			break;
		}
		/* Handle a DCD change */
		if (sio_ir & hooks->intr_delta_dcd) {
			ioc3_ack(is, idd, hooks->intr_delta_dcd);
			shadow = readl(&port->ip_serial_regs->shadow);

			if ((port->ip_notify & N_DDCD)
			    && (shadow & SHADOW_DCD)
			    && (port->ip_port)) {
				the_port = port->ip_port;
				uart_handle_dcd_change(the_port,
						shadow & SHADOW_DCD);
				wake_up_interruptible
				    (&the_port->info->delta_msr_wait);
			} else if ((port->ip_notify & N_DDCD)
				   && !(shadow & SHADOW_DCD)) {
				/* Flag delta DCD/no DCD */
				uart_handle_dcd_change(port->ip_port,
						shadow & SHADOW_DCD);
				port->ip_flags |= DCD_ON;
			}
		}

		/* Handle a CTS change */
		if (sio_ir & hooks->intr_delta_cts) {
			ioc3_ack(is, idd, hooks->intr_delta_cts);
			shadow = readl(&port->ip_serial_regs->shadow);

			if ((port->ip_notify & N_DCTS) && (port->ip_port)) {
				the_port = port->ip_port;
				uart_handle_cts_change(the_port, shadow
						& SHADOW_CTS);
				wake_up_interruptible
				    (&the_port->info->delta_msr_wait);
			}
		}

		/* rx timeout interrupt.  Must be some data available.  Put this
		 * before the check for rx_high since servicing this condition
		 * may cause that condition to clear.
		 */
		if (sio_ir & hooks->intr_rx_timer) {
			ioc3_ack(is, idd, hooks->intr_rx_timer);
			if ((port->ip_notify & N_DATA_READY)
						&& (port->ip_port)) {
				receive_chars(port->ip_port);
			}
		}

		/* rx high interrupt. Must be after rx_timer.  */
		else if (sio_ir & hooks->intr_rx_high) {
			/* Data available, notify upper layer */
			if ((port->ip_notify & N_DATA_READY) && port->ip_port) {
				receive_chars(port->ip_port);
			}

			/* We can't ACK this interrupt.  If receive_chars didn't
			 * cause the condition to clear, we'll have to disable
			 * the interrupt until the data is drained.
			 * If the read was aborted, don't disable the interrupt
			 * as this may cause us to hang indefinitely.  An
			 * aborted read generally means that this interrupt
			 * hasn't been delivered to the cpu yet anyway, even
			 * though we see it as asserted when we read the sio_ir.
			 */
			if ((sio_ir = PENDING(card_ptr, idd))
					& hooks->intr_rx_high) {
				if (port->ip_flags & READ_ABORTED) {
					rx_high_rd_aborted++;
				}
				else {
					card_ptr->ic_enable &= ~hooks->intr_rx_high;
					port->ip_flags |= INPUT_HIGH;
				}
			}
		}

		/* We got a low water interrupt: notify upper layer to
		 * send more data.  Must come before tx_mt since servicing
		 * this condition may cause that condition to clear.
		 */
		if (sio_ir & hooks->intr_tx_explicit) {
			port->ip_flags &= ~LOWAT_WRITTEN;
			ioc3_ack(is, idd, hooks->intr_tx_explicit);
			if (port->ip_notify & N_OUTPUT_LOWAT)
				ioc3_cb_output_lowat(port);
		}

		/* Handle tx_mt.  Must come after tx_explicit.  */
		else if (sio_ir & hooks->intr_tx_mt) {
			/* If we are expecting a lowat notification
			 * and we get to this point it probably means that for
			 * some reason the tx_explicit didn't work as expected
			 * (that can legitimately happen if the output buffer is
			 * filled up in just the right way).
			 * So send the notification now.
			 */
			if (port->ip_notify & N_OUTPUT_LOWAT) {
				ioc3_cb_output_lowat(port);

				/* We need to reload the sio_ir since the lowat
				 * call may have caused another write to occur,
				 * clearing the tx_mt condition.
				 */
				sio_ir = PENDING(card_ptr, idd);
			}

			/* If the tx_mt condition still persists even after the
			 * lowat call, we've got some work to do.
			 */
			if (sio_ir & hooks->intr_tx_mt) {
				/* If we are not currently expecting DMA input,
				 * and the transmitter has just gone idle,
				 * there is no longer any reason for DMA, so
				 * disable it.
				 */
				if (!(port->ip_notify
				      & (N_DATA_READY | N_DDCD))) {
					BUG_ON(!(port->ip_sscr
						 & SSCR_DMA_EN));
					port->ip_sscr &= ~SSCR_DMA_EN;
					writel(port->ip_sscr,
					       &port->ip_serial_regs->sscr);
				}
				/* Prevent infinite tx_mt interrupt */
				card_ptr->ic_enable &= ~hooks->intr_tx_mt;
			}
		}
		sio_ir = PENDING(card_ptr, idd);

		/* if the read was aborted and only hooks->intr_rx_high,
		 * clear hooks->intr_rx_high, so we do not loop forever.
		 */

		if (rx_high_rd_aborted && (sio_ir == hooks->intr_rx_high)) {
			sio_ir &= ~hooks->intr_rx_high;
		}
	} while (sio_ir & hooks->intr_all);

	spin_unlock_irqrestore(&port->ip_lock, flags);
	ioc3_enable(is, idd, card_ptr->ic_enable);
	return 0;
}

/**
 * ioc3uart_intr - field all serial interrupts
 * @is : submodule
 * @idd: driver data
 * @pending: interrupts to handle
 *
 */

static int ioc3uart_intr(struct ioc3_submodule *is,
			struct ioc3_driver_data *idd,
			unsigned int pending)
{
	int ret = 0;

	/*
	 * The upper level interrupt handler sends interrupts for both ports
	 * here. So we need to call for each port with its interrupts.
	 */

	if (pending & SIO_IR_SA)
		ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SA);
	if (pending & SIO_IR_SB)
		ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SB);

	return ret;
}

/**
 * ic3_type
 * @port: Port to operate with (we ignore since we only have one port)
 *
 */
static const char *ic3_type(struct uart_port *the_port)
{
	if (IS_RS232(the_port->line))
		return "SGI IOC3 Serial [rs232]";
	else
		return "SGI IOC3 Serial [rs422]";
}

/**
 * ic3_tx_empty - Is the transmitter empty?
 * @port: Port to operate on
 *
 */
static unsigned int ic3_tx_empty(struct uart_port *the_port)
{
	unsigned int ret = 0;
	struct ioc3_port *port = get_ioc3_port(the_port);

	if (readl(&port->ip_serial_regs->shadow) & SHADOW_TEMT)
		ret = TIOCSER_TEMT;
	return ret;
}

/**
 * ic3_stop_tx - stop the transmitter
 * @port: Port to operate on
 *
 */
static void ic3_stop_tx(struct uart_port *the_port)
{
	struct ioc3_port *port = get_ioc3_port(the_port);

	if (port)
		set_notification(port, N_OUTPUT_LOWAT, 0);
}

/**
 * ic3_stop_rx - stop the receiver
 * @port: Port to operate on
 *
 */
static void ic3_stop_rx(struct uart_port *the_port)
{
	struct ioc3_port *port = get_ioc3_port(the_port);

	if (port)
		port->ip_flags &= ~INPUT_ENABLE;
}

/**
 * null_void_function
 * @port: Port to operate on
 *
 */
static void null_void_function(struct uart_port *the_port)
{
}

/**
 * ic3_shutdown - shut down the port - free irq and disable
 * @port: port to shut down
 *
 */
static void ic3_shutdown(struct uart_port *the_port)
{
	unsigned long port_flags;
	struct ioc3_port *port;
	struct uart_info *info;

	port = get_ioc3_port(the_port);
	if (!port)
		return;

	info = the_port->info;
	wake_up_interruptible(&info->delta_msr_wait);

	spin_lock_irqsave(&the_port->lock, port_flags);
	set_notification(port, N_ALL, 0);
	spin_unlock_irqrestore(&the_port->lock, port_flags);
}

/**
 * ic3_set_mctrl - set control lines (dtr, rts, etc)
 * @port: Port to operate on
 * @mctrl: Lines to set/unset
 *
 */
static void ic3_set_mctrl(struct uart_port *the_port, unsigned int mctrl)
{
	unsigned char mcr = 0;

	if (mctrl & TIOCM_RTS)
		mcr |= UART_MCR_RTS;
	if (mctrl & TIOCM_DTR)
		mcr |= UART_MCR_DTR;
	if (mctrl & TIOCM_OUT1)
		mcr |= UART_MCR_OUT1;
	if (mctrl & TIOCM_OUT2)
		mcr |= UART_MCR_OUT2;
	if (mctrl & TIOCM_LOOP)
		mcr |= UART_MCR_LOOP;

	set_mcr(the_port, mcr, SHADOW_DTR);
}

/**
 * ic3_get_mctrl - get control line info
 * @port: port to operate on
 *
 */
static unsigned int ic3_get_mctrl(struct uart_port *the_port)
{
	struct ioc3_port *port = get_ioc3_port(the_port);
	uint32_t shadow;
	unsigned int ret = 0;

	if (!port)
		return 0;

	shadow = readl(&port->ip_serial_regs->shadow);
	if (shadow & SHADOW_DCD)
		ret |= TIOCM_CD;
	if (shadow & SHADOW_DR)
		ret |= TIOCM_DSR;
	if (shadow & SHADOW_CTS)
		ret |= TIOCM_CTS;
	return ret;
}

/**
 * ic3_start_tx - Start transmitter. Called with the_port->lock
 * @port: Port to operate on
 *
 */
static void ic3_start_tx(struct uart_port *the_port)
{
	struct ioc3_port *port = get_ioc3_port(the_port);

	if (port) {
		set_notification(port, N_OUTPUT_LOWAT, 1);
		enable_intrs(port, port->ip_hooks->intr_tx_mt);
	}
}

/**
 * ic3_break_ctl - handle breaks
 * @port: Port to operate on
 * @break_state: Break state
 *
 */
static void ic3_break_ctl(struct uart_port *the_port, int break_state)
{
}

/**
 * ic3_startup - Start up the serial port - always return 0 (We're always on)
 * @port: Port to operate on
 *
 */
static int ic3_startup(struct uart_port *the_port)
{
	int retval;
	struct ioc3_port *port;
	struct ioc3_card *card_ptr;
	unsigned long port_flags;

	if (!the_port) {
		NOT_PROGRESS();
		return -ENODEV;
	}
	port = get_ioc3_port(the_port);
	if (!port) {
		NOT_PROGRESS();
		return -ENODEV;
	}
	card_ptr = port->ip_card;
	port->ip_port = the_port;

	if (!card_ptr) {
		NOT_PROGRESS();
		return -ENODEV;
	}

	/* Start up the serial port */
	spin_lock_irqsave(&the_port->lock, port_flags);
	retval = ic3_startup_local(the_port);
	spin_unlock_irqrestore(&the_port->lock, port_flags);
	return retval;
}

/**
 * ic3_set_termios - set termios stuff
 * @port: port to operate on
 * @termios: New settings
 * @termios: Old
 *
 */
static void
ic3_set_termios(struct uart_port *the_port,
		struct ktermios *termios, struct ktermios *old_termios)
{
	unsigned long port_flags;

	spin_lock_irqsave(&the_port->lock, port_flags);
	ioc3_change_speed(the_port, termios, old_termios);
	spin_unlock_irqrestore(&the_port->lock, port_flags);
}

/**
 * ic3_request_port - allocate resources for port - no op....
 * @port: port to operate on
 *
 */
static int ic3_request_port(struct uart_port *port)
{
	return 0;
}

/* Associate the uart functions above - given to serial core */
static struct uart_ops ioc3_ops = {
	.tx_empty = ic3_tx_empty,
	.set_mctrl = ic3_set_mctrl,
	.get_mctrl = ic3_get_mctrl,
	.stop_tx = ic3_stop_tx,
	.start_tx = ic3_start_tx,
	.stop_rx = ic3_stop_rx,
	.enable_ms = null_void_function,
	.break_ctl = ic3_break_ctl,
	.startup = ic3_startup,
	.shutdown = ic3_shutdown,
	.set_termios = ic3_set_termios,
	.type = ic3_type,
	.release_port = null_void_function,
	.request_port = ic3_request_port,
};

/*
 * Boot-time initialization code
 */

static struct uart_driver ioc3_uart = {
	.owner = THIS_MODULE,
	.driver_name = "ioc3_serial",
	.dev_name = DEVICE_NAME,
	.major = DEVICE_MAJOR,
	.minor = DEVICE_MINOR,
	.nr = MAX_LOGICAL_PORTS
};

/**
 * ioc3_serial_core_attach - register with serial core
 *		This is done during pci probing
 * @is: submodule struct for this
 * @idd: handle for this card
 */
static inline int ioc3_serial_core_attach( struct ioc3_submodule *is,
				struct ioc3_driver_data *idd)
{
	struct ioc3_port *port;
	struct uart_port *the_port;
	struct ioc3_card *card_ptr = idd->data[is->id];
	int ii, phys_port;
	struct pci_dev *pdev = idd->pdev;

	DPRINT_CONFIG(("%s: attach pdev 0x%p - card_ptr 0x%p\n",
		       __func__, pdev, (void *)card_ptr));

	if (!card_ptr)
		return -ENODEV;

	/* once around for each logical port on this card */
	for (ii = 0; ii < LOGICAL_PORTS_PER_CARD; ii++) {
		phys_port = GET_PHYSICAL_PORT(ii);
		the_port = &card_ptr->ic_port[phys_port].
				icp_uart_port[GET_LOGICAL_PORT(ii)];
		port = card_ptr->ic_port[phys_port].icp_port;
		port->ip_port = the_port;

		DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p [%d/%d]\n",
			__func__, (void *)the_port, (void *)port,
				phys_port, ii));

		/* membase, iobase and mapbase just need to be non-0 */
		the_port->membase = (unsigned char __iomem *)1;
		the_port->iobase = (pdev->bus->number << 16) |  ii;
		the_port->line = (Num_of_ioc3_cards << 2) | ii;
		the_port->mapbase = 1;
		the_port->type = PORT_16550A;
		the_port->fifosize = FIFO_SIZE;
		the_port->ops = &ioc3_ops;
		the_port->irq = idd->irq_io;
		the_port->dev = &pdev->dev;

		if (uart_add_one_port(&ioc3_uart, the_port) < 0) {
			printk(KERN_WARNING
		          "%s: unable to add port %d bus %d\n",
			       __func__, the_port->line, pdev->bus->number);
		} else {
			DPRINT_CONFIG(("IOC3 serial port %d irq %d bus %d\n",
		          the_port->line, the_port->irq, pdev->bus->number));
		}

		/* all ports are rs232 for now */
		if (IS_PHYSICAL_PORT(ii))
			ioc3_set_proto(port, PROTO_RS232);
	}
	return 0;
}

/**
 * ioc3uart_remove - register detach function
 * @is: submodule struct for this submodule
 * @idd: ioc3 driver data for this submodule
 */

static int ioc3uart_remove(struct ioc3_submodule *is,
			struct ioc3_driver_data *idd)
{
	struct ioc3_card *card_ptr = idd->data[is->id];
	struct uart_port *the_port;
	struct ioc3_port *port;
	int ii;

	if (card_ptr) {
		for (ii = 0; ii < LOGICAL_PORTS_PER_CARD; ii++) {
			the_port = &card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].
					icp_uart_port[GET_LOGICAL_PORT(ii)];
			if (the_port)
				uart_remove_one_port(&ioc3_uart, the_port);
			port = card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].icp_port;
			if (port && IS_PHYSICAL_PORT(ii)
					&& (GET_PHYSICAL_PORT(ii) == 0)) {
				pci_free_consistent(port->ip_idd->pdev,
					TOTAL_RING_BUF_SIZE,
					(void *)port->ip_cpu_ringbuf,
					port->ip_dma_ringbuf);
				kfree(port);
				card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].
							icp_port = NULL;
			}
		}
		kfree(card_ptr);
		idd->data[is->id] = NULL;
	}
	return 0;
}

/**
 * ioc3uart_probe - card probe function called from shim driver
 * @is: submodule struct for this submodule
 * @idd: ioc3 driver data for this card
 */

static int __devinit
ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
{
	struct pci_dev *pdev = idd->pdev;
	struct ioc3_card *card_ptr;
	int ret = 0;
	struct ioc3_port *port;
	struct ioc3_port *ports[PORTS_PER_CARD];
	int phys_port;

	DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd));

	card_ptr = kzalloc(sizeof(struct ioc3_card), GFP_KERNEL);
	if (!card_ptr) {
		printk(KERN_WARNING "ioc3_attach_one"
		       ": unable to get memory for the IOC3\n");
		return -ENOMEM;
	}
	idd->data[is->id] = card_ptr;
	Submodule_slot = is->id;

	writel(((UARTA_BASE >> 3) << SIO_CR_SER_A_BASE_SHIFT) |
		((UARTB_BASE >> 3) << SIO_CR_SER_B_BASE_SHIFT) |
		(0xf << SIO_CR_CMD_PULSE_SHIFT), &idd->vma->sio_cr);

	pci_write_config_dword(pdev, PCI_LAT, 0xff00);

	/* Enable serial port mode select generic PIO pins as outputs */
	ioc3_gpcr_set(idd, GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL);

	/* Create port structures for each port */
	for (phys_port = 0; phys_port < PORTS_PER_CARD; phys_port++) {
		port = kzalloc(sizeof(struct ioc3_port), GFP_KERNEL);
		if (!port) {
			printk(KERN_WARNING
			       "IOC3 serial memory not available for port\n");
			goto out4;
		}
		spin_lock_init(&port->ip_lock);

		/* we need to remember the previous ones, to point back to
		 * them farther down - setting up the ring buffers.
		 */
		ports[phys_port] = port;

		/* init to something useful */
		card_ptr->ic_port[phys_port].icp_port = port;
		port->ip_is = is;
		port->ip_idd = idd;
		port->ip_baud = 9600;
		port->ip_card = card_ptr;
		port->ip_hooks = &hooks_array[phys_port];

		/* Setup each port */
		if (phys_port == 0) {
			port->ip_serial_regs = &idd->vma->port_a;
			port->ip_uart_regs = &idd->vma->sregs.uarta;

			DPRINT_CONFIG(("%s : Port A ip_serial_regs 0x%p "
				       "ip_uart_regs 0x%p\n",
				       __func__,
				       (void *)port->ip_serial_regs,
				       (void *)port->ip_uart_regs));

			/* setup ring buffers */
			port->ip_cpu_ringbuf = pci_alloc_consistent(pdev,
				TOTAL_RING_BUF_SIZE, &port->ip_dma_ringbuf);

			BUG_ON(!((((int64_t) port->ip_dma_ringbuf) &
				  (TOTAL_RING_BUF_SIZE - 1)) == 0));
			port->ip_inring = RING(port, RX_A);
			port->ip_outring = RING(port, TX_A);
			DPRINT_CONFIG(("%s : Port A ip_cpu_ringbuf 0x%p "
				       "ip_dma_ringbuf 0x%p, ip_inring 0x%p "
					"ip_outring 0x%p\n",
				       __func__,
				       (void *)port->ip_cpu_ringbuf,
				       (void *)port->ip_dma_ringbuf,
				       (void *)port->ip_inring,
				       (void *)port->ip_outring));
		}
		else {
			port->ip_serial_regs = &idd->vma->port_b;
			port->ip_uart_regs = &idd->vma->sregs.uartb;

			DPRINT_CONFIG(("%s : Port B ip_serial_regs 0x%p "
				       "ip_uart_regs 0x%p\n",
				       __func__,
				       (void *)port->ip_serial_regs,
				       (void *)port->ip_uart_regs));

			/* share the ring buffers */
			port->ip_dma_ringbuf =
			    ports[phys_port - 1]->ip_dma_ringbuf;
			port->ip_cpu_ringbuf =
			    ports[phys_port - 1]->ip_cpu_ringbuf;
			port->ip_inring = RING(port, RX_B);
			port->ip_outring = RING(port, TX_B);
			DPRINT_CONFIG(("%s : Port B ip_cpu_ringbuf 0x%p "
				       "ip_dma_ringbuf 0x%p, ip_inring 0x%p "
					"ip_outring 0x%p\n",
				       __func__,
				       (void *)port->ip_cpu_ringbuf,
				       (void *)port->ip_dma_ringbuf,
				       (void *)port->ip_inring,
				       (void *)port->ip_outring));
		}

		DPRINT_CONFIG(("%s : port %d [addr 0x%p] card_ptr 0x%p",
			       __func__,
			       phys_port, (void *)port, (void *)card_ptr));
		DPRINT_CONFIG((" ip_serial_regs 0x%p ip_uart_regs 0x%p\n",
			       (void *)port->ip_serial_regs,
			       (void *)port->ip_uart_regs));

		/* Initialize the hardware for IOC3 */
		port_init(port);

		DPRINT_CONFIG(("%s: phys_port %d port 0x%p inring 0x%p "
			       "outring 0x%p\n",
			       __func__,
			       phys_port, (void *)port,
			       (void *)port->ip_inring,
			       (void *)port->ip_outring));

	}

	/* register port with the serial core */

	if ((ret = ioc3_serial_core_attach(is, idd)))
		goto out4;

	Num_of_ioc3_cards++;

	return ret;

	/* error exits that give back resources */
out4:
	kfree(card_ptr);
	return ret;
}

static struct ioc3_submodule ioc3uart_submodule = {
	.name = "IOC3uart",
	.probe = ioc3uart_probe,
	.remove = ioc3uart_remove,
	/* call .intr for both ports initially */
	.irq_mask = SIO_IR_SA | SIO_IR_SB,
	.intr = ioc3uart_intr,
	.owner = THIS_MODULE,
};

/**
 * ioc3_detect - module init called,
 */
static int __devinit ioc3uart_init(void)
{
	int ret;

	/* register with serial core */
	if ((ret = uart_register_driver(&ioc3_uart)) < 0) {
		printk(KERN_WARNING
		       "%s: Couldn't register IOC3 uart serial driver\n",
		       __func__);
		return ret;
	}
	ret = ioc3_register_submodule(&ioc3uart_submodule);
	if (ret)
		uart_unregister_driver(&ioc3_uart);
	return ret;
}

static void __devexit ioc3uart_exit(void)
{
	ioc3_unregister_submodule(&ioc3uart_submodule);
	uart_unregister_driver(&ioc3_uart);
}

module_init(ioc3uart_init);
module_exit(ioc3uart_exit);

MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
MODULE_DESCRIPTION("Serial PCI driver module for SGI IOC3 card");
MODULE_LICENSE("GPL");
