From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E2F1C6FA91 for ; Tue, 20 Sep 2022 05:21:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229667AbiITFVF (ORCPT ); Tue, 20 Sep 2022 01:21:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37916 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229572AbiITFUx (ORCPT ); Tue, 20 Sep 2022 01:20:53 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE1A14DB7A; Mon, 19 Sep 2022 22:20:51 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 917321F889; Tue, 20 Sep 2022 05:20:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651250; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rG/RuZqj0s6o1zZB075A45sdYsusSoWW/nWCKNRy+j4=; b=0TndwT8Irvaz65JK4PQuLXA1r9Or8dZzulSYgk2LY2iwFTvi19BGbyyDQYc00DxXR8FV4e V0UcEoDgnI+REjHvJ99LV/EFyoDCG8/+RAwfZJ6GDQ5eKEq7G+rra3bQYsPuaItDkh7lJw oEsXw5lAULbrQZ3jeh0S9PEjplNBIuw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651250; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rG/RuZqj0s6o1zZB075A45sdYsusSoWW/nWCKNRy+j4=; b=PfuLgrKsT+5LTJiq5qsWX4ileX2mTCDLaxn0ajGoYDfynzGLB4suDo083oJ0IvMz4hn2Aj p6tfxM5GAjIclJCA== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 5BB6B2C142; Tue, 20 Sep 2022 05:20:50 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby , linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 01/10] tty: serial: move and cleanup vt8500_tx_empty() Date: Tue, 20 Sep 2022 07:20:41 +0200 Message-Id: <20220920052049.20507-2-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Make vt8500_tx_empty() more readable by introducing a new local variable and move the function before handle_tx(). That way we can reuse it in there too. Cc: Signed-off-by: Jiri Slaby Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v3] this is new in v3 -- extracted as a separate change from later patches drivers/tty/serial/vt8500_serial.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500= _serial.c index 508ad7afa6de..10fbdb09965f 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -187,6 +187,13 @@ static void handle_rx(struct uart_port *port) tty_flip_buffer_push(tport); } =20 +static unsigned int vt8500_tx_empty(struct uart_port *port) +{ + unsigned int idx =3D vt8500_read(port, VT8500_URFIDX) & 0x1f; + + return idx < 16 ? TIOCSER_TEMT : 0; +} + static void handle_tx(struct uart_port *port) { struct circ_buf *xmit =3D &port->state->xmit; @@ -201,7 +208,7 @@ static void handle_tx(struct uart_port *port) return; } =20 - while ((vt8500_read(port, VT8500_URFIDX) & 0x1f) < 16) { + while (vt8500_tx_empty(port)) { if (uart_circ_empty(xmit)) break; =20 @@ -260,12 +267,6 @@ static irqreturn_t vt8500_irq(int irq, void *dev_id) return IRQ_HANDLED; } =20 -static unsigned int vt8500_tx_empty(struct uart_port *port) -{ - return (vt8500_read(port, VT8500_URFIDX) & 0x1f) < 16 ? - TIOCSER_TEMT : 0; -} - static unsigned int vt8500_get_mctrl(struct uart_port *port) { unsigned int usr; --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 118ADC54EE9 for ; Tue, 20 Sep 2022 05:21:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230150AbiITFVL (ORCPT ); Tue, 20 Sep 2022 01:21:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229722AbiITFUy (ORCPT ); Tue, 20 Sep 2022 01:20:54 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3AB354DB6B; Mon, 19 Sep 2022 22:20:53 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id DEC3921CAC; Tue, 20 Sep 2022 05:20:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651250; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q2j1gKQOr1uxxBIOy9FBMHSzPifjlvk0WSprmVOm5tI=; b=TB7ValD4tq+6lrfOsEL0XqCBFMmyTXcYJGM/cYGpmLtabu2/N57LTU0spObr9aYBFMMxu2 AT7j8uex3oSCejgHHIGoQgGC5XPPjc4Y7i+b+wDlR+tARQzNC5H30e7OOU6AEtdMt1SzO0 02xGH3PetX1OJLJEgd5wKxQNGtvdko8= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651250; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q2j1gKQOr1uxxBIOy9FBMHSzPifjlvk0WSprmVOm5tI=; b=D8Y0qdcScKEcRODpwYokfEoxpfZGW7JThdHdxmBa0miUSeQsQJgy7P/oJoET3gLEReVFIN e3aM9fkl06IFiDBA== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 9C90B2C141; Tue, 20 Sep 2022 05:20:50 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby , Tobias Klauser Subject: [PATCH v4 02/10] tty: serial: clean up stop-tx part in altera_uart_tx_chars() Date: Tue, 20 Sep 2022 07:20:42 +0200 Message-Id: <20220920052049.20507-3-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The "stop TX" path in altera_uart_tx_chars() is open-coded, so: * use uart_circ_empty() to check if the buffer is empty, and * when true, call altera_uart_stop_tx(). Cc: Tobias Klauser Signed-off-by: Jiri Slaby Acked-by: Tobias Klauser Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] this is new in v4 -- extracted as a separate change drivers/tty/serial/altera_uart.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_u= art.c index a38db2cb8dc1..4170e66601ec 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -272,10 +272,8 @@ static void altera_uart_tx_chars(struct altera_uart *p= p) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); =20 - if (xmit->head =3D=3D xmit->tail) { - pp->imr &=3D ~ALTERA_UART_CONTROL_TRDY_MSK; - altera_uart_update_ctrl_reg(pp); - } + if (uart_circ_empty(xmit)) + altera_uart_stop_tx(port); } =20 static irqreturn_t altera_uart_interrupt(int irq, void *data) --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0EEC6ECAAD8 for ; Tue, 20 Sep 2022 05:21:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230030AbiITFVZ (ORCPT ); Tue, 20 Sep 2022 01:21:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229909AbiITFUy (ORCPT ); Tue, 20 Sep 2022 01:20:54 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3AAF94D4DD; Mon, 19 Sep 2022 22:20:53 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 2C6B221CB9; Tue, 20 Sep 2022 05:20:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651251; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UI2jWYkFC7yTyQ71uYKxabQJQdsHojOQkO52hXQioaY=; b=RcRxz1VdBnWER++nYaGrYWA3pzAoUVNe5xc7j1k2UaeRrL21lgV/MtqHIfjCjrnq8pCmLE n+rrCIHGM5wvVXaL/W1iYNMuYEN4r8nFUXIpeDxNn9R0rHF3RIAUrJj4hFk9XHhjcNK8On CMy1Ebfv+U709TYaLT9I/74s5Q/tEjU= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651251; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UI2jWYkFC7yTyQ71uYKxabQJQdsHojOQkO52hXQioaY=; b=qOY0EUaed4/ac2F5DBb1tXPyfi1oWtSOosFx/8Dbct0nT0tBBaSBFJ2R/0dlYF9RuryQDR qsC9ddav/qtD3oBQ== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id EB8A12C142; Tue, 20 Sep 2022 05:20:50 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby , Tobias Klauser Subject: [PATCH v4 03/10] tty: serial: altera_uart_{r,t}x_chars() need only uart_port Date: Tue, 20 Sep 2022 07:20:43 +0200 Message-Id: <20220920052049.20507-4-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Both altera_uart_{r,t}x_chars() need only uart_port, not altera_uart. So pass the former from altera_uart_interrupt() directly. Apart it maybe saves a dereference, this makes the transition of altera_uart_tx_chars() easier to follow in the next patch. Cc: Tobias Klauser Signed-off-by: Jiri Slaby Acked-by: Tobias Klauser Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] this is new in v4 -- extracted as a separate change drivers/tty/serial/altera_uart.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_u= art.c index 4170e66601ec..82f2790de28d 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -199,9 +199,8 @@ static void altera_uart_set_termios(struct uart_port *p= ort, */ } =20 -static void altera_uart_rx_chars(struct altera_uart *pp) +static void altera_uart_rx_chars(struct uart_port *port) { - struct uart_port *port =3D &pp->port; unsigned char ch, flag; unsigned short status; =20 @@ -246,9 +245,8 @@ static void altera_uart_rx_chars(struct altera_uart *pp) tty_flip_buffer_push(&port->state->port); } =20 -static void altera_uart_tx_chars(struct altera_uart *pp) +static void altera_uart_tx_chars(struct uart_port *port) { - struct uart_port *port =3D &pp->port; struct circ_buf *xmit =3D &port->state->xmit; =20 if (port->x_char) { @@ -286,9 +284,9 @@ static irqreturn_t altera_uart_interrupt(int irq, void = *data) =20 spin_lock(&port->lock); if (isr & ALTERA_UART_STATUS_RRDY_MSK) - altera_uart_rx_chars(pp); + altera_uart_rx_chars(port); if (isr & ALTERA_UART_STATUS_TRDY_MSK) - altera_uart_tx_chars(pp); + altera_uart_tx_chars(port); spin_unlock(&port->lock); =20 return IRQ_RETVAL(isr); --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F076DC6FA91 for ; Tue, 20 Sep 2022 05:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229764AbiITFVB (ORCPT ); Tue, 20 Sep 2022 01:21:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229684AbiITFUx (ORCPT ); Tue, 20 Sep 2022 01:20:53 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7ABB4DF11; Mon, 19 Sep 2022 22:20:52 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 654AA1F8A6; Tue, 20 Sep 2022 05:20:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651251; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PBb254ufDLViHW1psKMCbOT0ZEYgTcb/VpywoIn1+Pk=; b=JprHj6lqGzW/P7TP1CSeXgoLGRytYOf+MKeTqUmar/N8h/INk9kJc8ZdzZ8oloeAzTBGOe rCMhHBzMPpHkFlrmWUVy3TwD0S5O7L6N9Y7M2cniwUOdiedqdUEHhwSClxxG79xHXGzWzz FcsM+MCUVTK3wLT9tJl8mJtBzztjPZw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651251; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PBb254ufDLViHW1psKMCbOT0ZEYgTcb/VpywoIn1+Pk=; b=2eS108/4W2ZEiJdwrgU0c2YVtVlbK9qGheh98zt01LsFh9SxYeAoi6mdfk+rPrHP/gVyXm GTSNK4i+fmmTOsDg== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 37C282C141; Tue, 20 Sep 2022 05:20:51 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby Subject: [PATCH v4 04/10] tty: serial: extract lqasc_tx_ready() from lqasc_tx_chars() Date: Tue, 20 Sep 2022 07:20:44 +0200 Message-Id: <20220920052049.20507-5-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The condition in lqasc_tx_chars()'s loop is barely readable. Extract it to a separate function. This will make the cleanup in the next patches easier too. (Put it before lqasc_start_tx(), so that we can use it there later.) Signed-off-by: Jiri Slaby --- Notes: [v4] this is new in v4 -- extracted as a separate change drivers/tty/serial/lantiq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 6637b3caa6b7..6da1b7496c6c 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -139,6 +139,13 @@ lqasc_stop_tx(struct uart_port *port) return; } =20 +static bool lqasc_tx_ready(struct uart_port *port) +{ + u32 fstat =3D __raw_readl(port->membase + LTQ_ASC_FSTAT); + + return (fstat & ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF; +} + static void lqasc_start_tx(struct uart_port *port) { @@ -228,8 +235,7 @@ lqasc_tx_chars(struct uart_port *port) return; } =20 - while (((__raw_readl(port->membase + LTQ_ASC_FSTAT) & - ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) !=3D 0) { + while (lqasc_tx_ready(port)) { if (port->x_char) { writeb(port->x_char, port->membase + LTQ_ASC_TBUF); port->icount.tx++; --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAF0CC54EE9 for ; Tue, 20 Sep 2022 05:21:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230182AbiITFVP (ORCPT ); Tue, 20 Sep 2022 01:21:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229977AbiITFUy (ORCPT ); Tue, 20 Sep 2022 01:20:54 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96FF84F669; Mon, 19 Sep 2022 22:20:53 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 4B4371F8A8; Tue, 20 Sep 2022 05:20:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651252; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3DR+e5tUXrU5pDouwWQoOJcV84hEa4+bOrdcoGBahis=; b=AHlZ6BHmkCZhxrHKia31hETrcgXlk+z2qr1mmJoKqGy8iCeLFN5pmRIKSo6tvoGDZ+MsxV EGPlgFVnH9amtpbWjXAvi3U72/FyvTcEtWVA1poFSDX+sxjzNKR1QrW4VyDyzNMxLUnZV9 //Lmah+LrAYoJ6uR/44KRIvELBy9zh4= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651252; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3DR+e5tUXrU5pDouwWQoOJcV84hEa4+bOrdcoGBahis=; b=3KvSp9eNVo6hma1f/FIQVS47Gx+6sERkSqqH6QPNc8c3rEaFCIC3sAOFTTchzZYbg4zyld yOSEBD2qbOiPeoAA== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 6DF7E2C142; Tue, 20 Sep 2022 05:20:51 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby , Vladimir Zapolskiy , linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 05/10] tty: serial: extract tx_ready() from __serial_lpc32xx_tx() Date: Tue, 20 Sep 2022 07:20:45 +0200 Message-Id: <20220920052049.20507-6-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The condition in __serial_lpc32xx_tx()'s loop is barely readable. Extract it to a separate function. This will make the cleanup in the next patches easier too. Cc: Vladimir Zapolskiy Cc: Signed-off-by: Jiri Slaby Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] this is new in v4 -- extracted as a separate change drivers/tty/serial/lpc32xx_hs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_h= s.c index 0d5ef7df27d0..ed47f4768338 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -278,6 +278,13 @@ static void __serial_lpc32xx_rx(struct uart_port *port) =20 static void serial_lpc32xx_stop_tx(struct uart_port *port); =20 +static bool serial_lpc32xx_tx_ready(struct uart_port *port) +{ + u32 level =3D readl(LPC32XX_HSUART_LEVEL(port->membase)); + + return LPC32XX_HSU_TX_LEV(level) < 64; +} + static void __serial_lpc32xx_tx(struct uart_port *port) { struct circ_buf *xmit =3D &port->state->xmit; @@ -293,8 +300,7 @@ static void __serial_lpc32xx_tx(struct uart_port *port) goto exit_tx; =20 /* Transfer data */ - while (LPC32XX_HSU_TX_LEV(readl( - LPC32XX_HSUART_LEVEL(port->membase))) < 64) { + while (serial_lpc32xx_tx_ready(port)) { writel((u32) xmit->buf[xmit->tail], LPC32XX_HSUART_FIFO(port->membase)); xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D30FC54EE9 for ; Tue, 20 Sep 2022 05:21:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230213AbiITFVa (ORCPT ); Tue, 20 Sep 2022 01:21:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230020AbiITFUy (ORCPT ); Tue, 20 Sep 2022 01:20:54 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6BA050184; Mon, 19 Sep 2022 22:20:53 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 867981F8AB; Tue, 20 Sep 2022 05:20:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651252; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oYr7Z62BDiJmHGeEjwvvRpRLmgO1LxdvAVFhnRhBAuU=; b=gShQunqA0Rgna9E2rlYCaPjsbh+aRbdw8uxgzvHtnLorl9NLvg7g7GhtTuscdkAqxnM1nI //uO2xSaCn1i/WoTl4UgJBWI388oYH6jsZwYRjatTPH8N480KirwLCoCm7bS8HDsWhoELg Vspzw2t7eoJ+8mFF6SsfPO/oAcpoMig= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651252; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oYr7Z62BDiJmHGeEjwvvRpRLmgO1LxdvAVFhnRhBAuU=; b=xzZ8giAcMxfEo/SouinHWMmzrOIiXZCMRtaq8Vvo2sfP/TduXLv2poBA7DsfZ8z1G5Kz6a Z5N43FEfcD0IhGAA== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 56EA12C141; Tue, 20 Sep 2022 05:20:52 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby Subject: [PATCH v4 06/10] tty: serial: switch mpc52xx_uart_int_{r,t}x_chars() to bool Date: Tue, 20 Sep 2022 07:20:46 +0200 Message-Id: <20220920052049.20507-7-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" mpc52xx_uart_int_rx_chars() returns unsigned int. mpc52xx_uart_int_tx_chars() returns int. The both results are binary ORed to the "keepgoing" variable. Unify all three to bool as the only interesting value is whether we should keep looping (true/false). Signed-off-by: Jiri Slaby Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] this is new in v4 -- extracted as a separate change drivers/tty/serial/mpc52xx_uart.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx= _uart.c index 6f09b1cb3e1c..73362d4bc45d 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1364,7 +1364,7 @@ static const struct uart_ops mpc52xx_uart_ops =3D { /* Interrupt handling = */ /* =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D */ =20 -static inline unsigned int +static inline bool mpc52xx_uart_int_rx_chars(struct uart_port *port) { struct tty_port *tport =3D &port->state->port; @@ -1425,7 +1425,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) return psc_ops->raw_rx_rdy(port); } =20 -static inline int +static inline bool mpc52xx_uart_int_tx_chars(struct uart_port *port) { struct circ_buf *xmit =3D &port->state->xmit; @@ -1435,13 +1435,13 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) psc_ops->write_char(port, port->x_char); port->icount.tx++; port->x_char =3D 0; - return 1; + return true; } =20 /* Nothing to do ? */ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { mpc52xx_uart_stop_tx(port); - return 0; + return false; } =20 /* Send chars */ @@ -1460,23 +1460,23 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) /* Maybe we're done after all */ if (uart_circ_empty(xmit)) { mpc52xx_uart_stop_tx(port); - return 0; + return false; } =20 - return 1; + return true; } =20 static irqreturn_t mpc5xxx_uart_process_int(struct uart_port *port) { unsigned long pass =3D ISR_PASS_LIMIT; - unsigned int keepgoing; + bool keepgoing; u8 status; =20 /* While we have stuff to do, we continue */ do { /* If we don't find anything to do, we stop */ - keepgoing =3D 0; + keepgoing =3D false; =20 psc_ops->rx_clr_irq(port); if (psc_ops->rx_rdy(port)) @@ -1495,7 +1495,7 @@ mpc5xxx_uart_process_int(struct uart_port *port) =20 /* Limit number of iteration */ if (!(--pass)) - keepgoing =3D 0; + keepgoing =3D false; =20 } while (keepgoing); =20 --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0B06AC6FA82 for ; Tue, 20 Sep 2022 05:21:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230158AbiITFVV (ORCPT ); Tue, 20 Sep 2022 01:21:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230002AbiITFUy (ORCPT ); Tue, 20 Sep 2022 01:20:54 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 121BC4DB7A; Mon, 19 Sep 2022 22:20:54 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id BE5AA1F8B0; Tue, 20 Sep 2022 05:20:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651252; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dqYWbHDys658PO9cI+Q4Z9fm/eu7KUQM2lLlwljC3xU=; b=V0cjK7yIJU3KGRaV1ns5Ue01jzb1IEM9mQOPmKorxPHeY5lRbhV9x7x9mZSVX58sJss5MW 78fdsgzTs+nQsK7LnPaXZDUva6ysoh+tujDKX6v2A3uAW4CeVDpnphVBDXyrNAFsLKGRW5 Eki8M08bsuobCa07kmKLSDofdStwkdA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651252; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dqYWbHDys658PO9cI+Q4Z9fm/eu7KUQM2lLlwljC3xU=; b=Vcj6lXpcWhOmR7ycgpi0XPB/h6zk0jlUMC2iFU5fpMT6GqWLxQtTZ5nm5FIQpQI0oXnufP 9lnNPPUOqjTd1jDw== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 9058E2C142; Tue, 20 Sep 2022 05:20:52 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby Subject: [PATCH v4 07/10] tty: serial: extract serial_omap_put_char() from transmit_chars() Date: Tue, 20 Sep 2022 07:20:47 +0200 Message-Id: <20220920052049.20507-8-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This non-trivial code is doubled in transmit_chars(), so it deserves its own function. This will make next patches easier. Signed-off-by: Jiri Slaby Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] this is new in v4 -- extracted as a separate change drivers/tty/serial/omap-serial.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-ser= ial.c index c87d85b901a7..b7b76e49115e 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -337,19 +337,24 @@ static void serial_omap_stop_rx(struct uart_port *por= t) serial_out(up, UART_IER, up->ier); } =20 +static void serial_omap_put_char(struct uart_omap_port *up, unsigned char = ch) +{ + serial_out(up, UART_TX, ch); + + if ((up->port.rs485.flags & SER_RS485_ENABLED) && + !(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) + up->rs485_tx_filter_count++; +} + static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) { struct circ_buf *xmit =3D &up->port.state->xmit; int count; =20 if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); + serial_omap_put_char(up, up->port.x_char); up->port.icount.tx++; up->port.x_char =3D 0; - if ((up->port.rs485.flags & SER_RS485_ENABLED) && - !(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) - up->rs485_tx_filter_count++; - return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { @@ -358,12 +363,9 @@ static void transmit_chars(struct uart_omap_port *up, = unsigned int lsr) } count =3D up->port.fifosize / 4; do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); + serial_omap_put_char(up, xmit->buf[xmit->tail]); xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); up->port.icount.tx++; - if ((up->port.rs485.flags & SER_RS485_ENABLED) && - !(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) - up->rs485_tx_filter_count++; =20 if (uart_circ_empty(xmit)) break; --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 23661ECAAD8 for ; Tue, 20 Sep 2022 05:21:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230220AbiITFVd (ORCPT ); Tue, 20 Sep 2022 01:21:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230081AbiITFUz (ORCPT ); Tue, 20 Sep 2022 01:20:55 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 53A8651A24; Mon, 19 Sep 2022 22:20:54 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 13F511F8B3; Tue, 20 Sep 2022 05:20:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651253; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YnYIsxCL+KbExG01vZ8PgWu6CAjR2xXdwTGwXQEtYhU=; b=vYAQ9qHAJjYWYZhZQvUrQzJO9nZAoMwTMR/2MHuc2zp7HHSk8+QgEPFKL7QVN5OsfC6DIm ZKgUGpitBcu0lBJhXO456MOEAWP+ODFih4vkF2J4e9Kn//YFUUor4cL7Tf5eKTf9KMapAT vjxsiDMtxODIROS1MPEWhtPKCdQZzwo= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651253; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YnYIsxCL+KbExG01vZ8PgWu6CAjR2xXdwTGwXQEtYhU=; b=g9HauGzSZE9U5I1ImnQ5E7W3Yz3hhXntN4tYDbZkVbU+6flvuzwp4cjbThWueAn9wP6oxq t3n2G0/4nN5byjDQ== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id CA2612C141; Tue, 20 Sep 2022 05:20:52 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby Subject: [PATCH v4 08/10] tty: serial: introduce transmit helpers Date: Tue, 20 Sep 2022 07:20:48 +0200 Message-Id: <20220920052049.20507-9-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Many serial drivers do the same thing: * send x_char if set * keep sending from the xmit circular buffer until either - the loop reaches the end of the xmit buffer - TX is stopped - HW fifo is full * check for pending characters and: - wake up tty writers to fill for more data into xmit buffer - stop TX if there is nothing in the xmit buffer The only differences are: * how to write the character to the HW fifo * the check of the end condition: - is the HW fifo full? - is limit of the written characters reached? So unify the above into two helpers: * uart_port_tx_limited() -- it performs the above taking the written characters limit into account, and * uart_port_tx() -- the same as above, except it only checks the HW readiness, not the characters limit. The HW specific operations (as stated as "differences" above) are passed as arguments to the macros. They are: * tx_ready -- returns true if HW can accept more data. * put_char -- write a character to the device. * tx_done -- when the write loop is done, perform arbitrary action before potential invocation of ops->stop_tx() happens. Note that the above are macros. This means the code is generated in place and the above 3 arguments are "inlined". I.e. no added penalty by generating call instructions for every single character. Nor any indirect calls. (As in some previous versions of this patchset.) Signed-off-by: Jiri Slaby Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] switch from helper generators to helpers similar to wait_event() [Arnd] Documentation/driver-api/serial/driver.rst | 3 + include/linux/serial_core.h | 80 ++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/Documentation/driver-api/serial/driver.rst b/Documentation/dri= ver-api/serial/driver.rst index 23c6b956cd90..98d268555dcc 100644 --- a/Documentation/driver-api/serial/driver.rst +++ b/Documentation/driver-api/serial/driver.rst @@ -78,6 +78,9 @@ Other functions uart_get_lsr_info uart_handle_dcd_change uart_handle_cts_change uart_try_toggle_sysrq uart_get_console =20 +.. kernel-doc:: include/linux/serial_core.h + :identifiers: uart_port_tx_limited uart_port_tx + Other notes ----------- =20 diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index de992585ea64..b8338a0a52ee 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -663,6 +663,86 @@ struct uart_driver { =20 void uart_write_wakeup(struct uart_port *port); =20 +#define __uart_port_tx(uport, ch, tx_ready, put_char, tx_done, for_test, = \ + for_post) \ +({ \ + struct uart_port *__port =3D (uport); \ + struct circ_buf *xmit =3D &__port->state->xmit; \ + unsigned int pending; \ + \ + for (; (for_test) && (tx_ready); (for_post), __port->icount.tx++) { \ + if (__port->x_char) { \ + (ch) =3D __port->x_char; \ + (put_char); \ + __port->x_char =3D 0; \ + continue; \ + } \ + \ + if (uart_circ_empty(xmit) || uart_tx_stopped(__port)) \ + break; \ + \ + (ch) =3D xmit->buf[xmit->tail]; \ + (put_char); \ + xmit->tail =3D (xmit->tail + 1) % UART_XMIT_SIZE; \ + } \ + \ + (tx_done); \ + \ + pending =3D uart_circ_chars_pending(xmit); \ + if (pending < WAKEUP_CHARS) { \ + uart_write_wakeup(__port); \ + \ + if (pending =3D=3D 0) \ + __port->ops->stop_tx(__port); \ + } \ + \ + pending; \ +}) + +/** + * uart_port_tx_limited -- transmit helper for uart_port with count limiti= ng + * @port: uart port + * @ch: variable to store a character to be written to the HW + * @count: a limit of characters to send + * @tx_ready: can HW accept more data function + * @put_char: function to write a character + * @tx_done: function to call after the loop is done + * + * This helper transmits characters from the xmit buffer to the hardware u= sing + * @put_char(). It does so until @count characters are sent and while @tx_= ready + * evaluates to true. + * + * Returns: the number of characters in the xmit buffer when done. + * + * The expression in macro parameters shall be designed as follows: + * * **tx_ready:** should evaluate to true if the HW can accept more data= to + * be sent. This parameter can be %true, which means the HW is always r= eady. + * * **put_char:** shall write @ch to the device of @port. + * * **tx_done:** when the write loop is done, this can perform arbitrary + * action before potential invocation of ops->stop_tx() happens. If the + * driver does not need to do anything, use e.g. ({}). + * + * For all of them, @port->lock is held, interrupts are locally disabled a= nd + * the expressions must not sleep. + */ +#define uart_port_tx_limited(port, ch, count, tx_ready, put_char, tx_done)= ({ \ + unsigned int __count =3D (count); \ + __uart_port_tx(port, ch, tx_ready, put_char, tx_done, __count, \ + __count--); \ +}) + +/** + * uart_port_tx -- transmit helper for uart_port + * @port: uart port + * @ch: variable to store a character to be written to the HW + * @tx_ready: can HW accept more data function + * @put_char: function to write a character + * + * See uart_port_tx_limited() for more details. + */ +#define uart_port_tx(port, ch, tx_ready, put_char) \ + __uart_port_tx(port, ch, tx_ready, put_char, ({}), true, ({})) + /* * Baud rate helpers. */ --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A6DB5ECAAD8 for ; Tue, 20 Sep 2022 05:21:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230229AbiITFVj (ORCPT ); Tue, 20 Sep 2022 01:21:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230124AbiITFU5 (ORCPT ); Tue, 20 Sep 2022 01:20:57 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 645E44DF0E; Mon, 19 Sep 2022 22:20:55 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 16A5F1F8B5; Tue, 20 Sep 2022 05:20:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663651254; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jeAhahqiH1fpLt6mJAwtHx2gCou1fabthVR7hrn+x3E=; b=v5OjPgFNrAj95EN6kQzZJxYAFgNa/RUxyz4TOxjioRzd9GiugiQAnTsu5tBQ5vwfrR2JPU eKEY15TjXIDjpfk0CRU3wLFW1hrsg0CBPiv+WpV6UEg/cqf9Kb+3vQRUnNP2G+WkXIlZDb LGNkYfDqbcrFDZEjU1A/hOAUb/Hpw0c= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663651254; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jeAhahqiH1fpLt6mJAwtHx2gCou1fabthVR7hrn+x3E=; b=dilluUsNQMLN6ACFJWQ0B8D3eOrj1DJ9FGkk09RQORooBrGUYE1A6kf5CHpiQggMTS2SYf Szbwr4eMtFn5unAQ== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 293682C142; Tue, 20 Sep 2022 05:20:53 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby , Tobias Klauser , Richard Genoud , Nicolas Ferre , Alexandre Belloni , Claudiu Beznea , Vladimir Zapolskiy , Liviu Dudau , Sudeep Holla , Lorenzo Pieralisi , Shawn Guo , Sascha Hauer , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Manivannan Sadhasivam Subject: [PATCH v4 09/10] tty: serial: use uart_port_tx() helper Date: Tue, 20 Sep 2022 07:20:49 +0200 Message-Id: <20220920052049.20507-10-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org uart_port_tx() is a new helper to send characters to the device. Use it in these drivers. Cc: Tobias Klauser Cc: Richard Genoud Cc: Nicolas Ferre Cc: Alexandre Belloni Cc: Claudiu Beznea Cc: Vladimir Zapolskiy Cc: Liviu Dudau Cc: Sudeep Holla Cc: Lorenzo Pieralisi Cc: Shawn Guo Cc: Sascha Hauer Cc: Pengutronix Kernel Team Cc: Fabio Estevam Cc: NXP Linux Team Cc: "Andreas F=C3=A4rber" Cc: Manivannan Sadhasivam Signed-off-by: Jiri Slaby Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] switch from DEFINE_UART_PORT_TX_HELPER() (helper generator) to uart_port_tx() (akin to wait_event()) =20 [v3] remove stray \n removal (Ilpo) drivers/tty/serial/altera_uart.c | 29 ++++------------------ drivers/tty/serial/atmel_serial.c | 28 +++++---------------- drivers/tty/serial/fsl_lpuart.c | 30 ++++------------------- drivers/tty/serial/lantiq.c | 36 +++------------------------ drivers/tty/serial/lpc32xx_hs.c | 33 +++---------------------- drivers/tty/serial/mcf.c | 28 +++++---------------- drivers/tty/serial/mpc52xx_uart.c | 39 +++--------------------------- drivers/tty/serial/mps2-uart.c | 26 +++----------------- drivers/tty/serial/mxs-auart.c | 32 ++++++------------------ drivers/tty/serial/owl-uart.c | 32 +++--------------------- drivers/tty/serial/sa1100.c | 34 +++----------------------- drivers/tty/serial/vt8500_serial.c | 30 +++-------------------- 12 files changed, 58 insertions(+), 319 deletions(-) diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_u= art.c index 82f2790de28d..316074bb23e9 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c @@ -247,31 +247,12 @@ static void altera_uart_rx_chars(struct uart_port *po= rt) =20 static void altera_uart_tx_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - - if (port->x_char) { - /* Send special char - probably flow control */ - altera_uart_writel(port, port->x_char, ALTERA_UART_TXDATA_REG); - port->x_char =3D 0; - port->icount.tx++; - return; - } - - while (altera_uart_readl(port, ALTERA_UART_STATUS_REG) & - ALTERA_UART_STATUS_TRDY_MSK) { - if (xmit->head =3D=3D xmit->tail) - break; - altera_uart_writel(port, xmit->buf[xmit->tail], - ALTERA_UART_TXDATA_REG); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - altera_uart_stop_tx(port); + uart_port_tx(port, ch, + altera_uart_readl(port, ALTERA_UART_STATUS_REG) & + ALTERA_UART_STATUS_TRDY_MSK, + altera_uart_writel(port, ch, ALTERA_UART_TXDATA_REG)); } =20 static irqreturn_t altera_uart_interrupt(int irq, void *data) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_s= erial.c index ab4a9dfae07d..0e2b59bec6ce 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -816,30 +816,14 @@ static void atmel_rx_chars(struct uart_port *port) */ static void atmel_tx_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; struct atmel_uart_port *atmel_port =3D to_atmel_uart_port(port); + bool pending; + u8 ch; =20 - if (port->x_char && - (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) { - atmel_uart_write_char(port, port->x_char); - port->icount.tx++; - port->x_char =3D 0; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - return; - - while (atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY) { - atmel_uart_write_char(port, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (!uart_circ_empty(xmit)) { + pending =3D uart_port_tx(port, ch, + atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY, + atmel_uart_write_char(port, ch)); + if (pending) { /* we still have characters to transmit, so we should continue * transmitting them when TX is ready, regardless of * mode or duplexity diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuar= t.c index f21915015d67..e8a8c11b10a8 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -742,32 +742,12 @@ static int lpuart32_poll_get_char(struct uart_port *p= ort) =20 static inline void lpuart_transmit_buffer(struct lpuart_port *sport) { - struct circ_buf *xmit =3D &sport->port.state->xmit; - - if (sport->port.x_char) { - writeb(sport->port.x_char, sport->port.membase + UARTDR); - sport->port.icount.tx++; - sport->port.x_char =3D 0; - return; - } - - if (lpuart_stopped_or_empty(&sport->port)) { - lpuart_stop_tx(&sport->port); - return; - } - - while (!uart_circ_empty(xmit) && - (readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size)) { - writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&sport->port); + struct uart_port *port =3D &sport->port; + u8 ch; =20 - if (uart_circ_empty(xmit)) - lpuart_stop_tx(&sport->port); + uart_port_tx(port, ch, + readb(port->membase + UARTTCFIFO) < sport->txfifo_size, + writeb(ch, port->membase + UARTDR)); } =20 static inline void lpuart32_transmit_buffer(struct lpuart_port *sport) diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 6da1b7496c6c..06e813a232c5 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c @@ -95,7 +95,6 @@ #define ASCFSTAT_TXFREEMASK 0x3F000000 #define ASCFSTAT_TXFREEOFF 24 =20 -static void lqasc_tx_chars(struct uart_port *port); static struct ltq_uart_port *lqasc_port[MAXPORTS]; static struct uart_driver lqasc_reg; =20 @@ -151,9 +150,12 @@ lqasc_start_tx(struct uart_port *port) { unsigned long flags; struct ltq_uart_port *ltq_port =3D to_ltq_uart_port(port); + u8 ch; =20 spin_lock_irqsave(<q_port->lock, flags); - lqasc_tx_chars(port); + uart_port_tx(port, ch, + lqasc_tx_ready(port), + writeb(ch, port->membase + LTQ_ASC_TBUF)); spin_unlock_irqrestore(<q_port->lock, flags); return; } @@ -226,36 +228,6 @@ lqasc_rx_chars(struct uart_port *port) return 0; } =20 -static void -lqasc_tx_chars(struct uart_port *port) -{ - struct circ_buf *xmit =3D &port->state->xmit; - if (uart_tx_stopped(port)) { - lqasc_stop_tx(port); - return; - } - - while (lqasc_tx_ready(port)) { - if (port->x_char) { - writeb(port->x_char, port->membase + LTQ_ASC_TBUF); - port->icount.tx++; - port->x_char =3D 0; - continue; - } - - if (uart_circ_empty(xmit)) - break; - - writeb(port->state->xmit.buf[port->state->xmit.tail], - port->membase + LTQ_ASC_TBUF); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); -} - static irqreturn_t lqasc_tx_int(int irq, void *_port) { diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_h= s.c index ed47f4768338..b38fe4728c26 100644 --- a/drivers/tty/serial/lpc32xx_hs.c +++ b/drivers/tty/serial/lpc32xx_hs.c @@ -276,8 +276,6 @@ static void __serial_lpc32xx_rx(struct uart_port *port) tty_flip_buffer_push(tport); } =20 -static void serial_lpc32xx_stop_tx(struct uart_port *port); - static bool serial_lpc32xx_tx_ready(struct uart_port *port) { u32 level =3D readl(LPC32XX_HSUART_LEVEL(port->membase)); @@ -287,34 +285,11 @@ static bool serial_lpc32xx_tx_ready(struct uart_port = *port) =20 static void __serial_lpc32xx_tx(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - - if (port->x_char) { - writel((u32)port->x_char, LPC32XX_HSUART_FIFO(port->membase)); - port->icount.tx++; - port->x_char =3D 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - goto exit_tx; - - /* Transfer data */ - while (serial_lpc32xx_tx_ready(port)) { - writel((u32) xmit->buf[xmit->tail], - LPC32XX_HSUART_FIFO(port->membase)); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 -exit_tx: - if (uart_circ_empty(xmit)) - serial_lpc32xx_stop_tx(port); + uart_port_tx(port, ch, + serial_lpc32xx_tx_ready(port), + writel(ch, LPC32XX_HSUART_FIFO(port->membase))); } =20 static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) diff --git a/drivers/tty/serial/mcf.c b/drivers/tty/serial/mcf.c index b1cd9a76dd93..53b642ea46ba 100644 --- a/drivers/tty/serial/mcf.c +++ b/drivers/tty/serial/mcf.c @@ -327,29 +327,13 @@ static void mcf_rx_chars(struct mcf_uart *pp) static void mcf_tx_chars(struct mcf_uart *pp) { struct uart_port *port =3D &pp->port; - struct circ_buf *xmit =3D &port->state->xmit; - - if (port->x_char) { - /* Send special char - probably flow control */ - writeb(port->x_char, port->membase + MCFUART_UTB); - port->x_char =3D 0; - port->icount.tx++; - return; - } - - while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) { - if (uart_circ_empty(xmit)) - break; - writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE -1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + unsigned int pending; + u8 ch; =20 - if (uart_circ_empty(xmit)) { - mcf_stop_tx(port); + pending =3D uart_port_tx(port, ch, + readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY, + writeb(ch, port->membase + MCFUART_UTB)); + if (!pending) { /* Disable TX to negate RTS automatically */ if (port->rs485.flags & SER_RS485_ENABLED) writeb(MCFUART_UCR_TXDISABLE, diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx= _uart.c index 73362d4bc45d..384ca195e3d5 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -1428,42 +1428,11 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) static inline bool mpc52xx_uart_int_tx_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - - /* Process out of band chars */ - if (port->x_char) { - psc_ops->write_char(port, port->x_char); - port->icount.tx++; - port->x_char =3D 0; - return true; - } - - /* Nothing to do ? */ - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - mpc52xx_uart_stop_tx(port); - return false; - } - - /* Send chars */ - while (psc_ops->raw_tx_rdy(port)) { - psc_ops->write_char(port, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - /* Wake up */ - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - /* Maybe we're done after all */ - if (uart_circ_empty(xmit)) { - mpc52xx_uart_stop_tx(port); - return false; - } + u8 ch; =20 - return true; + return uart_port_tx(port, ch, + psc_ops->raw_tx_rdy(port), + psc_ops->write_char(port, ch)); } =20 static irqreturn_t diff --git a/drivers/tty/serial/mps2-uart.c b/drivers/tty/serial/mps2-uart.c index 2e3e6cf16817..860d161fa594 100644 --- a/drivers/tty/serial/mps2-uart.c +++ b/drivers/tty/serial/mps2-uart.c @@ -129,29 +129,11 @@ static void mps2_uart_stop_tx(struct uart_port *port) =20 static void mps2_uart_tx_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - - while (!(mps2_uart_read8(port, UARTn_STATE) & UARTn_STATE_TX_FULL)) { - if (port->x_char) { - mps2_uart_write8(port, port->x_char, UARTn_DATA); - port->x_char =3D 0; - port->icount.tx++; - continue; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - break; - - mps2_uart_write8(port, xmit->buf[xmit->tail], UARTn_DATA); - xmit->tail =3D (xmit->tail + 1) % UART_XMIT_SIZE; - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - mps2_uart_stop_tx(port); + uart_port_tx(port, ch, + mps2_uart_tx_empty(port), + mps2_uart_write8(port, ch, UARTn_DATA)); } =20 static void mps2_uart_start_tx(struct uart_port *port) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index d21a4f3ef2fe..ef6e7bb6105c 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -569,6 +569,8 @@ static int mxs_auart_dma_tx(struct mxs_auart_port *s, i= nt size) static void mxs_auart_tx_chars(struct mxs_auart_port *s) { struct circ_buf *xmit =3D &s->port.state->xmit; + bool pending; + u8 ch; =20 if (auart_dma_enabled(s)) { u32 i =3D 0; @@ -603,31 +605,13 @@ static void mxs_auart_tx_chars(struct mxs_auart_port = *s) return; } =20 - - while (!(mxs_read(s, REG_STAT) & AUART_STAT_TXFF)) { - if (s->port.x_char) { - s->port.icount.tx++; - mxs_write(s->port.x_char, s, REG_DATA); - s->port.x_char =3D 0; - continue; - } - if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { - s->port.icount.tx++; - mxs_write(xmit->buf[xmit->tail], s, REG_DATA); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - } else - break; - } - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&s->port); - - if (uart_circ_empty(&(s->port.state->xmit))) - mxs_clr(AUART_INTR_TXIEN, s, REG_INTR); - else + pending =3D uart_port_tx(&s->port, ch, + !(mxs_read(s, REG_STAT) & AUART_STAT_TXFF), + mxs_write(ch, s, REG_DATA)); + if (pending) mxs_set(AUART_INTR_TXIEN, s, REG_INTR); - - if (uart_tx_stopped(&s->port)) - mxs_auart_stop_tx(&s->port); + else + mxs_clr(AUART_INTR_TXIEN, s, REG_INTR); } =20 static void mxs_auart_rx_char(struct mxs_auart_port *s) diff --git a/drivers/tty/serial/owl-uart.c b/drivers/tty/serial/owl-uart.c index fde39cc1145d..e99970a9437f 100644 --- a/drivers/tty/serial/owl-uart.c +++ b/drivers/tty/serial/owl-uart.c @@ -181,35 +181,11 @@ static void owl_uart_start_tx(struct uart_port *port) =20 static void owl_uart_send_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - unsigned int ch; - - if (port->x_char) { - while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) - cpu_relax(); - owl_uart_write(port, port->x_char, OWL_UART_TXDAT); - port->icount.tx++; - port->x_char =3D 0; - } - - if (uart_tx_stopped(port)) - return; - - while (!(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU)) { - if (uart_circ_empty(xmit)) - break; + u8 ch; =20 - ch =3D xmit->buf[xmit->tail]; - owl_uart_write(port, ch, OWL_UART_TXDAT); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - owl_uart_stop_tx(port); + uart_port_tx(port, ch, + !(owl_uart_read(port, OWL_UART_STAT) & OWL_UART_STAT_TFFU), + owl_uart_write(port, ch, OWL_UART_TXDAT)); } =20 static void owl_uart_receive_chars(struct uart_port *port) diff --git a/drivers/tty/serial/sa1100.c b/drivers/tty/serial/sa1100.c index dd9e3253cab4..55107bbc00ce 100644 --- a/drivers/tty/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c @@ -228,14 +228,7 @@ sa1100_rx_chars(struct sa1100_port *sport) =20 static void sa1100_tx_chars(struct sa1100_port *sport) { - struct circ_buf *xmit =3D &sport->port.state->xmit; - - if (sport->port.x_char) { - UART_PUT_CHAR(sport, sport->port.x_char); - sport->port.icount.tx++; - sport->port.x_char =3D 0; - return; - } + u8 ch; =20 /* * Check the modem control lines before @@ -243,28 +236,9 @@ static void sa1100_tx_chars(struct sa1100_port *sport) */ sa1100_mctrl_check(sport); =20 - if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { - sa1100_stop_tx(&sport->port); - return; - } - - /* - * Tried using FIFO (not checking TNF) for fifo fill: - * still had the '4 bytes repeated' problem. - */ - while (UART_GET_UTSR1(sport) & UTSR1_TNF) { - UART_PUT_CHAR(sport, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - sport->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&sport->port); - - if (uart_circ_empty(xmit)) - sa1100_stop_tx(&sport->port); + uart_port_tx(&sport->port, ch, + UART_GET_UTSR1(sport) & UTSR1_TNF, + UART_PUT_CHAR(sport, ch)); } =20 static irqreturn_t sa1100_int(int irq, void *dev_id) diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500= _serial.c index 10fbdb09965f..deedb6513160 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -196,33 +196,11 @@ static unsigned int vt8500_tx_empty(struct uart_port = *port) =20 static void handle_tx(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; + u8 ch; =20 - if (port->x_char) { - writeb(port->x_char, port->membase + VT8500_TXFIFO); - port->icount.tx++; - port->x_char =3D 0; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - vt8500_stop_tx(port); - return; - } - - while (vt8500_tx_empty(port)) { - if (uart_circ_empty(xmit)) - break; - - writeb(xmit->buf[xmit->tail], port->membase + VT8500_TXFIFO); - - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - vt8500_stop_tx(port); + uart_port_tx(port, ch, + vt8500_tx_empty(port), + writeb(ch, port->membase + VT8500_TXFIFO)); } =20 static void vt8500_start_tx(struct uart_port *port) --=20 2.37.3 From nobody Thu Apr 2 22:59:58 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CAB11ECAAD8 for ; Tue, 20 Sep 2022 07:59:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229828AbiITH7D (ORCPT ); Tue, 20 Sep 2022 03:59:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230344AbiITH6t (ORCPT ); Tue, 20 Sep 2022 03:58:49 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 292782DFA; Tue, 20 Sep 2022 00:58:47 -0700 (PDT) Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id B7AA71F85D; Tue, 20 Sep 2022 07:58:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1663660725; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Sc1kkFYXOjlKs/IqOME2hwVVovuP1iWXSlhqWySE1dI=; b=K3bKSByLZfltwYwa1MHv0UuwlpmYaSomu9PMzUgfipqm7oVLmpopbVEStFKgmhASMwHJZP 6oSVloCvAts6DLUsp6q6zgDBxYJ3CCHjHoGnxHinjT5GgAmSuGzJzlS7xf6sXbByTk2u3+ hLVEpk5JuSm2gWsNsoJ6j410bfMUugw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1663660725; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Sc1kkFYXOjlKs/IqOME2hwVVovuP1iWXSlhqWySE1dI=; b=SdnPN/5ZxIMnj8kD0Hzvg9q0+lez3VQHohKzZdecCgeddeHdfuEe3yYV1zCpmGJ+6GW+do HuJLSgdr2p7+Z7Dw== Received: from localhost.localdomain (unknown [10.100.201.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by relay2.suse.de (Postfix) with ESMTPS id 1FCBD2C141; Tue, 20 Sep 2022 07:58:45 +0000 (UTC) From: Jiri Slaby To: gregkh@linuxfoundation.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Jiri Slaby , Russell King , Florian Fainelli , bcm-kernel-feedback-list@broadcom.com, =?UTF-8?q?Pali=20Roh=C3=A1r?= , Kevin Cernekee , Palmer Dabbelt , Paul Walmsley , Orson Zhai , Baolin Wang , Chunyan Zhang , Patrice Chotard , linux-riscv@lists.infradead.org Subject: [PATCH v4 10/10] tty: serial: use uart_port_tx_limited() Date: Tue, 20 Sep 2022 09:58:44 +0200 Message-Id: <20220920075844.29360-1-jslaby@suse.cz> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220920052049.20507-1-jslaby@suse.cz> References: <20220920052049.20507-1-jslaby@suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org uart_port_tx_limited() is a new helper to send characters to the device. Use it in these drivers. mux.c also needs to define tx_done(). But I'm not sure if the driver really wants to wait for all the characters to dismiss from the HW fifo at this code point. Hence I marked this as FIXME. Signed-off-by: Jiri Slaby Cc: Russell King Cc: Florian Fainelli Cc: bcm-kernel-feedback-list@broadcom.com Cc: "Pali Roh=C3=A1r" Cc: Kevin Cernekee Cc: Palmer Dabbelt Cc: Paul Walmsley Cc: Orson Zhai Cc: Baolin Wang Cc: Chunyan Zhang Cc: Patrice Chotard Cc: linux-riscv@lists.infradead.org Reviewed-by: Ilpo J=C3=A4rvinen --- Notes: [v4] switch from DEFINE_UART_PORT_TX_HELPER_LIMITED() (helper generator) to uart_port_tx_limited() (akin to wait_event()) drivers/tty/serial/21285.c | 32 +++---------------- drivers/tty/serial/altera_jtaguart.c | 40 ++++++----------------- drivers/tty/serial/amba-pl010.c | 32 +++---------------- drivers/tty/serial/apbuart.c | 34 +++----------------- drivers/tty/serial/bcm63xx_uart.c | 47 ++++++--------------------- drivers/tty/serial/mux.c | 45 ++++++++------------------ drivers/tty/serial/mvebu-uart.c | 38 +++------------------- drivers/tty/serial/omap-serial.c | 32 +++---------------- drivers/tty/serial/pxa.c | 33 +++---------------- drivers/tty/serial/rp2.c | 31 ++++-------------- drivers/tty/serial/serial_txx9.c | 32 +++---------------- drivers/tty/serial/sifive.c | 31 +++--------------- drivers/tty/serial/sprd_serial.c | 33 +++---------------- drivers/tty/serial/st-asc.c | 48 +++------------------------- 14 files changed, 87 insertions(+), 421 deletions(-) diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 2f17bf4b221e..84c1e3e365c8 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -154,35 +154,13 @@ static irqreturn_t serial21285_rx_chars(int irq, void= *dev_id) static irqreturn_t serial21285_tx_chars(int irq, void *dev_id) { struct uart_port *port =3D dev_id; - struct circ_buf *xmit =3D &port->state->xmit; - int count =3D 256; - - if (port->x_char) { - *CSR_UARTDR =3D port->x_char; - port->icount.tx++; - port->x_char =3D 0; - goto out; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - serial21285_stop_tx(port); - goto out; - } - - do { - *CSR_UARTDR =3D xmit->buf[xmit->tail]; - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0 && !(*CSR_UARTFLG & 0x20)); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - serial21285_stop_tx(port); + uart_port_tx_limited(port, ch, 256, + !(*CSR_UARTFLG & 0x20), + *CSR_UARTDR =3D ch, + ({})); =20 - out: return IRQ_HANDLED; } =20 diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/alte= ra_jtaguart.c index 23f339757894..f224f5141726 100644 --- a/drivers/tty/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c @@ -137,39 +137,17 @@ static void altera_jtaguart_rx_chars(struct altera_jt= aguart *pp) static void altera_jtaguart_tx_chars(struct altera_jtaguart *pp) { struct uart_port *port =3D &pp->port; - struct circ_buf *xmit =3D &port->state->xmit; - unsigned int pending, count; - - if (port->x_char) { - /* Send special char - probably flow control */ - writel(port->x_char, port->membase + ALTERA_JTAGUART_DATA_REG); - port->x_char =3D 0; - port->icount.tx++; - return; - } + unsigned int space; + u8 ch; =20 - pending =3D uart_circ_chars_pending(xmit); - if (pending > 0) { - count =3D (readl(port->membase + ALTERA_JTAGUART_CONTROL_REG) & - ALTERA_JTAGUART_CONTROL_WSPACE_MSK) >> - ALTERA_JTAGUART_CONTROL_WSPACE_OFF; - if (count > pending) - count =3D pending; - if (count > 0) { - pending -=3D count; - while (count--) { - writel(xmit->buf[xmit->tail], - port->membase + ALTERA_JTAGUART_DATA_REG); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - } - if (pending < WAKEUP_CHARS) - uart_write_wakeup(port); - } - } + space =3D readl(port->membase + ALTERA_JTAGUART_CONTROL_REG); + space &=3D ALTERA_JTAGUART_CONTROL_WSPACE_MSK; + space >>=3D ALTERA_JTAGUART_CONTROL_WSPACE_OFF; =20 - if (pending =3D=3D 0) - altera_jtaguart_stop_tx(port); + uart_port_tx_limited(port, ch, space, + true, + writel(ch, port->membase + ALTERA_JTAGUART_DATA_REG), + ({})); } =20 static irqreturn_t altera_jtaguart_interrupt(int irq, void *data) diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl01= 0.c index af27fb8ec145..a98fae2ca422 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c @@ -164,34 +164,12 @@ static void pl010_rx_chars(struct uart_port *port) =20 static void pl010_tx_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - int count; + u8 ch; =20 - if (port->x_char) { - writel(port->x_char, port->membase + UART01x_DR); - port->icount.tx++; - port->x_char =3D 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - pl010_stop_tx(port); - return; - } - - count =3D port->fifosize >> 1; - do { - writel(xmit->buf[xmit->tail], port->membase + UART01x_DR); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - pl010_stop_tx(port); + uart_port_tx_limited(port, ch, port->fifosize >> 1, + true, + writel(ch, port->membase + UART01x_DR), + ({})); } =20 static void pl010_modem_status(struct uart_amba_port *uap) diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 450f4edfda0f..915ee4b0d594 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -122,36 +122,12 @@ static void apbuart_rx_chars(struct uart_port *port) =20 static void apbuart_tx_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - int count; - - if (port->x_char) { - UART_PUT_CHAR(port, port->x_char); - port->icount.tx++; - port->x_char =3D 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - apbuart_stop_tx(port); - return; - } - - /* amba: fill FIFO */ - count =3D port->fifosize >> 1; - do { - UART_PUT_CHAR(port, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - apbuart_stop_tx(port); + uart_port_tx_limited(port, ch, port->fifosize >> 1, + true, + UART_PUT_CHAR(port, ch), + ({})); } =20 static irqreturn_t apbuart_int(int irq, void *dev_id) diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx= _uart.c index 5d9737c2d1f2..62bc7244dc67 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -303,53 +303,24 @@ static void bcm_uart_do_rx(struct uart_port *port) */ static void bcm_uart_do_tx(struct uart_port *port) { - struct circ_buf *xmit; - unsigned int val, max_count; - - if (port->x_char) { - bcm_uart_writel(port, port->x_char, UART_FIFO_REG); - port->icount.tx++; - port->x_char =3D 0; - return; - } - - if (uart_tx_stopped(port)) { - bcm_uart_stop_tx(port); - return; - } - - xmit =3D &port->state->xmit; - if (uart_circ_empty(xmit)) - goto txq_empty; + unsigned int val; + bool pending; + u8 ch; =20 val =3D bcm_uart_readl(port, UART_MCTL_REG); val =3D (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT; - max_count =3D port->fifosize - val; - - while (max_count--) { - unsigned int c; =20 - c =3D xmit->buf[xmit->tail]; - bcm_uart_writel(port, c, UART_FIFO_REG); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - goto txq_empty; - return; + pending =3D uart_port_tx_limited(port, ch, port->fifosize - val, + true, + bcm_uart_writel(port, ch, UART_FIFO_REG), + ({})); + if (pending) + return; =20 -txq_empty: /* nothing to send, disable transmit interrupt */ val =3D bcm_uart_readl(port, UART_IR_REG); val &=3D ~UART_TX_INT_MASK; bcm_uart_writel(port, val, UART_IR_REG); - return; } =20 /* diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index ed0e763f622a..85ce1e9af44a 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c @@ -171,6 +171,13 @@ static void mux_break_ctl(struct uart_port *port, int = break_state) { } =20 +static void mux_tx_done(struct uart_port *port) +{ + /* FIXME js: really needs to wait? */ + while (UART_GET_FIFO_CNT(port)) + udelay(1); +} + /** * mux_write - Write chars to the mux fifo. * @port: Ptr to the uart_port. @@ -180,39 +187,13 @@ static void mux_break_ctl(struct uart_port *port, int= break_state) */ static void mux_write(struct uart_port *port) { - int count; - struct circ_buf *xmit =3D &port->state->xmit; - - if(port->x_char) { - UART_PUT_CHAR(port, port->x_char); - port->icount.tx++; - port->x_char =3D 0; - return; - } - - if(uart_circ_empty(xmit) || uart_tx_stopped(port)) { - mux_stop_tx(port); - return; - } - - count =3D (port->fifosize) - UART_GET_FIFO_CNT(port); - do { - UART_PUT_CHAR(port, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if(uart_circ_empty(xmit)) - break; - - } while(--count > 0); - - while(UART_GET_FIFO_CNT(port))=20 - udelay(1); - - if(uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - mux_stop_tx(port); + uart_port_tx_limited(port, ch, + port->fifosize - UART_GET_FIFO_CNT(port), + true, + UART_PUT_CHAR(port, ch), + mux_tx_done(port)); } =20 /** diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uar= t.c index ba16e1da6bd3..7b566404cb33 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -335,40 +335,12 @@ static void mvebu_uart_rx_chars(struct uart_port *por= t, unsigned int status) =20 static void mvebu_uart_tx_chars(struct uart_port *port, unsigned int statu= s) { - struct circ_buf *xmit =3D &port->state->xmit; - unsigned int count; - unsigned int st; - - if (port->x_char) { - writel(port->x_char, port->membase + UART_TSH(port)); - port->icount.tx++; - port->x_char =3D 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - mvebu_uart_stop_tx(port); - return; - } - - for (count =3D 0; count < port->fifosize; count++) { - writel(xmit->buf[xmit->tail], port->membase + UART_TSH(port)); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - - if (uart_circ_empty(xmit)) - break; - - st =3D readl(port->membase + UART_STAT); - if (st & STAT_TX_FIFO_FUL) - break; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - mvebu_uart_stop_tx(port); + uart_port_tx_limited(port, ch, port->fifosize, + !(readl(port->membase + UART_STAT) & STAT_TX_FIFO_FUL), + writel(ch, port->membase + UART_TSH(port)), + ({})); } =20 static irqreturn_t mvebu_uart_isr(int irq, void *dev_id) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-ser= ial.c index b7b76e49115e..ccea746e1214 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -348,34 +348,12 @@ static void serial_omap_put_char(struct uart_omap_por= t *up, unsigned char ch) =20 static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) { - struct circ_buf *xmit =3D &up->port.state->xmit; - int count; + u8 ch; =20 - if (up->port.x_char) { - serial_omap_put_char(up, up->port.x_char); - up->port.icount.tx++; - up->port.x_char =3D 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_omap_stop_tx(&up->port); - return; - } - count =3D up->port.fifosize / 4; - do { - serial_omap_put_char(up, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - if (uart_circ_empty(xmit)) - serial_omap_stop_tx(&up->port); + uart_port_tx_limited(&up->port, ch, up->port.fifosize / 4, + true, + serial_omap_put_char(up, ch), + ({})); } =20 static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 2d25231fad84..444fa4b654ac 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -174,35 +174,12 @@ static inline void receive_chars(struct uart_pxa_port= *up, int *status) =20 static void transmit_chars(struct uart_pxa_port *up) { - struct circ_buf *xmit =3D &up->port.state->xmit; - int count; + u8 ch; =20 - if (up->port.x_char) { - serial_out(up, UART_TX, up->port.x_char); - up->port.icount.tx++; - up->port.x_char =3D 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial_pxa_stop_tx(&up->port); - return; - } - - count =3D up->port.fifosize / 2; - do { - serial_out(up, UART_TX, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); - - - if (uart_circ_empty(xmit)) - serial_pxa_stop_tx(&up->port); + uart_port_tx_limited(&up->port, ch, up->port.fifosize / 2, + true, + serial_out(up, UART_TX, ch), + ({})); } =20 static void serial_pxa_start_tx(struct uart_port *port) diff --git a/drivers/tty/serial/rp2.c b/drivers/tty/serial/rp2.c index b81afb06f1f4..749b873a5d99 100644 --- a/drivers/tty/serial/rp2.c +++ b/drivers/tty/serial/rp2.c @@ -427,32 +427,13 @@ static void rp2_rx_chars(struct rp2_uart_port *up) =20 static void rp2_tx_chars(struct rp2_uart_port *up) { - u16 max_tx =3D FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT); - struct circ_buf *xmit =3D &up->port.state->xmit; + u8 ch; =20 - if (uart_tx_stopped(&up->port)) { - rp2_uart_stop_tx(&up->port); - return; - } - - for (; max_tx !=3D 0; max_tx--) { - if (up->port.x_char) { - writeb(up->port.x_char, up->base + RP2_DATA_BYTE); - up->port.x_char =3D 0; - up->port.icount.tx++; - continue; - } - if (uart_circ_empty(xmit)) { - rp2_uart_stop_tx(&up->port); - break; - } - writeb(xmit->buf[xmit->tail], up->base + RP2_DATA_BYTE); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->port.icount.tx++; - } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&up->port); + uart_port_tx_limited(&up->port, ch, + FIFO_SIZE - readw(up->base + RP2_TX_FIFO_COUNT), + true, + writeb(ch, up->base + RP2_DATA_BYTE), + ({})); } =20 static void rp2_ch_interrupt(struct rp2_uart_port *up) diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_t= xx9.c index e12f1dc18c38..eab387b01e36 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -321,34 +321,12 @@ receive_chars(struct uart_port *up, unsigned int *sta= tus) =20 static inline void transmit_chars(struct uart_port *up) { - struct circ_buf *xmit =3D &up->state->xmit; - int count; + u8 ch; =20 - if (up->x_char) { - sio_out(up, TXX9_SITFIFO, up->x_char); - up->icount.tx++; - up->x_char =3D 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(up)) { - serial_txx9_stop_tx(up); - return; - } - - count =3D TXX9_SIO_TX_FIFO; - do { - sio_out(up, TXX9_SITFIFO, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - up->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(up); - - if (uart_circ_empty(xmit)) - serial_txx9_stop_tx(up); + uart_port_tx_limited(up, ch, TXX9_SIO_TX_FIFO, + true, + sio_out(up, TXX9_SITFIFO, ch), + ({})); } =20 static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id) diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index 4761f172103a..64cfd455f556 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -288,33 +288,12 @@ static void __ssp_transmit_char(struct sifive_serial_= port *ssp, int ch) */ static void __ssp_transmit_chars(struct sifive_serial_port *ssp) { - struct circ_buf *xmit =3D &ssp->port.state->xmit; - int count; - - if (ssp->port.x_char) { - __ssp_transmit_char(ssp, ssp->port.x_char); - ssp->port.icount.tx++; - ssp->port.x_char =3D 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&ssp->port)) { - sifive_serial_stop_tx(&ssp->port); - return; - } - count =3D SIFIVE_TX_FIFO_DEPTH; - do { - __ssp_transmit_char(ssp, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - ssp->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&ssp->port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - sifive_serial_stop_tx(&ssp->port); + uart_port_tx_limited(&ssp->port, ch, SIFIVE_TX_FIFO_DEPTH, + true, + __ssp_transmit_char(ssp, ch), + ({})); } =20 /** diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_ser= ial.c index 342a87967631..3f34f7bb7700 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -626,35 +626,12 @@ static inline void sprd_rx(struct uart_port *port) =20 static inline void sprd_tx(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - int count; - - if (port->x_char) { - serial_out(port, SPRD_TXD, port->x_char); - port->icount.tx++; - port->x_char =3D 0; - return; - } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - sprd_stop_tx(port); - return; - } - - count =3D THLD_TX_EMPTY; - do { - serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]); - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - sprd_stop_tx(port); + uart_port_tx_limited(port, ch, THLD_TX_EMPTY, + true, + serial_out(port, SPRD_TXD, ch), + ({})); } =20 /* this handles the interrupt from one port */ diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index fcecea689a0d..5215e6910f68 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -237,50 +237,12 @@ static inline unsigned asc_hw_txroom(struct uart_port= *port) */ static void asc_transmit_chars(struct uart_port *port) { - struct circ_buf *xmit =3D &port->state->xmit; - int txroom; - unsigned char c; - - txroom =3D asc_hw_txroom(port); - - if ((txroom !=3D 0) && port->x_char) { - c =3D port->x_char; - port->x_char =3D 0; - asc_out(port, ASC_TXBUF, c); - port->icount.tx++; - txroom =3D asc_hw_txroom(port); - } - - if (uart_tx_stopped(port)) { - /* - * We should try and stop the hardware here, but I - * don't think the ASC has any way to do that. - */ - asc_disable_tx_interrupts(port); - return; - } - - if (uart_circ_empty(xmit)) { - asc_disable_tx_interrupts(port); - return; - } - - if (txroom =3D=3D 0) - return; - - do { - c =3D xmit->buf[xmit->tail]; - xmit->tail =3D (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - asc_out(port, ASC_TXBUF, c); - port->icount.tx++; - txroom--; - } while ((txroom > 0) && (!uart_circ_empty(xmit))); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); + u8 ch; =20 - if (uart_circ_empty(xmit)) - asc_disable_tx_interrupts(port); + uart_port_tx_limited(port, ch, asc_hw_txroom(port), + true, + asc_out(port, ASC_TXBUF, ch), + ({})); } =20 static void asc_receive_chars(struct uart_port *port) --=20 2.37.3