Commit 0b35ff23 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge master.kernel.org:/home/rmk/linux-2.6-serial

parents 92dd7ca0 026d02a2
......@@ -107,8 +107,8 @@ hardware.
indicate that the signal is permanently active. If RI is
not available, the signal should not be indicated as active.
Locking: none.
Interrupts: caller dependent.
Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep
stop_tx(port,tty_stop)
......
......@@ -506,7 +506,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_NR_UARTS=17
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
......
......@@ -662,7 +662,7 @@ CONFIG_HW_CONSOLE=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_8250_NR_UARTS=8
CONFIG_SERIAL_8250_NR_UARTS=17
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
......
......@@ -514,7 +514,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_NR_UARTS=13
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
......
......@@ -661,7 +661,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_NR_UARTS=13
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
......
......@@ -517,7 +517,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_NR_UARTS=13
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
......
......@@ -105,7 +105,7 @@ static struct old_serial_port old_serial_port[] = {
SERIAL_PORT_DFNS /* defined in asm/serial.h */
};
#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS)
#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
#ifdef CONFIG_SERIAL_8250_RSA
......@@ -993,21 +993,24 @@ static void autoconfig_irq(struct uart_8250_port *up)
up->port.irq = (irq > 0) ? irq : 0;
}
static inline void __stop_tx(struct uart_8250_port *p)
{
if (p->ier & UART_IER_THRI) {
p->ier &= ~UART_IER_THRI;
serial_out(p, UART_IER, p->ier);
}
}
static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
if (up->ier & UART_IER_THRI) {
up->ier &= ~UART_IER_THRI;
serial_out(up, UART_IER, up->ier);
}
__stop_tx(up);
/*
* We only do this from uart_stop - if we run out of
* characters to send, we don't want to prevent the
* FIFO from emptying.
* We really want to stop the transmitter from sending.
*/
if (up->port.type == PORT_16C950 && tty_stop) {
if (up->port.type == PORT_16C950) {
up->acr |= UART_ACR_TXDIS;
serial_icr_write(up, UART_ACR, up->acr);
}
......@@ -1031,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
transmit_chars(up);
}
}
/*
* We only do this from uart_start
* Re-enable the transmitter if we disabled it.
*/
if (tty_start && up->port.type == PORT_16C950) {
if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
up->acr &= ~UART_ACR_TXDIS;
serial_icr_write(up, UART_ACR, up->acr);
}
......@@ -1155,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
return;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
serial8250_stop_tx(&up->port, 0);
__stop_tx(up);
return;
}
......@@ -1174,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
DEBUG_INTR("THRE...");
if (uart_circ_empty(xmit))
serial8250_stop_tx(&up->port, 0);
__stop_tx(up);
}
static _INLINE_ void check_modem_status(struct uart_8250_port *up)
......@@ -1376,13 +1380,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned long flags;
unsigned char status;
unsigned int ret;
spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
......
......@@ -86,7 +86,7 @@ config SERIAL_8250_ACPI
namespace, say Y here. If unsure, say N.
config SERIAL_8250_NR_UARTS
int "Maximum number of non-legacy 8250/16550 serial ports"
int "Maximum number of 8250/16550 serial ports"
depends on SERIAL_8250
default "4"
help
......
......@@ -556,13 +556,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
static unsigned int serial8250_get_mctrl(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned long flags;
unsigned char status;
unsigned int ret;
spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
......
......@@ -518,27 +518,28 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re
static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
{
struct zilog_channel *channel;
unsigned long flags;
unsigned char status;
spin_lock_irqsave(&port->lock, flags);
channel = ZILOG_CHANNEL_FROM_PORT(port);
status = readb(&channel->control);
ZSDELAY();
spin_unlock_irqrestore(&port->lock, flags);
return status;
}
/* The port lock is not held. */
static unsigned int ip22zilog_tx_empty(struct uart_port *port)
{
unsigned long flags;
unsigned char status;
unsigned int ret;
spin_lock_irqsave(&port->lock, flags);
status = ip22zilog_read_channel_status(port);
spin_unlock_irqrestore(&port->lock, flags);
if (status & Tx_BUF_EMP)
ret = TIOCSER_TEMT;
else
......@@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port)
return ret;
}
/* The port lock is not held. */
/* The port lock is held and interrupts are disabled. */
static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
{
unsigned char status;
......
......@@ -1058,12 +1058,9 @@ mpsc_get_mctrl(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
u32 mflags, status;
ulong iflags;
spin_lock_irqsave(&pi->port.lock, iflags);
status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
readl(pi->mpsc_base + MPSC_CHR_10);
spin_unlock_irqrestore(&pi->port.lock, iflags);
mflags = 0;
if (status & 0x1)
......
......@@ -604,7 +604,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl)
/*
* Get Modem Control bits (only the input ones, the core will
* or that with a cached value of the control ones)
* The port lock is not held.
* The port lock is held and interrupts are disabled.
*/
static unsigned int pmz_get_mctrl(struct uart_port *port)
{
......@@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port)
if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
return 0;
status = pmz_peek_status(to_pmz(port));
status = read_zsreg(uap, R0);
ret = 0;
if (status & DCD)
......
......@@ -274,14 +274,11 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port)
static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
{
struct uart_pxa_port *up = (struct uart_pxa_port *)port;
unsigned long flags;
unsigned char status;
unsigned int ret;
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
......
......@@ -182,6 +182,13 @@ static int uart_startup(struct uart_state *state, int init_hw)
uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
}
if (info->flags & UIF_CTS_FLOW) {
spin_lock_irq(&port->lock);
if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
info->tty->hw_stopped = 1;
spin_unlock_irq(&port->lock);
}
info->flags |= UIF_INITIALIZED;
clear_bit(TTY_IO_ERROR, &info->tty->flags);
......@@ -828,7 +835,10 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file)
if ((!file || !tty_hung_up_p(file)) &&
!(tty->flags & (1 << TTY_IO_ERROR))) {
result = port->mctrl;
spin_lock_irq(&port->lock);
result |= port->ops->get_mctrl(port);
spin_unlock_irq(&port->lock);
}
up(&state->sem);
......@@ -1131,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios
spin_unlock_irqrestore(&state->port->lock, flags);
}
/* Handle turning on CRTSCTS */
if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
spin_lock_irqsave(&state->port->lock, flags);
if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
tty->hw_stopped = 1;
state->port->ops->stop_tx(state->port, 0);
}
spin_unlock_irqrestore(&state->port->lock, flags);
}
#if 0
/*
* No need to wake up processes in open wait, since they
......@@ -1369,6 +1389,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
DECLARE_WAITQUEUE(wait, current);
struct uart_info *info = state->info;
struct uart_port *port = state->port;
unsigned int mctrl;
info->blocked_open++;
state->count--;
......@@ -1416,7 +1437,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
* and wait for the carrier to indicate that the
* modem is ready for us.
*/
if (port->ops->get_mctrl(port) & TIOCM_CAR)
spin_lock_irq(&port->lock);
mctrl = port->ops->get_mctrl(port);
spin_unlock_irq(&port->lock);
if (mctrl & TIOCM_CAR)
break;
up(&state->sem);
......@@ -1618,7 +1642,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
if(capable(CAP_SYS_ADMIN))
{
spin_lock_irq(&port->lock);
status = port->ops->get_mctrl(port);
spin_unlock_irq(&port->lock);
ret += sprintf(buf + ret, " tx:%d rx:%d",
port->icount.tx, port->icount.rx);
......
......@@ -442,13 +442,10 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port)
static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
{
struct uart_txx9_port *up = (struct uart_txx9_port *)port;
unsigned long flags;
unsigned int ret;
spin_lock_irqsave(&up->port.lock, flags);
ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
| ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
spin_unlock_irqrestore(&up->port.lock, flags);
return ret;
}
......
......@@ -426,18 +426,15 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl)
sunsab_tx_idle(up);
}
/* port->lock is not held. */
/* port->lock is held by caller and interrupts are disabled. */
static unsigned int sunsab_get_mctrl(struct uart_port *port)
{
struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
unsigned long flags;
unsigned char val;
unsigned int result;
result = 0;
spin_lock_irqsave(&up->port.lock, flags);
val = readb(&up->regs->r.pvr);
result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
......@@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port)
val = readb(&up->regs->r.star);
result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
spin_unlock_irqrestore(&up->port.lock, flags);
return result;
}
......
......@@ -572,13 +572,10 @@ static unsigned int sunsu_tx_empty(struct uart_port *port)
static unsigned int sunsu_get_mctrl(struct uart_port *port)
{
struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
unsigned long flags;
unsigned char status;
unsigned int ret;
spin_lock_irqsave(&up->port.lock, flags);
status = serial_in(up, UART_MSR);
spin_unlock_irqrestore(&up->port.lock, flags);
ret = 0;
if (status & UART_MSR_DCD)
......
......@@ -610,27 +610,28 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg
static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
{
struct zilog_channel __iomem *channel;
unsigned long flags;
unsigned char status;
spin_lock_irqsave(&port->lock, flags);
channel = ZILOG_CHANNEL_FROM_PORT(port);
status = sbus_readb(&channel->control);
ZSDELAY();
spin_unlock_irqrestore(&port->lock, flags);
return status;
}
/* The port lock is not held. */
static unsigned int sunzilog_tx_empty(struct uart_port *port)
{
unsigned long flags;
unsigned char status;
unsigned int ret;
spin_lock_irqsave(&port->lock, flags);
status = sunzilog_read_channel_status(port);
spin_unlock_irqrestore(&port->lock, flags);
if (status & Tx_BUF_EMP)
ret = TIOCSER_TEMT;
else
......@@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port)
return ret;
}
/* The port lock is not held. */
/* The port lock is held and interrupts are disabled. */
static unsigned int sunzilog_get_mctrl(struct uart_port *port)
{
unsigned char status;
......
......@@ -22,54 +22,9 @@
#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
#endif
#ifdef CONFIG_SERIAL_MANY_PORTS
#define FOURPORT_FLAGS ASYNC_FOURPORT
#define ACCENT_FLAGS 0
#define BOCA_FLAGS 0
#endif
#define STD_SERIAL_PORT_DEFNS \
#define SERIAL_PORT_DFNS \
/* UART CLK PORT IRQ FLAGS */ \
{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \
{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */
#ifdef CONFIG_SERIAL_MANY_PORTS
#define EXTRA_SERIAL_PORT_DEFNS \
{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \
{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \
{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \
{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \
{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \
{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \
{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \
{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \
{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \
{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \
{ 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \
{ 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \
{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \
{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \
{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \
{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \
{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \
{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \
{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \
{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \
{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \
{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \
{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \
{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \
{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \
{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \
{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \
{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */
#else
#define EXTRA_SERIAL_PORT_DEFNS
#endif
#define SERIAL_PORT_DFNS \
STD_SERIAL_PORT_DEFNS \
EXTRA_SERIAL_PORT_DEFNS
......@@ -30,34 +30,16 @@
#if defined(CONFIG_ARCH_A5K)
/* UART CLK PORT IRQ FLAGS */
#define STD_SERIAL_PORT_DEFNS \
#define SERIAL_PORT_DFNS \
{ 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS }, /* ttyS1 */
#else
#define STD_SERIAL_PORT_DEFNS \
#define SERIAL_PORT_DFNS \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS0 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS1 */
#endif
#define EXTRA_SERIAL_PORT_DEFNS \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \
{ 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */
#define SERIAL_PORT_DFNS \
STD_SERIAL_PORT_DEFNS \
EXTRA_SERIAL_PORT_DEFNS
#endif
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