aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorHisashi Nakamura <hisashi.nakamura.ak@renesas.com>2015-01-26 07:25:48 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-02 13:11:26 -0500
commit8b6ff84c2d445a476be5f5493b9deac00271eedd (patch)
tree95c39817f6df7d00e3f1b7fd61a423d69270e567 /drivers/tty/serial
parent51b31f1c6bbb3e741c930a71af8f0bcd4e5d4ded (diff)
serial: sh-sci: Fix R-Car SCIF and HSCIF overrun handling
When fifo overrun happened, the interrupt status refers to SCLSR register in R-Car SCIF and HSCIF. Thus, overrun handling takes SCLSR register into account. Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/sh-sci.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 508bdb527e10..5b50c792ad5f 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -997,12 +997,15 @@ static inline unsigned long port_rx_irq_mask(struct uart_port *port)
997static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) 997static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
998{ 998{
999 unsigned short ssr_status, scr_status, err_enabled; 999 unsigned short ssr_status, scr_status, err_enabled;
1000 unsigned short slr_status = 0;
1000 struct uart_port *port = ptr; 1001 struct uart_port *port = ptr;
1001 struct sci_port *s = to_sci_port(port); 1002 struct sci_port *s = to_sci_port(port);
1002 irqreturn_t ret = IRQ_NONE; 1003 irqreturn_t ret = IRQ_NONE;
1003 1004
1004 ssr_status = serial_port_in(port, SCxSR); 1005 ssr_status = serial_port_in(port, SCxSR);
1005 scr_status = serial_port_in(port, SCSCR); 1006 scr_status = serial_port_in(port, SCSCR);
1007 if (port->type == PORT_SCIF || port->type == PORT_HSCIF)
1008 slr_status = serial_port_in(port, SCLSR);
1006 err_enabled = scr_status & port_rx_irq_mask(port); 1009 err_enabled = scr_status & port_rx_irq_mask(port);
1007 1010
1008 /* Tx Interrupt */ 1011 /* Tx Interrupt */
@@ -1015,8 +1018,11 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
1015 * DR flags 1018 * DR flags
1016 */ 1019 */
1017 if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && 1020 if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) &&
1018 (scr_status & SCSCR_RIE)) 1021 (scr_status & SCSCR_RIE)) {
1022 if (port->type == PORT_SCIF || port->type == PORT_HSCIF)
1023 sci_handle_fifo_overrun(port);
1019 ret = sci_rx_interrupt(irq, ptr); 1024 ret = sci_rx_interrupt(irq, ptr);
1025 }
1020 1026
1021 /* Error Interrupt */ 1027 /* Error Interrupt */
1022 if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) 1028 if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
@@ -1026,6 +1032,12 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
1026 if ((ssr_status & SCxSR_BRK(port)) && err_enabled) 1032 if ((ssr_status & SCxSR_BRK(port)) && err_enabled)
1027 ret = sci_br_interrupt(irq, ptr); 1033 ret = sci_br_interrupt(irq, ptr);
1028 1034
1035 /* Overrun Interrupt */
1036 if (port->type == PORT_SCIF || port->type == PORT_HSCIF) {
1037 if (slr_status & 0x01)
1038 sci_handle_fifo_overrun(port);
1039 }
1040
1029 return ret; 1041 return ret;
1030} 1042}
1031 1043