/*
** mux.c:
**	serial driver for the Mux console found in some PA-RISC servers.
**
**	(c) Copyright 2002 Ryan Bradetich
**	(c) Copyright 2002 Hewlett-Packard Company
**
** 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.
**
** This Driver currently only supports the console (port 0) on the MUX.
** Additional work will be needed on this driver to enable the full
** functionality of the MUX.
**
*/

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/console.h>
#include <linux/delay.h> /* for udelay */
#include <linux/device.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/parisc-device.h>

#ifdef CONFIG_MAGIC_SYSRQ
#include <linux/sysrq.h>
#define SUPPORT_SYSRQ
#endif

#include <linux/serial_core.h>

#define MUX_OFFSET 0x800
#define MUX_LINE_OFFSET 0x80

#define MUX_FIFO_SIZE 255
#define MUX_POLL_DELAY (30 * HZ / 1000)

#define IO_DATA_REG_OFFSET 0x3c
#define IO_DCOUNT_REG_OFFSET 0x40

#define MUX_EOFIFO(status) ((status & 0xF000) == 0xF000)
#define MUX_STATUS(status) ((status & 0xF000) == 0x8000)
#define MUX_BREAK(status) ((status & 0xF000) == 0x2000)

#define MUX_NR 256
static unsigned int port_cnt __read_mostly;
struct mux_port {
	struct uart_port port;
	int enabled;
};
static struct mux_port mux_ports[MUX_NR];

static struct uart_driver mux_driver = {
	.owner = THIS_MODULE,
	.driver_name = "ttyB",
	.dev_name = "ttyB",
	.major = MUX_MAJOR,
	.minor = 0,
	.nr = MUX_NR,
};

static struct timer_list mux_timer;

#define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)
#define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET)

/**
 * get_mux_port_count - Get the number of available ports on the Mux.
 * @dev: The parisc device.
 *
 * This function is used to determine the number of ports the Mux
 * supports.  The IODC data reports the number of ports the Mux
 * can support, but there are cases where not all the Mux ports
 * are connected.  This function can override the IODC and
 * return the true port count.
 */
static int __init get_mux_port_count(struct parisc_device *dev)
{
	int status;
	u8 iodc_data[32];
	unsigned long bytecnt;

	/* If this is the built-in Mux for the K-Class (Eole CAP/MUX),
	 * we only need to allocate resources for 1 port since the
	 * other 7 ports are not connected.
	 */
	if(dev->id.hversion == 0x15)
		return 1;

	status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
	BUG_ON(status != PDC_OK);

	/* Return the number of ports specified in the iodc data. */
	return ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8;
}

/**
 * mux_tx_empty - Check if the transmitter fifo is empty.
 * @port: Ptr to the uart_port.
 *
 * This function test if the transmitter fifo for the port
 * described by 'port' is empty.  If it is empty, this function
 * should return TIOCSER_TEMT, otherwise return 0.
 */
static unsigned int mux_tx_empty(struct uart_port *port)
{
	return UART_GET_FIFO_CNT(port) ? 0 : TIOCSER_TEMT;
} 

/**
 * mux_set_mctrl - Set the current state of the modem control inputs.
 * @ports: Ptr to the uart_port.
 * @mctrl: Modem control bits.
 *
 * The Serial MUX does not support CTS, DCD or DSR so this function
 * is ignored.
 */
static void mux_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
}

/**
 * mux_get_mctrl - Returns the current state of modem control inputs.
 * @port: Ptr to the uart_port.
 *
 * The Serial MUX does not support CTS, DCD or DSR so these lines are
 * treated as permanently active.
 */
static unsigned int mux_get_mctrl(struct uart_port *port)
{ 
	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
}

/**
 * mux_stop_tx - Stop transmitting characters.
 * @port: Ptr to the uart_port.
 *
 * The Serial MUX does not support this function.
 */
static void mux_stop_tx(struct uart_port *port)
{
}

/**
 * mux_start_tx - Start transmitting characters.
 * @port: Ptr to the uart_port.
 *
 * The Serial Mux does not support this function.
 */
static void mux_start_tx(struct uart_port *port)
{
}

/**
 * mux_stop_rx - Stop receiving characters.
 * @port: Ptr to the uart_port.
 *
 * The Serial Mux does not support this function.
 */
static void mux_stop_rx(struct uart_port *port)
{
}

/**
 * mux_enable_ms - Enable modum status interrupts.
 * @port: Ptr to the uart_port.
 *
 * The Serial Mux does not support this function.
 */
static void mux_enable_ms(struct uart_port *port)
{
}

/**
 * mux_break_ctl - Control the transmitssion of a break signal.
 * @port: Ptr to the uart_port.
 * @break_state: Raise/Lower the break signal.
 *
 * The Serial Mux does not support this function.
 */
static void mux_break_ctl(struct uart_port *port, int break_state)
{
}

/**
 * mux_write - Write chars to the mux fifo.
 * @port: Ptr to the uart_port.
 *
 * This function writes all the data from the uart buffer to
 * the mux fifo.
 */
static void mux_write(struct uart_port *port)
{
	int count;
	struct circ_buf *xmit = &port->state->xmit;

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

	if(uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		mux_stop_tx(port);
		return;
	}

	count = (port->fifosize) - UART_GET_FIFO_CNT(port);
	do {
		UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if(uart_circ_empty(xmit))
			break;

	} while(--count > 0);

	while(UART_GET_FIFO_CNT(port)) 
		udelay(1);

	if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit))
		mux_stop_tx(port);
}

/**
 * mux_read - Read chars from the mux fifo.
 * @port: Ptr to the uart_port.
 *
 * This reads all available data from the mux's fifo and pushes
 * the data to the tty layer.
 */
static void mux_read(struct uart_port *port)
{
	struct tty_port *tport = &port->state->port;
	int data;
	__u32 start_count = port->icount.rx;

	while(1) {
		data = __raw_readl(port->membase + IO_DATA_REG_OFFSET);

		if (MUX_STATUS(data))
			continue;

		if (MUX_EOFIFO(data))
			break;

		port->icount.rx++;

		if (MUX_BREAK(data)) {
			port->icount.brk++;
			if(uart_handle_break(port))
				continue;
		}

		if (uart_handle_sysrq_char(port, data & 0xffu))
			continue;

		tty_insert_flip_char(tport, data & 0xFF, TTY_NORMAL);
	}
	
	if (start_count != port->icount.rx)
		tty_flip_buffer_push(tport);
}

/**
 * mux_startup - Initialize the port.
 * @port: Ptr to the uart_port.
 *
 * Grab any resources needed for this port and start the
 * mux timer.
 */
static int mux_startup(struct uart_port *port)
{
	mux_ports[port->line].enabled = 1;
	return 0;
}

/**
 * mux_shutdown - Disable the port.
 * @port: Ptr to the uart_port.
 *
 * Release any resources needed for the port.
 */
static void mux_shutdown(struct uart_port *port)
{
	mux_ports[port->line].enabled = 0;
}

/**
 * mux_set_termios - Chane port parameters.
 * @port: Ptr to the uart_port.
 * @termios: new termios settings.
 * @old: old termios settings.
 *
 * The Serial Mux does not support this function.
 */
static void
mux_set_termios(struct uart_port *port, struct ktermios *termios,
	        struct ktermios *old)
{
}

/**
 * mux_type - Describe the port.
 * @port: Ptr to the uart_port.
 *
 * Return a pointer to a string constant describing the
 * specified port.
 */
static const char *mux_type(struct uart_port *port)
{
	return "Mux";
}

/**
 * mux_release_port - Release memory and IO regions.
 * @port: Ptr to the uart_port.
 * 
 * Release any memory and IO region resources currently in use by
 * the port.
 */
static void mux_release_port(struct uart_port *port)
{
}

/**
 * mux_request_port - Request memory and IO regions.
 * @port: Ptr to the uart_port.
 *
 * Request any memory and IO region resources required by the port.
 * If any fail, no resources should be registered when this function
 * returns, and it should return -EBUSY on failure.
 */
static int mux_request_port(struct uart_port *port)
{
	return 0;
}

/**
 * mux_config_port - Perform port autoconfiguration.
 * @port: Ptr to the uart_port.
 * @type: Bitmask of required configurations.
 *
 * Perform any autoconfiguration steps for the port.  This function is
 * called if the UPF_BOOT_AUTOCONF flag is specified for the port.
 * [Note: This is required for now because of a bug in the Serial core.
 *  rmk has already submitted a patch to linus, should be available for
 *  2.5.47.]
 */
static void mux_config_port(struct uart_port *port, int type)
{
	port->type = PORT_MUX;
}

/**
 * mux_verify_port - Verify the port information.
 * @port: Ptr to the uart_port.
 * @ser: Ptr to the serial information.
 *
 * Verify the new serial port information contained within serinfo is
 * suitable for this port type.
 */
static int mux_verify_port(struct uart_port *port, struct serial_struct *ser)
{
	if(port->membase == NULL)
		return -EINVAL;

	return 0;
}

/**
 * mux_drv_poll - Mux poll function.
 * @unused: Unused variable
 *
 * This function periodically polls the Serial MUX to check for new data.
 */
static void mux_poll(unsigned long unused)
{  
	int i;

	for(i = 0; i < port_cnt; ++i) {
		if(!mux_ports[i].enabled)
			continue;

		mux_read(&mux_ports[i].port);
		mux_write(&mux_ports[i].port);
	}

	mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);
}


#ifdef CONFIG_SERIAL_MUX_CONSOLE
static void mux_console_write(struct console *co, const char *s, unsigned count)
{
	/* Wait until the FIFO drains. */
	while(UART_GET_FIFO_CNT(&mux_ports[0].port))
		udelay(1);

	while(count--) {
		if(*s == '\n') {
			UART_PUT_CHAR(&mux_ports[0].port, '\r');
		}
		UART_PUT_CHAR(&mux_ports[0].port, *s++);
	}

}

static int mux_console_setup(struct console *co, char *options)
{
        return 0;
}

struct tty_driver *mux_console_device(struct console *co, int *index)
{
        *index = co->index;
	return mux_driver.tty_driver;
}

static struct console mux_console = {
	.name =		"ttyB",
	.write =	mux_console_write,
	.device =	mux_console_device,
	.setup =	mux_console_setup,
	.flags =	CON_ENABLED | CON_PRINTBUFFER,
	.index =	0,
};

#define MUX_CONSOLE	&mux_console
#else
#define MUX_CONSOLE	NULL
#endif

static struct uart_ops mux_pops = {
	.tx_empty =		mux_tx_empty,
	.set_mctrl =		mux_set_mctrl,
	.get_mctrl =		mux_get_mctrl,
	.stop_tx =		mux_stop_tx,
	.start_tx =		mux_start_tx,
	.stop_rx =		mux_stop_rx,
	.enable_ms =		mux_enable_ms,
	.break_ctl =		mux_break_ctl,
	.startup =		mux_startup,
	.shutdown =		mux_shutdown,
	.set_termios =		mux_set_termios,
	.type =			mux_type,
	.release_port =		mux_release_port,
	.request_port =		mux_request_port,
	.config_port =		mux_config_port,
	.verify_port =		mux_verify_port,
};

/**
 * mux_probe - Determine if the Serial Mux should claim this device.
 * @dev: The parisc device.
 *
 * Deterimine if the Serial Mux should claim this chip (return 0)
 * or not (return 1).
 */
static int __init mux_probe(struct parisc_device *dev)
{
	int i, status;

	int port_count = get_mux_port_count(dev);
	printk(KERN_INFO "Serial mux driver (%d ports) Revision: 0.6\n", port_count);

	dev_set_drvdata(&dev->dev, (void *)(long)port_count);
	request_mem_region(dev->hpa.start + MUX_OFFSET,
                           port_count * MUX_LINE_OFFSET, "Mux");

	if(!port_cnt) {
		mux_driver.cons = MUX_CONSOLE;

		status = uart_register_driver(&mux_driver);
		if(status) {
			printk(KERN_ERR "Serial mux: Unable to register driver.\n");
			return 1;
		}
	}

	for(i = 0; i < port_count; ++i, ++port_cnt) {
		struct uart_port *port = &mux_ports[port_cnt].port;
		port->iobase	= 0;
		port->mapbase	= dev->hpa.start + MUX_OFFSET +
						(i * MUX_LINE_OFFSET);
		port->membase	= ioremap_nocache(port->mapbase, MUX_LINE_OFFSET);
		port->iotype	= UPIO_MEM;
		port->type	= PORT_MUX;
		port->irq	= 0;
		port->uartclk	= 0;
		port->fifosize	= MUX_FIFO_SIZE;
		port->ops	= &mux_pops;
		port->flags	= UPF_BOOT_AUTOCONF;
		port->line	= port_cnt;

		/* The port->timeout needs to match what is present in
		 * uart_wait_until_sent in serial_core.c.  Otherwise
		 * the time spent in msleep_interruptable will be very
		 * long, causing the appearance of a console hang.
		 */
		port->timeout   = HZ / 50;
		spin_lock_init(&port->lock);

		status = uart_add_one_port(&mux_driver, port);
		BUG_ON(status);
	}

	return 0;
}

static int mux_remove(struct parisc_device *dev)
{
	int i, j;
	int port_count = (long)dev_get_drvdata(&dev->dev);

	/* Find Port 0 for this card in the mux_ports list. */
	for(i = 0; i < port_cnt; ++i) {
		if(mux_ports[i].port.mapbase == dev->hpa.start + MUX_OFFSET)
			break;
	}
	BUG_ON(i + port_count > port_cnt);

	/* Release the resources associated with each port on the device. */
	for(j = 0; j < port_count; ++j, ++i) {
		struct uart_port *port = &mux_ports[i].port;

		uart_remove_one_port(&mux_driver, port);
		if(port->membase)
			iounmap(port->membase);
	}

	release_mem_region(dev->hpa.start + MUX_OFFSET, port_count * MUX_LINE_OFFSET);
	return 0;
}

/* Hack.  This idea was taken from the 8250_gsc.c on how to properly order
 * the serial port detection in the proper order.   The idea is we always
 * want the builtin mux to be detected before addin mux cards, so we
 * specifically probe for the builtin mux cards first.
 *
 * This table only contains the parisc_device_id of known builtin mux
 * devices.  All other mux cards will be detected by the generic mux_tbl.
 */
static struct parisc_device_id builtin_mux_tbl[] = {
	{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x15, 0x0000D }, /* All K-class */
	{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, 0x44, 0x0000D }, /* E35, E45, and E55 */
	{ 0, }
};

static struct parisc_device_id mux_tbl[] = {
	{ HPHW_A_DIRECT, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0000D },
	{ 0, }
};

MODULE_DEVICE_TABLE(parisc, builtin_mux_tbl);
MODULE_DEVICE_TABLE(parisc, mux_tbl);

static struct parisc_driver builtin_serial_mux_driver = {
	.name =		"builtin_serial_mux",
	.id_table =	builtin_mux_tbl,
	.probe =	mux_probe,
	.remove =       mux_remove,
};

static struct parisc_driver serial_mux_driver = {
	.name =		"serial_mux",
	.id_table =	mux_tbl,
	.probe =	mux_probe,
	.remove =       mux_remove,
};

/**
 * mux_init - Serial MUX initialization procedure.
 *
 * Register the Serial MUX driver.
 */
static int __init mux_init(void)
{
	register_parisc_driver(&builtin_serial_mux_driver);
	register_parisc_driver(&serial_mux_driver);

	if(port_cnt > 0) {
		/* Start the Mux timer */
		init_timer(&mux_timer);
		mux_timer.function = mux_poll;
		mod_timer(&mux_timer, jiffies + MUX_POLL_DELAY);

#ifdef CONFIG_SERIAL_MUX_CONSOLE
	        register_console(&mux_console);
#endif
	}

	return 0;
}

/**
 * mux_exit - Serial MUX cleanup procedure.
 *
 * Unregister the Serial MUX driver from the tty layer.
 */
static void __exit mux_exit(void)
{
	/* Delete the Mux timer. */
	if(port_cnt > 0) {
		del_timer(&mux_timer);
#ifdef CONFIG_SERIAL_MUX_CONSOLE
		unregister_console(&mux_console);
#endif
	}

	unregister_parisc_driver(&builtin_serial_mux_driver);
	unregister_parisc_driver(&serial_mux_driver);
	uart_unregister_driver(&mux_driver);
}

module_init(mux_init);
module_exit(mux_exit);

MODULE_AUTHOR("Ryan Bradetich");
MODULE_DESCRIPTION("Serial MUX driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_CHARDEV_MAJOR(MUX_MAJOR);
