* [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.