aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/sh-sci.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-06-08 05:19:37 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-06-08 05:19:37 -0400
commitdebf9507166eede1e676d27d3298cdfb27399cb4 (patch)
tree3c41311a485be79ab16d707c8c7f997990e95cd8 /drivers/tty/serial/sh-sci.c
parentb03034016184b7e9fd19f2a24ffb131953fdcc41 (diff)
serial: sh-sci: Generalize overrun handling.
This consolidates all of the broken out overrun handling and ensures that we have sensible defaults per-port type, in addition to making sure that overruns are flagged appropriately in the error mask for parts that haven't explicitly disabled support for it. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/tty/serial/sh-sci.c')
-rw-r--r--drivers/tty/serial/sh-sci.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 280c02af0eae..bb27885ea2e5 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -563,13 +563,19 @@ static int sci_handle_errors(struct uart_port *port)
563 int copied = 0; 563 int copied = 0;
564 unsigned short status = sci_in(port, SCxSR); 564 unsigned short status = sci_in(port, SCxSR);
565 struct tty_struct *tty = port->state->port.tty; 565 struct tty_struct *tty = port->state->port.tty;
566 struct sci_port *s = to_sci_port(port);
566 567
567 if (status & SCxSR_ORER(port)) { 568 /*
568 /* overrun error */ 569 * Handle overruns, if supported.
569 if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) 570 */
570 copied++; 571 if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) {
572 if (status & (1 << s->cfg->overrun_bit)) {
573 /* overrun error */
574 if (tty_insert_flip_char(tty, 0, TTY_OVERRUN))
575 copied++;
571 576
572 dev_notice(port->dev, "overrun error"); 577 dev_notice(port->dev, "overrun error");
578 }
573 } 579 }
574 580
575 if (status & SCxSR_FER(port)) { 581 if (status & SCxSR_FER(port)) {
@@ -617,12 +623,19 @@ static int sci_handle_errors(struct uart_port *port)
617static int sci_handle_fifo_overrun(struct uart_port *port) 623static int sci_handle_fifo_overrun(struct uart_port *port)
618{ 624{
619 struct tty_struct *tty = port->state->port.tty; 625 struct tty_struct *tty = port->state->port.tty;
626 struct sci_port *s = to_sci_port(port);
620 int copied = 0; 627 int copied = 0;
621 628
629 /*
630 * XXX: Technically not limited to non-SCIFs, it's simply the
631 * SCLSR check that is for the moment SCIF-specific. This
632 * probably wants to be revisited for SCIFA/B as well as for
633 * factoring in SCI overrun detection.
634 */
622 if (port->type != PORT_SCIF) 635 if (port->type != PORT_SCIF)
623 return 0; 636 return 0;
624 637
625 if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { 638 if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
626 sci_out(port, SCLSR, 0); 639 sci_out(port, SCLSR, 0);
627 640
628 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 641 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
@@ -1755,6 +1768,32 @@ static int __devinit sci_init_single(struct platform_device *dev,
1755 sci_port->break_timer.function = sci_break_timer; 1768 sci_port->break_timer.function = sci_break_timer;
1756 init_timer(&sci_port->break_timer); 1769 init_timer(&sci_port->break_timer);
1757 1770
1771 /*
1772 * Establish some sensible defaults for the error detection.
1773 */
1774 if (!p->error_mask)
1775 p->error_mask = (p->type == PORT_SCI) ?
1776 SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK;
1777
1778 /*
1779 * Establish sensible defaults for the overrun detection, unless
1780 * the part has explicitly disabled support for it.
1781 */
1782 if (p->overrun_bit != SCIx_NOT_SUPPORTED) {
1783 if (p->type == PORT_SCI)
1784 p->overrun_bit = 5;
1785 else if (p->scbrr_algo_id == SCBRR_ALGO_4)
1786 p->overrun_bit = 9;
1787 else
1788 p->overrun_bit = 0;
1789
1790 /*
1791 * Make the error mask inclusive of overrun detection, if
1792 * supported.
1793 */
1794 p->error_mask |= (1 << p->overrun_bit);
1795 }
1796
1758 sci_port->cfg = p; 1797 sci_port->cfg = p;
1759 1798
1760 port->mapbase = p->mapbase; 1799 port->mapbase = p->mapbase;