summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/serial/driver4
-rw-r--r--drivers/serial/8250.c3
-rw-r--r--drivers/serial/au1x00_uart.c3
-rw-r--r--drivers/serial/ip22zilog.c13
-rw-r--r--drivers/serial/mpsc.c3
-rw-r--r--drivers/serial/pmac_zilog.c4
-rw-r--r--drivers/serial/pxa.c3
-rw-r--r--drivers/serial/serial_core.c11
-rw-r--r--drivers/serial/serial_txx9.c3
-rw-r--r--drivers/serial/sunsab.c7
-rw-r--r--drivers/serial/sunsu.c3
-rw-r--r--drivers/serial/sunzilog.c13
12 files changed, 29 insertions, 41 deletions
diff --git a/Documentation/serial/driver b/Documentation/serial/driver
index e9c0178cd202..ac7eabbf662a 100644
--- a/Documentation/serial/driver
+++ b/Documentation/serial/driver
@@ -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)
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 34e75bc8f4cc..b53b53bb1475 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1376,13 +1376,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)
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index 5400dc2c087e..6104aeef1243 100644
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -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)
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 3ea46c069f6f..ea5bf4d4daa3 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -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;
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index a2a643318002..e43276c6a954 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -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)
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 85abd8a045e0..1c9f71617123 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -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)
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 08b08d6ae904..461c81c93207 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -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)
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 36b1ae083fb7..f5ce58d0514d 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -828,7 +828,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);
@@ -1369,6 +1372,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 +1420,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 +1625,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);
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 3f1051a4a13f..d085030df70b 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -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;
}
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 10e2990a40d4..8d198880756a 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -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;
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index ddc97c905e14..d57a3553aea3 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -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)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 8e65206d3d76..bff42a7b89d0 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -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;