// SPDX-License-Identifier: GPL-2.0
/*
 * UART driver for PNX8XXX SoCs
 *
 * Author: Per Hallsmark per.hallsmark@mvista.com
 * Ported to 2.6 kernel by EmbeddedAlley
 * Reworked by Vitaly Wool <vitalywool@gmail.com>
 *
 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
 * Copyright (C) 2000 Deep Blue Solutions Ltd.
 */

#if defined(CONFIG_SERIAL_PNX8XXX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#endif

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/serial_pnx8xxx.h>

#include <asm/io.h>
#include <asm/irq.h>

/* We'll be using StrongARM sa1100 serial port major/minor */
#define SERIAL_PNX8XXX_MAJOR	204
#define MINOR_START		5

#define NR_PORTS		2

#define PNX8XXX_ISR_PASS_LIMIT	256

/*
 * Convert from ignore_status_mask or read_status_mask to FIFO
 * and interrupt status bits
 */
#define SM_TO_FIFO(x)	((x) >> 10)
#define SM_TO_ISTAT(x)	((x) & 0x000001ff)
#define FIFO_TO_SM(x)	((x) << 10)
#define ISTAT_TO_SM(x)	((x) & 0x000001ff)

/*
 * This is the size of our serial port register set.
 */
#define UART_PORT_SIZE	0x1000

/*
 * This determines how often we check the modem status signals
 * for any change.  They generally aren't connected to an IRQ
 * so we have to poll them.  We also check immediately before
 * filling the TX fifo incase CTS has been dropped.
 */
#define MCTRL_TIMEOUT	(250*HZ/1000)

extern struct pnx8xxx_port pnx8xxx_ports[];

static inline int serial_in(struct pnx8xxx_port *sport, int offset)
{
	return (__raw_readl(sport->port.membase + offset));
}

static inline void serial_out(struct pnx8xxx_port *sport, int offset, int value)
{
	__raw_writel(value, sport->port.membase + offset);
}

/*
 * Handle any change of modem status signal since we were last called.
 */
static void pnx8xxx_mctrl_check(struct pnx8xxx_port *sport)
{
	unsigned int status, changed;

	status = sport->port.ops->get_mctrl(&sport->port);
	changed = status ^ sport->old_status;

	if (changed == 0)
		return;

	sport->old_status = status;

	if (changed & TIOCM_RI)
		sport->port.icount.rng++;
	if (changed & TIOCM_DSR)
		sport->port.icount.dsr++;
	if (changed & TIOCM_CAR)
		uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
	if (changed & TIOCM_CTS)
		uart_handle_cts_change(&sport->port, status & TIOCM_CTS);

	wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
}

/*
 * This is our per-port timeout handler, for checking the
 * modem status signals.
 */
static void pnx8xxx_timeout(struct timer_list *t)
{
	struct pnx8xxx_port *sport = from_timer(sport, t, timer);
	unsigned long flags;

	if (sport->port.state) {
		spin_lock_irqsave(&sport->port.lock, flags);
		pnx8xxx_mctrl_check(sport);
		spin_unlock_irqrestore(&sport->port.lock, flags);

		mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT);
	}
}

/*
 * interrupts disabled on entry
 */
static void pnx8xxx_stop_tx(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	u32 ien;

	/* Disable TX intr */
	ien = serial_in(sport, PNX8XXX_IEN);
	serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLTX);

	/* Clear all pending TX intr */
	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX);
}

/*
 * interrupts may not be disabled on entry
 */
static void pnx8xxx_start_tx(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	u32 ien;

	/* Clear all pending TX intr */
	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX);

	/* Enable TX intr */
	ien = serial_in(sport, PNX8XXX_IEN);
	serial_out(sport, PNX8XXX_IEN, ien | PNX8XXX_UART_INT_ALLTX);
}

/*
 * Interrupts enabled
 */
static void pnx8xxx_stop_rx(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	u32 ien;

	/* Disable RX intr */
	ien = serial_in(sport, PNX8XXX_IEN);
	serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLRX);

	/* Clear all pending RX intr */
	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX);
}

/*
 * Set the modem control timer to fire immediately.
 */
static void pnx8xxx_enable_ms(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);

	mod_timer(&sport->timer, jiffies);
}

static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
{
	unsigned int status, ch, flg;

	status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
		 ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT));
	while (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFIFO)) {
		ch = serial_in(sport, PNX8XXX_FIFO) & 0xff;

		sport->port.icount.rx++;

		flg = TTY_NORMAL;

		/*
		 * note that the error handling code is
		 * out of the main execution path
		 */
		if (status & (FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE |
					PNX8XXX_UART_FIFO_RXPAR |
					PNX8XXX_UART_FIFO_RXBRK) |
			      ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))) {
			if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXBRK)) {
				status &= ~(FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
					FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR));
				sport->port.icount.brk++;
				if (uart_handle_break(&sport->port))
					goto ignore_char;
			} else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR))
				sport->port.icount.parity++;
			else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE))
				sport->port.icount.frame++;
			if (status & ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))
				sport->port.icount.overrun++;

			status &= sport->port.read_status_mask;

			if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR))
				flg = TTY_PARITY;
			else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE))
				flg = TTY_FRAME;

#ifdef SUPPORT_SYSRQ
			sport->port.sysrq = 0;
#endif
		}

		if (uart_handle_sysrq_char(&sport->port, ch))
			goto ignore_char;

		uart_insert_char(&sport->port, status,
				ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN), ch, flg);

	ignore_char:
		serial_out(sport, PNX8XXX_LCR, serial_in(sport, PNX8XXX_LCR) |
				PNX8XXX_UART_LCR_RX_NEXT);
		status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
			 ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT));
	}

	spin_unlock(&sport->port.lock);
	tty_flip_buffer_push(&sport->port.state->port);
	spin_lock(&sport->port.lock);
}

static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport)
{
	struct circ_buf *xmit = &sport->port.state->xmit;

	if (sport->port.x_char) {
		serial_out(sport, PNX8XXX_FIFO, sport->port.x_char);
		sport->port.icount.tx++;
		sport->port.x_char = 0;
		return;
	}

	/*
	 * Check the modem control lines before
	 * transmitting anything.
	 */
	pnx8xxx_mctrl_check(sport);

	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
		pnx8xxx_stop_tx(&sport->port);
		return;
	}

	/*
	 * TX while bytes available
	 */
	while (((serial_in(sport, PNX8XXX_FIFO) &
					PNX8XXX_UART_FIFO_TXFIFO) >> 16) < 16) {
		serial_out(sport, PNX8XXX_FIFO, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		sport->port.icount.tx++;
		if (uart_circ_empty(xmit))
			break;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&sport->port);

	if (uart_circ_empty(xmit))
		pnx8xxx_stop_tx(&sport->port);
}

static irqreturn_t pnx8xxx_int(int irq, void *dev_id)
{
	struct pnx8xxx_port *sport = dev_id;
	unsigned int status;

	spin_lock(&sport->port.lock);
	/* Get the interrupts */
	status  = serial_in(sport, PNX8XXX_ISTAT) & serial_in(sport, PNX8XXX_IEN);

	/* Byte or break signal received */
	if (status & (PNX8XXX_UART_INT_RX | PNX8XXX_UART_INT_BREAK))
		pnx8xxx_rx_chars(sport);

	/* TX holding register empty - transmit a byte */
	if (status & PNX8XXX_UART_INT_TX)
		pnx8xxx_tx_chars(sport);

	/* Clear the ISTAT register */
	serial_out(sport, PNX8XXX_ICLR, status);

	spin_unlock(&sport->port.lock);
	return IRQ_HANDLED;
}

/*
 * Return TIOCSER_TEMT when transmitter is not busy.
 */
static unsigned int pnx8xxx_tx_empty(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);

	return serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA ? 0 : TIOCSER_TEMT;
}

static unsigned int pnx8xxx_get_mctrl(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	unsigned int mctrl = TIOCM_DSR;
	unsigned int msr;

	/* REVISIT */

	msr = serial_in(sport, PNX8XXX_MCR);

	mctrl |= msr & PNX8XXX_UART_MCR_CTS ? TIOCM_CTS : 0;
	mctrl |= msr & PNX8XXX_UART_MCR_DCD ? TIOCM_CAR : 0;

	return mctrl;
}

static void pnx8xxx_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
#if	0	/* FIXME */
	struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port;
	unsigned int msr;
#endif
}

/*
 * Interrupts always disabled.
 */
static void pnx8xxx_break_ctl(struct uart_port *port, int break_state)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	unsigned long flags;
	unsigned int lcr;

	spin_lock_irqsave(&sport->port.lock, flags);
	lcr = serial_in(sport, PNX8XXX_LCR);
	if (break_state == -1)
		lcr |= PNX8XXX_UART_LCR_TXBREAK;
	else
		lcr &= ~PNX8XXX_UART_LCR_TXBREAK;
	serial_out(sport, PNX8XXX_LCR, lcr);
	spin_unlock_irqrestore(&sport->port.lock, flags);
}

static int pnx8xxx_startup(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	int retval;

	/*
	 * Allocate the IRQ
	 */
	retval = request_irq(sport->port.irq, pnx8xxx_int, 0,
			     "pnx8xxx-uart", sport);
	if (retval)
		return retval;

	/*
	 * Finally, clear and enable interrupts
	 */

	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX |
			     PNX8XXX_UART_INT_ALLTX);

	serial_out(sport, PNX8XXX_IEN, serial_in(sport, PNX8XXX_IEN) |
			    PNX8XXX_UART_INT_ALLRX |
			    PNX8XXX_UART_INT_ALLTX);

	/*
	 * Enable modem status interrupts
	 */
	spin_lock_irq(&sport->port.lock);
	pnx8xxx_enable_ms(&sport->port);
	spin_unlock_irq(&sport->port.lock);

	return 0;
}

static void pnx8xxx_shutdown(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	int lcr;

	/*
	 * Stop our timer.
	 */
	del_timer_sync(&sport->timer);

	/*
	 * Disable all interrupts
	 */
	serial_out(sport, PNX8XXX_IEN, 0);

	/*
	 * Reset the Tx and Rx FIFOS, disable the break condition
	 */
	lcr = serial_in(sport, PNX8XXX_LCR);
	lcr &= ~PNX8XXX_UART_LCR_TXBREAK;
	lcr |= PNX8XXX_UART_LCR_TX_RST | PNX8XXX_UART_LCR_RX_RST;
	serial_out(sport, PNX8XXX_LCR, lcr);

	/*
	 * Clear all interrupts
	 */
	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX |
			     PNX8XXX_UART_INT_ALLTX);

	/*
	 * Free the interrupt
	 */
	free_irq(sport->port.irq, sport);
}

static void
pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios,
		   struct ktermios *old)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	unsigned long flags;
	unsigned int lcr_fcr, old_ien, baud, quot;
	unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;

	/*
	 * We only support CS7 and CS8.
	 */
	while ((termios->c_cflag & CSIZE) != CS7 &&
	       (termios->c_cflag & CSIZE) != CS8) {
		termios->c_cflag &= ~CSIZE;
		termios->c_cflag |= old_csize;
		old_csize = CS8;
	}

	if ((termios->c_cflag & CSIZE) == CS8)
		lcr_fcr = PNX8XXX_UART_LCR_8BIT;
	else
		lcr_fcr = 0;

	if (termios->c_cflag & CSTOPB)
		lcr_fcr |= PNX8XXX_UART_LCR_2STOPB;
	if (termios->c_cflag & PARENB) {
		lcr_fcr |= PNX8XXX_UART_LCR_PAREN;
		if (!(termios->c_cflag & PARODD))
			lcr_fcr |= PNX8XXX_UART_LCR_PAREVN;
	}

	/*
	 * Ask the core to calculate the divisor for us.
	 */
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
	quot = uart_get_divisor(port, baud);

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

	sport->port.read_status_mask = ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN) |
				ISTAT_TO_SM(PNX8XXX_UART_INT_EMPTY) |
				ISTAT_TO_SM(PNX8XXX_UART_INT_RX);
	if (termios->c_iflag & INPCK)
		sport->port.read_status_mask |=
			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR);
	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
		sport->port.read_status_mask |=
			ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK);

	/*
	 * Characters to ignore
	 */
	sport->port.ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		sport->port.ignore_status_mask |=
			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR);
	if (termios->c_iflag & IGNBRK) {
		sport->port.ignore_status_mask |=
			ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK);
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			sport->port.ignore_status_mask |=
				ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN);
	}

	/*
	 * ignore all characters if CREAD is not set
	 */
	if ((termios->c_cflag & CREAD) == 0)
		sport->port.ignore_status_mask |=
			ISTAT_TO_SM(PNX8XXX_UART_INT_RX);

	del_timer_sync(&sport->timer);

	/*
	 * Update the per-port timeout.
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	/*
	 * disable interrupts and drain transmitter
	 */
	old_ien = serial_in(sport, PNX8XXX_IEN);
	serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX |
					PNX8XXX_UART_INT_ALLRX));

	while (serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA)
		barrier();

	/* then, disable everything */
	serial_out(sport, PNX8XXX_IEN, 0);

	/* Reset the Rx and Tx FIFOs too */
	lcr_fcr |= PNX8XXX_UART_LCR_TX_RST;
	lcr_fcr |= PNX8XXX_UART_LCR_RX_RST;

	/* set the parity, stop bits and data size */
	serial_out(sport, PNX8XXX_LCR, lcr_fcr);

	/* set the baud rate */
	quot -= 1;
	serial_out(sport, PNX8XXX_BAUD, quot);

	serial_out(sport, PNX8XXX_ICLR, -1);

	serial_out(sport, PNX8XXX_IEN, old_ien);

	if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
		pnx8xxx_enable_ms(&sport->port);

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

static const char *pnx8xxx_type(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);

	return sport->port.type == PORT_PNX8XXX ? "PNX8XXX" : NULL;
}

/*
 * Release the memory region(s) being used by 'port'.
 */
static void pnx8xxx_release_port(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);

	release_mem_region(sport->port.mapbase, UART_PORT_SIZE);
}

/*
 * Request the memory region(s) being used by 'port'.
 */
static int pnx8xxx_request_port(struct uart_port *port)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	return request_mem_region(sport->port.mapbase, UART_PORT_SIZE,
			"pnx8xxx-uart") != NULL ? 0 : -EBUSY;
}

/*
 * Configure/autoconfigure the port.
 */
static void pnx8xxx_config_port(struct uart_port *port, int flags)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);

	if (flags & UART_CONFIG_TYPE &&
	    pnx8xxx_request_port(&sport->port) == 0)
		sport->port.type = PORT_PNX8XXX;
}

/*
 * Verify the new serial_struct (for TIOCSSERIAL).
 * The only change we allow are to the flags and type, and
 * even then only between PORT_PNX8XXX and PORT_UNKNOWN
 */
static int
pnx8xxx_verify_port(struct uart_port *port, struct serial_struct *ser)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port,	port);
	int ret = 0;

	if (ser->type != PORT_UNKNOWN && ser->type != PORT_PNX8XXX)
		ret = -EINVAL;
	if (sport->port.irq != ser->irq)
		ret = -EINVAL;
	if (ser->io_type != SERIAL_IO_MEM)
		ret = -EINVAL;
	if (sport->port.uartclk / 16 != ser->baud_base)
		ret = -EINVAL;
	if ((void *)sport->port.mapbase != ser->iomem_base)
		ret = -EINVAL;
	if (sport->port.iobase != ser->port)
		ret = -EINVAL;
	if (ser->hub6 != 0)
		ret = -EINVAL;
	return ret;
}

static const struct uart_ops pnx8xxx_pops = {
	.tx_empty	= pnx8xxx_tx_empty,
	.set_mctrl	= pnx8xxx_set_mctrl,
	.get_mctrl	= pnx8xxx_get_mctrl,
	.stop_tx	= pnx8xxx_stop_tx,
	.start_tx	= pnx8xxx_start_tx,
	.stop_rx	= pnx8xxx_stop_rx,
	.enable_ms	= pnx8xxx_enable_ms,
	.break_ctl	= pnx8xxx_break_ctl,
	.startup	= pnx8xxx_startup,
	.shutdown	= pnx8xxx_shutdown,
	.set_termios	= pnx8xxx_set_termios,
	.type		= pnx8xxx_type,
	.release_port	= pnx8xxx_release_port,
	.request_port	= pnx8xxx_request_port,
	.config_port	= pnx8xxx_config_port,
	.verify_port	= pnx8xxx_verify_port,
};


/*
 * Setup the PNX8XXX serial ports.
 *
 * Note also that we support "console=ttySx" where "x" is either 0 or 1.
 */
static void __init pnx8xxx_init_ports(void)
{
	static int first = 1;
	int i;

	if (!first)
		return;
	first = 0;

	for (i = 0; i < NR_PORTS; i++) {
		timer_setup(&pnx8xxx_ports[i].timer, pnx8xxx_timeout, 0);
		pnx8xxx_ports[i].port.ops = &pnx8xxx_pops;
	}
}

#ifdef CONFIG_SERIAL_PNX8XXX_CONSOLE

static void pnx8xxx_console_putchar(struct uart_port *port, int ch)
{
	struct pnx8xxx_port *sport =
		container_of(port, struct pnx8xxx_port, port);
	int status;

	do {
		/* Wait for UART_TX register to empty */
		status = serial_in(sport, PNX8XXX_FIFO);
	} while (status & PNX8XXX_UART_FIFO_TXFIFO);
	serial_out(sport, PNX8XXX_FIFO, ch);
}

/*
 * Interrupts are disabled on entering
 */static void
pnx8xxx_console_write(struct console *co, const char *s, unsigned int count)
{
	struct pnx8xxx_port *sport = &pnx8xxx_ports[co->index];
	unsigned int old_ien, status;

	/*
	 *	First, save IEN and then disable interrupts
	 */
	old_ien = serial_in(sport, PNX8XXX_IEN);
	serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX |
					PNX8XXX_UART_INT_ALLRX));

	uart_console_write(&sport->port, s, count, pnx8xxx_console_putchar);

	/*
	 *	Finally, wait for transmitter to become empty
	 *	and restore IEN
	 */
	do {
		/* Wait for UART_TX register to empty */
		status = serial_in(sport, PNX8XXX_FIFO);
	} while (status & PNX8XXX_UART_FIFO_TXFIFO);

	/* Clear TX and EMPTY interrupt */
	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_TX |
			     PNX8XXX_UART_INT_EMPTY);

	serial_out(sport, PNX8XXX_IEN, old_ien);
}

static int __init
pnx8xxx_console_setup(struct console *co, char *options)
{
	struct pnx8xxx_port *sport;
	int baud = 38400;
	int bits = 8;
	int parity = 'n';
	int flow = 'n';

	/*
	 * Check whether an invalid uart number has been specified, and
	 * if so, search for the first available port that does have
	 * console support.
	 */
	if (co->index == -1 || co->index >= NR_PORTS)
		co->index = 0;
	sport = &pnx8xxx_ports[co->index];

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

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

static struct uart_driver pnx8xxx_reg;
static struct console pnx8xxx_console = {
	.name		= "ttyS",
	.write		= pnx8xxx_console_write,
	.device		= uart_console_device,
	.setup		= pnx8xxx_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &pnx8xxx_reg,
};

static int __init pnx8xxx_rs_console_init(void)
{
	pnx8xxx_init_ports();
	register_console(&pnx8xxx_console);
	return 0;
}
console_initcall(pnx8xxx_rs_console_init);

#define PNX8XXX_CONSOLE	&pnx8xxx_console
#else
#define PNX8XXX_CONSOLE	NULL
#endif

static struct uart_driver pnx8xxx_reg = {
	.owner			= THIS_MODULE,
	.driver_name		= "ttyS",
	.dev_name		= "ttyS",
	.major			= SERIAL_PNX8XXX_MAJOR,
	.minor			= MINOR_START,
	.nr			= NR_PORTS,
	.cons			= PNX8XXX_CONSOLE,
};

static int pnx8xxx_serial_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct pnx8xxx_port *sport = platform_get_drvdata(pdev);

	return uart_suspend_port(&pnx8xxx_reg, &sport->port);
}

static int pnx8xxx_serial_resume(struct platform_device *pdev)
{
	struct pnx8xxx_port *sport = platform_get_drvdata(pdev);

	return uart_resume_port(&pnx8xxx_reg, &sport->port);
}

static int pnx8xxx_serial_probe(struct platform_device *pdev)
{
	struct resource *res = pdev->resource;
	int i;

	for (i = 0; i < pdev->num_resources; i++, res++) {
		if (!(res->flags & IORESOURCE_MEM))
			continue;

		for (i = 0; i < NR_PORTS; i++) {
			if (pnx8xxx_ports[i].port.mapbase != res->start)
				continue;

			pnx8xxx_ports[i].port.dev = &pdev->dev;
			uart_add_one_port(&pnx8xxx_reg, &pnx8xxx_ports[i].port);
			platform_set_drvdata(pdev, &pnx8xxx_ports[i]);
			break;
		}
	}

	return 0;
}

static int pnx8xxx_serial_remove(struct platform_device *pdev)
{
	struct pnx8xxx_port *sport = platform_get_drvdata(pdev);

	if (sport)
		uart_remove_one_port(&pnx8xxx_reg, &sport->port);

	return 0;
}

static struct platform_driver pnx8xxx_serial_driver = {
	.driver		= {
		.name	= "pnx8xxx-uart",
	},
	.probe		= pnx8xxx_serial_probe,
	.remove		= pnx8xxx_serial_remove,
	.suspend	= pnx8xxx_serial_suspend,
	.resume		= pnx8xxx_serial_resume,
};

static int __init pnx8xxx_serial_init(void)
{
	int ret;

	printk(KERN_INFO "Serial: PNX8XXX driver\n");

	pnx8xxx_init_ports();

	ret = uart_register_driver(&pnx8xxx_reg);
	if (ret == 0) {
		ret = platform_driver_register(&pnx8xxx_serial_driver);
		if (ret)
			uart_unregister_driver(&pnx8xxx_reg);
	}
	return ret;
}

static void __exit pnx8xxx_serial_exit(void)
{
	platform_driver_unregister(&pnx8xxx_serial_driver);
	uart_unregister_driver(&pnx8xxx_reg);
}

module_init(pnx8xxx_serial_init);
module_exit(pnx8xxx_serial_exit);

MODULE_AUTHOR("Embedded Alley Solutions, Inc.");
MODULE_DESCRIPTION("PNX8XXX SoCs serial port driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_PNX8XXX_MAJOR);
MODULE_ALIAS("platform:pnx8xxx-uart");
