/*
 * linux/drivers/mmc/card/sdio_uart.c - SDIO UART/GPS driver
 *
 * Based on drivers/serial/8250.c and drivers/serial/serial_core.c
 * by Russell King.
 *
 * Author:	Nicolas Pitre
 * Created:	June 15, 2007
 * Copyright:	MontaVista Software, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 */

/*
 * Note: Although this driver assumes a 16550A-like UART implementation,
 * it is not possible to leverage the common 8250/16550 driver, nor the
 * core UART infrastructure, as they assumes direct access to the hardware
 * registers, often under a spinlock.  This is not possible in the SDIO
 * context as SDIO access functions must be able to sleep.
 *
 * Because we need to lock the SDIO host to ensure an exclusive access to
 * the card, we simply rely on that lock to also prevent and serialize
 * concurrent access to the same port.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mutex.h>
#include <linux/seq_file.h>
#include <linux/serial_reg.h>
#include <linux/circ_buf.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/kfifo.h>
#include <linux/slab.h>

#include <linux/mmc/core.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>


#define UART_NR		8	/* Number of UARTs this driver can handle */


#define FIFO_SIZE	PAGE_SIZE
#define WAKEUP_CHARS	256

struct uart_icount {
	__u32	cts;
	__u32	dsr;
	__u32	rng;
	__u32	dcd;
	__u32	rx;
	__u32	tx;
	__u32	frame;
	__u32	overrun;
	__u32	parity;
	__u32	brk;
};

struct sdio_uart_port {
	struct tty_port		port;
	unsigned int		index;
	struct sdio_func	*func;
	struct mutex		func_lock;
	struct task_struct	*in_sdio_uart_irq;
	unsigned int		regs_offset;
	struct kfifo		xmit_fifo;
	spinlock_t		write_lock;
	struct uart_icount	icount;
	unsigned int		uartclk;
	unsigned int		mctrl;
	unsigned int		rx_mctrl;
	unsigned int		read_status_mask;
	unsigned int		ignore_status_mask;
	unsigned char		x_char;
	unsigned char           ier;
	unsigned char           lcr;
};

static struct sdio_uart_port *sdio_uart_table[UART_NR];
static DEFINE_SPINLOCK(sdio_uart_table_lock);

static int sdio_uart_add_port(struct sdio_uart_port *port)
{
	int index, ret = -EBUSY;

	mutex_init(&port->func_lock);
	spin_lock_init(&port->write_lock);
	if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL))
		return -ENOMEM;

	spin_lock(&sdio_uart_table_lock);
	for (index = 0; index < UART_NR; index++) {
		if (!sdio_uart_table[index]) {
			port->index = index;
			sdio_uart_table[index] = port;
			ret = 0;
			break;
		}
	}
	spin_unlock(&sdio_uart_table_lock);

	return ret;
}

static struct sdio_uart_port *sdio_uart_port_get(unsigned index)
{
	struct sdio_uart_port *port;

	if (index >= UART_NR)
		return NULL;

	spin_lock(&sdio_uart_table_lock);
	port = sdio_uart_table[index];
	if (port)
		tty_port_get(&port->port);
	spin_unlock(&sdio_uart_table_lock);

	return port;
}

static void sdio_uart_port_put(struct sdio_uart_port *port)
{
	tty_port_put(&port->port);
}

static void sdio_uart_port_remove(struct sdio_uart_port *port)
{
	struct sdio_func *func;
	struct tty_struct *tty;

	BUG_ON(sdio_uart_table[port->index] != port);

	spin_lock(&sdio_uart_table_lock);
	sdio_uart_table[port->index] = NULL;
	spin_unlock(&sdio_uart_table_lock);

	/*
	 * We're killing a port that potentially still is in use by
	 * the tty layer. Be careful to prevent any further access
	 * to the SDIO function and arrange for the tty layer to
	 * give up on that port ASAP.
	 * Beware: the lock ordering is critical.
	 */
	mutex_lock(&port->port.mutex);
	mutex_lock(&port->func_lock);
	func = port->func;
	sdio_claim_host(func);
	port->func = NULL;
	mutex_unlock(&port->func_lock);
	tty = tty_port_tty_get(&port->port);
	/* tty_hangup is async so is this safe as is ?? */
	if (tty) {
		tty_hangup(tty);
		tty_kref_put(tty);
	}
	mutex_unlock(&port->port.mutex);
	sdio_release_irq(func);
	sdio_disable_func(func);
	sdio_release_host(func);

	sdio_uart_port_put(port);
}

static int sdio_uart_claim_func(struct sdio_uart_port *port)
{
	mutex_lock(&port->func_lock);
	if (unlikely(!port->func)) {
		mutex_unlock(&port->func_lock);
		return -ENODEV;
	}
	if (likely(port->in_sdio_uart_irq != current))
		sdio_claim_host(port->func);
	mutex_unlock(&port->func_lock);
	return 0;
}

static inline void sdio_uart_release_func(struct sdio_uart_port *port)
{
	if (likely(port->in_sdio_uart_irq != current))
		sdio_release_host(port->func);
}

static inline unsigned int sdio_in(struct sdio_uart_port *port, int offset)
{
	unsigned char c;
	c = sdio_readb(port->func, port->regs_offset + offset, NULL);
	return c;
}

static inline void sdio_out(struct sdio_uart_port *port, int offset, int value)
{
	sdio_writeb(port->func, value, port->regs_offset + offset, NULL);
}

static unsigned int sdio_uart_get_mctrl(struct sdio_uart_port *port)
{
	unsigned char status;
	unsigned int ret;

	/* FIXME: What stops this losing the delta bits and breaking
	   sdio_uart_check_modem_status ? */
	status = sdio_in(port, UART_MSR);

	ret = 0;
	if (status & UART_MSR_DCD)
		ret |= TIOCM_CAR;
	if (status & UART_MSR_RI)
		ret |= TIOCM_RNG;
	if (status & UART_MSR_DSR)
		ret |= TIOCM_DSR;
	if (status & UART_MSR_CTS)
		ret |= TIOCM_CTS;
	return ret;
}

static void sdio_uart_write_mctrl(struct sdio_uart_port *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;

	sdio_out(port, UART_MCR, mcr);
}

static inline void sdio_uart_update_mctrl(struct sdio_uart_port *port,
					  unsigned int set, unsigned int clear)
{
	unsigned int old;

	old = port->mctrl;
	port->mctrl = (old & ~clear) | set;
	if (old != port->mctrl)
		sdio_uart_write_mctrl(port, port->mctrl);
}

#define sdio_uart_set_mctrl(port, x)	sdio_uart_update_mctrl(port, x, 0)
#define sdio_uart_clear_mctrl(port, x)	sdio_uart_update_mctrl(port, 0, x)

static void sdio_uart_change_speed(struct sdio_uart_port *port,
				   struct ktermios *termios,
				   struct ktermios *old)
{
	unsigned char cval, fcr = 0;
	unsigned int baud, quot;

	switch (termios->c_cflag & CSIZE) {
	case CS5:
		cval = UART_LCR_WLEN5;
		break;
	case CS6:
		cval = UART_LCR_WLEN6;
		break;
	case CS7:
		cval = UART_LCR_WLEN7;
		break;
	default:
	case CS8:
		cval = UART_LCR_WLEN8;
		break;
	}

	if (termios->c_cflag & CSTOPB)
		cval |= UART_LCR_STOP;
	if (termios->c_cflag & PARENB)
		cval |= UART_LCR_PARITY;
	if (!(termios->c_cflag & PARODD))
		cval |= UART_LCR_EPAR;

	for (;;) {
		baud = tty_termios_baud_rate(termios);
		if (baud == 0)
			baud = 9600;  /* Special case: B0 rate. */
		if (baud <= port->uartclk)
			break;
		/*
		 * Oops, the quotient was zero.  Try again with the old
		 * baud rate if possible, otherwise default to 9600.
		 */
		termios->c_cflag &= ~CBAUD;
		if (old) {
			termios->c_cflag |= old->c_cflag & CBAUD;
			old = NULL;
		} else
			termios->c_cflag |= B9600;
	}
	quot = (2 * port->uartclk + baud) / (2 * baud);

	if (baud < 2400)
		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
	else
		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;

	port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
	if (termios->c_iflag & (BRKINT | PARMRK))
		port->read_status_mask |= UART_LSR_BI;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= UART_LSR_BI;
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns too (for real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= UART_LSR_OE;
	}

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

	/*
	 * CTS flow control flag and modem status interrupts
	 */
	port->ier &= ~UART_IER_MSI;
	if ((termios->c_cflag & CRTSCTS) || !(termios->c_cflag & CLOCAL))
		port->ier |= UART_IER_MSI;

	port->lcr = cval;

	sdio_out(port, UART_IER, port->ier);
	sdio_out(port, UART_LCR, cval | UART_LCR_DLAB);
	sdio_out(port, UART_DLL, quot & 0xff);
	sdio_out(port, UART_DLM, quot >> 8);
	sdio_out(port, UART_LCR, cval);
	sdio_out(port, UART_FCR, fcr);

	sdio_uart_write_mctrl(port, port->mctrl);
}

static void sdio_uart_start_tx(struct sdio_uart_port *port)
{
	if (!(port->ier & UART_IER_THRI)) {
		port->ier |= UART_IER_THRI;
		sdio_out(port, UART_IER, port->ier);
	}
}

static void sdio_uart_stop_tx(struct sdio_uart_port *port)
{
	if (port->ier & UART_IER_THRI) {
		port->ier &= ~UART_IER_THRI;
		sdio_out(port, UART_IER, port->ier);
	}
}

static void sdio_uart_stop_rx(struct sdio_uart_port *port)
{
	port->ier &= ~UART_IER_RLSI;
	port->read_status_mask &= ~UART_LSR_DR;
	sdio_out(port, UART_IER, port->ier);
}

static void sdio_uart_receive_chars(struct sdio_uart_port *port,
				    unsigned int *status)
{
	struct tty_struct *tty = tty_port_tty_get(&port->port);
	unsigned int ch, flag;
	int max_count = 256;

	do {
		ch = sdio_in(port, UART_RX);
		flag = TTY_NORMAL;
		port->icount.rx++;

		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
					UART_LSR_FE | UART_LSR_OE))) {
			/*
			 * For statistics only
			 */
			if (*status & UART_LSR_BI) {
				*status &= ~(UART_LSR_FE | UART_LSR_PE);
				port->icount.brk++;
			} else if (*status & UART_LSR_PE)
				port->icount.parity++;
			else if (*status & UART_LSR_FE)
				port->icount.frame++;
			if (*status & UART_LSR_OE)
				port->icount.overrun++;

			/*
			 * Mask off conditions which should be ignored.
			 */
			*status &= port->read_status_mask;
			if (*status & UART_LSR_BI)
				flag = TTY_BREAK;
			else if (*status & UART_LSR_PE)
				flag = TTY_PARITY;
			else if (*status & UART_LSR_FE)
				flag = TTY_FRAME;
		}

		if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0)
			if (tty)
				tty_insert_flip_char(tty, ch, flag);

		/*
		 * Overrun is special.  Since it's reported immediately,
		 * it doesn't affect the current character.
		 */
		if (*status & ~port->ignore_status_mask & UART_LSR_OE)
			if (tty)
				tty_insert_flip_char(tty, 0, TTY_OVERRUN);

		*status = sdio_in(port, UART_LSR);
	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
	if (tty) {
		tty_flip_buffer_push(tty);
		tty_kref_put(tty);
	}
}

static void sdio_uart_transmit_chars(struct sdio_uart_port *port)
{
	struct kfifo *xmit = &port->xmit_fifo;
	int count;
	struct tty_struct *tty;
	u8 iobuf[16];
	int len;

	if (port->x_char) {
		sdio_out(port, UART_TX, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	tty = tty_port_tty_get(&port->port);

	if (tty == NULL || !kfifo_len(xmit) ||
				tty->stopped || tty->hw_stopped) {
		sdio_uart_stop_tx(port);
		tty_kref_put(tty);
		return;
	}

	len = kfifo_out_locked(xmit, iobuf, 16, &port->write_lock);
	for (count = 0; count < len; count++) {
		sdio_out(port, UART_TX, iobuf[count]);
		port->icount.tx++;
	}

	len = kfifo_len(xmit);
	if (len < WAKEUP_CHARS) {
		tty_wakeup(tty);
		if (len == 0)
			sdio_uart_stop_tx(port);
	}
	tty_kref_put(tty);
}

static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
{
	int status;
	struct tty_struct *tty;

	status = sdio_in(port, UART_MSR);

	if ((status & UART_MSR_ANY_DELTA) == 0)
		return;

	if (status & UART_MSR_TERI)
		port->icount.rng++;
	if (status & UART_MSR_DDSR)
		port->icount.dsr++;
	if (status & UART_MSR_DDCD) {
		port->icount.dcd++;
		/* DCD raise - wake for open */
		if (status & UART_MSR_DCD)
			wake_up_interruptible(&port->port.open_wait);
		else {
			/* DCD drop - hang up if tty attached */
			tty = tty_port_tty_get(&port->port);
			if (tty) {
				tty_hangup(tty);
				tty_kref_put(tty);
			}
		}
	}
	if (status & UART_MSR_DCTS) {
		port->icount.cts++;
		tty = tty_port_tty_get(&port->port);
		if (tty && (tty->termios.c_cflag & CRTSCTS)) {
			int cts = (status & UART_MSR_CTS);
			if (tty->hw_stopped) {
				if (cts) {
					tty->hw_stopped = 0;
					sdio_uart_start_tx(port);
					tty_wakeup(tty);
				}
			} else {
				if (!cts) {
					tty->hw_stopped = 1;
					sdio_uart_stop_tx(port);
				}
			}
		}
		tty_kref_put(tty);
	}
}

/*
 * This handles the interrupt from one port.
 */
static void sdio_uart_irq(struct sdio_func *func)
{
	struct sdio_uart_port *port = sdio_get_drvdata(func);
	unsigned int iir, lsr;

	/*
	 * In a few places sdio_uart_irq() is called directly instead of
	 * waiting for the actual interrupt to be raised and the SDIO IRQ
	 * thread scheduled in order to reduce latency.  However, some
	 * interaction with the tty core may end up calling us back
	 * (serial echo, flow control, etc.) through those same places
	 * causing undesirable effects.  Let's stop the recursion here.
	 */
	if (unlikely(port->in_sdio_uart_irq == current))
		return;

	iir = sdio_in(port, UART_IIR);
	if (iir & UART_IIR_NO_INT)
		return;

	port->in_sdio_uart_irq = current;
	lsr = sdio_in(port, UART_LSR);
	if (lsr & UART_LSR_DR)
		sdio_uart_receive_chars(port, &lsr);
	sdio_uart_check_modem_status(port);
	if (lsr & UART_LSR_THRE)
		sdio_uart_transmit_chars(port);
	port->in_sdio_uart_irq = NULL;
}

static int uart_carrier_raised(struct tty_port *tport)
{
	struct sdio_uart_port *port =
			container_of(tport, struct sdio_uart_port, port);
	unsigned int ret = sdio_uart_claim_func(port);
	if (ret)	/* Missing hardware shouldn't block for carrier */
		return 1;
	ret = sdio_uart_get_mctrl(port);
	sdio_uart_release_func(port);
	if (ret & TIOCM_CAR)
		return 1;
	return 0;
}

/**
 *	uart_dtr_rts		-	 port helper to set uart signals
 *	@tport: tty port to be updated
 *	@onoff: set to turn on DTR/RTS
 *
 *	Called by the tty port helpers when the modem signals need to be
 *	adjusted during an open, close and hangup.
 */

static void uart_dtr_rts(struct tty_port *tport, int onoff)
{
	struct sdio_uart_port *port =
			container_of(tport, struct sdio_uart_port, port);
	int ret = sdio_uart_claim_func(port);
	if (ret)
		return;
	if (onoff == 0)
		sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
	else
		sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
	sdio_uart_release_func(port);
}

/**
 *	sdio_uart_activate	-	start up hardware
 *	@tport: tty port to activate
 *	@tty: tty bound to this port
 *
 *	Activate a tty port. The port locking guarantees us this will be
 *	run exactly once per set of opens, and if successful will see the
 *	shutdown method run exactly once to match. Start up and shutdown are
 *	protected from each other by the internal locking and will not run
 *	at the same time even during a hangup event.
 *
 *	If we successfully start up the port we take an extra kref as we
 *	will keep it around until shutdown when the kref is dropped.
 */

static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
{
	struct sdio_uart_port *port =
			container_of(tport, struct sdio_uart_port, port);
	int ret;

	/*
	 * Set the TTY IO error marker - we will only clear this
	 * once we have successfully opened the port.
	 */
	set_bit(TTY_IO_ERROR, &tty->flags);

	kfifo_reset(&port->xmit_fifo);

	ret = sdio_uart_claim_func(port);
	if (ret)
		return ret;
	ret = sdio_enable_func(port->func);
	if (ret)
		goto err1;
	ret = sdio_claim_irq(port->func, sdio_uart_irq);
	if (ret)
		goto err2;

	/*
	 * Clear the FIFO buffers and disable them.
	 * (they will be reenabled in sdio_change_speed())
	 */
	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
		       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
	sdio_out(port, UART_FCR, 0);

	/*
	 * Clear the interrupt registers.
	 */
	(void) sdio_in(port, UART_LSR);
	(void) sdio_in(port, UART_RX);
	(void) sdio_in(port, UART_IIR);
	(void) sdio_in(port, UART_MSR);

	/*
	 * Now, initialize the UART
	 */
	sdio_out(port, UART_LCR, UART_LCR_WLEN8);

	port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;
	port->mctrl = TIOCM_OUT2;

	sdio_uart_change_speed(port, &tty->termios, NULL);

	if (tty->termios.c_cflag & CBAUD)
		sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);

	if (tty->termios.c_cflag & CRTSCTS)
		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
			tty->hw_stopped = 1;

	clear_bit(TTY_IO_ERROR, &tty->flags);

	/* Kick the IRQ handler once while we're still holding the host lock */
	sdio_uart_irq(port->func);

	sdio_uart_release_func(port);
	return 0;

err2:
	sdio_disable_func(port->func);
err1:
	sdio_uart_release_func(port);
	return ret;
}

/**
 *	sdio_uart_shutdown	-	stop hardware
 *	@tport: tty port to shut down
 *
 *	Deactivate a tty port. The port locking guarantees us this will be
 *	run only if a successful matching activate already ran. The two are
 *	protected from each other by the internal locking and will not run
 *	at the same time even during a hangup event.
 */

static void sdio_uart_shutdown(struct tty_port *tport)
{
	struct sdio_uart_port *port =
			container_of(tport, struct sdio_uart_port, port);
	int ret;

	ret = sdio_uart_claim_func(port);
	if (ret)
		return;

	sdio_uart_stop_rx(port);

	/* Disable interrupts from this port */
	sdio_release_irq(port->func);
	port->ier = 0;
	sdio_out(port, UART_IER, 0);

	sdio_uart_clear_mctrl(port, TIOCM_OUT2);

	/* Disable break condition and FIFOs. */
	port->lcr &= ~UART_LCR_SBC;
	sdio_out(port, UART_LCR, port->lcr);
	sdio_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
				 UART_FCR_CLEAR_RCVR |
				 UART_FCR_CLEAR_XMIT);
	sdio_out(port, UART_FCR, 0);

	sdio_disable_func(port->func);

	sdio_uart_release_func(port);
}

static void sdio_uart_port_destroy(struct tty_port *tport)
{
	struct sdio_uart_port *port =
		container_of(tport, struct sdio_uart_port, port);
	kfifo_free(&port->xmit_fifo);
	kfree(port);
}

/**
 *	sdio_uart_install	-	install method
 *	@driver: the driver in use (sdio_uart in our case)
 *	@tty: the tty being bound
 *
 *	Look up and bind the tty and the driver together. Initialize
 *	any needed private data (in our case the termios)
 */

static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty)
{
	int idx = tty->index;
	struct sdio_uart_port *port = sdio_uart_port_get(idx);
	int ret = tty_standard_install(driver, tty);

	if (ret == 0)
		/* This is the ref sdio_uart_port get provided */
		tty->driver_data = port;
	else
		sdio_uart_port_put(port);
	return ret;
}

/**
 *	sdio_uart_cleanup	-	called on the last tty kref drop
 *	@tty: the tty being destroyed
 *
 *	Called asynchronously when the last reference to the tty is dropped.
 *	We cannot destroy the tty->driver_data port kref until this point
 */

static void sdio_uart_cleanup(struct tty_struct *tty)
{
	struct sdio_uart_port *port = tty->driver_data;
	tty->driver_data = NULL;	/* Bug trap */
	sdio_uart_port_put(port);
}

/*
 *	Open/close/hangup is now entirely boilerplate
 */

static int sdio_uart_open(struct tty_struct *tty, struct file *filp)
{
	struct sdio_uart_port *port = tty->driver_data;
	return tty_port_open(&port->port, tty, filp);
}

static void sdio_uart_close(struct tty_struct *tty, struct file * filp)
{
	struct sdio_uart_port *port = tty->driver_data;
	tty_port_close(&port->port, tty, filp);
}

static void sdio_uart_hangup(struct tty_struct *tty)
{
	struct sdio_uart_port *port = tty->driver_data;
	tty_port_hangup(&port->port);
}

static int sdio_uart_write(struct tty_struct *tty, const unsigned char *buf,
			   int count)
{
	struct sdio_uart_port *port = tty->driver_data;
	int ret;

	if (!port->func)
		return -ENODEV;

	ret = kfifo_in_locked(&port->xmit_fifo, buf, count, &port->write_lock);
	if (!(port->ier & UART_IER_THRI)) {
		int err = sdio_uart_claim_func(port);
		if (!err) {
			sdio_uart_start_tx(port);
			sdio_uart_irq(port->func);
			sdio_uart_release_func(port);
		} else
			ret = err;
	}

	return ret;
}

static int sdio_uart_write_room(struct tty_struct *tty)
{
	struct sdio_uart_port *port = tty->driver_data;
	return FIFO_SIZE - kfifo_len(&port->xmit_fifo);
}

static int sdio_uart_chars_in_buffer(struct tty_struct *tty)
{
	struct sdio_uart_port *port = tty->driver_data;
	return kfifo_len(&port->xmit_fifo);
}

static void sdio_uart_send_xchar(struct tty_struct *tty, char ch)
{
	struct sdio_uart_port *port = tty->driver_data;

	port->x_char = ch;
	if (ch && !(port->ier & UART_IER_THRI)) {
		if (sdio_uart_claim_func(port) != 0)
			return;
		sdio_uart_start_tx(port);
		sdio_uart_irq(port->func);
		sdio_uart_release_func(port);
	}
}

static void sdio_uart_throttle(struct tty_struct *tty)
{
	struct sdio_uart_port *port = tty->driver_data;

	if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS))
		return;

	if (sdio_uart_claim_func(port) != 0)
		return;

	if (I_IXOFF(tty)) {
		port->x_char = STOP_CHAR(tty);
		sdio_uart_start_tx(port);
	}

	if (tty->termios.c_cflag & CRTSCTS)
		sdio_uart_clear_mctrl(port, TIOCM_RTS);

	sdio_uart_irq(port->func);
	sdio_uart_release_func(port);
}

static void sdio_uart_unthrottle(struct tty_struct *tty)
{
	struct sdio_uart_port *port = tty->driver_data;

	if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS))
		return;

	if (sdio_uart_claim_func(port) != 0)
		return;

	if (I_IXOFF(tty)) {
		if (port->x_char) {
			port->x_char = 0;
		} else {
			port->x_char = START_CHAR(tty);
			sdio_uart_start_tx(port);
		}
	}

	if (tty->termios.c_cflag & CRTSCTS)
		sdio_uart_set_mctrl(port, TIOCM_RTS);

	sdio_uart_irq(port->func);
	sdio_uart_release_func(port);
}

static void sdio_uart_set_termios(struct tty_struct *tty,
						struct ktermios *old_termios)
{
	struct sdio_uart_port *port = tty->driver_data;
	unsigned int cflag = tty->termios.c_cflag;

	if (sdio_uart_claim_func(port) != 0)
		return;

	sdio_uart_change_speed(port, &tty->termios, old_termios);

	/* Handle transition to B0 status */
	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
		sdio_uart_clear_mctrl(port, TIOCM_RTS | TIOCM_DTR);

	/* Handle transition away from B0 status */
	if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
		unsigned int mask = TIOCM_DTR;
		if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))
			mask |= TIOCM_RTS;
		sdio_uart_set_mctrl(port, mask);
	}

	/* Handle turning off CRTSCTS */
	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
		tty->hw_stopped = 0;
		sdio_uart_start_tx(port);
	}

	/* Handle turning on CRTSCTS */
	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
		if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) {
			tty->hw_stopped = 1;
			sdio_uart_stop_tx(port);
		}
	}

	sdio_uart_release_func(port);
}

static int sdio_uart_break_ctl(struct tty_struct *tty, int break_state)
{
	struct sdio_uart_port *port = tty->driver_data;
	int result;

	result = sdio_uart_claim_func(port);
	if (result != 0)
		return result;

	if (break_state == -1)
		port->lcr |= UART_LCR_SBC;
	else
		port->lcr &= ~UART_LCR_SBC;
	sdio_out(port, UART_LCR, port->lcr);

	sdio_uart_release_func(port);
	return 0;
}

static int sdio_uart_tiocmget(struct tty_struct *tty)
{
	struct sdio_uart_port *port = tty->driver_data;
	int result;

	result = sdio_uart_claim_func(port);
	if (!result) {
		result = port->mctrl | sdio_uart_get_mctrl(port);
		sdio_uart_release_func(port);
	}

	return result;
}

static int sdio_uart_tiocmset(struct tty_struct *tty,
			      unsigned int set, unsigned int clear)
{
	struct sdio_uart_port *port = tty->driver_data;
	int result;

	result = sdio_uart_claim_func(port);
	if (!result) {
		sdio_uart_update_mctrl(port, set, clear);
		sdio_uart_release_func(port);
	}

	return result;
}

static int sdio_uart_proc_show(struct seq_file *m, void *v)
{
	int i;

	seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
		       "", "", "");
	for (i = 0; i < UART_NR; i++) {
		struct sdio_uart_port *port = sdio_uart_port_get(i);
		if (port) {
			seq_printf(m, "%d: uart:SDIO", i);
			if (capable(CAP_SYS_ADMIN)) {
				seq_printf(m, " tx:%d rx:%d",
					      port->icount.tx, port->icount.rx);
				if (port->icount.frame)
					seq_printf(m, " fe:%d",
						      port->icount.frame);
				if (port->icount.parity)
					seq_printf(m, " pe:%d",
						      port->icount.parity);
				if (port->icount.brk)
					seq_printf(m, " brk:%d",
						      port->icount.brk);
				if (port->icount.overrun)
					seq_printf(m, " oe:%d",
						      port->icount.overrun);
				if (port->icount.cts)
					seq_printf(m, " cts:%d",
						      port->icount.cts);
				if (port->icount.dsr)
					seq_printf(m, " dsr:%d",
						      port->icount.dsr);
				if (port->icount.rng)
					seq_printf(m, " rng:%d",
						      port->icount.rng);
				if (port->icount.dcd)
					seq_printf(m, " dcd:%d",
						      port->icount.dcd);
			}
			sdio_uart_port_put(port);
			seq_putc(m, '\n');
		}
	}
	return 0;
}

static int sdio_uart_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, sdio_uart_proc_show, NULL);
}

static const struct file_operations sdio_uart_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= sdio_uart_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static const struct tty_port_operations sdio_uart_port_ops = {
	.dtr_rts = uart_dtr_rts,
	.carrier_raised = uart_carrier_raised,
	.shutdown = sdio_uart_shutdown,
	.activate = sdio_uart_activate,
	.destruct = sdio_uart_port_destroy,
};

static const struct tty_operations sdio_uart_ops = {
	.open			= sdio_uart_open,
	.close			= sdio_uart_close,
	.write			= sdio_uart_write,
	.write_room		= sdio_uart_write_room,
	.chars_in_buffer	= sdio_uart_chars_in_buffer,
	.send_xchar		= sdio_uart_send_xchar,
	.throttle		= sdio_uart_throttle,
	.unthrottle		= sdio_uart_unthrottle,
	.set_termios		= sdio_uart_set_termios,
	.hangup			= sdio_uart_hangup,
	.break_ctl		= sdio_uart_break_ctl,
	.tiocmget		= sdio_uart_tiocmget,
	.tiocmset		= sdio_uart_tiocmset,
	.install		= sdio_uart_install,
	.cleanup		= sdio_uart_cleanup,
	.proc_fops		= &sdio_uart_proc_fops,
};

static struct tty_driver *sdio_uart_tty_driver;

static int sdio_uart_probe(struct sdio_func *func,
			   const struct sdio_device_id *id)
{
	struct sdio_uart_port *port;
	int ret;

	port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL);
	if (!port)
		return -ENOMEM;

	if (func->class == SDIO_CLASS_UART) {
		pr_warning("%s: need info on UART class basic setup\n",
		       sdio_func_id(func));
		kfree(port);
		return -ENOSYS;
	} else if (func->class == SDIO_CLASS_GPS) {
		/*
		 * We need tuple 0x91.  It contains SUBTPL_SIOREG
		 * and SUBTPL_RCVCAPS.
		 */
		struct sdio_func_tuple *tpl;
		for (tpl = func->tuples; tpl; tpl = tpl->next) {
			if (tpl->code != 0x91)
				continue;
			if (tpl->size < 10)
				continue;
			if (tpl->data[1] == 0)  /* SUBTPL_SIOREG */
				break;
		}
		if (!tpl) {
			pr_warning(
       "%s: can't find tuple 0x91 subtuple 0 (SUBTPL_SIOREG) for GPS class\n",
			       sdio_func_id(func));
			kfree(port);
			return -EINVAL;
		}
		pr_debug("%s: Register ID = 0x%02x, Exp ID = 0x%02x\n",
		       sdio_func_id(func), tpl->data[2], tpl->data[3]);
		port->regs_offset = (tpl->data[4] << 0) |
				    (tpl->data[5] << 8) |
				    (tpl->data[6] << 16);
		pr_debug("%s: regs offset = 0x%x\n",
		       sdio_func_id(func), port->regs_offset);
		port->uartclk = tpl->data[7] * 115200;
		if (port->uartclk == 0)
			port->uartclk = 115200;
		pr_debug("%s: clk %d baudcode %u 4800-div %u\n",
		       sdio_func_id(func), port->uartclk,
		       tpl->data[7], tpl->data[8] | (tpl->data[9] << 8));
	} else {
		kfree(port);
		return -EINVAL;
	}

	port->func = func;
	sdio_set_drvdata(func, port);
	tty_port_init(&port->port);
	port->port.ops = &sdio_uart_port_ops;

	ret = sdio_uart_add_port(port);
	if (ret) {
		kfree(port);
	} else {
		struct device *dev;
		dev = tty_port_register_device(&port->port,
				sdio_uart_tty_driver, port->index, &func->dev);
		if (IS_ERR(dev)) {
			sdio_uart_port_remove(port);
			ret = PTR_ERR(dev);
		}
	}

	return ret;
}

static void sdio_uart_remove(struct sdio_func *func)
{
	struct sdio_uart_port *port = sdio_get_drvdata(func);

	tty_unregister_device(sdio_uart_tty_driver, port->index);
	sdio_uart_port_remove(port);
}

static const struct sdio_device_id sdio_uart_ids[] = {
	{ SDIO_DEVICE_CLASS(SDIO_CLASS_UART)		},
	{ SDIO_DEVICE_CLASS(SDIO_CLASS_GPS)		},
	{ /* end: all zeroes */				},
};

MODULE_DEVICE_TABLE(sdio, sdio_uart_ids);

static struct sdio_driver sdio_uart_driver = {
	.probe		= sdio_uart_probe,
	.remove		= sdio_uart_remove,
	.name		= "sdio_uart",
	.id_table	= sdio_uart_ids,
};

static int __init sdio_uart_init(void)
{
	int ret;
	struct tty_driver *tty_drv;

	sdio_uart_tty_driver = tty_drv = alloc_tty_driver(UART_NR);
	if (!tty_drv)
		return -ENOMEM;

	tty_drv->driver_name = "sdio_uart";
	tty_drv->name =   "ttySDIO";
	tty_drv->major = 0;  /* dynamically allocated */
	tty_drv->minor_start = 0;
	tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
	tty_drv->subtype = SERIAL_TYPE_NORMAL;
	tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
	tty_drv->init_termios = tty_std_termios;
	tty_drv->init_termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | CLOCAL;
	tty_drv->init_termios.c_ispeed = 4800;
	tty_drv->init_termios.c_ospeed = 4800;
	tty_set_operations(tty_drv, &sdio_uart_ops);

	ret = tty_register_driver(tty_drv);
	if (ret)
		goto err1;

	ret = sdio_register_driver(&sdio_uart_driver);
	if (ret)
		goto err2;

	return 0;

err2:
	tty_unregister_driver(tty_drv);
err1:
	put_tty_driver(tty_drv);
	return ret;
}

static void __exit sdio_uart_exit(void)
{
	sdio_unregister_driver(&sdio_uart_driver);
	tty_unregister_driver(sdio_uart_tty_driver);
	put_tty_driver(sdio_uart_tty_driver);
}

module_init(sdio_uart_init);
module_exit(sdio_uart_exit);

MODULE_AUTHOR("Nicolas Pitre");
MODULE_LICENSE("GPL");
