All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/33] serial: sh-sci: Miscellaneous and DMA Improvements
@ 2015-08-21 18:02 ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

	Hi,

This patch series contains several miscellaneous and DMA improvements
for the Renesas "SCI" serial driver. The goal is to prepare for enabling
DMA on DT-based R-Car Gen2 SoCs.

This series contains preparatory patches that have been sent before
(change logs in the individual patches), or are fairly simple, and thus
considered safe for applying.

The "RFC" patches actually enabling DMA will be sent in a separate
series ("[PATCH/RFC v3 0/4] serial: sh-sci: Add DT DMA support").

Note that SCI DMA support was originally written for SH-based systems,
and was never fully wired up in platform code in mainline, so the risk
for regressions is fairly small.

Thanks!

References:
  - [PATCH/RFC v2 00/29] serial: sh-sci: Miscellaneous and DMA
    Improvements (http://www.spinics.net/lists/linux-sh/msg43567.html)
  - [PATCH/RFC 0/8] serial: sh-sci: Add DT DMA support
    (http://www.spinics.net/lists/linux-sh/msg42258.html)
  - [PATCH/RFC 00/13] serial: sh-sci: Cleanups and bug fixes
    (http://www.spinics.net/lists/linux-serial/msg17122.html)

Geert Uytterhoeven (29):
  serial: sh-sci: Replace buggy big #ifdef by runtime logic
  serial: sh-sci: Prevent compiler warnings on 64-bit
  serial: sh-sci: Correct SCIF_ERROR_CLEAR for plain SCIF
  serial: sh-sci: Use SCIF_DR instead of hardcoded literal 1
  serial: sh-sci: Use SCSMR_CKS instead of hardcoded literal 3
  serial: sh-sci: Drop path in reference to serial_core.c
  serial: sh-sci: Improve readability of sampling rate configuration
  serial: sh-sci: Make sci_irq_desc[] const
  serial: sh-sci: Make sci_regmap[] const
  serial: sh-sci: Remove useless memory allocation failure printks
  serial: sh-sci: Remove bogus sci_handle_fifo_overrun() call on (H)SCIF
  serial: sh-sci: Improve DMA error messages
  serial: sh-sci: Improve comments for DMA timeout calculation
  serial: sh-sci: Handle DMA init failures inside sci_request_dma()
  serial: sh-sci: Use correct device for DMA mapping with IOMMU
  serial: sh-sci: Use min_t()/max_t() instead of casts
  serial: sh-sci: Switch to dma_map_single() for DMA transmission
  serial: sh-sci: Fix TX buffer mapping leak
  serial: sh-sci: Use DMA submission helpers instead of open-coding
  serial: sh-sci: Switch to generic DMA residue handling
  serial: sh-sci: Stop acknowledging DMA transmit completions
  serial: sh-sci: Simplify sci_submit_rx() error handling
  serial: sh-sci: Do not resubmit DMA descriptors
  serial: sh-sci: Fix race condition between RX worker and cleanup
  serial: sh-sci: Pass scatterlist to sci_dma_rx_push()
  serial: sh-sci: Use tty_insert_flip_string() for DMA receive
  serial: sh-sci: Use incrementing pointers instead of stack array
  serial: sh-sci: Don't call sci_rx_interrupt() on error when using DMA
  serial: sh-sci: Don't call sci_dma_rx_push() if no data has arrived

Kazuya Mizuguchi (1):
  serial: sh-sci: Fix exclusion of work_fn_rx and sci_dma_rx_complete

Yoshihiro Shimoda (3):
  serial: sh-sci: Return IRQ_HANDLED when overrun if detected
  serial: sh-sci: Fix NULL pointer dereference if HIGHMEM is enabled
  serial: sh-sci: Don't kick tx in sci_er_interrupt() when using DMA

 drivers/tty/serial/Kconfig  |   2 +-
 drivers/tty/serial/sh-sci.c | 416 ++++++++++++++++++++++++--------------------
 drivers/tty/serial/sh-sci.h |  49 ++----
 3 files changed, 241 insertions(+), 226 deletions(-)

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [PATCH v3 00/33] serial: sh-sci: Miscellaneous and DMA Improvements
@ 2015-08-21 18:02 ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

	Hi,

This patch series contains several miscellaneous and DMA improvements
for the Renesas "SCI" serial driver. The goal is to prepare for enabling
DMA on DT-based R-Car Gen2 SoCs.

This series contains preparatory patches that have been sent before
(change logs in the individual patches), or are fairly simple, and thus
considered safe for applying.

The "RFC" patches actually enabling DMA will be sent in a separate
series ("[PATCH/RFC v3 0/4] serial: sh-sci: Add DT DMA support").

Note that SCI DMA support was originally written for SH-based systems,
and was never fully wired up in platform code in mainline, so the risk
for regressions is fairly small.

Thanks!

References:
  - [PATCH/RFC v2 00/29] serial: sh-sci: Miscellaneous and DMA
    Improvements (http://www.spinics.net/lists/linux-sh/msg43567.html)
  - [PATCH/RFC 0/8] serial: sh-sci: Add DT DMA support
    (http://www.spinics.net/lists/linux-sh/msg42258.html)
  - [PATCH/RFC 00/13] serial: sh-sci: Cleanups and bug fixes
    (http://www.spinics.net/lists/linux-serial/msg17122.html)

Geert Uytterhoeven (29):
  serial: sh-sci: Replace buggy big #ifdef by runtime logic
  serial: sh-sci: Prevent compiler warnings on 64-bit
  serial: sh-sci: Correct SCIF_ERROR_CLEAR for plain SCIF
  serial: sh-sci: Use SCIF_DR instead of hardcoded literal 1
  serial: sh-sci: Use SCSMR_CKS instead of hardcoded literal 3
  serial: sh-sci: Drop path in reference to serial_core.c
  serial: sh-sci: Improve readability of sampling rate configuration
  serial: sh-sci: Make sci_irq_desc[] const
  serial: sh-sci: Make sci_regmap[] const
  serial: sh-sci: Remove useless memory allocation failure printks
  serial: sh-sci: Remove bogus sci_handle_fifo_overrun() call on (H)SCIF
  serial: sh-sci: Improve DMA error messages
  serial: sh-sci: Improve comments for DMA timeout calculation
  serial: sh-sci: Handle DMA init failures inside sci_request_dma()
  serial: sh-sci: Use correct device for DMA mapping with IOMMU
  serial: sh-sci: Use min_t()/max_t() instead of casts
  serial: sh-sci: Switch to dma_map_single() for DMA transmission
  serial: sh-sci: Fix TX buffer mapping leak
  serial: sh-sci: Use DMA submission helpers instead of open-coding
  serial: sh-sci: Switch to generic DMA residue handling
  serial: sh-sci: Stop acknowledging DMA transmit completions
  serial: sh-sci: Simplify sci_submit_rx() error handling
  serial: sh-sci: Do not resubmit DMA descriptors
  serial: sh-sci: Fix race condition between RX worker and cleanup
  serial: sh-sci: Pass scatterlist to sci_dma_rx_push()
  serial: sh-sci: Use tty_insert_flip_string() for DMA receive
  serial: sh-sci: Use incrementing pointers instead of stack array
  serial: sh-sci: Don't call sci_rx_interrupt() on error when using DMA
  serial: sh-sci: Don't call sci_dma_rx_push() if no data has arrived

Kazuya Mizuguchi (1):
  serial: sh-sci: Fix exclusion of work_fn_rx and sci_dma_rx_complete

Yoshihiro Shimoda (3):
  serial: sh-sci: Return IRQ_HANDLED when overrun if detected
  serial: sh-sci: Fix NULL pointer dereference if HIGHMEM is enabled
  serial: sh-sci: Don't kick tx in sci_er_interrupt() when using DMA

 drivers/tty/serial/Kconfig  |   2 +-
 drivers/tty/serial/sh-sci.c | 416 ++++++++++++++++++++++++--------------------
 drivers/tty/serial/sh-sci.h |  49 ++----
 3 files changed, 241 insertions(+), 226 deletions(-)

-- 
1.9.1

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [PATCH v3 01/33] serial: sh-sci: Replace buggy big #ifdef by runtime logic
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

The #ifdef logic to clear SCxSR bits using RMW on SCIFA/SCIFB and SCIF
variants with some SCIFA features (sh7705/SH7720/sh7721) has several
drawbacks:
  - It wasn't updated for newer R-Mobile variants (APE6),
  - It doesn't correctly handle SoCs with both SCIF and SCIFA/B (e.g.
    R-Car Gen2, but also legacy sh7723/sh7724),
  - It doesn't play well with ARM multi-platform kernels: on R-Car Gen2,
    SCIF/SCIFA/SCIFB/HSCIF were handled differently, depending on
    whether r8a7740 or sh73a0 support was enabled or not,

Replace the #ifdef logic by runtime logic to fix this.

SCIFA/SCIFB and SCIF on sh7705/sh7720/sh7721 use RMW to clear error
bits, other variants use plain stores, as before.

Note that this changes behavior for SCIFA on sh7723/sh7724 (these SoCs
have both SCIF and SCIFA), which didn't use RMW before.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Question: Can we simplify the logic and use RMW everywhere?
We seem to have been using it fine with (H)SCIF on R-Car Gen2 running
multi-platform kernels.

v3:
  - No changes,

v2:
  - No changes.
---
 drivers/tty/serial/sh-sci.c | 36 ++++++++++++++++++++++++++----------
 drivers/tty/serial/sh-sci.h | 33 ++++++++-------------------------
 2 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1b2f894bdc9e0e6e..b014fce1509d6535 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -489,6 +489,22 @@ static void sci_port_disable(struct sci_port *sci_port)
 	pm_runtime_put_sync(sci_port->port.dev);
 }
 
+static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask)
+{
+	if (port->type = PORT_SCI) {
+		/* Just store the mask */
+		serial_port_out(port, SCxSR, mask);
+	} else if (to_sci_port(port)->overrun_mask = SCIFA_ORER) {
+		/* SCIFA/SCIFB and SCIF on SH7705/SH7720/SH7721 */
+		/* Only clear the status bits we want to clear */
+		serial_port_out(port, SCxSR,
+				serial_port_in(port, SCxSR) & mask);
+	} else {
+		/* Store the mask, clear parity/framing errors */
+		serial_port_out(port, SCxSR, mask & ~(SCIF_FERC | SCIF_PERC));
+	}
+}
+
 #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
 
 #ifdef CONFIG_CONSOLE_POLL
@@ -500,7 +516,7 @@ static int sci_poll_get_char(struct uart_port *port)
 	do {
 		status = serial_port_in(port, SCxSR);
 		if (status & SCxSR_ERRORS(port)) {
-			serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+			sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 			continue;
 		}
 		break;
@@ -513,7 +529,7 @@ static int sci_poll_get_char(struct uart_port *port)
 
 	/* Dummy read */
 	serial_port_in(port, SCxSR);
-	serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 
 	return c;
 }
@@ -528,7 +544,7 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
 	} while (!(status & SCxSR_TDxE(port)));
 
 	serial_port_out(port, SCxTDR, c);
-	serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
+	sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
 }
 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
 
@@ -655,7 +671,7 @@ static void sci_transmit_chars(struct uart_port *port)
 		port->icount.tx++;
 	} while (--count > 0);
 
-	serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
@@ -666,7 +682,7 @@ static void sci_transmit_chars(struct uart_port *port)
 
 		if (port->type != PORT_SCI) {
 			serial_port_in(port, SCxSR); /* Dummy read */
-			serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+			sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
 		}
 
 		ctrl |= SCSCR_TIE;
@@ -750,7 +766,7 @@ static void sci_receive_chars(struct uart_port *port)
 		}
 
 		serial_port_in(port, SCxSR); /* dummy read */
-		serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+		sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 
 		copied += count;
 		port->icount.rx += count;
@@ -761,7 +777,7 @@ static void sci_receive_chars(struct uart_port *port)
 		tty_flip_buffer_push(tport);
 	} else {
 		serial_port_in(port, SCxSR); /* dummy read */
-		serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+		sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 	}
 }
 
@@ -982,14 +998,14 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 		if (sci_handle_errors(port)) {
 			/* discard character in rx buffer */
 			serial_port_in(port, SCxSR);
-			serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+			sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 		}
 	} else {
 		sci_handle_fifo_overrun(port);
 		sci_rx_interrupt(irq, ptr);
 	}
 
-	serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 
 	/* Kick the transmission */
 	sci_tx_interrupt(irq, ptr);
@@ -1003,7 +1019,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
 
 	/* Handle BREAKs */
 	sci_handle_breaks(port);
-	serial_port_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_BREAK_CLEAR(port));
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index 3393f67b4e843578..1e1edbd152673e8f 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -119,28 +119,11 @@ enum {
 
 #define SCxSR_ERRORS(port)	(to_sci_port(port)->error_mask)
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_ARCH_SH73A0) || \
-    defined(CONFIG_ARCH_R8A7740)
-
-# define SCxSR_RDxF_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_RDxF_CLEAR)
-# define SCxSR_ERROR_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_ERROR_CLEAR)
-# define SCxSR_TDxE_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_TDxE_CLEAR)
-# define SCxSR_BREAK_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_BREAK_CLEAR)
-#else
-# define SCxSR_RDxF_CLEAR(port) \
-	((((port)->type = PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR) & 0xff)
-# define SCxSR_ERROR_CLEAR(port) \
-	((((port)->type = PORT_SCI) ? SCI_ERROR_CLEAR : SCIF_ERROR_CLEAR) & 0xff)
-# define SCxSR_TDxE_CLEAR(port) \
-	((((port)->type = PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR) & 0xff)
-# define SCxSR_BREAK_CLEAR(port) \
-	((((port)->type = PORT_SCI) ? SCI_BREAK_CLEAR : SCIF_BREAK_CLEAR) & 0xff)
-#endif
-
+#define SCxSR_RDxF_CLEAR(port) \
+	(((port)->type = PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR)
+#define SCxSR_ERROR_CLEAR(port) \
+	(((port)->type = PORT_SCI) ? SCI_ERROR_CLEAR : SCIF_ERROR_CLEAR)
+#define SCxSR_TDxE_CLEAR(port) \
+	(((port)->type = PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR)
+#define SCxSR_BREAK_CLEAR(port) \
+	(((port)->type = PORT_SCI) ? SCI_BREAK_CLEAR : SCIF_BREAK_CLEAR)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 01/33] serial: sh-sci: Replace buggy big #ifdef by runtime logic
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

The #ifdef logic to clear SCxSR bits using RMW on SCIFA/SCIFB and SCIF
variants with some SCIFA features (sh7705/SH7720/sh7721) has several
drawbacks:
  - It wasn't updated for newer R-Mobile variants (APE6),
  - It doesn't correctly handle SoCs with both SCIF and SCIFA/B (e.g.
    R-Car Gen2, but also legacy sh7723/sh7724),
  - It doesn't play well with ARM multi-platform kernels: on R-Car Gen2,
    SCIF/SCIFA/SCIFB/HSCIF were handled differently, depending on
    whether r8a7740 or sh73a0 support was enabled or not,

Replace the #ifdef logic by runtime logic to fix this.

SCIFA/SCIFB and SCIF on sh7705/sh7720/sh7721 use RMW to clear error
bits, other variants use plain stores, as before.

Note that this changes behavior for SCIFA on sh7723/sh7724 (these SoCs
have both SCIF and SCIFA), which didn't use RMW before.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Question: Can we simplify the logic and use RMW everywhere?
We seem to have been using it fine with (H)SCIF on R-Car Gen2 running
multi-platform kernels.

v3:
  - No changes,

v2:
  - No changes.
---
 drivers/tty/serial/sh-sci.c | 36 ++++++++++++++++++++++++++----------
 drivers/tty/serial/sh-sci.h | 33 ++++++++-------------------------
 2 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1b2f894bdc9e0e6e..b014fce1509d6535 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -489,6 +489,22 @@ static void sci_port_disable(struct sci_port *sci_port)
 	pm_runtime_put_sync(sci_port->port.dev);
 }
 
+static void sci_clear_SCxSR(struct uart_port *port, unsigned int mask)
+{
+	if (port->type == PORT_SCI) {
+		/* Just store the mask */
+		serial_port_out(port, SCxSR, mask);
+	} else if (to_sci_port(port)->overrun_mask == SCIFA_ORER) {
+		/* SCIFA/SCIFB and SCIF on SH7705/SH7720/SH7721 */
+		/* Only clear the status bits we want to clear */
+		serial_port_out(port, SCxSR,
+				serial_port_in(port, SCxSR) & mask);
+	} else {
+		/* Store the mask, clear parity/framing errors */
+		serial_port_out(port, SCxSR, mask & ~(SCIF_FERC | SCIF_PERC));
+	}
+}
+
 #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
 
 #ifdef CONFIG_CONSOLE_POLL
@@ -500,7 +516,7 @@ static int sci_poll_get_char(struct uart_port *port)
 	do {
 		status = serial_port_in(port, SCxSR);
 		if (status & SCxSR_ERRORS(port)) {
-			serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+			sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 			continue;
 		}
 		break;
@@ -513,7 +529,7 @@ static int sci_poll_get_char(struct uart_port *port)
 
 	/* Dummy read */
 	serial_port_in(port, SCxSR);
-	serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 
 	return c;
 }
@@ -528,7 +544,7 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
 	} while (!(status & SCxSR_TDxE(port)));
 
 	serial_port_out(port, SCxTDR, c);
-	serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
+	sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
 }
 #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
 
@@ -655,7 +671,7 @@ static void sci_transmit_chars(struct uart_port *port)
 		port->icount.tx++;
 	} while (--count > 0);
 
-	serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
@@ -666,7 +682,7 @@ static void sci_transmit_chars(struct uart_port *port)
 
 		if (port->type != PORT_SCI) {
 			serial_port_in(port, SCxSR); /* Dummy read */
-			serial_port_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
+			sci_clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
 		}
 
 		ctrl |= SCSCR_TIE;
@@ -750,7 +766,7 @@ static void sci_receive_chars(struct uart_port *port)
 		}
 
 		serial_port_in(port, SCxSR); /* dummy read */
-		serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+		sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 
 		copied += count;
 		port->icount.rx += count;
@@ -761,7 +777,7 @@ static void sci_receive_chars(struct uart_port *port)
 		tty_flip_buffer_push(tport);
 	} else {
 		serial_port_in(port, SCxSR); /* dummy read */
-		serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+		sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 	}
 }
 
@@ -982,14 +998,14 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 		if (sci_handle_errors(port)) {
 			/* discard character in rx buffer */
 			serial_port_in(port, SCxSR);
-			serial_port_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+			sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
 		}
 	} else {
 		sci_handle_fifo_overrun(port);
 		sci_rx_interrupt(irq, ptr);
 	}
 
-	serial_port_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 
 	/* Kick the transmission */
 	sci_tx_interrupt(irq, ptr);
@@ -1003,7 +1019,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
 
 	/* Handle BREAKs */
 	sci_handle_breaks(port);
-	serial_port_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
+	sci_clear_SCxSR(port, SCxSR_BREAK_CLEAR(port));
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index 3393f67b4e843578..1e1edbd152673e8f 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -119,28 +119,11 @@ enum {
 
 #define SCxSR_ERRORS(port)	(to_sci_port(port)->error_mask)
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_ARCH_SH73A0) || \
-    defined(CONFIG_ARCH_R8A7740)
-
-# define SCxSR_RDxF_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_RDxF_CLEAR)
-# define SCxSR_ERROR_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_ERROR_CLEAR)
-# define SCxSR_TDxE_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_TDxE_CLEAR)
-# define SCxSR_BREAK_CLEAR(port) \
-	(serial_port_in(port, SCxSR) & SCIF_BREAK_CLEAR)
-#else
-# define SCxSR_RDxF_CLEAR(port) \
-	((((port)->type == PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR) & 0xff)
-# define SCxSR_ERROR_CLEAR(port) \
-	((((port)->type == PORT_SCI) ? SCI_ERROR_CLEAR : SCIF_ERROR_CLEAR) & 0xff)
-# define SCxSR_TDxE_CLEAR(port) \
-	((((port)->type == PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR) & 0xff)
-# define SCxSR_BREAK_CLEAR(port) \
-	((((port)->type == PORT_SCI) ? SCI_BREAK_CLEAR : SCIF_BREAK_CLEAR) & 0xff)
-#endif
-
+#define SCxSR_RDxF_CLEAR(port) \
+	(((port)->type == PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR)
+#define SCxSR_ERROR_CLEAR(port) \
+	(((port)->type == PORT_SCI) ? SCI_ERROR_CLEAR : SCIF_ERROR_CLEAR)
+#define SCxSR_TDxE_CLEAR(port) \
+	(((port)->type == PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR)
+#define SCxSR_BREAK_CLEAR(port) \
+	(((port)->type == PORT_SCI) ? SCI_BREAK_CLEAR : SCIF_BREAK_CLEAR)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 02/33] serial: sh-sci: Prevent compiler warnings on 64-bit
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Expressions involving "BIT(...)" create values of type "long", which is
64-bit on 64-bit.  Hence "~BIT(...)" no longer fits in 32-bit, which
will cause future compiler warnings when assigning to 32-bit variables:

    drivers/tty/serial/sh-sci.c: In function 'sci_init_single':
    drivers/tty/serial/sh-sci.h:58:25: warning: large integer implicitly truncated to unsigned type [-Woverflow]
     #define SCI_ERROR_CLEAR ~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER)
			     ^
    drivers/tty/serial/sh-sci.c:2325:27: note: in expansion of macro 'SCI_ERROR_CLEAR'
       sci_port->error_clear = SCI_ERROR_CLEAR;

As these values are (at most) 32-bit register values anyway, cast them
to "u32" at the definition level to prevent such compiler warnings.

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index 1e1edbd152673e8f..fe7108bc022a495a 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -54,10 +54,10 @@ enum {
 
 #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER)
 
-#define SCI_RDxF_CLEAR	~(SCI_RESERVED | SCI_RDRF)
-#define SCI_ERROR_CLEAR	~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER)
-#define SCI_TDxE_CLEAR	~(SCI_RESERVED | SCI_TEND | SCI_TDRE)
-#define SCI_BREAK_CLEAR	~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER)
+#define SCI_RDxF_CLEAR	(u32)(~(SCI_RESERVED | SCI_RDRF))
+#define SCI_ERROR_CLEAR	(u32)(~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER))
+#define SCI_TDxE_CLEAR	(u32)(~(SCI_RESERVED | SCI_TEND | SCI_TDRE))
+#define SCI_BREAK_CLEAR	(u32)(~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER))
 
 /* SCxSR (Serial Status Register) on SCIF, SCIFA, SCIFB, HSCIF */
 #define SCIF_ER		BIT(7)	/* Receive Error */
@@ -76,10 +76,10 @@ enum {
 
 #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_BRK | SCIF_ER)
 
-#define SCIF_RDxF_CLEAR		~(SCIF_DR | SCIF_RDF)
-#define SCIF_ERROR_CLEAR	~(SCIFA_ORER | SCIF_PER | SCIF_FER | SCIF_ER)
-#define SCIF_TDxE_CLEAR		~(SCIF_TDFE)
-#define SCIF_BREAK_CLEAR	~(SCIF_PER | SCIF_FER | SCIF_BRK)
+#define SCIF_RDxF_CLEAR		(u32)(~(SCIF_DR | SCIF_RDF))
+#define SCIF_ERROR_CLEAR	(u32)(~(SCIFA_ORER | SCIF_PER | SCIF_FER | SCIF_ER))
+#define SCIF_TDxE_CLEAR		(u32)(~(SCIF_TDFE))
+#define SCIF_BREAK_CLEAR	(u32)(~(SCIF_PER | SCIF_FER | SCIF_BRK))
 
 /* SCFCR (FIFO Control Register) */
 #define SCFCR_MCE	BIT(3)	/* Modem Control Enable */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 02/33] serial: sh-sci: Prevent compiler warnings on 64-bit
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Expressions involving "BIT(...)" create values of type "long", which is
64-bit on 64-bit.  Hence "~BIT(...)" no longer fits in 32-bit, which
will cause future compiler warnings when assigning to 32-bit variables:

    drivers/tty/serial/sh-sci.c: In function 'sci_init_single':
    drivers/tty/serial/sh-sci.h:58:25: warning: large integer implicitly truncated to unsigned type [-Woverflow]
     #define SCI_ERROR_CLEAR ~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER)
			     ^
    drivers/tty/serial/sh-sci.c:2325:27: note: in expansion of macro 'SCI_ERROR_CLEAR'
       sci_port->error_clear = SCI_ERROR_CLEAR;

As these values are (at most) 32-bit register values anyway, cast them
to "u32" at the definition level to prevent such compiler warnings.

Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index 1e1edbd152673e8f..fe7108bc022a495a 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -54,10 +54,10 @@ enum {
 
 #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER)
 
-#define SCI_RDxF_CLEAR	~(SCI_RESERVED | SCI_RDRF)
-#define SCI_ERROR_CLEAR	~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER)
-#define SCI_TDxE_CLEAR	~(SCI_RESERVED | SCI_TEND | SCI_TDRE)
-#define SCI_BREAK_CLEAR	~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER)
+#define SCI_RDxF_CLEAR	(u32)(~(SCI_RESERVED | SCI_RDRF))
+#define SCI_ERROR_CLEAR	(u32)(~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER))
+#define SCI_TDxE_CLEAR	(u32)(~(SCI_RESERVED | SCI_TEND | SCI_TDRE))
+#define SCI_BREAK_CLEAR	(u32)(~(SCI_RESERVED | SCI_PER | SCI_FER | SCI_ORER))
 
 /* SCxSR (Serial Status Register) on SCIF, SCIFA, SCIFB, HSCIF */
 #define SCIF_ER		BIT(7)	/* Receive Error */
@@ -76,10 +76,10 @@ enum {
 
 #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_BRK | SCIF_ER)
 
-#define SCIF_RDxF_CLEAR		~(SCIF_DR | SCIF_RDF)
-#define SCIF_ERROR_CLEAR	~(SCIFA_ORER | SCIF_PER | SCIF_FER | SCIF_ER)
-#define SCIF_TDxE_CLEAR		~(SCIF_TDFE)
-#define SCIF_BREAK_CLEAR	~(SCIF_PER | SCIF_FER | SCIF_BRK)
+#define SCIF_RDxF_CLEAR		(u32)(~(SCIF_DR | SCIF_RDF))
+#define SCIF_ERROR_CLEAR	(u32)(~(SCIFA_ORER | SCIF_PER | SCIF_FER | SCIF_ER))
+#define SCIF_TDxE_CLEAR		(u32)(~(SCIF_TDFE))
+#define SCIF_BREAK_CLEAR	(u32)(~(SCIF_PER | SCIF_FER | SCIF_BRK))
 
 /* SCFCR (FIFO Control Register) */
 #define SCFCR_MCE	BIT(3)	/* Modem Control Enable */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 03/33] serial: sh-sci: Correct SCIF_ERROR_CLEAR for plain SCIF
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

SCIF_ERROR_CLEAR includes SCIFA_ORER, which exists only on SCIFA/SCIFB
and SCIF on sh7705/sh7720/sh7721.

To fix this:
  1. Remove SCIFA_ORER from the definition of SCIF_ERROR_CLEAR,
  2. During initialization, store the error clear mask to use,
     incorporating the overrun bit only if it applies to the SCxSR
     register.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased on top of "serial: sh-sci: Prevent compiler warnings on
    64-bit", to avoid introducing a compiler warning,

v2:
  - No changes.
---
 drivers/tty/serial/sh-sci.c | 14 +++++++++++---
 drivers/tty/serial/sh-sci.h |  4 ++--
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index b014fce1509d6535..fa26be7f9414dfc2 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -84,6 +84,7 @@ struct sci_port {
 	unsigned int		overrun_reg;
 	unsigned int		overrun_mask;
 	unsigned int		error_mask;
+	unsigned int		error_clear;
 	unsigned int		sampling_rate;
 	resource_size_t		reg_size;
 
@@ -2319,15 +2320,22 @@ static int sci_init_single(struct platform_device *dev,
 	/*
 	 * Establish some sensible defaults for the error detection.
 	 */
-	sci_port->error_mask = (p->type = PORT_SCI) ?
-			SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK;
+	if (p->type = PORT_SCI) {
+		sci_port->error_mask = SCI_DEFAULT_ERROR_MASK;
+		sci_port->error_clear = SCI_ERROR_CLEAR;
+	} else {
+		sci_port->error_mask = SCIF_DEFAULT_ERROR_MASK;
+		sci_port->error_clear = SCIF_ERROR_CLEAR;
+	}
 
 	/*
 	 * Make the error mask inclusive of overrun detection, if
 	 * supported.
 	 */
-	if (sci_port->overrun_reg = SCxSR)
+	if (sci_port->overrun_reg = SCxSR) {
 		sci_port->error_mask |= sci_port->overrun_mask;
+		sci_port->error_clear &= ~sci_port->overrun_mask;
+	}
 
 	port->type		= p->type;
 	port->flags		= UPF_FIXED_PORT | p->flags;
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index fe7108bc022a495a..bf69bbdcc1f9aa39 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -77,7 +77,7 @@ enum {
 #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_BRK | SCIF_ER)
 
 #define SCIF_RDxF_CLEAR		(u32)(~(SCIF_DR | SCIF_RDF))
-#define SCIF_ERROR_CLEAR	(u32)(~(SCIFA_ORER | SCIF_PER | SCIF_FER | SCIF_ER))
+#define SCIF_ERROR_CLEAR	(u32)(~(SCIF_PER | SCIF_FER | SCIF_ER))
 #define SCIF_TDxE_CLEAR		(u32)(~(SCIF_TDFE))
 #define SCIF_BREAK_CLEAR	(u32)(~(SCIF_PER | SCIF_FER | SCIF_BRK))
 
@@ -122,7 +122,7 @@ enum {
 #define SCxSR_RDxF_CLEAR(port) \
 	(((port)->type = PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR)
 #define SCxSR_ERROR_CLEAR(port) \
-	(((port)->type = PORT_SCI) ? SCI_ERROR_CLEAR : SCIF_ERROR_CLEAR)
+	(to_sci_port(port)->error_clear)
 #define SCxSR_TDxE_CLEAR(port) \
 	(((port)->type = PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR)
 #define SCxSR_BREAK_CLEAR(port) \
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 03/33] serial: sh-sci: Correct SCIF_ERROR_CLEAR for plain SCIF
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

SCIF_ERROR_CLEAR includes SCIFA_ORER, which exists only on SCIFA/SCIFB
and SCIF on sh7705/sh7720/sh7721.

To fix this:
  1. Remove SCIFA_ORER from the definition of SCIF_ERROR_CLEAR,
  2. During initialization, store the error clear mask to use,
     incorporating the overrun bit only if it applies to the SCxSR
     register.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased on top of "serial: sh-sci: Prevent compiler warnings on
    64-bit", to avoid introducing a compiler warning,

v2:
  - No changes.
---
 drivers/tty/serial/sh-sci.c | 14 +++++++++++---
 drivers/tty/serial/sh-sci.h |  4 ++--
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index b014fce1509d6535..fa26be7f9414dfc2 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -84,6 +84,7 @@ struct sci_port {
 	unsigned int		overrun_reg;
 	unsigned int		overrun_mask;
 	unsigned int		error_mask;
+	unsigned int		error_clear;
 	unsigned int		sampling_rate;
 	resource_size_t		reg_size;
 
@@ -2319,15 +2320,22 @@ static int sci_init_single(struct platform_device *dev,
 	/*
 	 * Establish some sensible defaults for the error detection.
 	 */
-	sci_port->error_mask = (p->type == PORT_SCI) ?
-			SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK;
+	if (p->type == PORT_SCI) {
+		sci_port->error_mask = SCI_DEFAULT_ERROR_MASK;
+		sci_port->error_clear = SCI_ERROR_CLEAR;
+	} else {
+		sci_port->error_mask = SCIF_DEFAULT_ERROR_MASK;
+		sci_port->error_clear = SCIF_ERROR_CLEAR;
+	}
 
 	/*
 	 * Make the error mask inclusive of overrun detection, if
 	 * supported.
 	 */
-	if (sci_port->overrun_reg == SCxSR)
+	if (sci_port->overrun_reg == SCxSR) {
 		sci_port->error_mask |= sci_port->overrun_mask;
+		sci_port->error_clear &= ~sci_port->overrun_mask;
+	}
 
 	port->type		= p->type;
 	port->flags		= UPF_FIXED_PORT | p->flags;
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h
index fe7108bc022a495a..bf69bbdcc1f9aa39 100644
--- a/drivers/tty/serial/sh-sci.h
+++ b/drivers/tty/serial/sh-sci.h
@@ -77,7 +77,7 @@ enum {
 #define SCIF_DEFAULT_ERROR_MASK (SCIF_PER | SCIF_FER | SCIF_BRK | SCIF_ER)
 
 #define SCIF_RDxF_CLEAR		(u32)(~(SCIF_DR | SCIF_RDF))
-#define SCIF_ERROR_CLEAR	(u32)(~(SCIFA_ORER | SCIF_PER | SCIF_FER | SCIF_ER))
+#define SCIF_ERROR_CLEAR	(u32)(~(SCIF_PER | SCIF_FER | SCIF_ER))
 #define SCIF_TDxE_CLEAR		(u32)(~(SCIF_TDFE))
 #define SCIF_BREAK_CLEAR	(u32)(~(SCIF_PER | SCIF_FER | SCIF_BRK))
 
@@ -122,7 +122,7 @@ enum {
 #define SCxSR_RDxF_CLEAR(port) \
 	(((port)->type == PORT_SCI) ? SCI_RDxF_CLEAR : SCIF_RDxF_CLEAR)
 #define SCxSR_ERROR_CLEAR(port) \
-	(((port)->type == PORT_SCI) ? SCI_ERROR_CLEAR : SCIF_ERROR_CLEAR)
+	(to_sci_port(port)->error_clear)
 #define SCxSR_TDxE_CLEAR(port) \
 	(((port)->type == PORT_SCI) ? SCI_TDxE_CLEAR : SCIF_TDxE_CLEAR)
 #define SCxSR_BREAK_CLEAR(port) \
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 04/33] serial: sh-sci: Use SCIF_DR instead of hardcoded literal 1
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v3:
  - No changes,

v2:
  - Add Acked-by.
---
 drivers/tty/serial/sh-sci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index fa26be7f9414dfc2..300f641e730d1ac5 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -960,7 +960,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 		}
 		serial_port_out(port, SCSCR, scr);
 		/* Clear current interrupt */
-		serial_port_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
+		serial_port_out(port, SCxSR,
+				ssr & ~(SCIF_DR | SCxSR_RDxF(port)));
 		dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n",
 			jiffies, s->rx_timeout);
 		mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 04/33] serial: sh-sci: Use SCIF_DR instead of hardcoded literal 1
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v3:
  - No changes,

v2:
  - Add Acked-by.
---
 drivers/tty/serial/sh-sci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index fa26be7f9414dfc2..300f641e730d1ac5 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -960,7 +960,8 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 		}
 		serial_port_out(port, SCSCR, scr);
 		/* Clear current interrupt */
-		serial_port_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
+		serial_port_out(port, SCxSR,
+				ssr & ~(SCIF_DR | SCxSR_RDxF(port)));
 		dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n",
 			jiffies, s->rx_timeout);
 		mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 05/33] serial: sh-sci: Use SCSMR_CKS instead of hardcoded literal 3
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 300f641e730d1ac5..206673f44a2943af 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1969,7 +1969,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
 	sci_reset(port);
 
-	smr_val |= serial_port_in(port, SCSMR) & 3;
+	smr_val |= serial_port_in(port, SCSMR) & SCSMR_CKS;
 
 	uart_update_timeout(port, termios->c_cflag, baud);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 05/33] serial: sh-sci: Use SCSMR_CKS instead of hardcoded literal 3
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 300f641e730d1ac5..206673f44a2943af 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1969,7 +1969,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 
 	sci_reset(port);
 
-	smr_val |= serial_port_in(port, SCSMR) & 3;
+	smr_val |= serial_port_in(port, SCSMR) & SCSMR_CKS;
 
 	uart_update_timeout(port, termios->c_cflag, baud);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 06/33] serial: sh-sci: Drop path in reference to serial_core.c
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

serial_core.c was moved from drivers/serial/ to drivers/tty/serial/ a
while ago. Remove the path to make it move-proof.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 206673f44a2943af..dbb4bbdac37ce0d8 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2014,7 +2014,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
 	/*
 	 * Calculate delay for 2 DMA buffers (4 FIFO).
-	 * See drivers/serial/serial_core.c::uart_update_timeout(). With 10
+	 * See serial_core.c::uart_update_timeout(). With 10
 	 * bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function
 	 * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)."
 	 * Then below we calculate 5 jiffies (20ms) for 2 DMA buffers (4 FIFO
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 06/33] serial: sh-sci: Drop path in reference to serial_core.c
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

serial_core.c was moved from drivers/serial/ to drivers/tty/serial/ a
while ago. Remove the path to make it move-proof.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 206673f44a2943af..dbb4bbdac37ce0d8 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2014,7 +2014,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
 	/*
 	 * Calculate delay for 2 DMA buffers (4 FIFO).
-	 * See drivers/serial/serial_core.c::uart_update_timeout(). With 10
+	 * See serial_core.c::uart_update_timeout(). With 10
 	 * bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function
 	 * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)."
 	 * Then below we calculate 5 jiffies (20ms) for 2 DMA buffers (4 FIFO
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 07/33] serial: sh-sci: Improve readability of sampling rate configuration
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Reorder sampling_rate assignment for consistency in all cases of the
switch statement.
Avoid using the ternary conditional operator to make it more clear that
the value is overridden by platform data.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Reworded one-line summary,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index dbb4bbdac37ce0d8..9502f52d4b55808a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2205,7 +2205,6 @@ static int sci_init_single(struct platform_device *dev,
 {
 	struct uart_port *port = &sci_port->port;
 	const struct resource *res;
-	unsigned int sampling_rate;
 	unsigned int i;
 	int ret;
 
@@ -2250,37 +2249,37 @@ static int sci_init_single(struct platform_device *dev,
 		port->fifosize = 256;
 		sci_port->overrun_reg = SCxSR;
 		sci_port->overrun_mask = SCIFA_ORER;
-		sampling_rate = 16;
+		sci_port->sampling_rate = 16;
 		break;
 	case PORT_HSCIF:
 		port->fifosize = 128;
-		sampling_rate = 0;
 		sci_port->overrun_reg = SCLSR;
 		sci_port->overrun_mask = SCLSR_ORER;
+		sci_port->sampling_rate = 0;
 		break;
 	case PORT_SCIFA:
 		port->fifosize = 64;
 		sci_port->overrun_reg = SCxSR;
 		sci_port->overrun_mask = SCIFA_ORER;
-		sampling_rate = 16;
+		sci_port->sampling_rate = 16;
 		break;
 	case PORT_SCIF:
 		port->fifosize = 16;
 		if (p->regtype = SCIx_SH7705_SCIF_REGTYPE) {
 			sci_port->overrun_reg = SCxSR;
 			sci_port->overrun_mask = SCIFA_ORER;
-			sampling_rate = 16;
+			sci_port->sampling_rate = 16;
 		} else {
 			sci_port->overrun_reg = SCLSR;
 			sci_port->overrun_mask = SCLSR_ORER;
-			sampling_rate = 32;
+			sci_port->sampling_rate = 32;
 		}
 		break;
 	default:
 		port->fifosize = 1;
 		sci_port->overrun_reg = SCxSR;
 		sci_port->overrun_mask = SCI_ORER;
-		sampling_rate = 32;
+		sci_port->sampling_rate = 32;
 		break;
 	}
 
@@ -2288,8 +2287,8 @@ static int sci_init_single(struct platform_device *dev,
 	 * match the SoC datasheet, this should be investigated. Let platform
 	 * data override the sampling rate for now.
 	 */
-	sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate
-				: sampling_rate;
+	if (p->sampling_rate)
+		sci_port->sampling_rate = p->sampling_rate;
 
 	if (!early) {
 		sci_port->iclk = clk_get(&dev->dev, "sci_ick");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 07/33] serial: sh-sci: Improve readability of sampling rate configuration
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Reorder sampling_rate assignment for consistency in all cases of the
switch statement.
Avoid using the ternary conditional operator to make it more clear that
the value is overridden by platform data.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Reworded one-line summary,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index dbb4bbdac37ce0d8..9502f52d4b55808a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2205,7 +2205,6 @@ static int sci_init_single(struct platform_device *dev,
 {
 	struct uart_port *port = &sci_port->port;
 	const struct resource *res;
-	unsigned int sampling_rate;
 	unsigned int i;
 	int ret;
 
@@ -2250,37 +2249,37 @@ static int sci_init_single(struct platform_device *dev,
 		port->fifosize = 256;
 		sci_port->overrun_reg = SCxSR;
 		sci_port->overrun_mask = SCIFA_ORER;
-		sampling_rate = 16;
+		sci_port->sampling_rate = 16;
 		break;
 	case PORT_HSCIF:
 		port->fifosize = 128;
-		sampling_rate = 0;
 		sci_port->overrun_reg = SCLSR;
 		sci_port->overrun_mask = SCLSR_ORER;
+		sci_port->sampling_rate = 0;
 		break;
 	case PORT_SCIFA:
 		port->fifosize = 64;
 		sci_port->overrun_reg = SCxSR;
 		sci_port->overrun_mask = SCIFA_ORER;
-		sampling_rate = 16;
+		sci_port->sampling_rate = 16;
 		break;
 	case PORT_SCIF:
 		port->fifosize = 16;
 		if (p->regtype == SCIx_SH7705_SCIF_REGTYPE) {
 			sci_port->overrun_reg = SCxSR;
 			sci_port->overrun_mask = SCIFA_ORER;
-			sampling_rate = 16;
+			sci_port->sampling_rate = 16;
 		} else {
 			sci_port->overrun_reg = SCLSR;
 			sci_port->overrun_mask = SCLSR_ORER;
-			sampling_rate = 32;
+			sci_port->sampling_rate = 32;
 		}
 		break;
 	default:
 		port->fifosize = 1;
 		sci_port->overrun_reg = SCxSR;
 		sci_port->overrun_mask = SCI_ORER;
-		sampling_rate = 32;
+		sci_port->sampling_rate = 32;
 		break;
 	}
 
@@ -2288,8 +2287,8 @@ static int sci_init_single(struct platform_device *dev,
 	 * match the SoC datasheet, this should be investigated. Let platform
 	 * data override the sampling rate for now.
 	 */
-	sci_port->sampling_rate = p->sampling_rate ? p->sampling_rate
-				: sampling_rate;
+	if (p->sampling_rate)
+		sci_port->sampling_rate = p->sampling_rate;
 
 	if (!early) {
 		sci_port->iclk = clk_get(&dev->dev, "sci_ick");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 08/33] serial: sh-sci: Make sci_irq_desc[] const
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9502f52d4b55808a..1758039066515fb7 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1110,7 +1110,7 @@ static int sci_notifier(struct notifier_block *self,
 	return NOTIFY_OK;
 }
 
-static struct sci_irq_desc {
+static const struct sci_irq_desc {
 	const char	*desc;
 	irq_handler_t	handler;
 } sci_irq_desc[] = {
@@ -1152,7 +1152,7 @@ static int sci_request_irq(struct sci_port *port)
 	int i, j, ret = 0;
 
 	for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) {
-		struct sci_irq_desc *desc;
+		const struct sci_irq_desc *desc;
 		int irq;
 
 		if (SCIx_IRQ_IS_MUXED(port)) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 08/33] serial: sh-sci: Make sci_irq_desc[] const
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9502f52d4b55808a..1758039066515fb7 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1110,7 +1110,7 @@ static int sci_notifier(struct notifier_block *self,
 	return NOTIFY_OK;
 }
 
-static struct sci_irq_desc {
+static const struct sci_irq_desc {
 	const char	*desc;
 	irq_handler_t	handler;
 } sci_irq_desc[] = {
@@ -1152,7 +1152,7 @@ static int sci_request_irq(struct sci_port *port)
 	int i, j, ret = 0;
 
 	for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) {
-		struct sci_irq_desc *desc;
+		const struct sci_irq_desc *desc;
 		int irq;
 
 		if (SCIx_IRQ_IS_MUXED(port)) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 09/33] serial: sh-sci: Make sci_regmap[] const
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1758039066515fb7..383f6df3815a1747 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -147,7 +147,7 @@ struct plat_sci_reg {
 /* Helper for invalidating specific entries of an inherited map. */
 #define sci_reg_invalid	{ .offset = 0, .size = 0 }
 
-static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
 	[SCIx_PROBE_REGTYPE] = {
 		[0 ... SCIx_NR_REGS - 1] = sci_reg_invalid,
 	},
@@ -400,7 +400,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
  */
 static unsigned int sci_serial_in(struct uart_port *p, int offset)
 {
-	struct plat_sci_reg *reg = sci_getreg(p, offset);
+	const struct plat_sci_reg *reg = sci_getreg(p, offset);
 
 	if (reg->size = 8)
 		return ioread8(p->membase + (reg->offset << p->regshift));
@@ -414,7 +414,7 @@ static unsigned int sci_serial_in(struct uart_port *p, int offset)
 
 static void sci_serial_out(struct uart_port *p, int offset, int value)
 {
-	struct plat_sci_reg *reg = sci_getreg(p, offset);
+	const struct plat_sci_reg *reg = sci_getreg(p, offset);
 
 	if (reg->size = 8)
 		iowrite8(value, p->membase + (reg->offset << p->regshift));
@@ -552,7 +552,7 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
 static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 {
 	struct sci_port *s = to_sci_port(port);
-	struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
+	const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
 
 	/*
 	 * Use port-specific handler if provided.
@@ -582,7 +582,7 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 
 static int sci_txfill(struct uart_port *port)
 {
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 
 	reg = sci_getreg(port, SCTFDR);
 	if (reg->size)
@@ -602,7 +602,7 @@ static int sci_txroom(struct uart_port *port)
 
 static int sci_rxfill(struct uart_port *port)
 {
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 
 	reg = sci_getreg(port, SCRFDR);
 	if (reg->size)
@@ -883,7 +883,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
 {
 	struct tty_port *tport = &port->state->port;
 	struct sci_port *s = to_sci_port(port);
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 	int copied = 0;
 	u16 status;
 
@@ -1250,7 +1250,7 @@ static unsigned int sci_tx_empty(struct uart_port *port)
 static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
 	if (mctrl & TIOCM_LOOP) {
-		struct plat_sci_reg *reg;
+		const struct plat_sci_reg *reg;
 
 		/*
 		 * Standard loopback mode for SCFCR ports.
@@ -1621,7 +1621,7 @@ static void sci_stop_rx(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;
+	const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
 	unsigned short scscr, scsptr;
 
 	/* check wheter the port has SCSPTR */
@@ -1910,7 +1910,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq,
 
 static void sci_reset(struct uart_port *port)
 {
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 	unsigned int status;
 
 	do {
@@ -1928,7 +1928,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 			    struct ktermios *old)
 {
 	struct sci_port *s = to_sci_port(port);
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 	unsigned int baud, smr_val = 0, max_baud, cks = 0;
 	int t = -1;
 	unsigned int srr = 15;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 09/33] serial: sh-sci: Make sci_regmap[] const
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1758039066515fb7..383f6df3815a1747 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -147,7 +147,7 @@ struct plat_sci_reg {
 /* Helper for invalidating specific entries of an inherited map. */
 #define sci_reg_invalid	{ .offset = 0, .size = 0 }
 
-static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
+static const struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
 	[SCIx_PROBE_REGTYPE] = {
 		[0 ... SCIx_NR_REGS - 1] = sci_reg_invalid,
 	},
@@ -400,7 +400,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
  */
 static unsigned int sci_serial_in(struct uart_port *p, int offset)
 {
-	struct plat_sci_reg *reg = sci_getreg(p, offset);
+	const struct plat_sci_reg *reg = sci_getreg(p, offset);
 
 	if (reg->size == 8)
 		return ioread8(p->membase + (reg->offset << p->regshift));
@@ -414,7 +414,7 @@ static unsigned int sci_serial_in(struct uart_port *p, int offset)
 
 static void sci_serial_out(struct uart_port *p, int offset, int value)
 {
-	struct plat_sci_reg *reg = sci_getreg(p, offset);
+	const struct plat_sci_reg *reg = sci_getreg(p, offset);
 
 	if (reg->size == 8)
 		iowrite8(value, p->membase + (reg->offset << p->regshift));
@@ -552,7 +552,7 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
 static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 {
 	struct sci_port *s = to_sci_port(port);
-	struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
+	const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
 
 	/*
 	 * Use port-specific handler if provided.
@@ -582,7 +582,7 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
 
 static int sci_txfill(struct uart_port *port)
 {
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 
 	reg = sci_getreg(port, SCTFDR);
 	if (reg->size)
@@ -602,7 +602,7 @@ static int sci_txroom(struct uart_port *port)
 
 static int sci_rxfill(struct uart_port *port)
 {
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 
 	reg = sci_getreg(port, SCRFDR);
 	if (reg->size)
@@ -883,7 +883,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port)
 {
 	struct tty_port *tport = &port->state->port;
 	struct sci_port *s = to_sci_port(port);
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 	int copied = 0;
 	u16 status;
 
@@ -1250,7 +1250,7 @@ static unsigned int sci_tx_empty(struct uart_port *port)
 static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
 {
 	if (mctrl & TIOCM_LOOP) {
-		struct plat_sci_reg *reg;
+		const struct plat_sci_reg *reg;
 
 		/*
 		 * Standard loopback mode for SCFCR ports.
@@ -1621,7 +1621,7 @@ static void sci_stop_rx(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;
+	const struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR;
 	unsigned short scscr, scsptr;
 
 	/* check wheter the port has SCSPTR */
@@ -1910,7 +1910,7 @@ static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq,
 
 static void sci_reset(struct uart_port *port)
 {
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 	unsigned int status;
 
 	do {
@@ -1928,7 +1928,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 			    struct ktermios *old)
 {
 	struct sci_port *s = to_sci_port(port);
-	struct plat_sci_reg *reg;
+	const struct plat_sci_reg *reg;
 	unsigned int baud, smr_val = 0, max_baud, cks = 0;
 	int t = -1;
 	unsigned int srr = 15;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 10/33] serial: sh-sci: Remove useless memory allocation failure printks
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Printing an error on memory allocation failures is unnecessary.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 383f6df3815a1747..59ce9484875b2001 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1172,11 +1172,8 @@ static int sci_request_irq(struct sci_port *port)
 		desc = sci_irq_desc + i;
 		port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s",
 					    dev_name(up->dev), desc->desc);
-		if (!port->irqstr[j]) {
-			dev_err(up->dev, "Failed to allocate %s IRQ string\n",
-				desc->desc);
+		if (!port->irqstr[j])
 			goto out_nomem;
-		}
 
 		ret = request_irq(irq, desc->handler, up->irqflags,
 				  port->irqstr[j], port);
@@ -2588,10 +2585,8 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id)
 	info = match->data;
 
 	p = devm_kzalloc(&pdev->dev, sizeof(struct plat_sci_port), GFP_KERNEL);
-	if (!p) {
-		dev_err(&pdev->dev, "failed to allocate DT config data\n");
+	if (!p)
 		return NULL;
-	}
 
 	/* Get the line number for the aliases node. */
 	id = of_alias_get_id(np, "serial");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 10/33] serial: sh-sci: Remove useless memory allocation failure printks
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Printing an error on memory allocation failures is unnecessary.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 383f6df3815a1747..59ce9484875b2001 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1172,11 +1172,8 @@ static int sci_request_irq(struct sci_port *port)
 		desc = sci_irq_desc + i;
 		port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s",
 					    dev_name(up->dev), desc->desc);
-		if (!port->irqstr[j]) {
-			dev_err(up->dev, "Failed to allocate %s IRQ string\n",
-				desc->desc);
+		if (!port->irqstr[j])
 			goto out_nomem;
-		}
 
 		ret = request_irq(irq, desc->handler, up->irqflags,
 				  port->irqstr[j], port);
@@ -2588,10 +2585,8 @@ sci_parse_dt(struct platform_device *pdev, unsigned int *dev_id)
 	info = match->data;
 
 	p = devm_kzalloc(&pdev->dev, sizeof(struct plat_sci_port), GFP_KERNEL);
-	if (!p) {
-		dev_err(&pdev->dev, "failed to allocate DT config data\n");
+	if (!p)
 		return NULL;
-	}
 
 	/* Get the line number for the aliases node. */
 	id = of_alias_get_id(np, "serial");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 11/33] serial: sh-sci: Remove bogus sci_handle_fifo_overrun() call on (H)SCIF
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Commit 8b6ff84c2d445a47 ("serial: sh-sci: Fix R-Car SCIF and HSCIF
overrun handling") added overrun handling for (H)SCIF using the SCLSR
register, but also accidentally added a bogus call to
sci_handle_fifo_overrun() in the receive interrupt path.

Remove it again.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 59ce9484875b2001..017b33cf5587e809 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1066,11 +1066,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
 	 * DR flags
 	 */
 	if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) &&
-	    (scr_status & SCSCR_RIE)) {
-		if (port->type = PORT_SCIF || port->type = PORT_HSCIF)
-			sci_handle_fifo_overrun(port);
+	    (scr_status & SCSCR_RIE))
 		ret = sci_rx_interrupt(irq, ptr);
-	}
 
 	/* Error Interrupt */
 	if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 11/33] serial: sh-sci: Remove bogus sci_handle_fifo_overrun() call on (H)SCIF
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Commit 8b6ff84c2d445a47 ("serial: sh-sci: Fix R-Car SCIF and HSCIF
overrun handling") added overrun handling for (H)SCIF using the SCLSR
register, but also accidentally added a bogus call to
sci_handle_fifo_overrun() in the receive interrupt path.

Remove it again.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 59ce9484875b2001..017b33cf5587e809 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1066,11 +1066,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
 	 * DR flags
 	 */
 	if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) &&
-	    (scr_status & SCSCR_RIE)) {
-		if (port->type == PORT_SCIF || port->type == PORT_HSCIF)
-			sci_handle_fifo_overrun(port);
+	    (scr_status & SCSCR_RIE))
 		ret = sci_rx_interrupt(irq, ptr);
-	}
 
 	/* Error Interrupt */
 	if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 12/33] serial: sh-sci: Return IRQ_HANDLED when overrun if detected
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

This patch fix an issue that the driver may cause "nobody cared" IRQ
when this driver detects the overrun flag only.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 017b33cf5587e809..c4cb7a5a2b110753 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1078,8 +1078,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
 		ret = sci_br_interrupt(irq, ptr);
 
 	/* Overrun Interrupt */
-	if (orer_status & s->overrun_mask)
+	if (orer_status & s->overrun_mask) {
 		sci_handle_fifo_overrun(port);
+		ret = IRQ_HANDLED;
+	}
 
 	return ret;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 12/33] serial: sh-sci: Return IRQ_HANDLED when overrun if detected
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

This patch fix an issue that the driver may cause "nobody cared" IRQ
when this driver detects the overrun flag only.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 017b33cf5587e809..c4cb7a5a2b110753 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1078,8 +1078,10 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
 		ret = sci_br_interrupt(irq, ptr);
 
 	/* Overrun Interrupt */
-	if (orer_status & s->overrun_mask)
+	if (orer_status & s->overrun_mask) {
 		sci_handle_fifo_overrun(port);
+		ret = IRQ_HANDLED;
+	}
 
 	return ret;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 13/33] serial: sh-sci: Improve DMA error messages
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Make the life of the driver developer/debugger easier:
  - Add __func__ prefix to identical messages,
  - Add DMA directions to messages,
  - Add TX failure messages,
  - Always use "cookie %d" for DMA cookies,
  - "#%d" is reserved for the DMA cookie/descriptor index.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased,

v2:
  - Add "cookie %d" and ""#%d" consistency.
---
 drivers/tty/serial/sh-sci.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index c4cb7a5a2b110753..340700a11b152952 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1319,7 +1319,8 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count)
 	} else if (s->active_rx = s->cookie_rx[1]) {
 		active = 1;
 	} else {
-		dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
+			s->active_rx);
 		return 0;
 	}
 
@@ -1345,8 +1346,8 @@ static void sci_dma_rx_complete(void *arg)
 	unsigned long flags;
 	int count;
 
-	dev_dbg(port->dev, "%s(%d) active #%d\n",
-		__func__, port->line, s->active_rx);
+	dev_dbg(port->dev, "%s(%d) active cookie %d\n", __func__, port->line,
+		s->active_rx);
 
 	spin_lock_irqsave(&port->lock, flags);
 
@@ -1418,12 +1419,12 @@ static void sci_submit_rx(struct sci_port *s)
 				s->cookie_rx[i] = -EINVAL;
 			}
 			dev_warn(s->port.dev,
-				 "failed to re-start DMA, using PIO\n");
+				 "Failed to re-start Rx DMA, using PIO\n");
 			sci_rx_dma_release(s, true);
 			return;
 		}
-		dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n",
-			__func__, s->cookie_rx[i], i);
+		dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
+			s->cookie_rx[i], i);
 	}
 
 	s->active_rx = s->cookie_rx[0];
@@ -1443,7 +1444,8 @@ static void work_fn_rx(struct work_struct *work)
 	} else if (s->active_rx = s->cookie_rx[1]) {
 		new = 1;
 	} else {
-		dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
+			s->active_rx);
 		return;
 	}
 	desc = s->desc_rx[new];
@@ -1482,7 +1484,7 @@ static void work_fn_rx(struct work_struct *work)
 
 	s->active_rx = s->cookie_rx[!new];
 
-	dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n",
+	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
 }
 
@@ -1516,6 +1518,7 @@ static void work_fn_tx(struct work_struct *work)
 			sg, s->sg_len_tx, DMA_MEM_TO_DEV,
 			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc) {
+		dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n");
 		/* switch to PIO */
 		sci_tx_dma_release(s, true);
 		return;
@@ -1704,13 +1707,15 @@ static void sci_request_dma(struct uart_port *port)
 			    UART_XMIT_SIZE,
 			    (uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
 		nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
-		if (!nent)
+		if (!nent) {
+			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
 			sci_tx_dma_release(s, false);
-		else
+		} else {
 			dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n",
 				__func__,
 				sg_dma_len(&s->sg_tx), port->state->xmit.buf,
 				&sg_dma_address(&s->sg_tx));
+		}
 
 		s->sg_len_tx = nent;
 
@@ -1737,7 +1742,7 @@ static void sci_request_dma(struct uart_port *port)
 
 		if (!buf[0]) {
 			dev_warn(port->dev,
-				 "failed to allocate dma buffer, using PIO\n");
+				 "Failed to allocate Rx dma buffer, using PIO\n");
 			sci_rx_dma_release(s, true);
 			return;
 		}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 13/33] serial: sh-sci: Improve DMA error messages
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Make the life of the driver developer/debugger easier:
  - Add __func__ prefix to identical messages,
  - Add DMA directions to messages,
  - Add TX failure messages,
  - Always use "cookie %d" for DMA cookies,
  - "#%d" is reserved for the DMA cookie/descriptor index.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased,

v2:
  - Add "cookie %d" and ""#%d" consistency.
---
 drivers/tty/serial/sh-sci.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index c4cb7a5a2b110753..340700a11b152952 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1319,7 +1319,8 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count)
 	} else if (s->active_rx == s->cookie_rx[1]) {
 		active = 1;
 	} else {
-		dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
+			s->active_rx);
 		return 0;
 	}
 
@@ -1345,8 +1346,8 @@ static void sci_dma_rx_complete(void *arg)
 	unsigned long flags;
 	int count;
 
-	dev_dbg(port->dev, "%s(%d) active #%d\n",
-		__func__, port->line, s->active_rx);
+	dev_dbg(port->dev, "%s(%d) active cookie %d\n", __func__, port->line,
+		s->active_rx);
 
 	spin_lock_irqsave(&port->lock, flags);
 
@@ -1418,12 +1419,12 @@ static void sci_submit_rx(struct sci_port *s)
 				s->cookie_rx[i] = -EINVAL;
 			}
 			dev_warn(s->port.dev,
-				 "failed to re-start DMA, using PIO\n");
+				 "Failed to re-start Rx DMA, using PIO\n");
 			sci_rx_dma_release(s, true);
 			return;
 		}
-		dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n",
-			__func__, s->cookie_rx[i], i);
+		dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
+			s->cookie_rx[i], i);
 	}
 
 	s->active_rx = s->cookie_rx[0];
@@ -1443,7 +1444,8 @@ static void work_fn_rx(struct work_struct *work)
 	} else if (s->active_rx == s->cookie_rx[1]) {
 		new = 1;
 	} else {
-		dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
+		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
+			s->active_rx);
 		return;
 	}
 	desc = s->desc_rx[new];
@@ -1482,7 +1484,7 @@ static void work_fn_rx(struct work_struct *work)
 
 	s->active_rx = s->cookie_rx[!new];
 
-	dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n",
+	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
 }
 
@@ -1516,6 +1518,7 @@ static void work_fn_tx(struct work_struct *work)
 			sg, s->sg_len_tx, DMA_MEM_TO_DEV,
 			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc) {
+		dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n");
 		/* switch to PIO */
 		sci_tx_dma_release(s, true);
 		return;
@@ -1704,13 +1707,15 @@ static void sci_request_dma(struct uart_port *port)
 			    UART_XMIT_SIZE,
 			    (uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
 		nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
-		if (!nent)
+		if (!nent) {
+			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
 			sci_tx_dma_release(s, false);
-		else
+		} else {
 			dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n",
 				__func__,
 				sg_dma_len(&s->sg_tx), port->state->xmit.buf,
 				&sg_dma_address(&s->sg_tx));
+		}
 
 		s->sg_len_tx = nent;
 
@@ -1737,7 +1742,7 @@ static void sci_request_dma(struct uart_port *port)
 
 		if (!buf[0]) {
 			dev_warn(port->dev,
-				 "failed to allocate dma buffer, using PIO\n");
+				 "Failed to allocate Rx dma buffer, using PIO\n");
 			sci_rx_dma_release(s, true);
 			return;
 		}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 14/33] serial: sh-sci: Improve comments for DMA timeout calculation
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Reformat, grammar improvements, use "ms" instead of "msec".

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 340700a11b152952..cfef543df25271f5 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2015,13 +2015,13 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
 	/*
 	 * Calculate delay for 2 DMA buffers (4 FIFO).
-	 * See serial_core.c::uart_update_timeout(). With 10
-	 * bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function
-	 * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)."
-	 * Then below we calculate 5 jiffies (20ms) for 2 DMA buffers (4 FIFO
-	 * sizes), but when performing a faster transfer, value obtained by
-	 * this formula is may not enough. Therefore, if value is smaller than
-	 * 20msec, this sets 20msec as timeout of DMA.
+	 * See serial_core.c::uart_update_timeout().
+	 * With 10 bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above
+	 * function calculates 1 jiffie for the data plus 5 jiffies for the
+	 * "slop(e)." Then below we calculate 5 jiffies (20ms) for 2 DMA
+	 * buffers (4 FIFO sizes), but when performing a faster transfer, the
+	 * value obtained by this formula is too small. Therefore, if the value
+	 * is smaller than 20ms, use 20ms as the timeout value for DMA.
 	 */
 	if (s->chan_rx) {
 		unsigned int bits;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 14/33] serial: sh-sci: Improve comments for DMA timeout calculation
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Reformat, grammar improvements, use "ms" instead of "msec".

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 340700a11b152952..cfef543df25271f5 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -2015,13 +2015,13 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
 	/*
 	 * Calculate delay for 2 DMA buffers (4 FIFO).
-	 * See serial_core.c::uart_update_timeout(). With 10
-	 * bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function
-	 * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)."
-	 * Then below we calculate 5 jiffies (20ms) for 2 DMA buffers (4 FIFO
-	 * sizes), but when performing a faster transfer, value obtained by
-	 * this formula is may not enough. Therefore, if value is smaller than
-	 * 20msec, this sets 20msec as timeout of DMA.
+	 * See serial_core.c::uart_update_timeout().
+	 * With 10 bits (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above
+	 * function calculates 1 jiffie for the data plus 5 jiffies for the
+	 * "slop(e)." Then below we calculate 5 jiffies (20ms) for 2 DMA
+	 * buffers (4 FIFO sizes), but when performing a faster transfer, the
+	 * value obtained by this formula is too small. Therefore, if the value
+	 * is smaller than 20ms, use 20ms as the timeout value for DMA.
 	 */
 	if (s->chan_rx) {
 		unsigned int bits;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 15/33] serial: sh-sci: Handle DMA init failures inside sci_request_dma()
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Let sci_request_dma() handle failures to initialize DMA itself.
This way sci_tx_dma_release() and sci_rx_dma_release() don't have to
consider partial initialization, and thus don't need to reset DMA
addresses to DMA_ERROR_CODE, which is not 100% portable access
architectures.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index cfef543df25271f5..ea6ab6173ce9f239 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1371,9 +1371,8 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 	s->chan_rx = NULL;
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
 	dma_release_channel(chan);
-	if (sg_dma_address(&s->sg_rx[0]))
-		dma_free_coherent(port->dev, s->buf_len_rx * 2,
-				  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+	dma_free_coherent(port->dev, s->buf_len_rx * 2,
+			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
 	if (enable_pio)
 		sci_start_rx(port);
 }
@@ -1709,7 +1708,8 @@ static void sci_request_dma(struct uart_port *port)
 		nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
 		if (!nent) {
 			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
-			sci_tx_dma_release(s, false);
+			dma_release_channel(chan);
+			s->chan_tx = NULL;
 		} else {
 			dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n",
 				__func__,
@@ -1743,7 +1743,9 @@ static void sci_request_dma(struct uart_port *port)
 		if (!buf[0]) {
 			dev_warn(port->dev,
 				 "Failed to allocate Rx dma buffer, using PIO\n");
-			sci_rx_dma_release(s, true);
+			dma_release_channel(chan);
+			s->chan_rx = NULL;
+			sci_start_rx(port);
 			return;
 		}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 15/33] serial: sh-sci: Handle DMA init failures inside sci_request_dma()
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Let sci_request_dma() handle failures to initialize DMA itself.
This way sci_tx_dma_release() and sci_rx_dma_release() don't have to
consider partial initialization, and thus don't need to reset DMA
addresses to DMA_ERROR_CODE, which is not 100% portable access
architectures.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index cfef543df25271f5..ea6ab6173ce9f239 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1371,9 +1371,8 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 	s->chan_rx = NULL;
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
 	dma_release_channel(chan);
-	if (sg_dma_address(&s->sg_rx[0]))
-		dma_free_coherent(port->dev, s->buf_len_rx * 2,
-				  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+	dma_free_coherent(port->dev, s->buf_len_rx * 2,
+			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
 	if (enable_pio)
 		sci_start_rx(port);
 }
@@ -1709,7 +1708,8 @@ static void sci_request_dma(struct uart_port *port)
 		nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
 		if (!nent) {
 			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
-			sci_tx_dma_release(s, false);
+			dma_release_channel(chan);
+			s->chan_tx = NULL;
 		} else {
 			dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n",
 				__func__,
@@ -1743,7 +1743,9 @@ static void sci_request_dma(struct uart_port *port)
 		if (!buf[0]) {
 			dev_warn(port->dev,
 				 "Failed to allocate Rx dma buffer, using PIO\n");
-			sci_rx_dma_release(s, true);
+			dma_release_channel(chan);
+			s->chan_rx = NULL;
+			sci_start_rx(port);
 			return;
 		}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 16/33] serial: sh-sci: Use correct device for DMA mapping with IOMMU
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

To function correctly in the presence of an IOMMU, the DMA buffers must
be managed using the DMA channel's device instead of the platform
device's device.

Make sure to free the DMA memory before releasing the channel, not
after.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v3:
  - Fix call to dma_sync_sg_for_device() which I missed before,
  - Rebased on top of "serial: sh-sci: Handle DMA init failures inside
    sci_request_dma()",

v2:
  - Add Acked-by.
---
 drivers/tty/serial/sh-sci.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ea6ab6173ce9f239..9aa9720d7f09d10f 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1370,9 +1370,9 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 
 	s->chan_rx = NULL;
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
-	dma_release_channel(chan);
-	dma_free_coherent(port->dev, s->buf_len_rx * 2,
+	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2,
 			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+	dma_release_channel(chan);
 	if (enable_pio)
 		sci_start_rx(port);
 }
@@ -1523,7 +1523,7 @@ static void work_fn_tx(struct work_struct *work)
 		return;
 	}
 
-	dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE);
+	dma_sync_sg_for_device(chan->device->dev, sg, 1, DMA_TO_DEVICE);
 
 	spin_lock_irq(&port->lock);
 	s->desc_tx = desc;
@@ -1705,7 +1705,8 @@ static void sci_request_dma(struct uart_port *port)
 		sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
 			    UART_XMIT_SIZE,
 			    (uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
-		nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
+		nent = dma_map_sg(chan->device->dev, &s->sg_tx, 1,
+				  DMA_TO_DEVICE);
 		if (!nent) {
 			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
 			dma_release_channel(chan);
@@ -1737,8 +1738,9 @@ static void sci_request_dma(struct uart_port *port)
 		s->chan_rx = chan;
 
 		s->buf_len_rx = 2 * max(16, (int)port->fifosize);
-		buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2,
-					    &dma[0], GFP_KERNEL);
+		buf[0] = dma_alloc_coherent(chan->device->dev,
+					    s->buf_len_rx * 2, &dma[0],
+					    GFP_KERNEL);
 
 		if (!buf[0]) {
 			dev_warn(port->dev,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 16/33] serial: sh-sci: Use correct device for DMA mapping with IOMMU
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

To function correctly in the presence of an IOMMU, the DMA buffers must
be managed using the DMA channel's device instead of the platform
device's device.

Make sure to free the DMA memory before releasing the channel, not
after.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v3:
  - Fix call to dma_sync_sg_for_device() which I missed before,
  - Rebased on top of "serial: sh-sci: Handle DMA init failures inside
    sci_request_dma()",

v2:
  - Add Acked-by.
---
 drivers/tty/serial/sh-sci.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ea6ab6173ce9f239..9aa9720d7f09d10f 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1370,9 +1370,9 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 
 	s->chan_rx = NULL;
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
-	dma_release_channel(chan);
-	dma_free_coherent(port->dev, s->buf_len_rx * 2,
+	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2,
 			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+	dma_release_channel(chan);
 	if (enable_pio)
 		sci_start_rx(port);
 }
@@ -1523,7 +1523,7 @@ static void work_fn_tx(struct work_struct *work)
 		return;
 	}
 
-	dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE);
+	dma_sync_sg_for_device(chan->device->dev, sg, 1, DMA_TO_DEVICE);
 
 	spin_lock_irq(&port->lock);
 	s->desc_tx = desc;
@@ -1705,7 +1705,8 @@ static void sci_request_dma(struct uart_port *port)
 		sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
 			    UART_XMIT_SIZE,
 			    (uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
-		nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
+		nent = dma_map_sg(chan->device->dev, &s->sg_tx, 1,
+				  DMA_TO_DEVICE);
 		if (!nent) {
 			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
 			dma_release_channel(chan);
@@ -1737,8 +1738,9 @@ static void sci_request_dma(struct uart_port *port)
 		s->chan_rx = chan;
 
 		s->buf_len_rx = 2 * max(16, (int)port->fifosize);
-		buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2,
-					    &dma[0], GFP_KERNEL);
+		buf[0] = dma_alloc_coherent(chan->device->dev,
+					    s->buf_len_rx * 2, &dma[0],
+					    GFP_KERNEL);
 
 		if (!buf[0]) {
 			dev_warn(port->dev,
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 17/33] serial: sh-sci: Use min_t()/max_t() instead of casts
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

When comparing differently sized types, it's better to use
min_t()/max_t() than adding casts.

Also use "unsigned int" instead of "int", as that's the right type for
the length of an SG entry.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v3:
  - No changes,

v2:
  - Add Acked-by.
---
 drivers/tty/serial/sh-sci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9aa9720d7f09d10f..cb35c88645bb5784 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1507,7 +1507,8 @@ static void work_fn_tx(struct work_struct *work)
 	sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
 	sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
 		sg->offset;
-	sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
+	sg_dma_len(sg) = min_t(unsigned int,
+		CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
 		CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
 	spin_unlock_irq(&port->lock);
 
@@ -1737,7 +1738,7 @@ static void sci_request_dma(struct uart_port *port)
 
 		s->chan_rx = chan;
 
-		s->buf_len_rx = 2 * max(16, (int)port->fifosize);
+		s->buf_len_rx = 2 * max_t(size_t, 16, port->fifosize);
 		buf[0] = dma_alloc_coherent(chan->device->dev,
 					    s->buf_len_rx * 2, &dma[0],
 					    GFP_KERNEL);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 17/33] serial: sh-sci: Use min_t()/max_t() instead of casts
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

When comparing differently sized types, it's better to use
min_t()/max_t() than adding casts.

Also use "unsigned int" instead of "int", as that's the right type for
the length of an SG entry.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
v3:
  - No changes,

v2:
  - Add Acked-by.
---
 drivers/tty/serial/sh-sci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9aa9720d7f09d10f..cb35c88645bb5784 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1507,7 +1507,8 @@ static void work_fn_tx(struct work_struct *work)
 	sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
 	sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
 		sg->offset;
-	sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
+	sg_dma_len(sg) = min_t(unsigned int,
+		CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
 		CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
 	spin_unlock_irq(&port->lock);
 
@@ -1737,7 +1738,7 @@ static void sci_request_dma(struct uart_port *port)
 
 		s->chan_rx = chan;
 
-		s->buf_len_rx = 2 * max(16, (int)port->fifosize);
+		s->buf_len_rx = 2 * max_t(size_t, 16, port->fifosize);
 		buf[0] = dma_alloc_coherent(chan->device->dev,
 					    s->buf_len_rx * 2, &dma[0],
 					    GFP_KERNEL);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 18/33] serial: sh-sci: Switch to dma_map_single() for DMA transmission
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Simplify the DMA transmit code by using dma_map_single() instead of
constantly modifying the single-entry scatterlist to match what's
currently being transmitted.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 50 ++++++++++++++++++---------------------------
 1 file changed, 20 insertions(+), 30 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index cb35c88645bb5784..5a528b8985052017 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -109,8 +109,8 @@ struct sci_port {
 	dma_cookie_t			cookie_tx;
 	dma_cookie_t			cookie_rx[2];
 	dma_cookie_t			active_rx;
-	struct scatterlist		sg_tx;
-	unsigned int			sg_len_tx;
+	dma_addr_t			tx_dma_addr;
+	unsigned int			tx_dma_len;
 	struct scatterlist		sg_rx[2];
 	size_t				buf_len_rx;
 	struct sh_dmae_slave		param_tx;
@@ -1280,10 +1280,10 @@ static void sci_dma_tx_complete(void *arg)
 
 	spin_lock_irqsave(&port->lock, flags);
 
-	xmit->tail += sg_dma_len(&s->sg_tx);
+	xmit->tail += s->tx_dma_len;
 	xmit->tail &= UART_XMIT_SIZE - 1;
 
-	port->icount.tx += sg_dma_len(&s->sg_tx);
+	port->icount.tx += s->tx_dma_len;
 
 	async_tx_ack(s->desc_tx);
 	s->desc_tx = NULL;
@@ -1494,7 +1494,7 @@ static void work_fn_tx(struct work_struct *work)
 	struct dma_chan *chan = s->chan_tx;
 	struct uart_port *port = &s->port;
 	struct circ_buf *xmit = &port->state->xmit;
-	struct scatterlist *sg = &s->sg_tx;
+	dma_addr_t buf;
 
 	/*
 	 * DMA is idle now.
@@ -1504,19 +1504,15 @@ static void work_fn_tx(struct work_struct *work)
 	 * consistent xmit buffer state.
 	 */
 	spin_lock_irq(&port->lock);
-	sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
-	sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
-		sg->offset;
-	sg_dma_len(sg) = min_t(unsigned int,
+	buf = s->tx_dma_addr + (xmit->tail & (UART_XMIT_SIZE - 1));
+	s->tx_dma_len = min_t(unsigned int,
 		CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
 		CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
 	spin_unlock_irq(&port->lock);
 
-	BUG_ON(!sg_dma_len(sg));
-
-	desc = dmaengine_prep_slave_sg(chan,
-			sg, s->sg_len_tx, DMA_MEM_TO_DEV,
-			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	desc = dmaengine_prep_slave_single(chan, buf, s->tx_dma_len,
+					   DMA_MEM_TO_DEV,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc) {
 		dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n");
 		/* switch to PIO */
@@ -1524,7 +1520,8 @@ static void work_fn_tx(struct work_struct *work)
 		return;
 	}
 
-	dma_sync_sg_for_device(chan->device->dev, sg, 1, DMA_TO_DEVICE);
+	dma_sync_single_for_device(chan->device->dev, buf, s->tx_dma_len,
+				   DMA_TO_DEVICE);
 
 	spin_lock_irq(&port->lock);
 	s->desc_tx = desc;
@@ -1680,7 +1677,6 @@ static void sci_request_dma(struct uart_port *port)
 	struct sh_dmae_slave *param;
 	struct dma_chan *chan;
 	dma_cap_mask_t mask;
-	int nent;
 
 	dev_dbg(port->dev, "%s: port %d\n", __func__, port->line);
 
@@ -1700,27 +1696,21 @@ static void sci_request_dma(struct uart_port *port)
 	dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan);
 	if (chan) {
 		s->chan_tx = chan;
-		sg_init_table(&s->sg_tx, 1);
 		/* UART circular tx buffer is an aligned page. */
-		BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
-		sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
-			    UART_XMIT_SIZE,
-			    (uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
-		nent = dma_map_sg(chan->device->dev, &s->sg_tx, 1,
-				  DMA_TO_DEVICE);
-		if (!nent) {
+		s->tx_dma_addr = dma_map_single(chan->device->dev,
+						port->state->xmit.buf,
+						UART_XMIT_SIZE,
+						DMA_TO_DEVICE);
+		if (dma_mapping_error(chan->device->dev, s->tx_dma_addr)) {
 			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
 			dma_release_channel(chan);
 			s->chan_tx = NULL;
 		} else {
-			dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n",
-				__func__,
-				sg_dma_len(&s->sg_tx), port->state->xmit.buf,
-				&sg_dma_address(&s->sg_tx));
+			dev_dbg(port->dev, "%s: mapped %lu@%p to %pad\n",
+				__func__, UART_XMIT_SIZE,
+				port->state->xmit.buf, &s->tx_dma_addr);
 		}
 
-		s->sg_len_tx = nent;
-
 		INIT_WORK(&s->work_tx, work_fn_tx);
 	}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 18/33] serial: sh-sci: Switch to dma_map_single() for DMA transmission
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Simplify the DMA transmit code by using dma_map_single() instead of
constantly modifying the single-entry scatterlist to match what's
currently being transmitted.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 50 ++++++++++++++++++---------------------------
 1 file changed, 20 insertions(+), 30 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index cb35c88645bb5784..5a528b8985052017 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -109,8 +109,8 @@ struct sci_port {
 	dma_cookie_t			cookie_tx;
 	dma_cookie_t			cookie_rx[2];
 	dma_cookie_t			active_rx;
-	struct scatterlist		sg_tx;
-	unsigned int			sg_len_tx;
+	dma_addr_t			tx_dma_addr;
+	unsigned int			tx_dma_len;
 	struct scatterlist		sg_rx[2];
 	size_t				buf_len_rx;
 	struct sh_dmae_slave		param_tx;
@@ -1280,10 +1280,10 @@ static void sci_dma_tx_complete(void *arg)
 
 	spin_lock_irqsave(&port->lock, flags);
 
-	xmit->tail += sg_dma_len(&s->sg_tx);
+	xmit->tail += s->tx_dma_len;
 	xmit->tail &= UART_XMIT_SIZE - 1;
 
-	port->icount.tx += sg_dma_len(&s->sg_tx);
+	port->icount.tx += s->tx_dma_len;
 
 	async_tx_ack(s->desc_tx);
 	s->desc_tx = NULL;
@@ -1494,7 +1494,7 @@ static void work_fn_tx(struct work_struct *work)
 	struct dma_chan *chan = s->chan_tx;
 	struct uart_port *port = &s->port;
 	struct circ_buf *xmit = &port->state->xmit;
-	struct scatterlist *sg = &s->sg_tx;
+	dma_addr_t buf;
 
 	/*
 	 * DMA is idle now.
@@ -1504,19 +1504,15 @@ static void work_fn_tx(struct work_struct *work)
 	 * consistent xmit buffer state.
 	 */
 	spin_lock_irq(&port->lock);
-	sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
-	sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
-		sg->offset;
-	sg_dma_len(sg) = min_t(unsigned int,
+	buf = s->tx_dma_addr + (xmit->tail & (UART_XMIT_SIZE - 1));
+	s->tx_dma_len = min_t(unsigned int,
 		CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
 		CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
 	spin_unlock_irq(&port->lock);
 
-	BUG_ON(!sg_dma_len(sg));
-
-	desc = dmaengine_prep_slave_sg(chan,
-			sg, s->sg_len_tx, DMA_MEM_TO_DEV,
-			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	desc = dmaengine_prep_slave_single(chan, buf, s->tx_dma_len,
+					   DMA_MEM_TO_DEV,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 	if (!desc) {
 		dev_warn(port->dev, "Failed preparing Tx DMA descriptor\n");
 		/* switch to PIO */
@@ -1524,7 +1520,8 @@ static void work_fn_tx(struct work_struct *work)
 		return;
 	}
 
-	dma_sync_sg_for_device(chan->device->dev, sg, 1, DMA_TO_DEVICE);
+	dma_sync_single_for_device(chan->device->dev, buf, s->tx_dma_len,
+				   DMA_TO_DEVICE);
 
 	spin_lock_irq(&port->lock);
 	s->desc_tx = desc;
@@ -1680,7 +1677,6 @@ static void sci_request_dma(struct uart_port *port)
 	struct sh_dmae_slave *param;
 	struct dma_chan *chan;
 	dma_cap_mask_t mask;
-	int nent;
 
 	dev_dbg(port->dev, "%s: port %d\n", __func__, port->line);
 
@@ -1700,27 +1696,21 @@ static void sci_request_dma(struct uart_port *port)
 	dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan);
 	if (chan) {
 		s->chan_tx = chan;
-		sg_init_table(&s->sg_tx, 1);
 		/* UART circular tx buffer is an aligned page. */
-		BUG_ON((uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
-		sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
-			    UART_XMIT_SIZE,
-			    (uintptr_t)port->state->xmit.buf & ~PAGE_MASK);
-		nent = dma_map_sg(chan->device->dev, &s->sg_tx, 1,
-				  DMA_TO_DEVICE);
-		if (!nent) {
+		s->tx_dma_addr = dma_map_single(chan->device->dev,
+						port->state->xmit.buf,
+						UART_XMIT_SIZE,
+						DMA_TO_DEVICE);
+		if (dma_mapping_error(chan->device->dev, s->tx_dma_addr)) {
 			dev_warn(port->dev, "Failed mapping Tx DMA descriptor\n");
 			dma_release_channel(chan);
 			s->chan_tx = NULL;
 		} else {
-			dev_dbg(port->dev, "%s: mapped %d@%p to %pad\n",
-				__func__,
-				sg_dma_len(&s->sg_tx), port->state->xmit.buf,
-				&sg_dma_address(&s->sg_tx));
+			dev_dbg(port->dev, "%s: mapped %lu@%p to %pad\n",
+				__func__, UART_XMIT_SIZE,
+				port->state->xmit.buf, &s->tx_dma_addr);
 		}
 
-		s->sg_len_tx = nent;
-
 		INIT_WORK(&s->work_tx, work_fn_tx);
 	}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 19/33] serial: sh-sci: Fix TX buffer mapping leak
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

The mapped transmit buffer is never unmapped. This leaks quite some
mappings, as the mapping is done in uart_ops.startup(), i.e. every time
the device is opened. Unmap the buffer on device close.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased on top of "serial: sh-sci: Switch to dma_map_single() for
    DMA transmission", and thus converted from scatterlist to buffer.

v2:
  - Add TODO.
---
 drivers/tty/serial/sh-sci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 5a528b8985052017..4345aa422eed43a1 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1384,6 +1384,8 @@ static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
 
 	s->chan_tx = NULL;
 	s->cookie_tx = -EINVAL;
+	dma_unmap_single(chan->device->dev, s->tx_dma_addr, UART_XMIT_SIZE,
+			 DMA_TO_DEVICE);
 	dma_release_channel(chan);
 	if (enable_pio)
 		sci_start_tx(port);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 19/33] serial: sh-sci: Fix TX buffer mapping leak
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

The mapped transmit buffer is never unmapped. This leaks quite some
mappings, as the mapping is done in uart_ops.startup(), i.e. every time
the device is opened. Unmap the buffer on device close.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased on top of "serial: sh-sci: Switch to dma_map_single() for
    DMA transmission", and thus converted from scatterlist to buffer.

v2:
  - Add TODO.
---
 drivers/tty/serial/sh-sci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 5a528b8985052017..4345aa422eed43a1 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1384,6 +1384,8 @@ static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
 
 	s->chan_tx = NULL;
 	s->cookie_tx = -EINVAL;
+	dma_unmap_single(chan->device->dev, s->tx_dma_addr, UART_XMIT_SIZE,
+			 DMA_TO_DEVICE);
 	dma_release_channel(chan);
 	if (enable_pio)
 		sci_start_tx(port);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 20/33] serial: sh-sci: Use DMA submission helpers instead of open-coding
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Replace open-coded
  - calls to dma_async_tx_descriptor.tx_submit() by calls to the
    dmaengine_submit() helper,
  - dma_cookie_t comparisons by calls to dma_submit_error().

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 4345aa422eed43a1..294b283f5c8535c3 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1407,10 +1407,10 @@ static void sci_submit_rx(struct sci_port *s)
 			s->desc_rx[i] = desc;
 			desc->callback = sci_dma_rx_complete;
 			desc->callback_param = s;
-			s->cookie_rx[i] = desc->tx_submit(desc);
+			s->cookie_rx[i] = dmaengine_submit(desc);
 		}
 
-		if (!desc || s->cookie_rx[i] < 0) {
+		if (!desc || dma_submit_error(s->cookie_rx[i])) {
 			if (i) {
 				async_tx_ack(s->desc_rx[0]);
 				s->cookie_rx[0] = -EINVAL;
@@ -1476,8 +1476,8 @@ static void work_fn_rx(struct work_struct *work)
 		return;
 	}
 
-	s->cookie_rx[new] = desc->tx_submit(desc);
-	if (s->cookie_rx[new] < 0) {
+	s->cookie_rx[new] = dmaengine_submit(desc);
+	if (dma_submit_error(s->cookie_rx[new])) {
 		dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
 		sci_rx_dma_release(s, true);
 		return;
@@ -1530,8 +1530,8 @@ static void work_fn_tx(struct work_struct *work)
 	desc->callback = sci_dma_tx_complete;
 	desc->callback_param = s;
 	spin_unlock_irq(&port->lock);
-	s->cookie_tx = desc->tx_submit(desc);
-	if (s->cookie_tx < 0) {
+	s->cookie_tx = dmaengine_submit(desc);
+	if (dma_submit_error(s->cookie_tx)) {
 		dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n");
 		/* switch to PIO */
 		sci_tx_dma_release(s, true);
@@ -1562,7 +1562,7 @@ static void sci_start_tx(struct uart_port *port)
 	}
 
 	if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
-	    s->cookie_tx < 0) {
+	    dma_submit_error(s->cookie_tx)) {
 		s->cookie_tx = 0;
 		schedule_work(&s->work_tx);
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 20/33] serial: sh-sci: Use DMA submission helpers instead of open-coding
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Replace open-coded
  - calls to dma_async_tx_descriptor.tx_submit() by calls to the
    dmaengine_submit() helper,
  - dma_cookie_t comparisons by calls to dma_submit_error().

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 4345aa422eed43a1..294b283f5c8535c3 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1407,10 +1407,10 @@ static void sci_submit_rx(struct sci_port *s)
 			s->desc_rx[i] = desc;
 			desc->callback = sci_dma_rx_complete;
 			desc->callback_param = s;
-			s->cookie_rx[i] = desc->tx_submit(desc);
+			s->cookie_rx[i] = dmaengine_submit(desc);
 		}
 
-		if (!desc || s->cookie_rx[i] < 0) {
+		if (!desc || dma_submit_error(s->cookie_rx[i])) {
 			if (i) {
 				async_tx_ack(s->desc_rx[0]);
 				s->cookie_rx[0] = -EINVAL;
@@ -1476,8 +1476,8 @@ static void work_fn_rx(struct work_struct *work)
 		return;
 	}
 
-	s->cookie_rx[new] = desc->tx_submit(desc);
-	if (s->cookie_rx[new] < 0) {
+	s->cookie_rx[new] = dmaengine_submit(desc);
+	if (dma_submit_error(s->cookie_rx[new])) {
 		dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
 		sci_rx_dma_release(s, true);
 		return;
@@ -1530,8 +1530,8 @@ static void work_fn_tx(struct work_struct *work)
 	desc->callback = sci_dma_tx_complete;
 	desc->callback_param = s;
 	spin_unlock_irq(&port->lock);
-	s->cookie_tx = desc->tx_submit(desc);
-	if (s->cookie_tx < 0) {
+	s->cookie_tx = dmaengine_submit(desc);
+	if (dma_submit_error(s->cookie_tx)) {
 		dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n");
 		/* switch to PIO */
 		sci_tx_dma_release(s, true);
@@ -1562,7 +1562,7 @@ static void sci_start_tx(struct uart_port *port)
 	}
 
 	if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
-	    s->cookie_tx < 0) {
+	    dma_submit_error(s->cookie_tx)) {
 		s->cookie_tx = 0;
 		schedule_work(&s->work_tx);
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 21/33] serial: sh-sci: Switch to generic DMA residue handling
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Convert the SCI driver from the SHDMAE-specific partial DMA transfer
handling to the generic dmaengine residual data framework.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Use "%u" to format "unsigned int",

v2:
  - New.
---
 drivers/tty/serial/Kconfig  |  2 +-
 drivers/tty/serial/sh-sci.c | 16 +++++++++-------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index ed299b9e63752b4e..e9abde75179d3c1a 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -743,7 +743,7 @@ config SERIAL_SH_SCI_CONSOLE
 
 config SERIAL_SH_SCI_DMA
 	bool "DMA support"
-	depends on SERIAL_SH_SCI && SH_DMAE
+	depends on SERIAL_SH_SCI && DMA_ENGINE
 
 config SERIAL_PNX8XXX
 	bool "Enable PNX8XXX SoCs' UART Support"
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 294b283f5c8535c3..049036dfb6ddf32c 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1438,6 +1438,8 @@ static void work_fn_rx(struct work_struct *work)
 	struct sci_port *s = container_of(work, struct sci_port, work_rx);
 	struct uart_port *port = &s->port;
 	struct dma_async_tx_descriptor *desc;
+	struct dma_tx_state state;
+	enum dma_status status;
 	int new;
 
 	if (s->active_rx = s->cookie_rx[0]) {
@@ -1451,21 +1453,21 @@ static void work_fn_rx(struct work_struct *work)
 	}
 	desc = s->desc_rx[new];
 
-	if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) !-	    DMA_COMPLETE) {
+	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
+	if (status != DMA_COMPLETE) {
 		/* Handle incomplete DMA receive */
 		struct dma_chan *chan = s->chan_rx;
-		struct shdma_desc *sh_desc = container_of(desc,
-					struct shdma_desc, async_tx);
 		unsigned long flags;
+		unsigned int read;
 		int count;
 
 		dmaengine_terminate_all(chan);
-		dev_dbg(port->dev, "Read %zu bytes with cookie %d\n",
-			sh_desc->partial, sh_desc->cookie);
+		read = sg_dma_len(&s->sg_rx[new]) - state.residue;
+		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
+			s->active_rx);
 
 		spin_lock_irqsave(&port->lock, flags);
-		count = sci_dma_rx_push(s, sh_desc->partial);
+		count = sci_dma_rx_push(s, read);
 		spin_unlock_irqrestore(&port->lock, flags);
 
 		if (count)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 21/33] serial: sh-sci: Switch to generic DMA residue handling
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Convert the SCI driver from the SHDMAE-specific partial DMA transfer
handling to the generic dmaengine residual data framework.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Use "%u" to format "unsigned int",

v2:
  - New.
---
 drivers/tty/serial/Kconfig  |  2 +-
 drivers/tty/serial/sh-sci.c | 16 +++++++++-------
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index ed299b9e63752b4e..e9abde75179d3c1a 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -743,7 +743,7 @@ config SERIAL_SH_SCI_CONSOLE
 
 config SERIAL_SH_SCI_DMA
 	bool "DMA support"
-	depends on SERIAL_SH_SCI && SH_DMAE
+	depends on SERIAL_SH_SCI && DMA_ENGINE
 
 config SERIAL_PNX8XXX
 	bool "Enable PNX8XXX SoCs' UART Support"
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 294b283f5c8535c3..049036dfb6ddf32c 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1438,6 +1438,8 @@ static void work_fn_rx(struct work_struct *work)
 	struct sci_port *s = container_of(work, struct sci_port, work_rx);
 	struct uart_port *port = &s->port;
 	struct dma_async_tx_descriptor *desc;
+	struct dma_tx_state state;
+	enum dma_status status;
 	int new;
 
 	if (s->active_rx == s->cookie_rx[0]) {
@@ -1451,21 +1453,21 @@ static void work_fn_rx(struct work_struct *work)
 	}
 	desc = s->desc_rx[new];
 
-	if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) !=
-	    DMA_COMPLETE) {
+	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
+	if (status != DMA_COMPLETE) {
 		/* Handle incomplete DMA receive */
 		struct dma_chan *chan = s->chan_rx;
-		struct shdma_desc *sh_desc = container_of(desc,
-					struct shdma_desc, async_tx);
 		unsigned long flags;
+		unsigned int read;
 		int count;
 
 		dmaengine_terminate_all(chan);
-		dev_dbg(port->dev, "Read %zu bytes with cookie %d\n",
-			sh_desc->partial, sh_desc->cookie);
+		read = sg_dma_len(&s->sg_rx[new]) - state.residue;
+		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
+			s->active_rx);
 
 		spin_lock_irqsave(&port->lock, flags);
-		count = sci_dma_rx_push(s, sh_desc->partial);
+		count = sci_dma_rx_push(s, read);
 		spin_unlock_irqrestore(&port->lock, flags);
 
 		if (count)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 22/33] serial: sh-sci: Stop acknowledging DMA transmit completions
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

As dmaengine_prep_slave_sg() is called with the DMA_CTRL_ACK flag set
for DMA transmit requests, there's no need to explicitly acknowledge DMA
transmit requests in the DMA transmit completion callback.

Hence remove the call to async_tx_ack(), and remove the now unused
dma_async_tx_descriptor pointer in the sci_port structure.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 049036dfb6ddf32c..1191a6c486640983 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -104,7 +104,6 @@ struct sci_port {
 	struct dma_chan			*chan_rx;
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
-	struct dma_async_tx_descriptor	*desc_tx;
 	struct dma_async_tx_descriptor	*desc_rx[2];
 	dma_cookie_t			cookie_tx;
 	dma_cookie_t			cookie_rx[2];
@@ -1285,9 +1284,6 @@ static void sci_dma_tx_complete(void *arg)
 
 	port->icount.tx += s->tx_dma_len;
 
-	async_tx_ack(s->desc_tx);
-	s->desc_tx = NULL;
-
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
 
@@ -1528,7 +1524,6 @@ static void work_fn_tx(struct work_struct *work)
 				   DMA_TO_DEVICE);
 
 	spin_lock_irq(&port->lock);
-	s->desc_tx = desc;
 	desc->callback = sci_dma_tx_complete;
 	desc->callback_param = s;
 	spin_unlock_irq(&port->lock);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 22/33] serial: sh-sci: Stop acknowledging DMA transmit completions
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

As dmaengine_prep_slave_sg() is called with the DMA_CTRL_ACK flag set
for DMA transmit requests, there's no need to explicitly acknowledge DMA
transmit requests in the DMA transmit completion callback.

Hence remove the call to async_tx_ack(), and remove the now unused
dma_async_tx_descriptor pointer in the sci_port structure.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 049036dfb6ddf32c..1191a6c486640983 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -104,7 +104,6 @@ struct sci_port {
 	struct dma_chan			*chan_rx;
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
-	struct dma_async_tx_descriptor	*desc_tx;
 	struct dma_async_tx_descriptor	*desc_rx[2];
 	dma_cookie_t			cookie_tx;
 	dma_cookie_t			cookie_rx[2];
@@ -1285,9 +1284,6 @@ static void sci_dma_tx_complete(void *arg)
 
 	port->icount.tx += s->tx_dma_len;
 
-	async_tx_ack(s->desc_tx);
-	s->desc_tx = NULL;
-
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
 
@@ -1528,7 +1524,6 @@ static void work_fn_tx(struct work_struct *work)
 				   DMA_TO_DEVICE);
 
 	spin_lock_irq(&port->lock);
-	s->desc_tx = desc;
 	desc->callback = sci_dma_tx_complete;
 	desc->callback_param = s;
 	spin_unlock_irq(&port->lock);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 23/33] serial: sh-sci: Simplify sci_submit_rx() error handling
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Simplify the error handling in sci_submit_rx() by
  - Moving it to the end of the function,
  - Just calling dmaengine_terminate_all() instead of calling
    async_tx_ack() for all already submitted descriptors.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1191a6c486640983..9c2bc0f23d3af08c 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1398,28 +1398,16 @@ static void sci_submit_rx(struct sci_port *s)
 
 		desc = dmaengine_prep_slave_sg(chan,
 			sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+		if (!desc)
+			goto fail;
 
-		if (desc) {
-			s->desc_rx[i] = desc;
-			desc->callback = sci_dma_rx_complete;
-			desc->callback_param = s;
-			s->cookie_rx[i] = dmaengine_submit(desc);
-		}
+		s->desc_rx[i] = desc;
+		desc->callback = sci_dma_rx_complete;
+		desc->callback_param = s;
+		s->cookie_rx[i] = dmaengine_submit(desc);
+		if (dma_submit_error(s->cookie_rx[i]))
+			goto fail;
 
-		if (!desc || dma_submit_error(s->cookie_rx[i])) {
-			if (i) {
-				async_tx_ack(s->desc_rx[0]);
-				s->cookie_rx[0] = -EINVAL;
-			}
-			if (desc) {
-				async_tx_ack(desc);
-				s->cookie_rx[i] = -EINVAL;
-			}
-			dev_warn(s->port.dev,
-				 "Failed to re-start Rx DMA, using PIO\n");
-			sci_rx_dma_release(s, true);
-			return;
-		}
 		dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
 			s->cookie_rx[i], i);
 	}
@@ -1427,6 +1415,18 @@ static void sci_submit_rx(struct sci_port *s)
 	s->active_rx = s->cookie_rx[0];
 
 	dma_async_issue_pending(chan);
+	return;
+
+fail:
+	if (i)
+		dmaengine_terminate_all(chan);
+	for (i = 0; i < 2; i++) {
+		s->desc_rx[i] = NULL;
+		s->cookie_rx[i] = -EINVAL;
+	}
+	s->active_rx = -EINVAL;
+	dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n");
+	sci_rx_dma_release(s, true);
 }
 
 static void work_fn_rx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 23/33] serial: sh-sci: Simplify sci_submit_rx() error handling
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Simplify the error handling in sci_submit_rx() by
  - Moving it to the end of the function,
  - Just calling dmaengine_terminate_all() instead of calling
    async_tx_ack() for all already submitted descriptors.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - No changes,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 1191a6c486640983..9c2bc0f23d3af08c 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1398,28 +1398,16 @@ static void sci_submit_rx(struct sci_port *s)
 
 		desc = dmaengine_prep_slave_sg(chan,
 			sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+		if (!desc)
+			goto fail;
 
-		if (desc) {
-			s->desc_rx[i] = desc;
-			desc->callback = sci_dma_rx_complete;
-			desc->callback_param = s;
-			s->cookie_rx[i] = dmaengine_submit(desc);
-		}
+		s->desc_rx[i] = desc;
+		desc->callback = sci_dma_rx_complete;
+		desc->callback_param = s;
+		s->cookie_rx[i] = dmaengine_submit(desc);
+		if (dma_submit_error(s->cookie_rx[i]))
+			goto fail;
 
-		if (!desc || dma_submit_error(s->cookie_rx[i])) {
-			if (i) {
-				async_tx_ack(s->desc_rx[0]);
-				s->cookie_rx[0] = -EINVAL;
-			}
-			if (desc) {
-				async_tx_ack(desc);
-				s->cookie_rx[i] = -EINVAL;
-			}
-			dev_warn(s->port.dev,
-				 "Failed to re-start Rx DMA, using PIO\n");
-			sci_rx_dma_release(s, true);
-			return;
-		}
 		dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
 			s->cookie_rx[i], i);
 	}
@@ -1427,6 +1415,18 @@ static void sci_submit_rx(struct sci_port *s)
 	s->active_rx = s->cookie_rx[0];
 
 	dma_async_issue_pending(chan);
+	return;
+
+fail:
+	if (i)
+		dmaengine_terminate_all(chan);
+	for (i = 0; i < 2; i++) {
+		s->desc_rx[i] = NULL;
+		s->cookie_rx[i] = -EINVAL;
+	}
+	s->active_rx = -EINVAL;
+	dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n");
+	sci_rx_dma_release(s, true);
 }
 
 static void work_fn_rx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 24/33] serial: sh-sci: Do not resubmit DMA descriptors
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Resubmission of DMA descriptors is explicitly forbidden by the DMA
engine API.

Hence pass DMA_CTRL_ACK to dmaengine_prep_slave_sg(), and prepare a new
DMA descriptor instead of reusing the old one.
Remove sci_port.desc_rx[], as there's no longer a need to access the
active descriptor.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Resubmission is explicitly forbidden by the DMA engine API, cfr.
    commit 06f10e2f936424496d44e5541c220845c8c55345 ("Documentation:
    dmaengine: fix the DMA_CTRL_ACK documentation"),
  - Drop now unused sci_port.desc_rx[],
  - Drop superfluous return at end of work_fn_rx(),
  - Rebased,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9c2bc0f23d3af08c..e318f002da399e70 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -104,7 +104,6 @@ struct sci_port {
 	struct dma_chan			*chan_rx;
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
-	struct dma_async_tx_descriptor	*desc_rx[2];
 	dma_cookie_t			cookie_tx;
 	dma_cookie_t			cookie_rx[2];
 	dma_cookie_t			active_rx;
@@ -1397,11 +1396,11 @@ static void sci_submit_rx(struct sci_port *s)
 		struct dma_async_tx_descriptor *desc;
 
 		desc = dmaengine_prep_slave_sg(chan,
-			sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+			sg, 1, DMA_DEV_TO_MEM,
+			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 		if (!desc)
 			goto fail;
 
-		s->desc_rx[i] = desc;
 		desc->callback = sci_dma_rx_complete;
 		desc->callback_param = s;
 		s->cookie_rx[i] = dmaengine_submit(desc);
@@ -1420,10 +1419,8 @@ static void sci_submit_rx(struct sci_port *s)
 fail:
 	if (i)
 		dmaengine_terminate_all(chan);
-	for (i = 0; i < 2; i++) {
-		s->desc_rx[i] = NULL;
+	for (i = 0; i < 2; i++)
 		s->cookie_rx[i] = -EINVAL;
-	}
 	s->active_rx = -EINVAL;
 	dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n");
 	sci_rx_dma_release(s, true);
@@ -1447,7 +1444,6 @@ static void work_fn_rx(struct work_struct *work)
 			s->active_rx);
 		return;
 	}
-	desc = s->desc_rx[new];
 
 	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
 	if (status != DMA_COMPLETE) {
@@ -1474,17 +1470,27 @@ static void work_fn_rx(struct work_struct *work)
 		return;
 	}
 
+	desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1,
+				       DMA_DEV_TO_MEM,
+				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		goto fail;
+
+	desc->callback = sci_dma_rx_complete;
+	desc->callback_param = s;
 	s->cookie_rx[new] = dmaengine_submit(desc);
-	if (dma_submit_error(s->cookie_rx[new])) {
-		dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
-		sci_rx_dma_release(s, true);
-		return;
-	}
+	if (dma_submit_error(s->cookie_rx[new]))
+		goto fail;
 
 	s->active_rx = s->cookie_rx[!new];
 
 	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
+	return;
+
+fail:
+	dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
+	sci_rx_dma_release(s, true);
 }
 
 static void work_fn_tx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 24/33] serial: sh-sci: Do not resubmit DMA descriptors
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Resubmission of DMA descriptors is explicitly forbidden by the DMA
engine API.

Hence pass DMA_CTRL_ACK to dmaengine_prep_slave_sg(), and prepare a new
DMA descriptor instead of reusing the old one.
Remove sci_port.desc_rx[], as there's no longer a need to access the
active descriptor.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Resubmission is explicitly forbidden by the DMA engine API, cfr.
    commit 06f10e2f936424496d44e5541c220845c8c55345 ("Documentation:
    dmaengine: fix the DMA_CTRL_ACK documentation"),
  - Drop now unused sci_port.desc_rx[],
  - Drop superfluous return at end of work_fn_rx(),
  - Rebased,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 9c2bc0f23d3af08c..e318f002da399e70 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -104,7 +104,6 @@ struct sci_port {
 	struct dma_chan			*chan_rx;
 
 #ifdef CONFIG_SERIAL_SH_SCI_DMA
-	struct dma_async_tx_descriptor	*desc_rx[2];
 	dma_cookie_t			cookie_tx;
 	dma_cookie_t			cookie_rx[2];
 	dma_cookie_t			active_rx;
@@ -1397,11 +1396,11 @@ static void sci_submit_rx(struct sci_port *s)
 		struct dma_async_tx_descriptor *desc;
 
 		desc = dmaengine_prep_slave_sg(chan,
-			sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
+			sg, 1, DMA_DEV_TO_MEM,
+			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 		if (!desc)
 			goto fail;
 
-		s->desc_rx[i] = desc;
 		desc->callback = sci_dma_rx_complete;
 		desc->callback_param = s;
 		s->cookie_rx[i] = dmaengine_submit(desc);
@@ -1420,10 +1419,8 @@ static void sci_submit_rx(struct sci_port *s)
 fail:
 	if (i)
 		dmaengine_terminate_all(chan);
-	for (i = 0; i < 2; i++) {
-		s->desc_rx[i] = NULL;
+	for (i = 0; i < 2; i++)
 		s->cookie_rx[i] = -EINVAL;
-	}
 	s->active_rx = -EINVAL;
 	dev_warn(s->port.dev, "Failed to re-start Rx DMA, using PIO\n");
 	sci_rx_dma_release(s, true);
@@ -1447,7 +1444,6 @@ static void work_fn_rx(struct work_struct *work)
 			s->active_rx);
 		return;
 	}
-	desc = s->desc_rx[new];
 
 	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
 	if (status != DMA_COMPLETE) {
@@ -1474,17 +1470,27 @@ static void work_fn_rx(struct work_struct *work)
 		return;
 	}
 
+	desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1,
+				       DMA_DEV_TO_MEM,
+				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		goto fail;
+
+	desc->callback = sci_dma_rx_complete;
+	desc->callback_param = s;
 	s->cookie_rx[new] = dmaengine_submit(desc);
-	if (dma_submit_error(s->cookie_rx[new])) {
-		dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
-		sci_rx_dma_release(s, true);
-		return;
-	}
+	if (dma_submit_error(s->cookie_rx[new]))
+		goto fail;
 
 	s->active_rx = s->cookie_rx[!new];
 
 	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
+	return;
+
+fail:
+	dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
+	sci_rx_dma_release(s, true);
 }
 
 static void work_fn_tx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 25/33] serial: sh-sci: Fix exclusion of work_fn_rx and sci_dma_rx_complete
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>

There is a problem when the sci_dma_rx_complete() is processed
before cancel process of work_fn_rx() completes by rx_timer_fn().
This patch locks work_fn_rx().

Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased,

v2:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index e318f002da399e70..f6ed203dde41bf83 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1433,8 +1433,10 @@ static void work_fn_rx(struct work_struct *work)
 	struct dma_async_tx_descriptor *desc;
 	struct dma_tx_state state;
 	enum dma_status status;
+	unsigned long flags;
 	int new;
 
+	spin_lock_irqsave(&port->lock, flags);
 	if (s->active_rx = s->cookie_rx[0]) {
 		new = 0;
 	} else if (s->active_rx = s->cookie_rx[1]) {
@@ -1442,14 +1444,13 @@ static void work_fn_rx(struct work_struct *work)
 	} else {
 		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
 			s->active_rx);
-		return;
+		goto out;
 	}
 
 	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
 	if (status != DMA_COMPLETE) {
 		/* Handle incomplete DMA receive */
 		struct dma_chan *chan = s->chan_rx;
-		unsigned long flags;
 		unsigned int read;
 		int count;
 
@@ -1458,16 +1459,14 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		spin_lock_irqsave(&port->lock, flags);
 		count = sci_dma_rx_push(s, read);
-		spin_unlock_irqrestore(&port->lock, flags);
 
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
 
 		sci_submit_rx(s);
 
-		return;
+		goto out;
 	}
 
 	desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1,
@@ -1486,11 +1485,14 @@ static void work_fn_rx(struct work_struct *work)
 
 	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
+out:
+	spin_unlock_irqrestore(&port->lock, flags);
 	return;
 
 fail:
 	dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
 	sci_rx_dma_release(s, true);
+	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static void work_fn_tx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 25/33] serial: sh-sci: Fix exclusion of work_fn_rx and sci_dma_rx_complete
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>

There is a problem when the sci_dma_rx_complete() is processed
before cancel process of work_fn_rx() completes by rx_timer_fn().
This patch locks work_fn_rx().

Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Rebased,

v2:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index e318f002da399e70..f6ed203dde41bf83 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1433,8 +1433,10 @@ static void work_fn_rx(struct work_struct *work)
 	struct dma_async_tx_descriptor *desc;
 	struct dma_tx_state state;
 	enum dma_status status;
+	unsigned long flags;
 	int new;
 
+	spin_lock_irqsave(&port->lock, flags);
 	if (s->active_rx == s->cookie_rx[0]) {
 		new = 0;
 	} else if (s->active_rx == s->cookie_rx[1]) {
@@ -1442,14 +1444,13 @@ static void work_fn_rx(struct work_struct *work)
 	} else {
 		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
 			s->active_rx);
-		return;
+		goto out;
 	}
 
 	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
 	if (status != DMA_COMPLETE) {
 		/* Handle incomplete DMA receive */
 		struct dma_chan *chan = s->chan_rx;
-		unsigned long flags;
 		unsigned int read;
 		int count;
 
@@ -1458,16 +1459,14 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		spin_lock_irqsave(&port->lock, flags);
 		count = sci_dma_rx_push(s, read);
-		spin_unlock_irqrestore(&port->lock, flags);
 
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
 
 		sci_submit_rx(s);
 
-		return;
+		goto out;
 	}
 
 	desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1,
@@ -1486,11 +1485,14 @@ static void work_fn_rx(struct work_struct *work)
 
 	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
+out:
+	spin_unlock_irqrestore(&port->lock, flags);
 	return;
 
 fail:
 	dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
 	sci_rx_dma_release(s, true);
+	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static void work_fn_tx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 26/33] serial: sh-sci: Fix race condition between RX worker and cleanup
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

During serial port shutdown, the DMA receive worker function may still
be called after the receive DMA cleanup function has been called.
Fix this race condition between work_fn_rx() and sci_rx_dma_release() by
acquiring the port's spinlock in sci_rx_dma_release().
This requires releasing the spinlock in work_fn_rx() before calling (any
function that may call) sci_rx_dma_release().

Terminate all active receive DMA descriptors to release them, and to
make sure no more completions come in.

Do the same in sci_tx_dma_release() for symmetry, although the serial
upper layer will no longer submit more data at this point of time.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Move invalidation of cookies inside the lock,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index f6ed203dde41bf83..35e24b726fe605d1 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1362,9 +1362,13 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 {
 	struct dma_chan *chan = s->chan_rx;
 	struct uart_port *port = &s->port;
+	unsigned long flags;
 
+	spin_lock_irqsave(&port->lock, flags);
 	s->chan_rx = NULL;
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
+	spin_unlock_irqrestore(&port->lock, flags);
+	dmaengine_terminate_all(chan);
 	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2,
 			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
 	dma_release_channel(chan);
@@ -1376,9 +1380,13 @@ static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
 {
 	struct dma_chan *chan = s->chan_tx;
 	struct uart_port *port = &s->port;
+	unsigned long flags;
 
+	spin_lock_irqsave(&port->lock, flags);
 	s->chan_tx = NULL;
 	s->cookie_tx = -EINVAL;
+	spin_unlock_irqrestore(&port->lock, flags);
+	dmaengine_terminate_all(chan);
 	dma_unmap_single(chan->device->dev, s->tx_dma_addr, UART_XMIT_SIZE,
 			 DMA_TO_DEVICE);
 	dma_release_channel(chan);
@@ -1444,7 +1452,8 @@ static void work_fn_rx(struct work_struct *work)
 	} else {
 		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
 			s->active_rx);
-		goto out;
+		spin_unlock_irqrestore(&port->lock, flags);
+		return;
 	}
 
 	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
@@ -1464,9 +1473,10 @@ static void work_fn_rx(struct work_struct *work)
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
 
-		sci_submit_rx(s);
+		spin_unlock_irqrestore(&port->lock, flags);
 
-		goto out;
+		sci_submit_rx(s);
+		return;
 	}
 
 	desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1,
@@ -1485,14 +1495,13 @@ static void work_fn_rx(struct work_struct *work)
 
 	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
-out:
 	spin_unlock_irqrestore(&port->lock, flags);
 	return;
 
 fail:
+	spin_unlock_irqrestore(&port->lock, flags);
 	dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
 	sci_rx_dma_release(s, true);
-	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static void work_fn_tx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 26/33] serial: sh-sci: Fix race condition between RX worker and cleanup
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

During serial port shutdown, the DMA receive worker function may still
be called after the receive DMA cleanup function has been called.
Fix this race condition between work_fn_rx() and sci_rx_dma_release() by
acquiring the port's spinlock in sci_rx_dma_release().
This requires releasing the spinlock in work_fn_rx() before calling (any
function that may call) sci_rx_dma_release().

Terminate all active receive DMA descriptors to release them, and to
make sure no more completions come in.

Do the same in sci_tx_dma_release() for symmetry, although the serial
upper layer will no longer submit more data at this point of time.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Move invalidation of cookies inside the lock,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index f6ed203dde41bf83..35e24b726fe605d1 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1362,9 +1362,13 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 {
 	struct dma_chan *chan = s->chan_rx;
 	struct uart_port *port = &s->port;
+	unsigned long flags;
 
+	spin_lock_irqsave(&port->lock, flags);
 	s->chan_rx = NULL;
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
+	spin_unlock_irqrestore(&port->lock, flags);
+	dmaengine_terminate_all(chan);
 	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2,
 			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
 	dma_release_channel(chan);
@@ -1376,9 +1380,13 @@ static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
 {
 	struct dma_chan *chan = s->chan_tx;
 	struct uart_port *port = &s->port;
+	unsigned long flags;
 
+	spin_lock_irqsave(&port->lock, flags);
 	s->chan_tx = NULL;
 	s->cookie_tx = -EINVAL;
+	spin_unlock_irqrestore(&port->lock, flags);
+	dmaengine_terminate_all(chan);
 	dma_unmap_single(chan->device->dev, s->tx_dma_addr, UART_XMIT_SIZE,
 			 DMA_TO_DEVICE);
 	dma_release_channel(chan);
@@ -1444,7 +1452,8 @@ static void work_fn_rx(struct work_struct *work)
 	} else {
 		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
 			s->active_rx);
-		goto out;
+		spin_unlock_irqrestore(&port->lock, flags);
+		return;
 	}
 
 	status = dmaengine_tx_status(s->chan_rx, s->active_rx, &state);
@@ -1464,9 +1473,10 @@ static void work_fn_rx(struct work_struct *work)
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
 
-		sci_submit_rx(s);
+		spin_unlock_irqrestore(&port->lock, flags);
 
-		goto out;
+		sci_submit_rx(s);
+		return;
 	}
 
 	desc = dmaengine_prep_slave_sg(s->chan_rx, &s->sg_rx[new], 1,
@@ -1485,14 +1495,13 @@ static void work_fn_rx(struct work_struct *work)
 
 	dev_dbg(port->dev, "%s: cookie %d #%d, new active cookie %d\n",
 		__func__, s->cookie_rx[new], new, s->active_rx);
-out:
 	spin_unlock_irqrestore(&port->lock, flags);
 	return;
 
 fail:
+	spin_unlock_irqrestore(&port->lock, flags);
 	dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
 	sci_rx_dma_release(s, true);
-	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static void work_fn_tx(struct work_struct *work)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 27/33] serial: sh-sci: Pass scatterlist to sci_dma_rx_push()
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Currently sci_dma_rx_push() has to find the active scatterlist itself,
but in some cases the caller already knows.

Hence let the caller pass the scatterlist, and introduce a helper to
find the active DMA request while we're at it.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Use "cookie %d" for DMA cookies,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 48 ++++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 35e24b726fe605d1..2b44004e5115fa59 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1301,24 +1301,15 @@ static void sci_dma_tx_complete(void *arg)
 }
 
 /* Locking: called with port lock held */
-static int sci_dma_rx_push(struct sci_port *s, size_t count)
+static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
+			   size_t count)
 {
 	struct uart_port *port = &s->port;
 	struct tty_port *tport = &port->state->port;
-	int i, active, room;
+	int i, room;
 
 	room = tty_buffer_request_room(tport, count);
 
-	if (s->active_rx = s->cookie_rx[0]) {
-		active = 0;
-	} else if (s->active_rx = s->cookie_rx[1]) {
-		active = 1;
-	} else {
-		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
-			s->active_rx);
-		return 0;
-	}
-
 	if (room < count)
 		dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
 			 count - room);
@@ -1326,27 +1317,41 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count)
 		return room;
 
 	for (i = 0; i < room; i++)
-		tty_insert_flip_char(tport, ((u8 *)sg_virt(&s->sg_rx[active]))[i],
-				     TTY_NORMAL);
+		tty_insert_flip_char(tport, ((u8 *)sg_virt(sg))[i], TTY_NORMAL);
 
 	port->icount.rx += room;
 
 	return room;
 }
 
+static int sci_dma_rx_find_active(struct sci_port *s)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(s->cookie_rx); i++)
+		if (s->active_rx = s->cookie_rx[i])
+			return i;
+
+	dev_err(s->port.dev, "%s: Rx cookie %d not found!\n", __func__,
+		s->active_rx);
+	return -1;
+}
+
 static void sci_dma_rx_complete(void *arg)
 {
 	struct sci_port *s = arg;
 	struct uart_port *port = &s->port;
 	unsigned long flags;
-	int count;
+	int active, count = 0;
 
 	dev_dbg(port->dev, "%s(%d) active cookie %d\n", __func__, port->line,
 		s->active_rx);
 
 	spin_lock_irqsave(&port->lock, flags);
 
-	count = sci_dma_rx_push(s, s->buf_len_rx);
+	active = sci_dma_rx_find_active(s);
+	if (active >= 0)
+		count = sci_dma_rx_push(s, &s->sg_rx[active], s->buf_len_rx);
 
 	mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
 
@@ -1445,13 +1450,8 @@ static void work_fn_rx(struct work_struct *work)
 	int new;
 
 	spin_lock_irqsave(&port->lock, flags);
-	if (s->active_rx = s->cookie_rx[0]) {
-		new = 0;
-	} else if (s->active_rx = s->cookie_rx[1]) {
-		new = 1;
-	} else {
-		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
-			s->active_rx);
+	new = sci_dma_rx_find_active(s);
+	if (new < 0) {
 		spin_unlock_irqrestore(&port->lock, flags);
 		return;
 	}
@@ -1468,7 +1468,7 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		count = sci_dma_rx_push(s, read);
+		count = sci_dma_rx_push(s, &s->sg_rx[new], read);
 
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 27/33] serial: sh-sci: Pass scatterlist to sci_dma_rx_push()
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Currently sci_dma_rx_push() has to find the active scatterlist itself,
but in some cases the caller already knows.

Hence let the caller pass the scatterlist, and introduce a helper to
find the active DMA request while we're at it.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Use "cookie %d" for DMA cookies,

v2:
  - New.
---
 drivers/tty/serial/sh-sci.c | 48 ++++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 35e24b726fe605d1..2b44004e5115fa59 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1301,24 +1301,15 @@ static void sci_dma_tx_complete(void *arg)
 }
 
 /* Locking: called with port lock held */
-static int sci_dma_rx_push(struct sci_port *s, size_t count)
+static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
+			   size_t count)
 {
 	struct uart_port *port = &s->port;
 	struct tty_port *tport = &port->state->port;
-	int i, active, room;
+	int i, room;
 
 	room = tty_buffer_request_room(tport, count);
 
-	if (s->active_rx == s->cookie_rx[0]) {
-		active = 0;
-	} else if (s->active_rx == s->cookie_rx[1]) {
-		active = 1;
-	} else {
-		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
-			s->active_rx);
-		return 0;
-	}
-
 	if (room < count)
 		dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
 			 count - room);
@@ -1326,27 +1317,41 @@ static int sci_dma_rx_push(struct sci_port *s, size_t count)
 		return room;
 
 	for (i = 0; i < room; i++)
-		tty_insert_flip_char(tport, ((u8 *)sg_virt(&s->sg_rx[active]))[i],
-				     TTY_NORMAL);
+		tty_insert_flip_char(tport, ((u8 *)sg_virt(sg))[i], TTY_NORMAL);
 
 	port->icount.rx += room;
 
 	return room;
 }
 
+static int sci_dma_rx_find_active(struct sci_port *s)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(s->cookie_rx); i++)
+		if (s->active_rx == s->cookie_rx[i])
+			return i;
+
+	dev_err(s->port.dev, "%s: Rx cookie %d not found!\n", __func__,
+		s->active_rx);
+	return -1;
+}
+
 static void sci_dma_rx_complete(void *arg)
 {
 	struct sci_port *s = arg;
 	struct uart_port *port = &s->port;
 	unsigned long flags;
-	int count;
+	int active, count = 0;
 
 	dev_dbg(port->dev, "%s(%d) active cookie %d\n", __func__, port->line,
 		s->active_rx);
 
 	spin_lock_irqsave(&port->lock, flags);
 
-	count = sci_dma_rx_push(s, s->buf_len_rx);
+	active = sci_dma_rx_find_active(s);
+	if (active >= 0)
+		count = sci_dma_rx_push(s, &s->sg_rx[active], s->buf_len_rx);
 
 	mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
 
@@ -1445,13 +1450,8 @@ static void work_fn_rx(struct work_struct *work)
 	int new;
 
 	spin_lock_irqsave(&port->lock, flags);
-	if (s->active_rx == s->cookie_rx[0]) {
-		new = 0;
-	} else if (s->active_rx == s->cookie_rx[1]) {
-		new = 1;
-	} else {
-		dev_err(port->dev, "%s: Rx cookie %d not found!\n", __func__,
-			s->active_rx);
+	new = sci_dma_rx_find_active(s);
+	if (new < 0) {
 		spin_unlock_irqrestore(&port->lock, flags);
 		return;
 	}
@@ -1468,7 +1468,7 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		count = sci_dma_rx_push(s, read);
+		count = sci_dma_rx_push(s, &s->sg_rx[new], read);
 
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 28/33] serial: sh-sci: Use tty_insert_flip_string() for DMA receive
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Switch from using tty_buffer_request_room() and looping over
tty_insert_flip_char() to tty_insert_flip_string().
Keep track of buffer overruns in the icount structure, like
serial_core.c does.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 2b44004e5115fa59..57b1cc1da67d228a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1306,22 +1306,18 @@ static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
 {
 	struct uart_port *port = &s->port;
 	struct tty_port *tport = &port->state->port;
-	int i, room;
+	int copied;
 
-	room = tty_buffer_request_room(tport, count);
-
-	if (room < count)
+	copied = tty_insert_flip_string(tport, sg_virt(sg), count);
+	if (copied < count) {
 		dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
-			 count - room);
-	if (!room)
-		return room;
-
-	for (i = 0; i < room; i++)
-		tty_insert_flip_char(tport, ((u8 *)sg_virt(sg))[i], TTY_NORMAL);
+			 count - copied);
+		port->icount.buf_overrun++;
+	}
 
-	port->icount.rx += room;
+	port->icount.rx += copied;
 
-	return room;
+	return copied;
 }
 
 static int sci_dma_rx_find_active(struct sci_port *s)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 28/33] serial: sh-sci: Use tty_insert_flip_string() for DMA receive
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

Switch from using tty_buffer_request_room() and looping over
tty_insert_flip_char() to tty_insert_flip_string().
Keep track of buffer overruns in the icount structure, like
serial_core.c does.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 2b44004e5115fa59..57b1cc1da67d228a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1306,22 +1306,18 @@ static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
 {
 	struct uart_port *port = &s->port;
 	struct tty_port *tport = &port->state->port;
-	int i, room;
+	int copied;
 
-	room = tty_buffer_request_room(tport, count);
-
-	if (room < count)
+	copied = tty_insert_flip_string(tport, sg_virt(sg), count);
+	if (copied < count) {
 		dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
-			 count - room);
-	if (!room)
-		return room;
-
-	for (i = 0; i < room; i++)
-		tty_insert_flip_char(tport, ((u8 *)sg_virt(sg))[i], TTY_NORMAL);
+			 count - copied);
+		port->icount.buf_overrun++;
+	}
 
-	port->icount.rx += room;
+	port->icount.rx += copied;
 
-	return room;
+	return copied;
 }
 
 static int sci_dma_rx_find_active(struct sci_port *s)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 29/33] serial: sh-sci: Use incrementing pointers instead of stack array
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

There's no need to keep all buffer and DMA pointers on the stack.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Extracted from "[PATCH/RFC v2 28/29] serial: sh-sci: Add (H)SCIF DMA
    support".
---
 drivers/tty/serial/sh-sci.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 57b1cc1da67d228a..681e52a087c2e821 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1734,18 +1734,16 @@ static void sci_request_dma(struct uart_port *port)
 	chan = dma_request_channel(mask, filter, param);
 	dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
 	if (chan) {
-		dma_addr_t dma[2];
-		void *buf[2];
-		int i;
+		unsigned int i;
+		dma_addr_t dma;
+		void *buf;
 
 		s->chan_rx = chan;
 
 		s->buf_len_rx = 2 * max_t(size_t, 16, port->fifosize);
-		buf[0] = dma_alloc_coherent(chan->device->dev,
-					    s->buf_len_rx * 2, &dma[0],
-					    GFP_KERNEL);
-
-		if (!buf[0]) {
+		buf = dma_alloc_coherent(chan->device->dev, s->buf_len_rx * 2,
+					 &dma, GFP_KERNEL);
+		if (!buf) {
 			dev_warn(port->dev,
 				 "Failed to allocate Rx dma buffer, using PIO\n");
 			dma_release_channel(chan);
@@ -1754,16 +1752,16 @@ static void sci_request_dma(struct uart_port *port)
 			return;
 		}
 
-		buf[1] = buf[0] + s->buf_len_rx;
-		dma[1] = dma[0] + s->buf_len_rx;
-
 		for (i = 0; i < 2; i++) {
 			struct scatterlist *sg = &s->sg_rx[i];
 
 			sg_init_table(sg, 1);
-			sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
-				    (uintptr_t)buf[i] & ~PAGE_MASK);
-			sg_dma_address(sg) = dma[i];
+			sg_set_page(sg, virt_to_page(buf), s->buf_len_rx,
+				    (uintptr_t)buf & ~PAGE_MASK);
+			sg_dma_address(sg) = dma;
+
+			buf += s->buf_len_rx;
+			dma += s->buf_len_rx;
 		}
 
 		INIT_WORK(&s->work_rx, work_fn_rx);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 29/33] serial: sh-sci: Use incrementing pointers instead of stack array
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

There's no need to keep all buffer and DMA pointers on the stack.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Extracted from "[PATCH/RFC v2 28/29] serial: sh-sci: Add (H)SCIF DMA
    support".
---
 drivers/tty/serial/sh-sci.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 57b1cc1da67d228a..681e52a087c2e821 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1734,18 +1734,16 @@ static void sci_request_dma(struct uart_port *port)
 	chan = dma_request_channel(mask, filter, param);
 	dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
 	if (chan) {
-		dma_addr_t dma[2];
-		void *buf[2];
-		int i;
+		unsigned int i;
+		dma_addr_t dma;
+		void *buf;
 
 		s->chan_rx = chan;
 
 		s->buf_len_rx = 2 * max_t(size_t, 16, port->fifosize);
-		buf[0] = dma_alloc_coherent(chan->device->dev,
-					    s->buf_len_rx * 2, &dma[0],
-					    GFP_KERNEL);
-
-		if (!buf[0]) {
+		buf = dma_alloc_coherent(chan->device->dev, s->buf_len_rx * 2,
+					 &dma, GFP_KERNEL);
+		if (!buf) {
 			dev_warn(port->dev,
 				 "Failed to allocate Rx dma buffer, using PIO\n");
 			dma_release_channel(chan);
@@ -1754,16 +1752,16 @@ static void sci_request_dma(struct uart_port *port)
 			return;
 		}
 
-		buf[1] = buf[0] + s->buf_len_rx;
-		dma[1] = dma[0] + s->buf_len_rx;
-
 		for (i = 0; i < 2; i++) {
 			struct scatterlist *sg = &s->sg_rx[i];
 
 			sg_init_table(sg, 1);
-			sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
-				    (uintptr_t)buf[i] & ~PAGE_MASK);
-			sg_dma_address(sg) = dma[i];
+			sg_set_page(sg, virt_to_page(buf), s->buf_len_rx,
+				    (uintptr_t)buf & ~PAGE_MASK);
+			sg_dma_address(sg) = dma;
+
+			buf += s->buf_len_rx;
+			dma += s->buf_len_rx;
 		}
 
 		INIT_WORK(&s->work_rx, work_fn_rx);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 30/33] serial: sh-sci: Fix NULL pointer dereference if HIGHMEM is enabled
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

This patch fixes an issue that this driver causes a NULL pointer
dereference in the following conditions:
 - CONFIG_HIGHMEM and CONFIG_SERIAL_SH_SCI_DMA are enabled
 - This driver runs on the sci_dma_rx_push()

This issue was caused by virt_to_page(buf) in the sci_request_dma()
because this driver didn't check if the "buf" was valid or not.  So,
this patch uses the "buf" from dma_alloc_coherent() as is, not page.

This patch also fixes a WARNING issue in sci_rx_dma_release():

    WARNING: CPU: 0 PID: 1328 at lib/dma-debug.c:1125 check_unmap+0x444/0x848()
    rcar-dmac e6700000.dma-controller: DMA-API: device driver frees DMA memory with different CPU address [device address=0x000000006dd89000] [sized bytes] [cpu alloc address=0x000000016189c000] [cpu free address=0x0000000080000000]

    WARNING: CPU: 1 PID: 1 at drivers/base/dma-mapping.c:334 dma_common_free_remap+0x48/0x6c()
    trying to free invalid coherent area:   (null)

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
[geert] Rebased
[geert] Reworded
[geert] Dropped .rx_chunk, as it's always identical to .rx_buf[0]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 681e52a087c2e821..70e16f402e3108f4 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -110,6 +110,7 @@ struct sci_port {
 	dma_addr_t			tx_dma_addr;
 	unsigned int			tx_dma_len;
 	struct scatterlist		sg_rx[2];
+	void				*rx_buf[2];
 	size_t				buf_len_rx;
 	struct sh_dmae_slave		param_tx;
 	struct sh_dmae_slave		param_rx;
@@ -1301,14 +1302,13 @@ static void sci_dma_tx_complete(void *arg)
 }
 
 /* Locking: called with port lock held */
-static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
-			   size_t count)
+static int sci_dma_rx_push(struct sci_port *s, void *buf, size_t count)
 {
 	struct uart_port *port = &s->port;
 	struct tty_port *tport = &port->state->port;
 	int copied;
 
-	copied = tty_insert_flip_string(tport, sg_virt(sg), count);
+	copied = tty_insert_flip_string(tport, buf, count);
 	if (copied < count) {
 		dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
 			 count - copied);
@@ -1347,7 +1347,7 @@ static void sci_dma_rx_complete(void *arg)
 
 	active = sci_dma_rx_find_active(s);
 	if (active >= 0)
-		count = sci_dma_rx_push(s, &s->sg_rx[active], s->buf_len_rx);
+		count = sci_dma_rx_push(s, s->rx_buf[active], s->buf_len_rx);
 
 	mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
 
@@ -1370,8 +1370,8 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
 	spin_unlock_irqrestore(&port->lock, flags);
 	dmaengine_terminate_all(chan);
-	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2,
-			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2, s->rx_buf[0],
+			  sg_dma_address(&s->sg_rx[0]));
 	dma_release_channel(chan);
 	if (enable_pio)
 		sci_start_rx(port);
@@ -1464,7 +1464,7 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		count = sci_dma_rx_push(s, &s->sg_rx[new], read);
+		count = sci_dma_rx_push(s, s->rx_buf[new], read);
 
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
@@ -1756,9 +1756,9 @@ static void sci_request_dma(struct uart_port *port)
 			struct scatterlist *sg = &s->sg_rx[i];
 
 			sg_init_table(sg, 1);
-			sg_set_page(sg, virt_to_page(buf), s->buf_len_rx,
-				    (uintptr_t)buf & ~PAGE_MASK);
+			s->rx_buf[i] = buf;
 			sg_dma_address(sg) = dma;
+			sg->length = s->buf_len_rx;
 
 			buf += s->buf_len_rx;
 			dma += s->buf_len_rx;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 30/33] serial: sh-sci: Fix NULL pointer dereference if HIGHMEM is enabled
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

This patch fixes an issue that this driver causes a NULL pointer
dereference in the following conditions:
 - CONFIG_HIGHMEM and CONFIG_SERIAL_SH_SCI_DMA are enabled
 - This driver runs on the sci_dma_rx_push()

This issue was caused by virt_to_page(buf) in the sci_request_dma()
because this driver didn't check if the "buf" was valid or not.  So,
this patch uses the "buf" from dma_alloc_coherent() as is, not page.

This patch also fixes a WARNING issue in sci_rx_dma_release():

    WARNING: CPU: 0 PID: 1328 at lib/dma-debug.c:1125 check_unmap+0x444/0x848()
    rcar-dmac e6700000.dma-controller: DMA-API: device driver frees DMA memory with different CPU address [device address=0x000000006dd89000] [size=64 bytes] [cpu alloc address=0x000000016189c000] [cpu free address=0x0000000080000000]

    WARNING: CPU: 1 PID: 1 at drivers/base/dma-mapping.c:334 dma_common_free_remap+0x48/0x6c()
    trying to free invalid coherent area:   (null)

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
[geert] Rebased
[geert] Reworded
[geert] Dropped .rx_chunk, as it's always identical to .rx_buf[0]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 681e52a087c2e821..70e16f402e3108f4 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -110,6 +110,7 @@ struct sci_port {
 	dma_addr_t			tx_dma_addr;
 	unsigned int			tx_dma_len;
 	struct scatterlist		sg_rx[2];
+	void				*rx_buf[2];
 	size_t				buf_len_rx;
 	struct sh_dmae_slave		param_tx;
 	struct sh_dmae_slave		param_rx;
@@ -1301,14 +1302,13 @@ static void sci_dma_tx_complete(void *arg)
 }
 
 /* Locking: called with port lock held */
-static int sci_dma_rx_push(struct sci_port *s, struct scatterlist *sg,
-			   size_t count)
+static int sci_dma_rx_push(struct sci_port *s, void *buf, size_t count)
 {
 	struct uart_port *port = &s->port;
 	struct tty_port *tport = &port->state->port;
 	int copied;
 
-	copied = tty_insert_flip_string(tport, sg_virt(sg), count);
+	copied = tty_insert_flip_string(tport, buf, count);
 	if (copied < count) {
 		dev_warn(port->dev, "Rx overrun: dropping %zu bytes\n",
 			 count - copied);
@@ -1347,7 +1347,7 @@ static void sci_dma_rx_complete(void *arg)
 
 	active = sci_dma_rx_find_active(s);
 	if (active >= 0)
-		count = sci_dma_rx_push(s, &s->sg_rx[active], s->buf_len_rx);
+		count = sci_dma_rx_push(s, s->rx_buf[active], s->buf_len_rx);
 
 	mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
 
@@ -1370,8 +1370,8 @@ static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
 	s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
 	spin_unlock_irqrestore(&port->lock, flags);
 	dmaengine_terminate_all(chan);
-	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2,
-			  sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
+	dma_free_coherent(chan->device->dev, s->buf_len_rx * 2, s->rx_buf[0],
+			  sg_dma_address(&s->sg_rx[0]));
 	dma_release_channel(chan);
 	if (enable_pio)
 		sci_start_rx(port);
@@ -1464,7 +1464,7 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		count = sci_dma_rx_push(s, &s->sg_rx[new], read);
+		count = sci_dma_rx_push(s, s->rx_buf[new], read);
 
 		if (count)
 			tty_flip_buffer_push(&port->state->port);
@@ -1756,9 +1756,9 @@ static void sci_request_dma(struct uart_port *port)
 			struct scatterlist *sg = &s->sg_rx[i];
 
 			sg_init_table(sg, 1);
-			sg_set_page(sg, virt_to_page(buf), s->buf_len_rx,
-				    (uintptr_t)buf & ~PAGE_MASK);
+			s->rx_buf[i] = buf;
 			sg_dma_address(sg) = dma;
+			sg->length = s->buf_len_rx;
 
 			buf += s->buf_len_rx;
 			dma += s->buf_len_rx;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 31/33] serial: sh-sci: Don't call sci_rx_interrupt() on error when using DMA
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

The error handler calls sci_rx_interrupt() to drain the receive FIFO if
an error condition happens.

However, if DMA is enabled on SCIFA or SCIFB, this will call
disable_irq_nosync() twice. Due to this imbalance, the receive interrupt
will never be re-enabled, and reception stops forever.

To fix this, restrict draining the FIFO to PIO mode, and just call
sci_receive_chars() directly.

Inspired by a patch from Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com>.

Reported-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 70e16f402e3108f4..82456fb09138dc2a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -993,6 +993,7 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 {
 	struct uart_port *port = ptr;
+	struct sci_port *s = to_sci_port(port);
 
 	/* Handle errors */
 	if (port->type = PORT_SCI) {
@@ -1003,7 +1004,8 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 		}
 	} else {
 		sci_handle_fifo_overrun(port);
-		sci_rx_interrupt(irq, ptr);
+		if (!s->chan_rx)
+			sci_receive_chars(ptr);
 	}
 
 	sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 31/33] serial: sh-sci: Don't call sci_rx_interrupt() on error when using DMA
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

The error handler calls sci_rx_interrupt() to drain the receive FIFO if
an error condition happens.

However, if DMA is enabled on SCIFA or SCIFB, this will call
disable_irq_nosync() twice. Due to this imbalance, the receive interrupt
will never be re-enabled, and reception stops forever.

To fix this, restrict draining the FIFO to PIO mode, and just call
sci_receive_chars() directly.

Inspired by a patch from Yoshihiro Shimoda
<yoshihiro.shimoda.uh@renesas.com>.

Reported-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 70e16f402e3108f4..82456fb09138dc2a 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -993,6 +993,7 @@ static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 {
 	struct uart_port *port = ptr;
+	struct sci_port *s = to_sci_port(port);
 
 	/* Handle errors */
 	if (port->type == PORT_SCI) {
@@ -1003,7 +1004,8 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 		}
 	} else {
 		sci_handle_fifo_overrun(port);
-		sci_rx_interrupt(irq, ptr);
+		if (!s->chan_rx)
+			sci_receive_chars(ptr);
 	}
 
 	sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 32/33] serial: sh-sci: Don't kick tx in sci_er_interrupt() when using DMA
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

If CONFIG_SERIAL_SH_SCI_DMA is enabled, the driver doesn't enable TIE
on SCIF or HSCIF. However, this driver may call sci_tx_interrupt()
in sci_er_interrupt(). After that, the driver cannot care of the
interrupt, and then "irq 109: nobody cared" happens on r8a7791/koelsch
board. This patch fixes the issue.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
[geert] Keep kicking tx when using PIO
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 82456fb09138dc2a..ffcbf6eaf5f98723 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1011,7 +1011,8 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 	sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 
 	/* Kick the transmission */
-	sci_tx_interrupt(irq, ptr);
+	if (!s->chan_tx)
+		sci_tx_interrupt(irq, ptr);
 
 	return IRQ_HANDLED;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 32/33] serial: sh-sci: Don't kick tx in sci_er_interrupt() when using DMA
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

From: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>

If CONFIG_SERIAL_SH_SCI_DMA is enabled, the driver doesn't enable TIE
on SCIF or HSCIF. However, this driver may call sci_tx_interrupt()
in sci_er_interrupt(). After that, the driver cannot care of the
interrupt, and then "irq 109: nobody cared" happens on r8a7791/koelsch
board. This patch fixes the issue.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
[geert] Keep kicking tx when using PIO
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - Assimilated into my series.
---
 drivers/tty/serial/sh-sci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 82456fb09138dc2a..ffcbf6eaf5f98723 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1011,7 +1011,8 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr)
 	sci_clear_SCxSR(port, SCxSR_ERROR_CLEAR(port));
 
 	/* Kick the transmission */
-	sci_tx_interrupt(irq, ptr);
+	if (!s->chan_tx)
+		sci_tx_interrupt(irq, ptr);
 
 	return IRQ_HANDLED;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 33/33] serial: sh-sci: Don't call sci_dma_rx_push() if no data has arrived
  2015-08-21 18:02 ` Geert Uytterhoeven
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

On receive DMA time-out, avoid calling sci_dma_rx_push() if no data was
transferred by the timed out DMA request.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ffcbf6eaf5f98723..d8b73e791a554823 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1467,10 +1467,11 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		count = sci_dma_rx_push(s, s->rx_buf[new], read);
-
-		if (count)
-			tty_flip_buffer_push(&port->state->port);
+		if (read) {
+			count = sci_dma_rx_push(s, s->rx_buf[new], read);
+			if (count)
+				tty_flip_buffer_push(&port->state->port);
+		}
 
 		spin_unlock_irqrestore(&port->lock, flags);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v3 33/33] serial: sh-sci: Don't call sci_dma_rx_push() if no data has arrived
@ 2015-08-21 18:02   ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2015-08-21 18:02 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Magnus Damm, Yoshihiro Shimoda, Laurent Pinchart,
	Nobuhiro Iwamatsu, Yoshihiro Kaneko, Kazuya Mizuguchi,
	Koji Matsuoka, Wolfram Sang, Guennadi Liakhovetski, linux-serial,
	linux-sh, Geert Uytterhoeven

On receive DMA time-out, avoid calling sci_dma_rx_push() if no data was
transferred by the timed out DMA request.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
v3:
  - New.
---
 drivers/tty/serial/sh-sci.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index ffcbf6eaf5f98723..d8b73e791a554823 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1467,10 +1467,11 @@ static void work_fn_rx(struct work_struct *work)
 		dev_dbg(port->dev, "Read %u bytes with cookie %d\n", read,
 			s->active_rx);
 
-		count = sci_dma_rx_push(s, s->rx_buf[new], read);
-
-		if (count)
-			tty_flip_buffer_push(&port->state->port);
+		if (read) {
+			count = sci_dma_rx_push(s, s->rx_buf[new], read);
+			if (count)
+				tty_flip_buffer_push(&port->state->port);
+		}
 
 		spin_unlock_irqrestore(&port->lock, flags);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2015-08-21 18:02 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-21 18:02 [PATCH v3 00/33] serial: sh-sci: Miscellaneous and DMA Improvements Geert Uytterhoeven
2015-08-21 18:02 ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 01/33] serial: sh-sci: Replace buggy big #ifdef by runtime logic Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 02/33] serial: sh-sci: Prevent compiler warnings on 64-bit Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 03/33] serial: sh-sci: Correct SCIF_ERROR_CLEAR for plain SCIF Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 04/33] serial: sh-sci: Use SCIF_DR instead of hardcoded literal 1 Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 05/33] serial: sh-sci: Use SCSMR_CKS instead of hardcoded literal 3 Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 06/33] serial: sh-sci: Drop path in reference to serial_core.c Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 07/33] serial: sh-sci: Improve readability of sampling rate configuration Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 08/33] serial: sh-sci: Make sci_irq_desc[] const Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 09/33] serial: sh-sci: Make sci_regmap[] const Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 10/33] serial: sh-sci: Remove useless memory allocation failure printks Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 11/33] serial: sh-sci: Remove bogus sci_handle_fifo_overrun() call on (H)SCIF Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 12/33] serial: sh-sci: Return IRQ_HANDLED when overrun if detected Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 13/33] serial: sh-sci: Improve DMA error messages Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 14/33] serial: sh-sci: Improve comments for DMA timeout calculation Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 15/33] serial: sh-sci: Handle DMA init failures inside sci_request_dma() Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 16/33] serial: sh-sci: Use correct device for DMA mapping with IOMMU Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 17/33] serial: sh-sci: Use min_t()/max_t() instead of casts Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 18/33] serial: sh-sci: Switch to dma_map_single() for DMA transmission Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 19/33] serial: sh-sci: Fix TX buffer mapping leak Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 20/33] serial: sh-sci: Use DMA submission helpers instead of open-coding Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 21/33] serial: sh-sci: Switch to generic DMA residue handling Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 22/33] serial: sh-sci: Stop acknowledging DMA transmit completions Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 23/33] serial: sh-sci: Simplify sci_submit_rx() error handling Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 24/33] serial: sh-sci: Do not resubmit DMA descriptors Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 25/33] serial: sh-sci: Fix exclusion of work_fn_rx and sci_dma_rx_complete Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 26/33] serial: sh-sci: Fix race condition between RX worker and cleanup Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 27/33] serial: sh-sci: Pass scatterlist to sci_dma_rx_push() Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 28/33] serial: sh-sci: Use tty_insert_flip_string() for DMA receive Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 29/33] serial: sh-sci: Use incrementing pointers instead of stack array Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 30/33] serial: sh-sci: Fix NULL pointer dereference if HIGHMEM is enabled Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 31/33] serial: sh-sci: Don't call sci_rx_interrupt() on error when using DMA Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 32/33] serial: sh-sci: Don't kick tx in sci_er_interrupt() " Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven
2015-08-21 18:02 ` [PATCH v3 33/33] serial: sh-sci: Don't call sci_dma_rx_push() if no data has arrived Geert Uytterhoeven
2015-08-21 18:02   ` Geert Uytterhoeven

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.