From: bigeasy@linutronix.de (Sebastian Andrzej Siewior) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 10/16] tty: serial: 8250_dma: optimize the xmit path due to UART_BUG_DMA_TX Date: Wed, 10 Sep 2014 21:30:05 +0200 Message-ID: <1410377411-26656-11-git-send-email-bigeasy@linutronix.de> (raw) In-Reply-To: <1410377411-26656-1-git-send-email-bigeasy@linutronix.de> Due to UART_BUG_DMA_TX the am335x has to put the first one byte into the TX FIFO to get things going. If we get to serial8250_tx_dma() via __dma_tx_complete() then the DMA engine just finished and the FIFO is full and we can't put the first byte into the TX FIFO as kick start so we leave with THRI enabled. The result is that we end up manually filling the FIFO. We could be a little better at this and try DMA once again. If it works, it works and if not we do it manually. v8?v9: - fix receiving THRI interrupts after DMA operation completed and the next one would fail (length < 4 bytes). - while at it makes sure we fail with an error for zero lenght transfers with the TX bug or runtime PM - make sure THRI is always cleared after DMA is fired. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- drivers/tty/serial/8250/8250_core.c | 17 +++++++++++++++-- drivers/tty/serial/8250/8250_dma.c | 27 +++++++++++++++++++-------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 39b1c7318f17..660d19771bbe 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1599,9 +1599,22 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) serial8250_modem_status(up); if ((!up->dma || (up->dma && up->dma->tx_err)) && (status & UART_LSR_THRE)) { - serial8250_tx_chars(up); - } + if (!up->dma) { + serial8250_tx_chars(up); + } else { + if (uart_tx_stopped(&up->port) || + uart_circ_empty(&up->port.state->xmit)) { + up->dma->tx_err = 0; + serial8250_tx_chars(up); + } else { + /* try again due to UART_BUG_DMA_TX+full fifo */ + dma_err = serial8250_tx_dma(up); + if (dma_err) + serial8250_tx_chars(up); + } + } + } spin_unlock_irqrestore(&port->lock, flags); return 1; } diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 48dc57aad0dd..e836d128e63a 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -86,12 +86,23 @@ int serial8250_tx_dma(struct uart_8250_port *p) unsigned int skip_byte = 0; int ret; - if (uart_tx_stopped(&p->port) || dma->tx_running || - uart_circ_empty(xmit)) + if (dma->tx_running) return 0; + if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) { - dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); + /* + * Even if no data, we need to return an error for the two cases + * below so serial8250_tx_chars() is invoked and properly clears + * THRI and/or runtime suspend. + */ + if (dma->tx_err || p->capabilities & UART_CAP_RPM) { + ret = -EBUSY; + goto err; + } + return 0; + } + dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); if (p->bugs & UART_BUG_DMA_TX) { u8 tx_lvl; @@ -142,12 +153,12 @@ int serial8250_tx_dma(struct uart_8250_port *p) UART_XMIT_SIZE, DMA_TO_DEVICE); dma_async_issue_pending(dma->txchan); - if (dma->tx_err) { + if (dma->tx_err) dma->tx_err = 0; - if (p->ier & UART_IER_THRI) { - p->ier &= ~UART_IER_THRI; - serial_out(p, UART_IER, p->ier); - } + + if (p->ier & UART_IER_THRI) { + p->ier &= ~UART_IER_THRI; + serial_out(p, UART_IER, p->ier); } if (skip_byte) serial_out(p, UART_TX, xmit->buf[xmit->tail]); -- 2.1.0
next prev parent reply index Thread overview: 97+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-09-10 19:29 [PATCH 00/16 v9] omap 8250 based uart + DMA Sebastian Andrzej Siewior 2014-09-10 19:29 ` [PATCH 01/16] tty: serial: 8250_core: allow to set ->throttle / ->unthrottle callbacks Sebastian Andrzej Siewior 2014-09-10 19:29 ` [PATCH 02/16] tty: serial: 8250_core: add run time pm Sebastian Andrzej Siewior 2014-09-29 9:46 ` Frans Klaver 2014-09-29 13:39 ` Sebastian Andrzej Siewior 2014-09-10 19:29 ` [PATCH 03/16] tty: serial: 8250_core: read only RX if there is something in the FIFO Sebastian Andrzej Siewior 2015-02-09 13:34 ` Nicolas Schichan 2015-02-09 23:34 ` Peter Hurley 2015-02-10 9:32 ` Sebastian Andrzej Siewior 2015-02-10 12:04 ` Nicolas Schichan 2015-02-10 17:46 ` Peter Hurley 2015-02-11 20:01 ` Peter Hurley 2015-02-11 20:03 ` Tony Lindgren 2015-02-11 20:42 ` Peter Hurley 2015-02-12 8:45 ` Sebastian Andrzej Siewior 2015-02-12 9:40 ` Russell King - ARM Linux 2015-02-12 16:32 ` Peter Hurley 2015-02-12 19:23 ` Sebastian Andrzej Siewior 2015-02-12 19:55 ` Peter Hurley 2015-02-12 20:34 ` Sebastian Andrzej Siewior 2015-02-13 18:51 ` Sebastian Andrzej Siewior 2015-02-13 23:15 ` Russell King - ARM Linux 2015-02-15 17:32 ` [PATCH] serial: 8250: Revert "tty: serial: 8250_core: read only RX if there is something in the FIFO" Sebastian Andrzej Siewior 2015-05-12 20:25 ` Tony Lindgren 2014-09-10 19:29 ` [PATCH 04/16] tty: serial: 8250_core: use the ->line argument as a hint in serial8250_find_match_or_unused() Sebastian Andrzej Siewior 2014-09-10 19:30 ` [PATCH 05/16] tty: serial: 8250_core: remove UART_IER_RDI in serial8250_stop_rx() Sebastian Andrzej Siewior 2014-09-11 11:19 ` Heikki Krogerus 2014-09-10 19:30 ` [PATCH 06/16] tty: serial: Add 8250-core based omap driver Sebastian Andrzej Siewior 2014-09-11 11:57 ` Peter Hurley 2014-09-16 17:01 ` Sebastian Andrzej Siewior 2014-09-29 9:38 ` Frans Klaver 2014-09-29 13:27 ` Sebastian Andrzej Siewior 2014-09-29 13:34 ` Frans Klaver 2014-09-10 19:30 ` [PATCH 07/16] tty: serial: 8250_dma: handle error on TX submit Sebastian Andrzej Siewior 2014-09-10 19:30 ` [PATCH 08/16] tty: serial: 8250_dma: enqueue RX dma again on completion Sebastian Andrzej Siewior 2014-09-10 19:30 ` [PATCH 09/16] tty: serial: 8250_dma: Add a TX trigger workaround for AM33xx Sebastian Andrzej Siewior 2014-09-11 11:17 ` Heikki Krogerus 2014-09-11 11:42 ` Sebastian Andrzej Siewior 2014-09-11 12:32 ` Peter Hurley 2014-09-11 12:50 ` Sebastian Andrzej Siewior 2014-09-11 14:35 ` Peter Hurley 2014-09-15 17:01 ` Sebastian Andrzej Siewior 2014-09-16 16:55 ` Sebastian Andrzej Siewior 2014-09-17 12:20 ` Peter Hurley 2014-09-17 16:25 ` Sebastian Andrzej Siewior 2014-09-29 16:15 ` Sebastian Andrzej Siewior 2014-09-11 15:11 ` Frans Klaver 2014-09-11 16:04 ` Sebastian Andrzej Siewior 2014-09-11 17:04 ` Frans Klaver 2014-09-12 7:23 ` Sebastian Andrzej Siewior [not found] ` <20140912094010.GE28458@ci00147.xsens-tech.local> 2014-09-12 9:51 ` Sebastian Andrzej Siewior 2014-09-12 10:28 ` Frans Klaver 2014-09-15 16:42 ` Sebastian Andrzej Siewior 2014-09-16 9:05 ` Frans Klaver 2014-09-16 12:42 ` Frans Klaver 2014-09-16 14:23 ` Frans Klaver 2014-09-17 10:28 ` Frans Klaver 2014-09-21 20:41 ` Sebastian Andrzej Siewior 2014-09-22 9:28 ` Frans Klaver 2014-09-24 7:56 ` Sebastian Andrzej Siewior 2014-09-25 15:14 ` Sebastian Andrzej Siewior 2014-09-25 15:18 ` Frans Klaver 2014-09-29 8:50 ` Frans Klaver 2014-09-29 9:54 ` Sebastian Andrzej Siewior 2014-09-29 10:30 ` Frans Klaver 2014-09-30 8:44 ` Frans Klaver 2014-10-02 10:27 ` Sebastian Andrzej Siewior 2014-10-13 14:55 ` Frans Klaver 2014-09-23 17:03 ` Peter Hurley 2014-09-24 7:53 ` Sebastian Andrzej Siewior 2014-09-25 10:42 ` Sebastian Andrzej Siewior 2014-09-25 11:31 ` Peter Hurley 2014-09-25 13:11 ` Sebastian Andrzej Siewior 2014-09-17 16:34 ` Sebastian Andrzej Siewior 2014-09-19 10:22 ` Heikki Krogerus 2014-09-19 10:58 ` Sebastian Andrzej Siewior 2014-09-19 11:25 ` Peter Hurley 2014-09-22 7:46 ` Heikki Krogerus 2014-09-25 9:24 ` Sebastian Andrzej Siewior 2014-09-10 19:30 ` Sebastian Andrzej Siewior [this message] 2014-09-10 19:30 ` [PATCH 11/16] tty: serial: 8250_dma: keep own book keeping about RX transfers Sebastian Andrzej Siewior 2014-09-10 19:30 ` [PATCH 12/16] tty: serial: 8250_dma: handle the UART RDI event while DMA remains idle Sebastian Andrzej Siewior 2014-09-29 9:23 ` Frans Klaver 2014-09-10 19:30 ` [PATCH 13/16] tty: serial: 8250_dma: add pm runtime Sebastian Andrzej Siewior 2014-09-29 9:26 ` Frans Klaver 2014-09-29 9:56 ` Sebastian Andrzej Siewior 2014-09-10 19:30 ` [PATCH 14/16] arm: dts: am33xx: add DMA properties for UART Sebastian Andrzej Siewior 2014-09-10 19:30 ` [PATCH 15/16] arm: dts: dra7: " Sebastian Andrzej Siewior 2014-09-10 19:30 ` [PATCH 16/16] tty: serial: 8250: omap: add dma support Sebastian Andrzej Siewior 2014-09-12 22:43 ` [PATCH 00/16 v9] omap 8250 based uart + DMA Tony Lindgren 2014-09-15 11:50 ` Sebastian Andrzej Siewior 2014-09-16 12:57 ` Sebastian Andrzej Siewior 2014-09-16 16:48 ` Tony Lindgren 2014-09-16 21:30 ` Tony Lindgren 2014-09-17 8:38 ` Sebastian Andrzej Siewior 2014-09-17 9:05 ` Sebastian Andrzej Siewior 2014-09-26 16:02 ` Greg KH
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1410377411-26656-11-git-send-email-bigeasy@linutronix.de \ --to=bigeasy@linutronix.de \ --cc=linux-arm-kernel@lists.infradead.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Linux-ARM-Kernel Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 linux-arm-kernel linux-arm-kernel/ https://lore.kernel.org/linux-arm-kernel \ linux-arm-kernel@lists.infradead.org public-inbox-index linux-arm-kernel Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git