/*
 * Blackfin On-Chip Sport Emulated UART Driver
 *
 * Copyright 2006-2009 Analog Devices Inc.
 *
 * Enter bugs at http://blackfin.uclinux.org/
 *
 * Licensed under the GPL-2 or later.
 */

/*
 * This driver and the hardware supported are in term of EE-191 of ADI.
 * http://www.analog.com/static/imported-files/application_notes/EE191.pdf 
 * This application note describe how to implement a UART on a Sharc DSP,
 * but this driver is implemented on Blackfin Processor.
 * Transmit Frame Sync is not used by this driver to transfer data out.
 */

/* #define DEBUG */

#define DRV_NAME "bfin-sport-uart"
#define DEVICE_NAME	"ttySS"
#define pr_fmt(fmt) DRV_NAME ": " fmt

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>

#include <asm/bfin_sport.h>
#include <asm/delay.h>
#include <asm/portmux.h>

#include "bfin_sport_uart.h"

struct sport_uart_port {
	struct uart_port	port;
	int			err_irq;
	unsigned short		csize;
	unsigned short		rxmask;
	unsigned short		txmask1;
	unsigned short		txmask2;
	unsigned char		stopb;
/*	unsigned char		parib; */
#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
	int cts_pin;
	int rts_pin;
#endif
};

static int sport_uart_tx_chars(struct sport_uart_port *up);
static void sport_stop_tx(struct uart_port *port);

static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
{
	pr_debug("%s value:%x, mask1=0x%x, mask2=0x%x\n", __func__, value,
		up->txmask1, up->txmask2);

	/* Place Start and Stop bits */
	__asm__ __volatile__ (
		"%[val] <<= 1;"
		"%[val] = %[val] & %[mask1];"
		"%[val] = %[val] | %[mask2];"
		: [val]"+d"(value)
		: [mask1]"d"(up->txmask1), [mask2]"d"(up->txmask2)
		: "ASTAT"
	);
	pr_debug("%s value:%x\n", __func__, value);

	SPORT_PUT_TX(up, value);
}

static inline unsigned char rx_one_byte(struct sport_uart_port *up)
{
	unsigned int value;
	unsigned char extract;
	u32 tmp_mask1, tmp_mask2, tmp_shift, tmp;

	if ((up->csize + up->stopb) > 7)
		value = SPORT_GET_RX32(up);
	else
		value = SPORT_GET_RX(up);

	pr_debug("%s value:%x, cs=%d, mask=0x%x\n", __func__, value,
		up->csize, up->rxmask);

	/* Extract data */
	__asm__ __volatile__ (
		"%[extr] = 0;"
		"%[mask1] = %[rxmask];"
		"%[mask2] = 0x0200(Z);"
		"%[shift] = 0;"
		"LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];"
		".Lloop_s:"
		"%[tmp] = extract(%[val], %[mask1].L)(Z);"
		"%[tmp] <<= %[shift];"
		"%[extr] = %[extr] | %[tmp];"
		"%[mask1] = %[mask1] - %[mask2];"
		".Lloop_e:"
		"%[shift] += 1;"
		: [extr]"=&d"(extract), [shift]"=&d"(tmp_shift), [tmp]"=&d"(tmp),
		  [mask1]"=&d"(tmp_mask1), [mask2]"=&d"(tmp_mask2)
		: [val]"d"(value), [rxmask]"d"(up->rxmask), [lc]"a"(up->csize)
		: "ASTAT", "LB0", "LC0", "LT0"
	);

	pr_debug("	extract:%x\n", extract);
	return extract;
}

static int sport_uart_setup(struct sport_uart_port *up, int size, int baud_rate)
{
	int tclkdiv, rclkdiv;
	unsigned int sclk = get_sclk();

	/* Set TCR1 and TCR2, TFSR is not enabled for uart */
	SPORT_PUT_TCR1(up, (LATFS | ITFS | TFSR | TLSBIT | ITCLK));
	SPORT_PUT_TCR2(up, size + 1);
	pr_debug("%s TCR1:%x, TCR2:%x\n", __func__, SPORT_GET_TCR1(up), SPORT_GET_TCR2(up));

	/* Set RCR1 and RCR2 */
	SPORT_PUT_RCR1(up, (RCKFE | LARFS | LRFS | RFSR | IRCLK));
	SPORT_PUT_RCR2(up, (size + 1) * 2 - 1);
	pr_debug("%s RCR1:%x, RCR2:%x\n", __func__, SPORT_GET_RCR1(up), SPORT_GET_RCR2(up));

	tclkdiv = sclk / (2 * baud_rate) - 1;
	/* The actual uart baud rate of devices vary between +/-2%. The sport
	 * RX sample rate should be faster than the double of the worst case,
	 * otherwise, wrong data are received. So, set sport RX clock to be
	 * 3% faster.
	 */
	rclkdiv = sclk / (2 * baud_rate * 2 * 97 / 100) - 1;
	SPORT_PUT_TCLKDIV(up, tclkdiv);
	SPORT_PUT_RCLKDIV(up, rclkdiv);
	SSYNC();
	pr_debug("%s sclk:%d, baud_rate:%d, tclkdiv:%d, rclkdiv:%d\n",
			__func__, sclk, baud_rate, tclkdiv, rclkdiv);

	return 0;
}

static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
{
	struct sport_uart_port *up = dev_id;
	struct tty_struct *tty = up->port.state->port.tty;
	unsigned int ch;

	spin_lock(&up->port.lock);

	while (SPORT_GET_STAT(up) & RXNE) {
		ch = rx_one_byte(up);
		up->port.icount.rx++;

		if (!uart_handle_sysrq_char(&up->port, ch))
			tty_insert_flip_char(tty, ch, TTY_NORMAL);
	}
	tty_flip_buffer_push(tty);

	spin_unlock(&up->port.lock);

	return IRQ_HANDLED;
}

static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
{
	struct sport_uart_port *up = dev_id;

	spin_lock(&up->port.lock);
	sport_uart_tx_chars(up);
	spin_unlock(&up->port.lock);

	return IRQ_HANDLED;
}

static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
{
	struct sport_uart_port *up = dev_id;
	struct tty_struct *tty = up->port.state->port.tty;
	unsigned int stat = SPORT_GET_STAT(up);

	spin_lock(&up->port.lock);

	/* Overflow in RX FIFO */
	if (stat & ROVF) {
		up->port.icount.overrun++;
		tty_insert_flip_char(tty, 0, TTY_OVERRUN);
		SPORT_PUT_STAT(up, ROVF); /* Clear ROVF bit */
	}
	/* These should not happen */
	if (stat & (TOVF | TUVF | RUVF)) {
		pr_err("SPORT Error:%s %s %s\n",
		       (stat & TOVF) ? "TX overflow" : "",
		       (stat & TUVF) ? "TX underflow" : "",
		       (stat & RUVF) ? "RX underflow" : "");
		SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
		SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);
	}
	SSYNC();

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

#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
static unsigned int sport_get_mctrl(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;
	if (up->cts_pin < 0)
		return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;

	/* CTS PIN is negative assertive. */
	if (SPORT_UART_GET_CTS(up))
		return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
	else
		return TIOCM_DSR | TIOCM_CAR;
}

static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;
	if (up->rts_pin < 0)
		return;

	/* RTS PIN is negative assertive. */
	if (mctrl & TIOCM_RTS)
		SPORT_UART_ENABLE_RTS(up);
	else
		SPORT_UART_DISABLE_RTS(up);
}

/*
 * Handle any change of modem status signal.
 */
static irqreturn_t sport_mctrl_cts_int(int irq, void *dev_id)
{
	struct sport_uart_port *up = (struct sport_uart_port *)dev_id;
	unsigned int status;

	status = sport_get_mctrl(&up->port);
	uart_handle_cts_change(&up->port, status & TIOCM_CTS);

	return IRQ_HANDLED;
}
#else
static unsigned int sport_get_mctrl(struct uart_port *port)
{
	pr_debug("%s enter\n", __func__);
	return TIOCM_CTS | TIOCM_CD | TIOCM_DSR;
}

static void sport_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	pr_debug("%s enter\n", __func__);
}
#endif

/* Reqeust IRQ, Setup clock */
static int sport_startup(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;
	int ret;

	pr_debug("%s enter\n", __func__);
	ret = request_irq(up->port.irq, sport_uart_rx_irq, 0,
		"SPORT_UART_RX", up);
	if (ret) {
		dev_err(port->dev, "unable to request SPORT RX interrupt\n");
		return ret;
	}

	ret = request_irq(up->port.irq+1, sport_uart_tx_irq, 0,
		"SPORT_UART_TX", up);
	if (ret) {
		dev_err(port->dev, "unable to request SPORT TX interrupt\n");
		goto fail1;
	}

	ret = request_irq(up->err_irq, sport_uart_err_irq, 0,
		"SPORT_UART_STATUS", up);
	if (ret) {
		dev_err(port->dev, "unable to request SPORT status interrupt\n");
		goto fail2;
	}

#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
	if (up->cts_pin >= 0) {
		if (request_irq(gpio_to_irq(up->cts_pin),
			sport_mctrl_cts_int,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
			IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) {
			up->cts_pin = -1;
			dev_info(port->dev, "Unable to attach BlackFin UART \
				over SPORT CTS interrupt. So, disable it.\n");
		}
	}
	if (up->rts_pin >= 0)
		gpio_direction_output(up->rts_pin, 0);
#endif

	return 0;
 fail2:
	free_irq(up->port.irq+1, up);
 fail1:
	free_irq(up->port.irq, up);

	return ret;
}

/*
 * sport_uart_tx_chars
 *
 * ret 1 means need to enable sport.
 * ret 0 means do nothing.
 */
static int sport_uart_tx_chars(struct sport_uart_port *up)
{
	struct circ_buf *xmit = &up->port.state->xmit;

	if (SPORT_GET_STAT(up) & TXF)
		return 0;

	if (up->port.x_char) {
		tx_one_byte(up, up->port.x_char);
		up->port.icount.tx++;
		up->port.x_char = 0;
		return 1;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
		/* The waiting loop to stop SPORT TX from TX interrupt is
		 * too long. This may block SPORT RX interrupts and cause
		 * RX FIFO overflow. So, do stop sport TX only after the last
		 * char in TX FIFO is moved into the shift register.
		 */
		if (SPORT_GET_STAT(up) & TXHRE)
			sport_stop_tx(&up->port);
		return 0;
	}

	while(!(SPORT_GET_STAT(up) & TXF) && !uart_circ_empty(xmit)) {
		tx_one_byte(up, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
		up->port.icount.tx++;
	}

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

	return 1;
}

static unsigned int sport_tx_empty(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;
	unsigned int stat;

	stat = SPORT_GET_STAT(up);
	pr_debug("%s stat:%04x\n", __func__, stat);
	if (stat & TXHRE) {
		return TIOCSER_TEMT;
	} else
		return 0;
}

static void sport_stop_tx(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;

	pr_debug("%s enter\n", __func__);

	if (!(SPORT_GET_TCR1(up) & TSPEN))
		return;

	/* Although the hold register is empty, last byte is still in shift
	 * register and not sent out yet. So, put a dummy data into TX FIFO.
	 * Then, sport tx stops when last byte is shift out and the dummy
	 * data is moved into the shift register.
	 */
	SPORT_PUT_TX(up, 0xffff);
	while (!(SPORT_GET_STAT(up) & TXHRE))
		cpu_relax();

	SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
	SSYNC();

	return;
}

static void sport_start_tx(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;

	pr_debug("%s enter\n", __func__);

	/* Write data into SPORT FIFO before enable SPROT to transmit */
	if (sport_uart_tx_chars(up)) {
		/* Enable transmit, then an interrupt will generated */
		SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
		SSYNC();
	}

	pr_debug("%s exit\n", __func__);
}

static void sport_stop_rx(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;

	pr_debug("%s enter\n", __func__);
	/* Disable sport to stop rx */
	SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN));
	SSYNC();
}

static void sport_enable_ms(struct uart_port *port)
{
	pr_debug("%s enter\n", __func__);
}

static void sport_break_ctl(struct uart_port *port, int break_state)
{
	pr_debug("%s enter\n", __func__);
}

static void sport_shutdown(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;

	dev_dbg(port->dev, "%s enter\n", __func__);

	/* Disable sport */
	SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
	SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN));
	SSYNC();

	free_irq(up->port.irq, up);
	free_irq(up->port.irq+1, up);
	free_irq(up->err_irq, up);
#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
	if (up->cts_pin >= 0)
		free_irq(gpio_to_irq(up->cts_pin), up);
#endif
}

static const char *sport_type(struct uart_port *port)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;

	pr_debug("%s enter\n", __func__);
	return up->port.type == PORT_BFIN_SPORT ? "BFIN-SPORT-UART" : NULL;
}

static void sport_release_port(struct uart_port *port)
{
	pr_debug("%s enter\n", __func__);
}

static int sport_request_port(struct uart_port *port)
{
	pr_debug("%s enter\n", __func__);
	return 0;
}

static void sport_config_port(struct uart_port *port, int flags)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;

	pr_debug("%s enter\n", __func__);
	up->port.type = PORT_BFIN_SPORT;
}

static int sport_verify_port(struct uart_port *port, struct serial_struct *ser)
{
	pr_debug("%s enter\n", __func__);
	return 0;
}

static void sport_set_termios(struct uart_port *port,
		struct ktermios *termios, struct ktermios *old)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;
	unsigned long flags;
	int i;

	pr_debug("%s enter, c_cflag:%08x\n", __func__, termios->c_cflag);

	switch (termios->c_cflag & CSIZE) {
	case CS8:
		up->csize = 8;
		break;
	case CS7:
		up->csize = 7;
		break;
	case CS6:
		up->csize = 6;
		break;
	case CS5:
		up->csize = 5;
		break;
	default:
		pr_warning("requested word length not supported\n");
	}

	if (termios->c_cflag & CSTOPB) {
		up->stopb = 1;
	}
	if (termios->c_cflag & PARENB) {
		pr_warning("PAREN bits is not supported yet\n");
		/* up->parib = 1; */
	}

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

	port->read_status_mask = 0;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;

	/* RX extract mask */
	up->rxmask = 0x01 | (((up->csize + up->stopb) * 2 - 1) << 0x8);
	/* TX masks, 8 bit data and 1 bit stop for example:
	 * mask1 = b#0111111110
	 * mask2 = b#1000000000
	 */
	for (i = 0, up->txmask1 = 0; i < up->csize; i++)
		up->txmask1 |= (1<<i);
	up->txmask2 = (1<<i);
	if (up->stopb) {
		++i;
		up->txmask2 |= (1<<i);
	}
	up->txmask1 <<= 1;
	up->txmask2 <<= 1;
	/* uart baud rate */
	port->uartclk = uart_get_baud_rate(port, termios, old, 0, get_sclk()/16);

	/* Disable UART */
	SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
	SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) & ~RSPEN);

	sport_uart_setup(up, up->csize + up->stopb, port->uartclk);

	/* driver TX line high after config, one dummy data is
	 * necessary to stop sport after shift one byte
	 */
	SPORT_PUT_TX(up, 0xffff);
	SPORT_PUT_TX(up, 0xffff);
	SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
	SSYNC();
	while (!(SPORT_GET_STAT(up) & TXHRE))
		cpu_relax();
	SPORT_PUT_TCR1(up, SPORT_GET_TCR1(up) & ~TSPEN);
	SSYNC();

	/* Port speed changed, update the per-port timeout. */
	uart_update_timeout(port, termios->c_cflag, port->uartclk);

	/* Enable sport rx */
	SPORT_PUT_RCR1(up, SPORT_GET_RCR1(up) | RSPEN);
	SSYNC();

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

struct uart_ops sport_uart_ops = {
	.tx_empty	= sport_tx_empty,
	.set_mctrl	= sport_set_mctrl,
	.get_mctrl	= sport_get_mctrl,
	.stop_tx	= sport_stop_tx,
	.start_tx	= sport_start_tx,
	.stop_rx	= sport_stop_rx,
	.enable_ms	= sport_enable_ms,
	.break_ctl	= sport_break_ctl,
	.startup	= sport_startup,
	.shutdown	= sport_shutdown,
	.set_termios	= sport_set_termios,
	.type		= sport_type,
	.release_port	= sport_release_port,
	.request_port	= sport_request_port,
	.config_port	= sport_config_port,
	.verify_port	= sport_verify_port,
};

#define BFIN_SPORT_UART_MAX_PORTS 4

static struct sport_uart_port *bfin_sport_uart_ports[BFIN_SPORT_UART_MAX_PORTS];

#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
#define CLASS_BFIN_SPORT_CONSOLE	"bfin-sport-console"

static int __init
sport_uart_console_setup(struct console *co, char *options)
{
	struct sport_uart_port *up;
	int baud = 57600;
	int bits = 8;
	int parity = 'n';
# ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
	int flow = 'r';
# else
	int flow = 'n';
# endif

	/* Check whether an invalid uart number has been specified */
	if (co->index < 0 || co->index >= BFIN_SPORT_UART_MAX_PORTS)
		return -ENODEV;

	up = bfin_sport_uart_ports[co->index];
	if (!up)
		return -ENODEV;

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

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

static void sport_uart_console_putchar(struct uart_port *port, int ch)
{
	struct sport_uart_port *up = (struct sport_uart_port *)port;

	while (SPORT_GET_STAT(up) & TXF)
		barrier();

	tx_one_byte(up, ch);
}

/*
 * Interrupts are disabled on entering
 */
static void
sport_uart_console_write(struct console *co, const char *s, unsigned int count)
{
	struct sport_uart_port *up = bfin_sport_uart_ports[co->index];
	unsigned long flags;

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

	if (SPORT_GET_TCR1(up) & TSPEN)
		uart_console_write(&up->port, s, count, sport_uart_console_putchar);
	else {
		/* dummy data to start sport */
		while (SPORT_GET_STAT(up) & TXF)
			barrier();
		SPORT_PUT_TX(up, 0xffff);
		/* Enable transmit, then an interrupt will generated */
		SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) | TSPEN));
		SSYNC();

		uart_console_write(&up->port, s, count, sport_uart_console_putchar);

		/* Although the hold register is empty, last byte is still in shift
		 * register and not sent out yet. So, put a dummy data into TX FIFO.
		 * Then, sport tx stops when last byte is shift out and the dummy
		 * data is moved into the shift register.
		 */
		while (SPORT_GET_STAT(up) & TXF)
			barrier();
		SPORT_PUT_TX(up, 0xffff);
		while (!(SPORT_GET_STAT(up) & TXHRE))
			barrier();

		/* Stop sport tx transfer */
		SPORT_PUT_TCR1(up, (SPORT_GET_TCR1(up) & ~TSPEN));
		SSYNC();
	}

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

static struct uart_driver sport_uart_reg;

static struct console sport_uart_console = {
	.name		= DEVICE_NAME,
	.write		= sport_uart_console_write,
	.device		= uart_console_device,
	.setup		= sport_uart_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data		= &sport_uart_reg,
};

#define SPORT_UART_CONSOLE	(&sport_uart_console)
#else
#define SPORT_UART_CONSOLE	NULL
#endif /* CONFIG_SERIAL_BFIN_SPORT_CONSOLE */


static struct uart_driver sport_uart_reg = {
	.owner		= THIS_MODULE,
	.driver_name	= DRV_NAME,
	.dev_name	= DEVICE_NAME,
	.major		= 204,
	.minor		= 84,
	.nr		= BFIN_SPORT_UART_MAX_PORTS,
	.cons		= SPORT_UART_CONSOLE,
};

#ifdef CONFIG_PM
static int sport_uart_suspend(struct device *dev)
{
	struct sport_uart_port *sport = dev_get_drvdata(dev);

	dev_dbg(dev, "%s enter\n", __func__);
	if (sport)
		uart_suspend_port(&sport_uart_reg, &sport->port);

	return 0;
}

static int sport_uart_resume(struct device *dev)
{
	struct sport_uart_port *sport = dev_get_drvdata(dev);

	dev_dbg(dev, "%s enter\n", __func__);
	if (sport)
		uart_resume_port(&sport_uart_reg, &sport->port);

	return 0;
}

static struct dev_pm_ops bfin_sport_uart_dev_pm_ops = {
	.suspend	= sport_uart_suspend,
	.resume		= sport_uart_resume,
};
#endif

static int __devinit sport_uart_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct sport_uart_port *sport;
	int ret = 0;

	dev_dbg(&pdev->dev, "%s enter\n", __func__);

	if (pdev->id < 0 || pdev->id >= BFIN_SPORT_UART_MAX_PORTS) {
		dev_err(&pdev->dev, "Wrong sport uart platform device id.\n");
		return -ENOENT;
	}

	if (bfin_sport_uart_ports[pdev->id] == NULL) {
		bfin_sport_uart_ports[pdev->id] =
			kzalloc(sizeof(struct sport_uart_port), GFP_KERNEL);
		sport = bfin_sport_uart_ports[pdev->id];
		if (!sport) {
			dev_err(&pdev->dev,
				"Fail to malloc sport_uart_port\n");
			return -ENOMEM;
		}

		ret = peripheral_request_list(
			(unsigned short *)pdev->dev.platform_data, DRV_NAME);
		if (ret) {
			dev_err(&pdev->dev,
				"Fail to request SPORT peripherals\n");
			goto out_error_free_mem;
		}

		spin_lock_init(&sport->port.lock);
		sport->port.fifosize  = SPORT_TX_FIFO_SIZE,
		sport->port.ops       = &sport_uart_ops;
		sport->port.line      = pdev->id;
		sport->port.iotype    = UPIO_MEM;
		sport->port.flags     = UPF_BOOT_AUTOCONF;

		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		if (res == NULL) {
			dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
			ret = -ENOENT;
			goto out_error_free_peripherals;
		}

		sport->port.membase = ioremap(res->start, resource_size(res));
		if (!sport->port.membase) {
			dev_err(&pdev->dev, "Cannot map sport IO\n");
			ret = -ENXIO;
			goto out_error_free_peripherals;
		}
		sport->port.mapbase = res->start;

		sport->port.irq = platform_get_irq(pdev, 0);
		if ((int)sport->port.irq < 0) {
			dev_err(&pdev->dev, "No sport RX/TX IRQ specified\n");
			ret = -ENOENT;
			goto out_error_unmap;
		}

		sport->err_irq = platform_get_irq(pdev, 1);
		if (sport->err_irq < 0) {
			dev_err(&pdev->dev, "No sport status IRQ specified\n");
			ret = -ENOENT;
			goto out_error_unmap;
		}
#ifdef CONFIG_SERIAL_BFIN_SPORT_CTSRTS
		res = platform_get_resource(pdev, IORESOURCE_IO, 0);
		if (res == NULL)
			sport->cts_pin = -1;
		else
			sport->cts_pin = res->start;

		res = platform_get_resource(pdev, IORESOURCE_IO, 1);
		if (res == NULL)
			sport->rts_pin = -1;
		else
			sport->rts_pin = res->start;

		if (sport->rts_pin >= 0)
			gpio_request(sport->rts_pin, DRV_NAME);
#endif
	}

#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
	if (!is_early_platform_device(pdev)) {
#endif
		sport = bfin_sport_uart_ports[pdev->id];
		sport->port.dev = &pdev->dev;
		dev_set_drvdata(&pdev->dev, sport);
		ret = uart_add_one_port(&sport_uart_reg, &sport->port);
#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
	}
#endif
	if (!ret)
		return 0;

	if (sport) {
out_error_unmap:
		iounmap(sport->port.membase);
out_error_free_peripherals:
		peripheral_free_list(
			(unsigned short *)pdev->dev.platform_data);
out_error_free_mem:
		kfree(sport);
		bfin_sport_uart_ports[pdev->id] = NULL;
	}

	return ret;
}

static int __devexit sport_uart_remove(struct platform_device *pdev)
{
	struct sport_uart_port *sport = platform_get_drvdata(pdev);

	dev_dbg(&pdev->dev, "%s enter\n", __func__);
	dev_set_drvdata(&pdev->dev, NULL);

	if (sport) {
		uart_remove_one_port(&sport_uart_reg, &sport->port);
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
		if (sport->rts_pin >= 0)
			gpio_free(sport->rts_pin);
#endif
		iounmap(sport->port.membase);
		peripheral_free_list(
			(unsigned short *)pdev->dev.platform_data);
		kfree(sport);
		bfin_sport_uart_ports[pdev->id] = NULL;
	}

	return 0;
}

static struct platform_driver sport_uart_driver = {
	.probe		= sport_uart_probe,
	.remove		= __devexit_p(sport_uart_remove),
	.driver		= {
		.name	= DRV_NAME,
#ifdef CONFIG_PM
		.pm	= &bfin_sport_uart_dev_pm_ops,
#endif
	},
};

#ifdef CONFIG_SERIAL_BFIN_SPORT_CONSOLE
static __initdata struct early_platform_driver early_sport_uart_driver = {
	.class_str = CLASS_BFIN_SPORT_CONSOLE,
	.pdrv = &sport_uart_driver,
	.requested_id = EARLY_PLATFORM_ID_UNSET,
};

static int __init sport_uart_rs_console_init(void)
{
	early_platform_driver_register(&early_sport_uart_driver, DRV_NAME);

	early_platform_driver_probe(CLASS_BFIN_SPORT_CONSOLE,
		BFIN_SPORT_UART_MAX_PORTS, 0);

	register_console(&sport_uart_console);

	return 0;
}
console_initcall(sport_uart_rs_console_init);
#endif

static int __init sport_uart_init(void)
{
	int ret;

	pr_info("Blackfin uart over sport driver\n");

	ret = uart_register_driver(&sport_uart_reg);
	if (ret) {
		pr_err("failed to register %s:%d\n",
				sport_uart_reg.driver_name, ret);
		return ret;
	}

	ret = platform_driver_register(&sport_uart_driver);
	if (ret) {
		pr_err("failed to register sport uart driver:%d\n", ret);
		uart_unregister_driver(&sport_uart_reg);
	}

	return ret;
}
module_init(sport_uart_init);

static void __exit sport_uart_exit(void)
{
	platform_driver_unregister(&sport_uart_driver);
	uart_unregister_driver(&sport_uart_reg);
}
module_exit(sport_uart_exit);

MODULE_AUTHOR("Sonic Zhang, Roy Huang");
MODULE_DESCRIPTION("Blackfin serial over SPORT driver");
MODULE_LICENSE("GPL");
