/*
 * 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>
#include <linux/slab.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_state *state;

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

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

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

	head = state->xmit.head;
	tail = state->xmit.tail;
	start = (char *)&state->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;
			state->xmit.tail = tail;
			start = (char *)&state->xmit.buf[tail];
		}
	}
	if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
		uart_write_wakeup(the_port);

	if (uart_circ_empty(&state->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, iflag;
	int baud;
	int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
	struct uart_state *state = the_port->state;

	cflag = new_termios->c_cflag;
	iflag = new_termios->c_iflag;

	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;

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

	if (iflag & IGNPAR)
		the_port->ignore_status_mask &= ~(N_PARITY_ERROR
						  | N_FRAMING_ERROR);
	if (iflag & IGNBRK) {
		the_port->ignore_status_mask &= ~N_BREAK;
		if (iflag & IGNPAR)
			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->state->
						     port.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_state *state = the_port->state;
	struct ioc3_port *port = get_ioc3_port(the_port);
	unsigned long pflags;

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

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

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

	read_count = do_read(the_port, ch, MAX_CHARS);
	if (read_count > 0) {
		flip = 1;
		read_room = tty_insert_flip_string(tty, ch, read_count);
		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->state->port.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->state->port.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_state *state;

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

	state = the_port->state;
	wake_up_interruptible(&state->port.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;
	int cnt;

	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");
			ret = -ENOMEM;
			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:
	for (cnt = 0; cnt < phys_port; cnt++)
		kfree(ports[cnt]);

	kfree(card_ptr);
	return ret;
}

static struct ioc3_submodule ioc3uart_ops = {
	.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 __init 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_ops);
	if (ret)
		uart_unregister_driver(&ioc3_uart);
	return ret;
}

static void __exit ioc3uart_exit(void)
{
	ioc3_unregister_submodule(&ioc3uart_ops);
	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");
