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>
This commit is contained in:
Paul Mundt 2011-06-08 18:19:37 +09:00
parent b030340161
commit debf950716
3 changed files with 77 additions and 56 deletions

View File

@ -563,13 +563,19 @@ static int sci_handle_errors(struct uart_port *port)
int copied = 0; int copied = 0;
unsigned short status = sci_in(port, SCxSR); unsigned short status = sci_in(port, SCxSR);
struct tty_struct *tty = port->state->port.tty; struct tty_struct *tty = port->state->port.tty;
struct sci_port *s = to_sci_port(port);
if (status & SCxSR_ORER(port)) { /*
/* overrun error */ * Handle overruns, if supported.
if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) */
copied++; 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)) { 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) static int sci_handle_fifo_overrun(struct uart_port *port)
{ {
struct tty_struct *tty = port->state->port.tty; struct tty_struct *tty = port->state->port.tty;
struct sci_port *s = to_sci_port(port);
int copied = 0; 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) if (port->type != PORT_SCIF)
return 0; 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); sci_out(port, SCLSR, 0);
tty_insert_flip_char(tty, 0, TTY_OVERRUN); 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; sci_port->break_timer.function = sci_break_timer;
init_timer(&sci_port->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; sci_port->cfg = p;
port->mapbase = p->mapbase; port->mapbase = p->mapbase;

View File

@ -19,11 +19,9 @@
defined(CONFIG_ARCH_SH7372) defined(CONFIG_ARCH_SH7372)
# define PORT_PTCR 0xA405011EUL # define PORT_PTCR 0xA405011EUL
# define PORT_PVCR 0xA4050122UL # define PORT_PVCR 0xA4050122UL
# define SCIF_ORER 0x0200 /* overrun error bit */
#elif defined(CONFIG_SH_RTS7751R2D) #elif defined(CONFIG_SH_RTS7751R2D)
# define SCSPTR1 0xFFE0001C /* 8 bit SCIF */ # define SCSPTR1 0xFFE0001C /* 8 bit SCIF */
# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
@ -32,15 +30,12 @@
defined(CONFIG_CPU_SUBTYPE_SH7751R) defined(CONFIG_CPU_SUBTYPE_SH7751R)
# define SCSPTR1 0xffe0001c /* 8 bit SCI */ # define SCSPTR1 0xffe0001c /* 8 bit SCI */
# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7760) #elif defined(CONFIG_CPU_SUBTYPE_SH7760)
# define SCSPTR0 0xfe600024 /* 16 bit SCIF */ # define SCSPTR0 0xfe600024 /* 16 bit SCIF */
# define SCSPTR1 0xfe610024 /* 16 bit SCIF */ # define SCSPTR1 0xfe610024 /* 16 bit SCIF */
# define SCSPTR2 0xfe620024 /* 16 bit SCIF */ # define SCSPTR2 0xfe620024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
# define SCSPTR0 0xA4400000 /* 16 bit SCIF */ # define SCSPTR0 0xA4400000 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
# define PACR 0xa4050100 # define PACR 0xa4050100
# define PBCR 0xa4050102 # define PBCR 0xa4050102
#elif defined(CONFIG_CPU_SUBTYPE_SH7343) #elif defined(CONFIG_CPU_SUBTYPE_SH7343)
@ -48,35 +43,24 @@
#elif defined(CONFIG_CPU_SUBTYPE_SH7722) #elif defined(CONFIG_CPU_SUBTYPE_SH7722)
# define PWDR 0xA4050166 # define PWDR 0xA4050166
# define PSCR 0xA405011E # define PSCR 0xA405011E
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7366) #elif defined(CONFIG_CPU_SUBTYPE_SH7366)
# define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ # define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */
# define SCSPTR0 SCPDR0 # define SCSPTR0 SCPDR0
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) #elif defined(CONFIG_CPU_SUBTYPE_SH7723)
# define SCSPTR0 0xa4050160 # define SCSPTR0 0xa4050160
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH4_202) #elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
# define SCSPTR2 0xffe80020 /* 16 bit SCIF */ # define SCSPTR2 0xffe80020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7757) #elif defined(CONFIG_CPU_SUBTYPE_SH7757)
# define SCSPTR0 0xfe4b0020 # define SCSPTR0 0xfe4b0020
# define SCIF_ORER 0x0001
#elif defined(CONFIG_CPU_SUBTYPE_SH7763) #elif defined(CONFIG_CPU_SUBTYPE_SH7763)
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */ # define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7770) #elif defined(CONFIG_CPU_SUBTYPE_SH7770)
# define SCSPTR0 0xff923020 /* 16 bit SCIF */ # define SCSPTR0 0xff923020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7780) #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */ # define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SH7786) defined(CONFIG_CPU_SUBTYPE_SH7786)
# define SCSPTR0 0xffea0024 /* 16 bit SCIF */ # define SCSPTR0 0xffea0024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
defined(CONFIG_CPU_SUBTYPE_SH7203) || \ defined(CONFIG_CPU_SUBTYPE_SH7203) || \
defined(CONFIG_CPU_SUBTYPE_SH7206) || \ defined(CONFIG_CPU_SUBTYPE_SH7206) || \
@ -84,36 +68,12 @@
# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
#elif defined(CONFIG_CPU_SUBTYPE_SH7619) #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
# define SCSPTR0 0xf8400020 /* 16 bit SCIF */ # define SCSPTR0 0xf8400020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* overrun error bit */
#elif defined(CONFIG_CPU_SUBTYPE_SHX3) #elif defined(CONFIG_CPU_SUBTYPE_SHX3)
# define SCSPTR0 0xffc30020 /* 16 bit SCIF */ # define SCSPTR0 0xffc30020 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
#else #else
# error CPU subtype not defined # error CPU subtype not defined
#endif #endif
/* SCxSR SCI */
#define SCI_TDRE 0x80 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
#define SCI_RDRF 0x40 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
#define SCI_ORER 0x20 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
#define SCI_FER 0x10 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
#define SCI_PER 0x08 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
#define SCI_TEND 0x04 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
/* SCI_MPB 0x02 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
/* SCI_MPBT 0x01 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
#define SCI_ERRORS ( SCI_PER | SCI_FER | SCI_ORER)
/* SCxSR SCIF */
#define SCIF_ER 0x0080 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_TEND 0x0040 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_TDFE 0x0020 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_BRK 0x0010 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_FER 0x0008 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_PER 0x0004 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_RDF 0x0002 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#define SCIF_DR 0x0001 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) || \
@ -121,35 +81,27 @@
defined(CONFIG_ARCH_SH7367) || \ defined(CONFIG_ARCH_SH7367) || \
defined(CONFIG_ARCH_SH7377) || \ defined(CONFIG_ARCH_SH7377) || \
defined(CONFIG_ARCH_SH7372) defined(CONFIG_ARCH_SH7372)
# define SCIF_ORER 0x0200
# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
# define SCIF_RFDC_MASK 0x007f # define SCIF_RFDC_MASK 0x007f
# define SCIF_TXROOM_MAX 64 # define SCIF_TXROOM_MAX 64
#elif defined(CONFIG_CPU_SUBTYPE_SH7763) #elif defined(CONFIG_CPU_SUBTYPE_SH7763)
# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK )
# define SCIF_RFDC_MASK 0x007f # define SCIF_RFDC_MASK 0x007f
# define SCIF_TXROOM_MAX 64 # define SCIF_TXROOM_MAX 64
/* SH7763 SCIF2 support */ /* SH7763 SCIF2 support */
# define SCIF2_RFDC_MASK 0x001f # define SCIF2_RFDC_MASK 0x001f
# define SCIF2_TXROOM_MAX 16 # define SCIF2_TXROOM_MAX 16
#else #else
# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
# define SCIF_RFDC_MASK 0x001f # define SCIF_RFDC_MASK 0x001f
# define SCIF_TXROOM_MAX 16 # define SCIF_TXROOM_MAX 16
#endif #endif
#ifndef SCIF_ORER
#define SCIF_ORER 0x0000
#endif
#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
#define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
#define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) #define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)
#define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) #define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER)
#define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
#define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
#define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER)
#define SCxSR_ERRORS(port) (to_sci_port(port)->cfg->error_mask)
#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \

View File

@ -8,6 +8,8 @@
* Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
*/ */
#define SCIx_NOT_SUPPORTED (-1)
enum { enum {
SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */
SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */
@ -25,6 +27,28 @@ enum {
#define SCSCR_CKE1 (1 << 1) #define SCSCR_CKE1 (1 << 1)
#define SCSCR_CKE0 (1 << 0) #define SCSCR_CKE0 (1 << 0)
/* SCxSR SCI */
#define SCI_TDRE 0x80
#define SCI_RDRF 0x40
#define SCI_ORER 0x20
#define SCI_FER 0x10
#define SCI_PER 0x08
#define SCI_TEND 0x04
#define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER)
/* SCxSR SCIF */
#define SCIF_ER 0x0080
#define SCIF_TEND 0x0040
#define SCIF_TDFE 0x0020
#define SCIF_BRK 0x0010
#define SCIF_FER 0x0008
#define SCIF_PER 0x0004
#define SCIF_RDF 0x0002
#define SCIF_DR 0x0001
#define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
/* Offsets into the sci_port->irqs array */ /* Offsets into the sci_port->irqs array */
enum { enum {
SCIx_ERI_IRQ, SCIx_ERI_IRQ,
@ -56,6 +80,12 @@ struct plat_sci_port {
unsigned int scbrr_algo_id; /* SCBRR calculation algo */ unsigned int scbrr_algo_id; /* SCBRR calculation algo */
unsigned int scscr; /* SCSCR initialization */ unsigned int scscr; /* SCSCR initialization */
/*
* Platform overrides if necessary, defaults otherwise.
*/
int overrun_bit;
unsigned int error_mask;
struct device *dma_dev; struct device *dma_dev;
unsigned int dma_slave_tx; unsigned int dma_slave_tx;