[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>
This commit is contained in:
parent
b129a8ccd5
commit
0f302dc354
@ -896,8 +896,8 @@ source "drivers/char/pcmcia/Kconfig"
|
|||||||
|
|
||||||
config MWAVE
|
config MWAVE
|
||||||
tristate "ACP Modem (Mwave) support"
|
tristate "ACP Modem (Mwave) support"
|
||||||
depends on X86
|
depends on X86 && BROKEN
|
||||||
select SERIAL_8250
|
select SERIAL_8250 # PLEASE DO NOT DO THIS - move this driver to drivers/serial
|
||||||
---help---
|
---help---
|
||||||
The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
|
The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
|
||||||
kernel driver and a user level application. Together these components
|
kernel driver and a user level application. Together these components
|
||||||
|
@ -6,7 +6,7 @@ menu "Misc devices"
|
|||||||
|
|
||||||
config IBM_ASM
|
config IBM_ASM
|
||||||
tristate "Device driver for IBM RSA service processor"
|
tristate "Device driver for IBM RSA service processor"
|
||||||
depends on X86 && PCI && EXPERIMENTAL
|
depends on X86 && PCI && EXPERIMENTAL && BROKEN
|
||||||
---help---
|
---help---
|
||||||
This option enables device driver support for in-band access to the
|
This option enables device driver support for in-band access to the
|
||||||
IBM RSA (Condor) service processor in eServer xSeries systems.
|
IBM RSA (Condor) service processor in eServer xSeries systems.
|
||||||
|
@ -447,7 +447,7 @@ config NET_SB1250_MAC
|
|||||||
|
|
||||||
config SGI_IOC3_ETH
|
config SGI_IOC3_ETH
|
||||||
bool "SGI IOC3 Ethernet"
|
bool "SGI IOC3 Ethernet"
|
||||||
depends on NET_ETHERNET && PCI && SGI_IP27
|
depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN
|
||||||
select CRC32
|
select CRC32
|
||||||
select MII
|
select MII
|
||||||
help
|
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");
|
MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
|
||||||
#endif
|
#endif
|
||||||
MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
|
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
|
config SERIAL_TXX9
|
||||||
bool "TMPTX39XX/49XX SIO support"
|
bool "TMPTX39XX/49XX SIO support"
|
||||||
depends HAS_TXX9_SERIAL
|
depends HAS_TXX9_SERIAL && BROKEN
|
||||||
select SERIAL_CORE
|
select SERIAL_CORE
|
||||||
default y
|
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;
|
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)
|
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)
|
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);
|
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_write_wakeup);
|
||||||
EXPORT_SYMBOL(uart_register_driver);
|
EXPORT_SYMBOL(uart_register_driver);
|
||||||
EXPORT_SYMBOL(uart_unregister_driver);
|
EXPORT_SYMBOL(uart_unregister_driver);
|
||||||
EXPORT_SYMBOL(uart_suspend_port);
|
EXPORT_SYMBOL(uart_suspend_port);
|
||||||
EXPORT_SYMBOL(uart_resume_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_add_one_port);
|
||||||
EXPORT_SYMBOL(uart_remove_one_port);
|
EXPORT_SYMBOL(uart_remove_one_port);
|
||||||
|
|
||||||
|
@ -176,10 +176,6 @@ struct serial_icounter_struct {
|
|||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
#include <linux/compiler.h>
|
#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: */
|
/* Allow architectures to override entries in serial8250_ports[] at run time: */
|
||||||
struct uart_port; /* forward declaration */
|
struct uart_port; /* forward declaration */
|
||||||
extern int early_serial_setup(struct uart_port *port);
|
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);
|
int uart_register_driver(struct uart_driver *uart);
|
||||||
void uart_unregister_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_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_remove_one_port(struct uart_driver *reg, struct uart_port *port);
|
||||||
int uart_match_port(struct uart_port *port1, struct uart_port *port2);
|
int uart_match_port(struct uart_port *port1, struct uart_port *port2);
|
||||||
|
Loading…
Reference in New Issue
Block a user