diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-06-08 18:19:37 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-06-08 18:19:37 +0900 |
commit | debf9507166eede1e676d27d3298cdfb27399cb4 (patch) | |
tree | 3c41311a485be79ab16d707c8c7f997990e95cd8 /drivers/tty/serial/sh-sci.c | |
parent | b03034016184b7e9fd19f2a24ffb131953fdcc41 (diff) | |
download | blackbird-op-linux-debf9507166eede1e676d27d3298cdfb27399cb4.tar.gz blackbird-op-linux-debf9507166eede1e676d27d3298cdfb27399cb4.zip |
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) int copied = 0; unsigned short status = sci_in(port, SCxSR); struct tty_struct *tty = port->state->port.tty; + struct sci_port *s = to_sci_port(port); - if (status & SCxSR_ORER(port)) { - /* overrun error */ - if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) - copied++; + /* + * Handle overruns, if supported. + */ + if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) { + if (status & (1 << s->cfg->overrun_bit)) { + /* overrun error */ + if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) + copied++; - dev_notice(port->dev, "overrun error"); + dev_notice(port->dev, "overrun error"); + } } if (status & SCxSR_FER(port)) { @@ -617,12 +623,19 @@ static int sci_handle_errors(struct uart_port *port) static int sci_handle_fifo_overrun(struct uart_port *port) { struct tty_struct *tty = port->state->port.tty; + struct sci_port *s = to_sci_port(port); int copied = 0; + /* + * XXX: Technically not limited to non-SCIFs, it's simply the + * SCLSR check that is for the moment SCIF-specific. This + * probably wants to be revisited for SCIFA/B as well as for + * factoring in SCI overrun detection. + */ if (port->type != PORT_SCIF) return 0; - if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { + if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { sci_out(port, SCLSR, 0); tty_insert_flip_char(tty, 0, TTY_OVERRUN); @@ -1755,6 +1768,32 @@ static int __devinit sci_init_single(struct platform_device *dev, sci_port->break_timer.function = sci_break_timer; init_timer(&sci_port->break_timer); + /* + * Establish some sensible defaults for the error detection. + */ + if (!p->error_mask) + p->error_mask = (p->type == PORT_SCI) ? + SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; + + /* + * Establish sensible defaults for the overrun detection, unless + * the part has explicitly disabled support for it. + */ + if (p->overrun_bit != SCIx_NOT_SUPPORTED) { + if (p->type == PORT_SCI) + p->overrun_bit = 5; + else if (p->scbrr_algo_id == SCBRR_ALGO_4) + p->overrun_bit = 9; + else + p->overrun_bit = 0; + + /* + * Make the error mask inclusive of overrun detection, if + * supported. + */ + p->error_mask |= (1 << p->overrun_bit); + } + sci_port->cfg = p; port->mapbase = p->mapbase; |