diff options
-rw-r--r-- | Documentation/serial/driver | 4 | ||||
-rw-r--r-- | drivers/serial/8250.c | 3 | ||||
-rw-r--r-- | drivers/serial/au1x00_uart.c | 3 | ||||
-rw-r--r-- | drivers/serial/ip22zilog.c | 13 | ||||
-rw-r--r-- | drivers/serial/mpsc.c | 3 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.c | 4 | ||||
-rw-r--r-- | drivers/serial/pxa.c | 3 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 11 | ||||
-rw-r--r-- | drivers/serial/serial_txx9.c | 3 | ||||
-rw-r--r-- | drivers/serial/sunsab.c | 7 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 3 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 13 |
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. | |||
107 | indicate that the signal is permanently active. If RI is | 107 | indicate that the signal is permanently active. If RI is |
108 | not available, the signal should not be indicated as active. | 108 | not available, the signal should not be indicated as active. |
109 | 109 | ||
110 | Locking: none. | 110 | Locking: port->lock taken. |
111 | Interrupts: caller dependent. | 111 | Interrupts: locally disabled. |
112 | This call must not sleep | 112 | This call must not sleep |
113 | 113 | ||
114 | stop_tx(port,tty_stop) | 114 | 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) | |||
1376 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1376 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
1377 | { | 1377 | { |
1378 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1378 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
1379 | unsigned long flags; | ||
1380 | unsigned char status; | 1379 | unsigned char status; |
1381 | unsigned int ret; | 1380 | unsigned int ret; |
1382 | 1381 | ||
1383 | spin_lock_irqsave(&up->port.lock, flags); | ||
1384 | status = serial_in(up, UART_MSR); | 1382 | status = serial_in(up, UART_MSR); |
1385 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1386 | 1383 | ||
1387 | ret = 0; | 1384 | ret = 0; |
1388 | if (status & UART_MSR_DCD) | 1385 | 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) | |||
556 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 556 | static 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/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 | |||
518 | static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port) | 518 | static __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. */ |
536 | static unsigned int ip22zilog_tx_empty(struct uart_port *port) | 531 | static 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. */ |
551 | static unsigned int ip22zilog_get_mctrl(struct uart_port *port) | 552 | static 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..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) | |||
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 | */ |
609 | static unsigned int pmz_get_mctrl(struct uart_port *port) | 609 | static 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) |
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) | |||
274 | static unsigned int serial_pxa_get_mctrl(struct uart_port *port) | 274 | static 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 | ||
281 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | 280 | return 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/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) | |||
828 | if ((!file || !tty_hung_up_p(file)) && | 828 | if ((!file || !tty_hung_up_p(file)) && |
829 | !(tty->flags & (1 << TTY_IO_ERROR))) { | 829 | !(tty->flags & (1 << TTY_IO_ERROR))) { |
830 | result = port->mctrl; | 830 | result = port->mctrl; |
831 | |||
832 | spin_lock_irq(&port->lock); | ||
831 | result |= port->ops->get_mctrl(port); | 833 | result |= port->ops->get_mctrl(port); |
834 | spin_unlock_irq(&port->lock); | ||
832 | } | 835 | } |
833 | up(&state->sem); | 836 | up(&state->sem); |
834 | 837 | ||
@@ -1369,6 +1372,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) | |||
1369 | DECLARE_WAITQUEUE(wait, current); | 1372 | DECLARE_WAITQUEUE(wait, current); |
1370 | struct uart_info *info = state->info; | 1373 | struct uart_info *info = state->info; |
1371 | struct uart_port *port = state->port; | 1374 | struct uart_port *port = state->port; |
1375 | unsigned int mctrl; | ||
1372 | 1376 | ||
1373 | info->blocked_open++; | 1377 | info->blocked_open++; |
1374 | state->count--; | 1378 | state->count--; |
@@ -1416,7 +1420,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) | |||
1416 | * and wait for the carrier to indicate that the | 1420 | * and wait for the carrier to indicate that the |
1417 | * modem is ready for us. | 1421 | * modem is ready for us. |
1418 | */ | 1422 | */ |
1419 | if (port->ops->get_mctrl(port) & TIOCM_CAR) | 1423 | spin_lock_irq(&port->lock); |
1424 | mctrl = port->ops->get_mctrl(port); | ||
1425 | spin_unlock_irq(&port->lock); | ||
1426 | if (mctrl & TIOCM_CAR) | ||
1420 | break; | 1427 | break; |
1421 | 1428 | ||
1422 | up(&state->sem); | 1429 | up(&state->sem); |
@@ -1618,7 +1625,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i) | |||
1618 | 1625 | ||
1619 | if(capable(CAP_SYS_ADMIN)) | 1626 | if(capable(CAP_SYS_ADMIN)) |
1620 | { | 1627 | { |
1628 | spin_lock_irq(&port->lock); | ||
1621 | status = port->ops->get_mctrl(port); | 1629 | status = port->ops->get_mctrl(port); |
1630 | spin_unlock_irq(&port->lock); | ||
1622 | 1631 | ||
1623 | ret += sprintf(buf + ret, " tx:%d rx:%d", | 1632 | ret += sprintf(buf + ret, " tx:%d rx:%d", |
1624 | port->icount.tx, port->icount.rx); | 1633 | 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) | |||
442 | static unsigned int serial_txx9_get_mctrl(struct uart_port *port) | 442 | static 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. */ |
430 | static unsigned int sunsab_get_mctrl(struct uart_port *port) | 430 | static 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) | |||
572 | static unsigned int sunsu_get_mctrl(struct uart_port *port) | 572 | static 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 | |||
610 | static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port) | 610 | static __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. */ |
628 | static unsigned int sunzilog_tx_empty(struct uart_port *port) | 623 | static 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. */ |
643 | static unsigned int sunzilog_get_mctrl(struct uart_port *port) | 644 | static unsigned int sunzilog_get_mctrl(struct uart_port *port) |
644 | { | 645 | { |
645 | unsigned char status; | 646 | unsigned char status; |