Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit debf9507 authored by Paul Mundt's avatar Paul Mundt
Browse files

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: default avatarPaul Mundt <lethal@linux-sh.org>
parent b0303401
Loading
Loading
Loading
Loading
+45 −6
Original line number Original line Diff line number Diff line
@@ -563,14 +563,20 @@ 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)) {
	/*
	 * Handle overruns, if supported.
	 */
	if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) {
		if (status & (1 << s->cfg->overrun_bit)) {
			/* overrun error */
			/* overrun error */
			if (tty_insert_flip_char(tty, 0, TTY_OVERRUN))
			if (tty_insert_flip_char(tty, 0, TTY_OVERRUN))
				copied++;
				copied++;


			dev_notice(port->dev, "overrun error");
			dev_notice(port->dev, "overrun error");
		}
		}
	}


	if (status & SCxSR_FER(port)) {
	if (status & SCxSR_FER(port)) {
		if (sci_rxd_in(port) == 0) {
		if (sci_rxd_in(port) == 0) {
@@ -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;
+2 −50
Original line number Original line Diff line number Diff line
@@ -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) || \
+30 −0
Original line number Original line Diff line number Diff line
@@ -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;