Commit 0f302dc3 authored by Sascha Hauer's avatar Sascha Hauer Committed by Russell King

[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: default avatarSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent b129a8cc
......@@ -896,8 +896,8 @@ source "drivers/char/pcmcia/Kconfig"
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
......
......@@ -6,7 +6,7 @@ menu "Misc devices"
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.
......
......@@ -447,7 +447,7 @@ config NET_SB1250_MAC
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
......
......@@ -2590,82 +2590,3 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
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);
......@@ -830,7 +830,7 @@ config SERIAL_M32R_PLDSIO
config SERIAL_TXX9
bool "TMPTX39XX/49XX SIO support"
depends HAS_TXX9_SERIAL
depends HAS_TXX9_SERIAL && BROKEN
select SERIAL_CORE
default y
......
......@@ -291,13 +291,31 @@ static unsigned int imx_tx_empty(struct uart_port *port)
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;
}
/*
......
......@@ -2289,143 +2289,11 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2)
}
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);
......
......@@ -176,10 +176,6 @@ struct serial_icounter_struct {
#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);
......
......@@ -360,8 +360,6 @@ struct tty_driver *uart_console_device(struct console *co, int *index);
*/
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment