[ARM] 2866/1: add i.MX set_mctrl / get_mctrl functions

Patch from Sascha Hauer

This patch adds support for setting and getting RTS / CTS via
set_mtctrl / get_mctrl functions.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 7333b41..42734d3 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -896,8 +896,8 @@
 
 config MWAVE
 	tristate "ACP Modem (Mwave) support"
-	depends on X86
-	select SERIAL_8250
+	depends on X86 && BROKEN
+	select SERIAL_8250 # PLEASE DO NOT DO THIS - move this driver to drivers/serial
 	---help---
 	  The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
 	  kernel driver and a user level application. Together these components
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7fc692a..dea6589 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -6,7 +6,7 @@
 
 config IBM_ASM
 	tristate "Device driver for IBM RSA service processor"
-	depends on X86 && PCI && EXPERIMENTAL
+	depends on X86 && PCI && EXPERIMENTAL && BROKEN
 	---help---
 	  This option enables device driver support for in-band access to the
 	  IBM RSA (Condor) service processor in eServer xSeries systems.
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e0239a1..7d8bcb3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@
 
 config SGI_IOC3_ETH
 	bool "SGI IOC3 Ethernet"
-	depends on NET_ETHERNET && PCI && SGI_IP27
+	depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN
 	select CRC32
 	select MII
 	help
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index cedb5f2..30a0a3d 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2590,82 +2590,3 @@
 MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
 #endif
 MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
-
-/**
- *	register_serial - configure a 16x50 serial port at runtime
- *	@req: request structure
- *
- *	Configure the serial port specified by the request. If the
- *	port exists and is in use an error is returned. If the port
- *	is not currently in the table it is added.
- *
- *	The port is then probed and if necessary the IRQ is autodetected
- *	If this fails an error is returned.
- *
- *	On success the port is ready to use and the line number is returned.
- *
- *	Note: this function is deprecated - use serial8250_register_port
- *	instead.
- */
-int register_serial(struct serial_struct *req)
-{
-	struct uart_port port;
-
-	port.iobase   = req->port;
-	port.membase  = req->iomem_base;
-	port.irq      = req->irq;
-	port.uartclk  = req->baud_base * 16;
-	port.fifosize = req->xmit_fifo_size;
-	port.regshift = req->iomem_reg_shift;
-	port.iotype   = req->io_type;
-	port.flags    = req->flags | UPF_BOOT_AUTOCONF;
-	port.mapbase  = req->iomap_base;
-	port.dev      = NULL;
-
-	if (share_irqs)
-		port.flags |= UPF_SHARE_IRQ;
-
-	if (HIGH_BITS_OFFSET)
-		port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
-
-	/*
-	 * If a clock rate wasn't specified by the low level driver, then
-	 * default to the standard clock rate.  This should be 115200 (*16)
-	 * and should not depend on the architecture's BASE_BAUD definition.
-	 * However, since this API will be deprecated, it's probably a
-	 * better idea to convert the drivers to use the new API
-	 * (serial8250_register_port and serial8250_unregister_port).
-	 */
-	if (port.uartclk == 0) {
-		printk(KERN_WARNING
-		       "Serial: registering port at [%08x,%08lx,%p] irq %d with zero baud_base\n",
-		       port.iobase, port.mapbase, port.membase, port.irq);
-		printk(KERN_WARNING "Serial: see %s:%d for more information\n",
-		       __FILE__, __LINE__);
-		dump_stack();
-
-		/*
-		 * Fix it up for now, but this is only a temporary measure.
-		 */
-		port.uartclk = BASE_BAUD * 16;
-	}
-
-	return serial8250_register_port(&port);
-}
-EXPORT_SYMBOL(register_serial);
-
-/**
- *	unregister_serial - remove a 16x50 serial port at runtime
- *	@line: serial line number
- *
- *	Remove one serial port.  This may not be called from interrupt
- *	context.  We hand the port back to our local PM control.
- *
- *	Note: this function is deprecated - use serial8250_unregister_port
- *	instead.
- */
-void unregister_serial(int line)
-{
-	serial8250_unregister_port(line);
-}
-EXPORT_SYMBOL(unregister_serial);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d579761..74b80f7 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -830,7 +830,7 @@
 
 config SERIAL_TXX9
 	bool "TMPTX39XX/49XX SIO support"
-	depends HAS_TXX9_SERIAL
+	depends HAS_TXX9_SERIAL && BROKEN
 	select SERIAL_CORE
 	default y
 
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 8861bcf..4c985e6 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -291,13 +291,31 @@
 	return USR2((u32)sport->port.membase) & USR2_TXDC ?  TIOCSER_TEMT : 0;
 }
 
+/*
+ * We have a modem side uart, so the meanings of RTS and CTS are inverted.
+ */
 static unsigned int imx_get_mctrl(struct uart_port *port)
 {
-	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+        struct imx_port *sport = (struct imx_port *)port;
+        unsigned int tmp = TIOCM_DSR | TIOCM_CAR;
+
+        if (USR1((u32)sport->port.membase) & USR1_RTSS)
+                tmp |= TIOCM_CTS;
+
+        if (UCR2((u32)sport->port.membase) & UCR2_CTS)
+                tmp |= TIOCM_RTS;
+
+        return tmp;
 }
 
 static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
+        struct imx_port *sport = (struct imx_port *)port;
+
+        if (mctrl & TIOCM_RTS)
+                UCR2((u32)sport->port.membase) |= UCR2_CTS;
+        else
+                UCR2((u32)sport->port.membase) &= ~UCR2_CTS;
 }
 
 /*
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index ac3a0bf..dea156a 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -2289,143 +2289,11 @@
 }
 EXPORT_SYMBOL(uart_match_port);
 
-/*
- *	Try to find an unused uart_state slot for a port.
- */
-static struct uart_state *
-uart_find_match_or_unused(struct uart_driver *drv, struct uart_port *port)
-{
-	int i;
-
-	/*
-	 * First, find a port entry which matches.  Note: if we do
-	 * find a matching entry, and it has a non-zero use count,
-	 * then we can't register the port.
-	 */
-	for (i = 0; i < drv->nr; i++)
-		if (uart_match_port(drv->state[i].port, port))
-			return &drv->state[i];
-
-	/*
-	 * We didn't find a matching entry, so look for the first
-	 * free entry.  We look for one which hasn't been previously
-	 * used (indicated by zero iobase).
-	 */
-	for (i = 0; i < drv->nr; i++)
-		if (drv->state[i].port->type == PORT_UNKNOWN &&
-		    drv->state[i].port->iobase == 0 &&
-		    drv->state[i].count == 0)
-			return &drv->state[i];
-
-	/*
-	 * That also failed.  Last resort is to find any currently
-	 * entry which doesn't have a real port associated with it.
-	 */
-	for (i = 0; i < drv->nr; i++)
-		if (drv->state[i].port->type == PORT_UNKNOWN &&
-		    drv->state[i].count == 0)
-			return &drv->state[i];
-
-	return NULL;
-}
-
-/**
- *	uart_register_port: register uart settings with a port
- *	@drv: pointer to the uart low level driver structure for this port
- *	@port: uart port structure describing the port
- *
- *	Register UART settings with the specified low level driver.  Detect
- *	the type of the port if UPF_BOOT_AUTOCONF is set, and detect the
- *	IRQ if UPF_AUTO_IRQ is set.
- *
- *	We try to pick the same port for the same IO base address, so that
- *	when a modem is plugged in, unplugged and plugged back in, it gets
- *	allocated the same port.
- *
- *	Returns negative error, or positive line number.
- */
-int uart_register_port(struct uart_driver *drv, struct uart_port *port)
-{
-	struct uart_state *state;
-	int ret;
-
-	down(&port_sem);
-
-	state = uart_find_match_or_unused(drv, port);
-
-	if (state) {
-		/*
-		 * Ok, we've found a line that we can use.
-		 *
-		 * If we find a port that matches this one, and it appears
-		 * to be in-use (even if it doesn't have a type) we shouldn't
-		 * alter it underneath itself - the port may be open and
-		 * trying to do useful work.
-		 */
-		if (uart_users(state) != 0) {
-			ret = -EBUSY;
-			goto out;
-		}
-
-		/*
-		 * If the port is already initialised, don't touch it.
-		 */
-		if (state->port->type == PORT_UNKNOWN) {
-			state->port->iobase   = port->iobase;
-			state->port->membase  = port->membase;
-			state->port->irq      = port->irq;
-			state->port->uartclk  = port->uartclk;
-			state->port->fifosize = port->fifosize;
-			state->port->regshift = port->regshift;
-			state->port->iotype   = port->iotype;
-			state->port->flags    = port->flags;
-			state->port->line     = state - drv->state;
-			state->port->mapbase  = port->mapbase;
-
-			uart_configure_port(drv, state, state->port);
-		}
-
-		ret = state->port->line;
-	} else
-		ret = -ENOSPC;
- out:
-	up(&port_sem);
-	return ret;
-}
-
-/**
- *	uart_unregister_port - de-allocate a port
- *	@drv: pointer to the uart low level driver structure for this port
- *	@line: line index previously returned from uart_register_port()
- *
- *	Hang up the specified line associated with the low level driver,
- *	and mark the port as unused.
- */
-void uart_unregister_port(struct uart_driver *drv, int line)
-{
-	struct uart_state *state;
-
-	if (line < 0 || line >= drv->nr) {
-		printk(KERN_ERR "Attempt to unregister ");
-		printk("%s%d", drv->dev_name, line);
-		printk("\n");
-		return;
-	}
-
-	state = drv->state + line;
-
-	down(&port_sem);
-	uart_unconfigure_port(drv, state);
-	up(&port_sem);
-}
-
 EXPORT_SYMBOL(uart_write_wakeup);
 EXPORT_SYMBOL(uart_register_driver);
 EXPORT_SYMBOL(uart_unregister_driver);
 EXPORT_SYMBOL(uart_suspend_port);
 EXPORT_SYMBOL(uart_resume_port);
-EXPORT_SYMBOL(uart_register_port);
-EXPORT_SYMBOL(uart_unregister_port);
 EXPORT_SYMBOL(uart_add_one_port);
 EXPORT_SYMBOL(uart_remove_one_port);
 
diff --git a/include/linux/serial.h b/include/linux/serial.h
index 9f2d852..12cd9cf6 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -176,10 +176,6 @@
 #ifdef __KERNEL__
 #include <linux/compiler.h>
 
-/* Export to allow PCMCIA to use this - Dave Hinds */
-extern int __deprecated register_serial(struct serial_struct *req);
-extern void __deprecated unregister_serial(int line);
-
 /* Allow architectures to override entries in serial8250_ports[] at run time: */
 struct uart_port;	/* forward declaration */
 extern int early_serial_setup(struct uart_port *port);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 1c53302..cf0f64e 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -360,8 +360,6 @@
  */
 int uart_register_driver(struct uart_driver *uart);
 void uart_unregister_driver(struct uart_driver *uart);
-void __deprecated uart_unregister_port(struct uart_driver *reg, int line);
-int __deprecated uart_register_port(struct uart_driver *reg, struct uart_port *port);
 int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
 int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
 int uart_match_port(struct uart_port *port1, struct uart_port *port2);