aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/8250.c36
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/au1x00_uart.c3
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c32
-rw-r--r--drivers/serial/ip22zilog.c13
-rw-r--r--drivers/serial/mpsc.c3
-rw-r--r--drivers/serial/pmac_zilog.c13
-rw-r--r--drivers/serial/pxa.c3
-rw-r--r--drivers/serial/s3c2410.c5
-rw-r--r--drivers/serial/serial_core.c42
-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
14 files changed, 111 insertions, 67 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 34e75bc8f4cc..7e8fc7c1d4cc 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -105,7 +105,7 @@ static struct old_serial_port old_serial_port[] = {
105 SERIAL_PORT_DFNS /* defined in asm/serial.h */ 105 SERIAL_PORT_DFNS /* defined in asm/serial.h */
106}; 106};
107 107
108#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) 108#define UART_NR CONFIG_SERIAL_8250_NR_UARTS
109 109
110#ifdef CONFIG_SERIAL_8250_RSA 110#ifdef CONFIG_SERIAL_8250_RSA
111 111
@@ -993,21 +993,24 @@ static void autoconfig_irq(struct uart_8250_port *up)
993 up->port.irq = (irq > 0) ? irq : 0; 993 up->port.irq = (irq > 0) ? irq : 0;
994} 994}
995 995
996static inline void __stop_tx(struct uart_8250_port *p)
997{
998 if (p->ier & UART_IER_THRI) {
999 p->ier &= ~UART_IER_THRI;
1000 serial_out(p, UART_IER, p->ier);
1001 }
1002}
1003
996static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) 1004static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
997{ 1005{
998 struct uart_8250_port *up = (struct uart_8250_port *)port; 1006 struct uart_8250_port *up = (struct uart_8250_port *)port;
999 1007
1000 if (up->ier & UART_IER_THRI) { 1008 __stop_tx(up);
1001 up->ier &= ~UART_IER_THRI;
1002 serial_out(up, UART_IER, up->ier);
1003 }
1004 1009
1005 /* 1010 /*
1006 * We only do this from uart_stop - if we run out of 1011 * We really want to stop the transmitter from sending.
1007 * characters to send, we don't want to prevent the
1008 * FIFO from emptying.
1009 */ 1012 */
1010 if (up->port.type == PORT_16C950 && tty_stop) { 1013 if (up->port.type == PORT_16C950) {
1011 up->acr |= UART_ACR_TXDIS; 1014 up->acr |= UART_ACR_TXDIS;
1012 serial_icr_write(up, UART_ACR, up->acr); 1015 serial_icr_write(up, UART_ACR, up->acr);
1013 } 1016 }
@@ -1031,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
1031 transmit_chars(up); 1034 transmit_chars(up);
1032 } 1035 }
1033 } 1036 }
1037
1034 /* 1038 /*
1035 * We only do this from uart_start 1039 * Re-enable the transmitter if we disabled it.
1036 */ 1040 */
1037 if (tty_start && up->port.type == PORT_16C950) { 1041 if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
1038 up->acr &= ~UART_ACR_TXDIS; 1042 up->acr &= ~UART_ACR_TXDIS;
1039 serial_icr_write(up, UART_ACR, up->acr); 1043 serial_icr_write(up, UART_ACR, up->acr);
1040 } 1044 }
@@ -1155,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
1155 return; 1159 return;
1156 } 1160 }
1157 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 1161 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
1158 serial8250_stop_tx(&up->port, 0); 1162 __stop_tx(up);
1159 return; 1163 return;
1160 } 1164 }
1161 1165
@@ -1174,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
1174 DEBUG_INTR("THRE..."); 1178 DEBUG_INTR("THRE...");
1175 1179
1176 if (uart_circ_empty(xmit)) 1180 if (uart_circ_empty(xmit))
1177 serial8250_stop_tx(&up->port, 0); 1181 __stop_tx(up);
1178} 1182}
1179 1183
1180static _INLINE_ void check_modem_status(struct uart_8250_port *up) 1184static _INLINE_ void check_modem_status(struct uart_8250_port *up)
@@ -1376,13 +1380,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
1376static unsigned int serial8250_get_mctrl(struct uart_port *port) 1380static unsigned int serial8250_get_mctrl(struct uart_port *port)
1377{ 1381{
1378 struct uart_8250_port *up = (struct uart_8250_port *)port; 1382 struct uart_8250_port *up = (struct uart_8250_port *)port;
1379 unsigned long flags;
1380 unsigned char status; 1383 unsigned char status;
1381 unsigned int ret; 1384 unsigned int ret;
1382 1385
1383 spin_lock_irqsave(&up->port.lock, flags);
1384 status = serial_in(up, UART_MSR); 1386 status = serial_in(up, UART_MSR);
1385 spin_unlock_irqrestore(&up->port.lock, flags);
1386 1387
1387 ret = 0; 1388 ret = 0;
1388 if (status & UART_MSR_DCD) 1389 if (status & UART_MSR_DCD)
@@ -2060,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void)
2060 up->port.ops = &serial8250_pops; 2061 up->port.ops = &serial8250_pops;
2061 } 2062 }
2062 2063
2063 for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); 2064 for (i = 0, up = serial8250_ports;
2065 i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
2064 i++, up++) { 2066 i++, up++) {
2065 up->port.iobase = old_serial_port[i].port; 2067 up->port.iobase = old_serial_port[i].port;
2066 up->port.irq = irq_canonicalize(old_serial_port[i].irq); 2068 up->port.irq = irq_canonicalize(old_serial_port[i].irq);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e879bce160df..e0d0a470ddfc 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -86,7 +86,7 @@ config SERIAL_8250_ACPI
86 namespace, say Y here. If unsure, say N. 86 namespace, say Y here. If unsure, say N.
87 87
88config SERIAL_8250_NR_UARTS 88config SERIAL_8250_NR_UARTS
89 int "Maximum number of non-legacy 8250/16550 serial ports" 89 int "Maximum number of 8250/16550 serial ports"
90 depends on SERIAL_8250 90 depends on SERIAL_8250
91 default "4" 91 default "4"
92 help 92 help
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)
556static unsigned int serial8250_get_mctrl(struct uart_port *port) 556static unsigned int serial8250_get_mctrl(struct uart_port *port)
557{ 557{
558 struct uart_8250_port *up = (struct uart_8250_port *)port; 558 struct uart_8250_port *up = (struct uart_8250_port *)port;
559 unsigned long flags;
560 unsigned char status; 559 unsigned char status;
561 unsigned int ret; 560 unsigned int ret;
562 561
563 spin_lock_irqsave(&up->port.lock, flags);
564 status = serial_in(up, UART_MSR); 562 status = serial_in(up, UART_MSR);
565 spin_unlock_irqrestore(&up->port.lock, flags);
566 563
567 ret = 0; 564 ret = 0;
568 if (status & UART_MSR_DCD) 565 if (status & UART_MSR_DCD)
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index de26cf7b003c..7911912f50c7 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -94,12 +94,42 @@ void smc1_lineif(struct uart_cpm_port *pinfo)
94 ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; 94 ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
95 } 95 }
96 96
97#ifdef CONFIG_MPC885ADS
98 /* Enable SMC1 transceivers */
99 {
100 volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4);
101 uint tmp;
102
103 tmp = in_be32(bcsr1);
104 tmp &= ~BCSR1_RS232EN_1;
105 out_be32(bcsr1, tmp);
106 iounmap(bcsr1);
107 }
108#endif
109
97 pinfo->brg = 1; 110 pinfo->brg = 1;
98} 111}
99 112
100void smc2_lineif(struct uart_cpm_port *pinfo) 113void smc2_lineif(struct uart_cpm_port *pinfo)
101{ 114{
102 /* XXX SMC2: insert port configuration here */ 115#ifdef CONFIG_MPC885ADS
116 volatile cpm8xx_t *cp = cpmp;
117 volatile uint __iomem *bcsr1;
118 uint tmp;
119
120 cp->cp_pepar |= 0x00000c00;
121 cp->cp_pedir &= ~0x00000c00;
122 cp->cp_peso &= ~0x00000400;
123 cp->cp_peso |= 0x00000800;
124
125 /* Enable SMC2 transceivers */
126 bcsr1 = ioremap(BCSR1, 4);
127 tmp = in_be32(bcsr1);
128 tmp &= ~BCSR1_RS232EN_2;
129 out_be32(bcsr1, tmp);
130 iounmap(bcsr1);
131#endif
132
103 pinfo->brg = 2; 133 pinfo->brg = 2;
104} 134}
105 135
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
518static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port) 518static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
519{ 519{
520 struct zilog_channel *channel; 520 struct zilog_channel *channel;
521 unsigned long flags;
522 unsigned char status; 521 unsigned char status;
523 522
524 spin_lock_irqsave(&port->lock, flags);
525
526 channel = ZILOG_CHANNEL_FROM_PORT(port); 523 channel = ZILOG_CHANNEL_FROM_PORT(port);
527 status = readb(&channel->control); 524 status = readb(&channel->control);
528 ZSDELAY(); 525 ZSDELAY();
529 526
530 spin_unlock_irqrestore(&port->lock, flags);
531
532 return status; 527 return status;
533} 528}
534 529
535/* The port lock is not held. */ 530/* The port lock is not held. */
536static unsigned int ip22zilog_tx_empty(struct uart_port *port) 531static unsigned int ip22zilog_tx_empty(struct uart_port *port)
537{ 532{
533 unsigned long flags;
538 unsigned char status; 534 unsigned char status;
539 unsigned int ret; 535 unsigned int ret;
540 536
537 spin_lock_irqsave(&port->lock, flags);
538
541 status = ip22zilog_read_channel_status(port); 539 status = ip22zilog_read_channel_status(port);
540
541 spin_unlock_irqrestore(&port->lock, flags);
542
542 if (status & Tx_BUF_EMP) 543 if (status & Tx_BUF_EMP)
543 ret = TIOCSER_TEMT; 544 ret = TIOCSER_TEMT;
544 else 545 else
@@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port)
547 return ret; 548 return ret;
548} 549}
549 550
550/* The port lock is not held. */ 551/* The port lock is held and interrupts are disabled. */
551static unsigned int ip22zilog_get_mctrl(struct uart_port *port) 552static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
552{ 553{
553 unsigned char status; 554 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)
1058{ 1058{
1059 struct mpsc_port_info *pi = (struct mpsc_port_info *)port; 1059 struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
1060 u32 mflags, status; 1060 u32 mflags, status;
1061 ulong iflags;
1062 1061
1063 spin_lock_irqsave(&pi->port.lock, iflags);
1064 status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m : 1062 status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
1065 readl(pi->mpsc_base + MPSC_CHR_10); 1063 readl(pi->mpsc_base + MPSC_CHR_10);
1066 spin_unlock_irqrestore(&pi->port.lock, iflags);
1067 1064
1068 mflags = 0; 1065 mflags = 0;
1069 if (status & 0x1) 1066 if (status & 0x1)
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 85abd8a045e0..7db2f37532cf 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)
604/* 604/*
605 * Get Modem Control bits (only the input ones, the core will 605 * Get Modem Control bits (only the input ones, the core will
606 * or that with a cached value of the control ones) 606 * or that with a cached value of the control ones)
607 * The port lock is not held. 607 * The port lock is held and interrupts are disabled.
608 */ 608 */
609static unsigned int pmz_get_mctrl(struct uart_port *port) 609static unsigned int pmz_get_mctrl(struct uart_port *port)
610{ 610{
@@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port)
615 if (ZS_IS_ASLEEP(uap) || uap->node == NULL) 615 if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
616 return 0; 616 return 0;
617 617
618 status = pmz_peek_status(to_pmz(port)); 618 status = read_zsreg(uap, R0);
619 619
620 ret = 0; 620 ret = 0;
621 if (status & DCD) 621 if (status & DCD)
@@ -1545,7 +1545,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap)
1545/* 1545/*
1546 * Called upon match with an escc node in the devive-tree. 1546 * Called upon match with an escc node in the devive-tree.
1547 */ 1547 */
1548static int pmz_attach(struct macio_dev *mdev, const struct of_match *match) 1548static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
1549{ 1549{
1550 int i; 1550 int i;
1551 1551
@@ -1850,20 +1850,17 @@ err_out:
1850 return rc; 1850 return rc;
1851} 1851}
1852 1852
1853static struct of_match pmz_match[] = 1853static struct of_device_id pmz_match[] =
1854{ 1854{
1855 { 1855 {
1856 .name = "ch-a", 1856 .name = "ch-a",
1857 .type = OF_ANY_MATCH,
1858 .compatible = OF_ANY_MATCH
1859 }, 1857 },
1860 { 1858 {
1861 .name = "ch-b", 1859 .name = "ch-b",
1862 .type = OF_ANY_MATCH,
1863 .compatible = OF_ANY_MATCH
1864 }, 1860 },
1865 {}, 1861 {},
1866}; 1862};
1863MODULE_DEVICE_TABLE (of, pmz_match);
1867 1864
1868static struct macio_driver pmz_driver = 1865static struct macio_driver pmz_driver =
1869{ 1866{
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)
274static unsigned int serial_pxa_get_mctrl(struct uart_port *port) 274static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
275{ 275{
276 struct uart_pxa_port *up = (struct uart_pxa_port *)port; 276 struct uart_pxa_port *up = (struct uart_pxa_port *)port;
277 unsigned long flags;
278 unsigned char status; 277 unsigned char status;
279 unsigned int ret; 278 unsigned int ret;
280 279
281return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; 280return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
282 spin_lock_irqsave(&up->port.lock, flags);
283 status = serial_in(up, UART_MSR); 281 status = serial_in(up, UART_MSR);
284 spin_unlock_irqrestore(&up->port.lock, flags);
285 282
286 ret = 0; 283 ret = 0;
287 if (status & UART_MSR_DCD) 284 if (status & UART_MSR_DCD)
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 5c4678478b1d..7365d4b50b95 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port)
522static int s3c24xx_serial_startup(struct uart_port *port) 522static int s3c24xx_serial_startup(struct uart_port *port)
523{ 523{
524 struct s3c24xx_uart_port *ourport = to_ourport(port); 524 struct s3c24xx_uart_port *ourport = to_ourport(port);
525 unsigned long flags;
526 int ret; 525 int ret;
527 526
528 dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", 527 dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
529 port->mapbase, port->membase); 528 port->mapbase, port->membase);
530 529
531 local_irq_save(flags);
532
533 rx_enabled(port) = 1; 530 rx_enabled(port) = 1;
534 531
535 ret = request_irq(RX_IRQ(port), 532 ret = request_irq(RX_IRQ(port),
@@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct uart_port *port)
563 /* the port reset code should have done the correct 560 /* the port reset code should have done the correct
564 * register setup for the port controls */ 561 * register setup for the port controls */
565 562
566 local_irq_restore(flags);
567 return ret; 563 return ret;
568 564
569 err: 565 err:
570 s3c24xx_serial_shutdown(port); 566 s3c24xx_serial_shutdown(port);
571 local_irq_restore(flags);
572 return ret; 567 return ret;
573} 568}
574 569
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 36b1ae083fb7..54699c3a00ab 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -182,6 +182,13 @@ static int uart_startup(struct uart_state *state, int init_hw)
182 uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); 182 uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
183 } 183 }
184 184
185 if (info->flags & UIF_CTS_FLOW) {
186 spin_lock_irq(&port->lock);
187 if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
188 info->tty->hw_stopped = 1;
189 spin_unlock_irq(&port->lock);
190 }
191
185 info->flags |= UIF_INITIALIZED; 192 info->flags |= UIF_INITIALIZED;
186 193
187 clear_bit(TTY_IO_ERROR, &info->tty->flags); 194 clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -828,7 +835,10 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file)
828 if ((!file || !tty_hung_up_p(file)) && 835 if ((!file || !tty_hung_up_p(file)) &&
829 !(tty->flags & (1 << TTY_IO_ERROR))) { 836 !(tty->flags & (1 << TTY_IO_ERROR))) {
830 result = port->mctrl; 837 result = port->mctrl;
838
839 spin_lock_irq(&port->lock);
831 result |= port->ops->get_mctrl(port); 840 result |= port->ops->get_mctrl(port);
841 spin_unlock_irq(&port->lock);
832 } 842 }
833 up(&state->sem); 843 up(&state->sem);
834 844
@@ -1131,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios
1131 spin_unlock_irqrestore(&state->port->lock, flags); 1141 spin_unlock_irqrestore(&state->port->lock, flags);
1132 } 1142 }
1133 1143
1144 /* Handle turning on CRTSCTS */
1145 if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
1146 spin_lock_irqsave(&state->port->lock, flags);
1147 if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
1148 tty->hw_stopped = 1;
1149 state->port->ops->stop_tx(state->port, 0);
1150 }
1151 spin_unlock_irqrestore(&state->port->lock, flags);
1152 }
1153
1134#if 0 1154#if 0
1135 /* 1155 /*
1136 * No need to wake up processes in open wait, since they 1156 * 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)
1369 DECLARE_WAITQUEUE(wait, current); 1389 DECLARE_WAITQUEUE(wait, current);
1370 struct uart_info *info = state->info; 1390 struct uart_info *info = state->info;
1371 struct uart_port *port = state->port; 1391 struct uart_port *port = state->port;
1392 unsigned int mctrl;
1372 1393
1373 info->blocked_open++; 1394 info->blocked_open++;
1374 state->count--; 1395 state->count--;
@@ -1416,7 +1437,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
1416 * and wait for the carrier to indicate that the 1437 * and wait for the carrier to indicate that the
1417 * modem is ready for us. 1438 * modem is ready for us.
1418 */ 1439 */
1419 if (port->ops->get_mctrl(port) & TIOCM_CAR) 1440 spin_lock_irq(&port->lock);
1441 mctrl = port->ops->get_mctrl(port);
1442 spin_unlock_irq(&port->lock);
1443 if (mctrl & TIOCM_CAR)
1420 break; 1444 break;
1421 1445
1422 up(&state->sem); 1446 up(&state->sem);
@@ -1618,7 +1642,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
1618 1642
1619 if(capable(CAP_SYS_ADMIN)) 1643 if(capable(CAP_SYS_ADMIN))
1620 { 1644 {
1645 spin_lock_irq(&port->lock);
1621 status = port->ops->get_mctrl(port); 1646 status = port->ops->get_mctrl(port);
1647 spin_unlock_irq(&port->lock);
1622 1648
1623 ret += sprintf(buf + ret, " tx:%d rx:%d", 1649 ret += sprintf(buf + ret, " tx:%d rx:%d",
1624 port->icount.tx, port->icount.rx); 1650 port->icount.tx, port->icount.rx);
@@ -1782,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co,
1782 struct termios termios; 1808 struct termios termios;
1783 int i; 1809 int i;
1784 1810
1811 /*
1812 * Ensure that the serial console lock is initialised
1813 * early.
1814 */
1815 spin_lock_init(&port->lock);
1816
1785 memset(&termios, 0, sizeof(struct termios)); 1817 memset(&termios, 0, sizeof(struct termios));
1786 1818
1787 termios.c_cflag = CREAD | HUPCL | CLOCAL; 1819 termios.c_cflag = CREAD | HUPCL | CLOCAL;
@@ -2170,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2170 2202
2171 state->port = port; 2203 state->port = port;
2172 2204
2173 spin_lock_init(&port->lock);
2174 port->cons = drv->cons; 2205 port->cons = drv->cons;
2175 port->info = state->info; 2206 port->info = state->info;
2176 2207
2208 /*
2209 * If this port is a console, then the spinlock is already
2210 * initialised.
2211 */
2212 if (!uart_console(port))
2213 spin_lock_init(&port->lock);
2214
2177 uart_configure_port(drv, state, port); 2215 uart_configure_port(drv, state, port);
2178 2216
2179 /* 2217 /*
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)
442static unsigned int serial_txx9_get_mctrl(struct uart_port *port) 442static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
443{ 443{
444 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 444 struct uart_txx9_port *up = (struct uart_txx9_port *)port;
445 unsigned long flags;
446 unsigned int ret; 445 unsigned int ret;
447 446
448 spin_lock_irqsave(&up->port.lock, flags);
449 ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) 447 ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
450 | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); 448 | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
451 spin_unlock_irqrestore(&up->port.lock, flags);
452 449
453 return ret; 450 return ret;
454} 451}
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)
426 sunsab_tx_idle(up); 426 sunsab_tx_idle(up);
427} 427}
428 428
429/* port->lock is not held. */ 429/* port->lock is held by caller and interrupts are disabled. */
430static unsigned int sunsab_get_mctrl(struct uart_port *port) 430static unsigned int sunsab_get_mctrl(struct uart_port *port)
431{ 431{
432 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; 432 struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
433 unsigned long flags;
434 unsigned char val; 433 unsigned char val;
435 unsigned int result; 434 unsigned int result;
436 435
437 result = 0; 436 result = 0;
438 437
439 spin_lock_irqsave(&up->port.lock, flags);
440
441 val = readb(&up->regs->r.pvr); 438 val = readb(&up->regs->r.pvr);
442 result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR; 439 result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
443 440
@@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port)
447 val = readb(&up->regs->r.star); 444 val = readb(&up->regs->r.star);
448 result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0; 445 result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
449 446
450 spin_unlock_irqrestore(&up->port.lock, flags);
451
452 return result; 447 return result;
453} 448}
454 449
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)
572static unsigned int sunsu_get_mctrl(struct uart_port *port) 572static unsigned int sunsu_get_mctrl(struct uart_port *port)
573{ 573{
574 struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; 574 struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
575 unsigned long flags;
576 unsigned char status; 575 unsigned char status;
577 unsigned int ret; 576 unsigned int ret;
578 577
579 spin_lock_irqsave(&up->port.lock, flags);
580 status = serial_in(up, UART_MSR); 578 status = serial_in(up, UART_MSR);
581 spin_unlock_irqrestore(&up->port.lock, flags);
582 579
583 ret = 0; 580 ret = 0;
584 if (status & UART_MSR_DCD) 581 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
610static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port) 610static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
611{ 611{
612 struct zilog_channel __iomem *channel; 612 struct zilog_channel __iomem *channel;
613 unsigned long flags;
614 unsigned char status; 613 unsigned char status;
615 614
616 spin_lock_irqsave(&port->lock, flags);
617
618 channel = ZILOG_CHANNEL_FROM_PORT(port); 615 channel = ZILOG_CHANNEL_FROM_PORT(port);
619 status = sbus_readb(&channel->control); 616 status = sbus_readb(&channel->control);
620 ZSDELAY(); 617 ZSDELAY();
621 618
622 spin_unlock_irqrestore(&port->lock, flags);
623
624 return status; 619 return status;
625} 620}
626 621
627/* The port lock is not held. */ 622/* The port lock is not held. */
628static unsigned int sunzilog_tx_empty(struct uart_port *port) 623static unsigned int sunzilog_tx_empty(struct uart_port *port)
629{ 624{
625 unsigned long flags;
630 unsigned char status; 626 unsigned char status;
631 unsigned int ret; 627 unsigned int ret;
632 628
629 spin_lock_irqsave(&port->lock, flags);
630
633 status = sunzilog_read_channel_status(port); 631 status = sunzilog_read_channel_status(port);
632
633 spin_unlock_irqrestore(&port->lock, flags);
634
634 if (status & Tx_BUF_EMP) 635 if (status & Tx_BUF_EMP)
635 ret = TIOCSER_TEMT; 636 ret = TIOCSER_TEMT;
636 else 637 else
@@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port)
639 return ret; 640 return ret;
640} 641}
641 642
642/* The port lock is not held. */ 643/* The port lock is held and interrupts are disabled. */
643static unsigned int sunzilog_get_mctrl(struct uart_port *port) 644static unsigned int sunzilog_get_mctrl(struct uart_port *port)
644{ 645{
645 unsigned char status; 646 unsigned char status;