diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-06-08 05:19:37 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-06-08 05:19:37 -0400 |
commit | debf9507166eede1e676d27d3298cdfb27399cb4 (patch) | |
tree | 3c41311a485be79ab16d707c8c7f997990e95cd8 /drivers/tty/serial/sh-sci.c | |
parent | b03034016184b7e9fd19f2a24ffb131953fdcc41 (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.c | 51 |
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) | |||
617 | static int sci_handle_fifo_overrun(struct uart_port *port) | 623 | static 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; |