Skip to content

Commit

Permalink
Merge master.kernel.org:/home/rmk/linux-2.6-serial
Browse files Browse the repository at this point in the history
  • Loading branch information
Linus Torvalds committed Jun 30, 2005
2 parents 92dd7ca + 026d02a commit 0b35ff2
Show file tree
Hide file tree
Showing 30 changed files with 82 additions and 572 deletions.
4 changes: 2 additions & 2 deletions Documentation/serial/driver
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion arch/parisc/configs/712_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/parisc/configs/a500_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/parisc/configs/b180_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/parisc/configs/c3000_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/parisc/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
33 changes: 17 additions & 16 deletions drivers/serial/8250.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -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)
Expand Down Expand 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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/serial/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions drivers/serial/au1x00_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 7 additions & 6 deletions drivers/serial/ip22zilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions drivers/serial/mpsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions drivers/serial/pmac_zilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
Expand Down
3 changes: 0 additions & 3 deletions drivers/serial/pxa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 27 additions & 1 deletion drivers/serial/serial_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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--;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 0 additions & 3 deletions drivers/serial/serial_txx9.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
7 changes: 1 addition & 6 deletions drivers/serial/sunsab.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}

Expand Down
3 changes: 0 additions & 3 deletions drivers/serial/sunsu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 0b35ff2

Please sign in to comment.