From bbb4ce50f3169b08764f9965fd5b9655646d545a Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Fri, 6 Apr 2012 09:59:14 +0900 Subject: serial: sh-sci: modify sci_break_ctl() SCIF modules which have SCSPTR can output the break signal. Now that we have a way of determining port features/capabilities, add trivial break control via SCSPTR support. Tested on sh7757lcr. Signed-off-by: Yoshihiro Shimoda Reviewed-by: Simon Horman Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 3158e17..3e471fc 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1564,10 +1564,32 @@ static void sci_enable_ms(struct uart_port *port) static void sci_break_ctl(struct uart_port *port, int break_state) { - /* - * Not supported by hardware. Most parts couple break and rx - * interrupts together, with break detection always enabled. - */ + struct sci_port *s = to_sci_port(port); + unsigned short scscr, scsptr; + + switch (s->cfg->regtype) { + case SCIx_SH4_SCIF_REGTYPE: + scsptr = serial_port_in(port, SCSPTR); + scscr = serial_port_in(port, SCSCR); + + if (break_state == -1) { + scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT; + scscr &= ~SCSCR_TE; + } else { + scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO; + scscr |= SCSCR_TE; + } + + serial_port_out(port, SCSPTR, scsptr); + serial_port_out(port, SCSCR, scscr); + break; + default: + /* + * Not supported by hardware. Most parts couple break and rx + * interrupts together, with break detection always enabled. + */ + break; + } } #ifdef CONFIG_SERIAL_SH_SCI_DMA -- cgit v1.1 From a4e02f6d83d4fcdb13bcaba76878fc5ea0da9911 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Thu, 12 Apr 2012 19:19:21 +0900 Subject: serial: sh-sci: Update break_ctl handling for all SCSPTR-capable regtypes. This updates the earlier break_ctl support regardless of regtype so long as the requisite SCSPTR exists. This is the same approach used by sci_init_pins() for providing a generic solution now that we're able to detect register capabilities on a per-port basis. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 3e471fc..be31d85 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1565,31 +1565,31 @@ static void sci_enable_ms(struct uart_port *port) static void sci_break_ctl(struct uart_port *port, int break_state) { struct sci_port *s = to_sci_port(port); + struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; unsigned short scscr, scsptr; - switch (s->cfg->regtype) { - case SCIx_SH4_SCIF_REGTYPE: - scsptr = serial_port_in(port, SCSPTR); - scscr = serial_port_in(port, SCSCR); - - if (break_state == -1) { - scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT; - scscr &= ~SCSCR_TE; - } else { - scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO; - scscr |= SCSCR_TE; - } - - serial_port_out(port, SCSPTR, scsptr); - serial_port_out(port, SCSCR, scscr); - break; - default: + /* check wheter the port has SCSPTR */ + if (!reg->size) { /* * Not supported by hardware. Most parts couple break and rx * interrupts together, with break detection always enabled. */ - break; + return; } + + scsptr = serial_port_in(port, SCSPTR); + scscr = serial_port_in(port, SCSCR); + + if (break_state == -1) { + scsptr = (scsptr | SCSPTR_SPB2IO) & ~SCSPTR_SPB2DT; + scscr &= ~SCSCR_TE; + } else { + scsptr = (scsptr | SCSPTR_SPB2DT) & ~SCSPTR_SPB2IO; + scscr |= SCSCR_TE; + } + + serial_port_out(port, SCSPTR, scsptr); + serial_port_out(port, SCSCR, scscr); } #ifdef CONFIG_SERIAL_SH_SCI_DMA -- cgit v1.1 From 0e8963de1fe95e7fbc30c79c1dbc7cb1ea0cf699 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 18 May 2012 18:21:06 +0900 Subject: serial: sh-sci: Fix for port types without BRI interrupts. In doing the evt2irq() + muxed vector conversion for various port types it became apparent that some of the legacy port types will presently error out due to the irq requesting logic attempting to acquire the non-existent BRI IRQ. This adds some sanity checks to the request/free path to ensure that non-existence of a source in itself is not an error. This should restore functionality for legacy PORT_SCI ports. Signed-off-by: Paul Mundt --- drivers/tty/serial/sh-sci.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/tty') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index be31d85..4604153 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1052,9 +1052,17 @@ static int sci_request_irq(struct sci_port *port) if (SCIx_IRQ_IS_MUXED(port)) { i = SCIx_MUX_IRQ; irq = up->irq; - } else + } else { irq = port->cfg->irqs[i]; + /* + * Certain port types won't support all of the + * available interrupt sources. + */ + if (unlikely(!irq)) + continue; + } + desc = sci_irq_desc + i; port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", dev_name(up->dev), desc->desc); @@ -1094,6 +1102,15 @@ static void sci_free_irq(struct sci_port *port) * IRQ first. */ for (i = 0; i < SCIx_NR_IRQS; i++) { + unsigned int irq = port->cfg->irqs[i]; + + /* + * Certain port types won't support all of the available + * interrupt sources. + */ + if (unlikely(!irq)) + continue; + free_irq(port->cfg->irqs[i], port); kfree(port->irqstr[i]); -- cgit v1.1