aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/tty/serial/sh-sci.c51
-rw-r--r--drivers/tty/serial/sh-sci.h52
-rw-r--r--include/linux/serial_sci.h30
3 files changed, 77 insertions, 56 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;
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index ed1c09c0454a..caab353a98b5 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -19,11 +19,9 @@
19 defined(CONFIG_ARCH_SH7372) 19 defined(CONFIG_ARCH_SH7372)
20# define PORT_PTCR 0xA405011EUL 20# define PORT_PTCR 0xA405011EUL
21# define PORT_PVCR 0xA4050122UL 21# define PORT_PVCR 0xA4050122UL
22# define SCIF_ORER 0x0200 /* overrun error bit */
23#elif defined(CONFIG_SH_RTS7751R2D) 22#elif defined(CONFIG_SH_RTS7751R2D)
24# define SCSPTR1 0xFFE0001C /* 8 bit SCIF */ 23# define SCSPTR1 0xFFE0001C /* 8 bit SCIF */
25# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ 24# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
26# define SCIF_ORER 0x0001 /* overrun error bit */
27#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ 25#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \
28 defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ 26 defined(CONFIG_CPU_SUBTYPE_SH7750R) || \
29 defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ 27 defined(CONFIG_CPU_SUBTYPE_SH7750S) || \
@@ -32,15 +30,12 @@
32 defined(CONFIG_CPU_SUBTYPE_SH7751R) 30 defined(CONFIG_CPU_SUBTYPE_SH7751R)
33# define SCSPTR1 0xffe0001c /* 8 bit SCI */ 31# define SCSPTR1 0xffe0001c /* 8 bit SCI */
34# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ 32# define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
35# define SCIF_ORER 0x0001 /* overrun error bit */
36#elif defined(CONFIG_CPU_SUBTYPE_SH7760) 33#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
37# define SCSPTR0 0xfe600024 /* 16 bit SCIF */ 34# define SCSPTR0 0xfe600024 /* 16 bit SCIF */
38# define SCSPTR1 0xfe610024 /* 16 bit SCIF */ 35# define SCSPTR1 0xfe610024 /* 16 bit SCIF */
39# define SCSPTR2 0xfe620024 /* 16 bit SCIF */ 36# define SCSPTR2 0xfe620024 /* 16 bit SCIF */
40# define SCIF_ORER 0x0001 /* overrun error bit */
41#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) 37#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
42# define SCSPTR0 0xA4400000 /* 16 bit SCIF */ 38# define SCSPTR0 0xA4400000 /* 16 bit SCIF */
43# define SCIF_ORER 0x0001 /* overrun error bit */
44# define PACR 0xa4050100 39# define PACR 0xa4050100
45# define PBCR 0xa4050102 40# define PBCR 0xa4050102
46#elif defined(CONFIG_CPU_SUBTYPE_SH7343) 41#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
@@ -48,35 +43,24 @@
48#elif defined(CONFIG_CPU_SUBTYPE_SH7722) 43#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
49# define PWDR 0xA4050166 44# define PWDR 0xA4050166
50# define PSCR 0xA405011E 45# define PSCR 0xA405011E
51# define SCIF_ORER 0x0001 /* overrun error bit */
52#elif defined(CONFIG_CPU_SUBTYPE_SH7366) 46#elif defined(CONFIG_CPU_SUBTYPE_SH7366)
53# define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ 47# define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */
54# define SCSPTR0 SCPDR0 48# define SCSPTR0 SCPDR0
55# define SCIF_ORER 0x0001 /* overrun error bit */
56#elif defined(CONFIG_CPU_SUBTYPE_SH7723) 49#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
57# define SCSPTR0 0xa4050160 50# define SCSPTR0 0xa4050160
58# define SCIF_ORER 0x0001 /* overrun error bit */
59#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
60# define SCIF_ORER 0x0001 /* overrun error bit */
61#elif defined(CONFIG_CPU_SUBTYPE_SH4_202) 51#elif defined(CONFIG_CPU_SUBTYPE_SH4_202)
62# define SCSPTR2 0xffe80020 /* 16 bit SCIF */ 52# define SCSPTR2 0xffe80020 /* 16 bit SCIF */
63# define SCIF_ORER 0x0001 /* overrun error bit */
64#elif defined(CONFIG_CPU_SUBTYPE_SH7757) 53#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
65# define SCSPTR0 0xfe4b0020 54# define SCSPTR0 0xfe4b0020
66# define SCIF_ORER 0x0001
67#elif defined(CONFIG_CPU_SUBTYPE_SH7763) 55#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
68# define SCSPTR0 0xffe00024 /* 16 bit SCIF */ 56# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
69# define SCIF_ORER 0x0001 /* overrun error bit */
70#elif defined(CONFIG_CPU_SUBTYPE_SH7770) 57#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
71# define SCSPTR0 0xff923020 /* 16 bit SCIF */ 58# define SCSPTR0 0xff923020 /* 16 bit SCIF */
72# define SCIF_ORER 0x0001 /* overrun error bit */
73#elif defined(CONFIG_CPU_SUBTYPE_SH7780) 59#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
74# define SCSPTR0 0xffe00024 /* 16 bit SCIF */ 60# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
75# define SCIF_ORER 0x0001 /* Overrun error bit */
76#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ 61#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
77 defined(CONFIG_CPU_SUBTYPE_SH7786) 62 defined(CONFIG_CPU_SUBTYPE_SH7786)
78# define SCSPTR0 0xffea0024 /* 16 bit SCIF */ 63# define SCSPTR0 0xffea0024 /* 16 bit SCIF */
79# define SCIF_ORER 0x0001 /* Overrun error bit */
80#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ 64#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \
81 defined(CONFIG_CPU_SUBTYPE_SH7203) || \ 65 defined(CONFIG_CPU_SUBTYPE_SH7203) || \
82 defined(CONFIG_CPU_SUBTYPE_SH7206) || \ 66 defined(CONFIG_CPU_SUBTYPE_SH7206) || \
@@ -84,36 +68,12 @@
84# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ 68# define SCSPTR0 0xfffe8020 /* 16 bit SCIF */
85#elif defined(CONFIG_CPU_SUBTYPE_SH7619) 69#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
86# define SCSPTR0 0xf8400020 /* 16 bit SCIF */ 70# define SCSPTR0 0xf8400020 /* 16 bit SCIF */
87# define SCIF_ORER 0x0001 /* overrun error bit */
88#elif defined(CONFIG_CPU_SUBTYPE_SHX3) 71#elif defined(CONFIG_CPU_SUBTYPE_SHX3)
89# define SCSPTR0 0xffc30020 /* 16 bit SCIF */ 72# define SCSPTR0 0xffc30020 /* 16 bit SCIF */
90# define SCIF_ORER 0x0001 /* Overrun error bit */
91#else 73#else
92# error CPU subtype not defined 74# error CPU subtype not defined
93#endif 75#endif
94 76
95/* SCxSR SCI */
96#define SCI_TDRE 0x80 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
97#define SCI_RDRF 0x40 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
98#define SCI_ORER 0x20 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
99#define SCI_FER 0x10 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
100#define SCI_PER 0x08 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
101#define SCI_TEND 0x04 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
102/* SCI_MPB 0x02 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
103/* SCI_MPBT 0x01 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */
104
105#define SCI_ERRORS ( SCI_PER | SCI_FER | SCI_ORER)
106
107/* SCxSR SCIF */
108#define SCIF_ER 0x0080 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
109#define SCIF_TEND 0x0040 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
110#define SCIF_TDFE 0x0020 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
111#define SCIF_BRK 0x0010 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
112#define SCIF_FER 0x0008 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
113#define SCIF_PER 0x0004 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
114#define SCIF_RDF 0x0002 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
115#define SCIF_DR 0x0001 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */
116
117#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 77#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
118 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 78 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
119 defined(CONFIG_CPU_SUBTYPE_SH7721) || \ 79 defined(CONFIG_CPU_SUBTYPE_SH7721) || \
@@ -121,35 +81,27 @@
121 defined(CONFIG_ARCH_SH7367) || \ 81 defined(CONFIG_ARCH_SH7367) || \
122 defined(CONFIG_ARCH_SH7377) || \ 82 defined(CONFIG_ARCH_SH7377) || \
123 defined(CONFIG_ARCH_SH7372) 83 defined(CONFIG_ARCH_SH7372)
124# define SCIF_ORER 0x0200
125# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER)
126# define SCIF_RFDC_MASK 0x007f 84# define SCIF_RFDC_MASK 0x007f
127# define SCIF_TXROOM_MAX 64 85# define SCIF_TXROOM_MAX 64
128#elif defined(CONFIG_CPU_SUBTYPE_SH7763) 86#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
129# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK )
130# define SCIF_RFDC_MASK 0x007f 87# define SCIF_RFDC_MASK 0x007f
131# define SCIF_TXROOM_MAX 64 88# define SCIF_TXROOM_MAX 64
132/* SH7763 SCIF2 support */ 89/* SH7763 SCIF2 support */
133# define SCIF2_RFDC_MASK 0x001f 90# define SCIF2_RFDC_MASK 0x001f
134# define SCIF2_TXROOM_MAX 16 91# define SCIF2_TXROOM_MAX 16
135#else 92#else
136# define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
137# define SCIF_RFDC_MASK 0x001f 93# define SCIF_RFDC_MASK 0x001f
138# define SCIF_TXROOM_MAX 16 94# define SCIF_TXROOM_MAX 16
139#endif 95#endif
140 96
141#ifndef SCIF_ORER
142#define SCIF_ORER 0x0000
143#endif
144
145#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) 97#define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
146#define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
147#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) 98#define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
148#define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) 99#define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)
149#define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) 100#define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER)
150#define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) 101#define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
151#define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) 102#define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
152#define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER) 103
104#define SCxSR_ERRORS(port) (to_sci_port(port)->cfg->error_mask)
153 105
154#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ 106#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
155 defined(CONFIG_CPU_SUBTYPE_SH7720) || \ 107 defined(CONFIG_CPU_SUBTYPE_SH7720) || \
diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h
index a2afc9fbe186..5fac3bccfd87 100644
--- a/include/linux/serial_sci.h
+++ b/include/linux/serial_sci.h
@@ -8,6 +8,8 @@
8 * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) 8 * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts)
9 */ 9 */
10 10
11#define SCIx_NOT_SUPPORTED (-1)
12
11enum { 13enum {
12 SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */ 14 SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */
13 SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */ 15 SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */
@@ -25,6 +27,28 @@ enum {
25#define SCSCR_CKE1 (1 << 1) 27#define SCSCR_CKE1 (1 << 1)
26#define SCSCR_CKE0 (1 << 0) 28#define SCSCR_CKE0 (1 << 0)
27 29
30/* SCxSR SCI */
31#define SCI_TDRE 0x80
32#define SCI_RDRF 0x40
33#define SCI_ORER 0x20
34#define SCI_FER 0x10
35#define SCI_PER 0x08
36#define SCI_TEND 0x04
37
38#define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER)
39
40/* SCxSR SCIF */
41#define SCIF_ER 0x0080
42#define SCIF_TEND 0x0040
43#define SCIF_TDFE 0x0020
44#define SCIF_BRK 0x0010
45#define SCIF_FER 0x0008
46#define SCIF_PER 0x0004
47#define SCIF_RDF 0x0002
48#define SCIF_DR 0x0001
49
50#define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK)
51
28/* Offsets into the sci_port->irqs array */ 52/* Offsets into the sci_port->irqs array */
29enum { 53enum {
30 SCIx_ERI_IRQ, 54 SCIx_ERI_IRQ,
@@ -56,6 +80,12 @@ struct plat_sci_port {
56 unsigned int scbrr_algo_id; /* SCBRR calculation algo */ 80 unsigned int scbrr_algo_id; /* SCBRR calculation algo */
57 unsigned int scscr; /* SCSCR initialization */ 81 unsigned int scscr; /* SCSCR initialization */
58 82
83 /*
84 * Platform overrides if necessary, defaults otherwise.
85 */
86 int overrun_bit;
87 unsigned int error_mask;
88
59 struct device *dma_dev; 89 struct device *dma_dev;
60 90
61 unsigned int dma_slave_tx; 91 unsigned int dma_slave_tx;