diff options
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r-- | drivers/serial/sh-sci.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 0251077693d1..b0feea493985 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -625,6 +625,27 @@ static inline int sci_handle_errors(struct uart_port *port) | |||
625 | return copied; | 625 | return copied; |
626 | } | 626 | } |
627 | 627 | ||
628 | static inline int sci_handle_fifo_overrun(struct uart_port *port) | ||
629 | { | ||
630 | struct tty_struct *tty = port->info->port.tty; | ||
631 | int copied = 0; | ||
632 | |||
633 | if (port->type != PORT_SCIF) | ||
634 | return 0; | ||
635 | |||
636 | if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { | ||
637 | sci_out(port, SCLSR, 0); | ||
638 | |||
639 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
640 | tty_flip_buffer_push(tty); | ||
641 | |||
642 | dev_notice(port->dev, "overrun error\n"); | ||
643 | copied++; | ||
644 | } | ||
645 | |||
646 | return copied; | ||
647 | } | ||
648 | |||
628 | static inline int sci_handle_breaks(struct uart_port *port) | 649 | static inline int sci_handle_breaks(struct uart_port *port) |
629 | { | 650 | { |
630 | int copied = 0; | 651 | int copied = 0; |
@@ -647,20 +668,11 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
647 | dev_dbg(port->dev, "BREAK detected\n"); | 668 | dev_dbg(port->dev, "BREAK detected\n"); |
648 | } | 669 | } |
649 | 670 | ||
650 | #if defined(SCIF_ORER) | ||
651 | /* XXX: Handle SCIF overrun error */ | ||
652 | if (port->type != PORT_SCI && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { | ||
653 | sci_out(port, SCLSR, 0); | ||
654 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { | ||
655 | copied++; | ||
656 | dev_notice(port->dev, "overrun error\n"); | ||
657 | } | ||
658 | } | ||
659 | #endif | ||
660 | |||
661 | if (copied) | 671 | if (copied) |
662 | tty_flip_buffer_push(tty); | 672 | tty_flip_buffer_push(tty); |
663 | 673 | ||
674 | copied += sci_handle_fifo_overrun(port); | ||
675 | |||
664 | return copied; | 676 | return copied; |
665 | } | 677 | } |
666 | 678 | ||
@@ -698,16 +710,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) | |||
698 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); | 710 | sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); |
699 | } | 711 | } |
700 | } else { | 712 | } else { |
701 | #if defined(SCIF_ORER) | 713 | sci_handle_fifo_overrun(port); |
702 | if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { | ||
703 | struct tty_struct *tty = port->info->port.tty; | ||
704 | |||
705 | sci_out(port, SCLSR, 0); | ||
706 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
707 | tty_flip_buffer_push(tty); | ||
708 | dev_notice(port->dev, "overrun error\n"); | ||
709 | } | ||
710 | #endif | ||
711 | sci_rx_interrupt(irq, ptr); | 714 | sci_rx_interrupt(irq, ptr); |
712 | } | 715 | } |
713 | 716 | ||