From: Jiri Slaby <jirislaby@kernel.org>
To: Crescent Hsieh <crescentcy.hsieh@moxa.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
FangpingFP.Cheng@moxa.com, Epson.Chiang@moxa.com
Subject: Re: [PATCH v3 10/15] serial: 8250_mxpcie: defer uart_write_wakeup() to workqueue
Date: Thu, 9 Jul 2026 10:07:07 +0200 [thread overview]
Message-ID: <009b213a-bc0a-41a0-8655-80cf262c2174@kernel.org> (raw)
In-Reply-To: <20260709053314.435629-11-crescentcy.hsieh@moxa.com>
On 09. 07. 26, 7:33, Crescent Hsieh wrote:
> Avoid calling uart_write_wakeup() directly from the interrupt-driven TX
> path.
>
> Defer the wakeup to a per-port work item and coalesce multiple TX events
> using a pending flag, so only one wakeup is scheduled while a previous
> one is still outstanding.
I am a bit worried of this added complexity. So what's the measured
benefit of this actually?
What multiple TX events do you mean to coalesce? The work would run
right after the ISR is completed, or what am I missing?
I am likely missing also the purpose of the MOXA_EVENT_TXLOW flag. The
work won't be scheduled twice. And when it is scheduled once, the event
is set, so no need to check it in the work. Or do you plan on more EVENTs?
> Signed-off-by: Crescent Hsieh <crescentcy.hsieh@moxa.com>
> ---
> drivers/tty/serial/8250/8250_mxpcie.c | 34 +++++++++++++++++++++++----
> 1 file changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/tty/serial/8250/8250_mxpcie.c b/drivers/tty/serial/8250/8250_mxpcie.c
> index c7467fb94021..7b39ad19b331 100644
> --- a/drivers/tty/serial/8250/8250_mxpcie.c
> +++ b/drivers/tty/serial/8250/8250_mxpcie.c
> @@ -15,6 +15,7 @@
> #include <linux/pci.h>
> #include <linux/tty_flip.h>
> #include <linux/types.h>
> +#include <linux/workqueue.h>
>
> #include <linux/8250_pci.h>
> #include <linux/serial_8250.h>
> @@ -104,7 +105,12 @@
> #define MOXA_EVEN_RS_MASK GENMASK(3, 0)
> #define MOXA_ODD_RS_MASK GENMASK(7, 4)
>
> +#define MOXA_EVENT_TXLOW BIT(0)
> +
> struct mxpcie8250_port {
> + struct uart_port *port;
> + struct work_struct work;
> + unsigned long event_flags;
> int line;
> };
>
> @@ -328,6 +334,8 @@ static void mxpcie8250_tx_chars(struct uart_8250_port *up)
> {
> struct uart_port *port = &up->port;
> struct tty_port *tport = &port->state->port;
> + struct device *dev = port->dev;
> + struct mxpcie8250 *priv = dev_get_drvdata(dev);
> unsigned int count, txsize;
> unsigned char c;
>
> @@ -348,9 +356,10 @@ static void mxpcie8250_tx_chars(struct uart_8250_port *up)
>
> serial_out(up, MOXA_PUART_TX_FIFO_MEM + i, c);
> }
> - if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
> - uart_write_wakeup(port);
> -
> + if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) {
> + if (!test_and_set_bit(MOXA_EVENT_TXLOW, &priv->port[port->port_id].event_flags))
> + schedule_work(&priv->port[port->port_id].work);
> + }
> if (kfifo_is_empty(&tport->xmit_fifo) && !(up->capabilities & UART_CAP_RPM))
> port->ops->stop_tx(port);
> }
> @@ -377,6 +386,14 @@ static int mxpcie8250_handle_irq(struct uart_port *port)
> return 1;
> }
>
> +static void mxpcie8250_work_handler(struct work_struct *work)
> +{
> + struct mxpcie8250_port *priv_port = container_of(work, struct mxpcie8250_port, work);
> +
> + if (test_and_clear_bit(MOXA_EVENT_TXLOW, &priv_port->event_flags))
> + uart_write_wakeup(priv_port->port);
> +}
> +
> static void mxpcie8250_init_board(struct pci_dev *pdev, struct mxpcie8250 *priv)
> {
> void __iomem *bar2_base = priv->bar2_base;
> @@ -432,7 +449,7 @@ static void mxpcie8250_setup_port(struct pci_dev *pdev,
> static int mxpcie8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> {
> struct device *dev = &pdev->dev;
> - struct uart_8250_port up = {};
> + struct uart_8250_port up = {}, *new_port;
> struct mxpcie8250 *priv;
> unsigned short device = pdev->device;
> unsigned int num_ports;
> @@ -492,6 +509,11 @@ static int mxpcie8250_probe(struct pci_dev *pdev, const struct pci_device_id *id
> up.port.iotype, priv->port[i].line);
> break;
> }
> + new_port = serial8250_get_port(priv->port[i].line);
> +
> + priv->port[i].port = &new_port->port;
> +
> + INIT_WORK(&priv->port[i].work, mxpcie8250_work_handler);
> }
> pci_set_drvdata(pdev, priv);
>
> @@ -502,8 +524,10 @@ static void mxpcie8250_remove(struct pci_dev *pdev)
> {
> struct mxpcie8250 *priv = pci_get_drvdata(pdev);
>
> - for (unsigned int i = 0; i < priv->num_ports; i++)
> + for (unsigned int i = 0; i < priv->num_ports; i++) {
> + cancel_work_sync(&priv->port[i].work);
> serial8250_unregister_port(priv->port[i].line);
> + }
> }
>
> static const struct pci_device_id mxpcie8250_pci_ids[] = {
--
js
suse labs
next prev parent reply other threads:[~2026-07-09 8:07 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-09 5:32 [PATCH v3 00/15] serial: 8250: add Moxa MUEx50 PCIe board support Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 01/15] serial: 8250: split Moxa PCIe serial board support out of 8250_pci Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 02/15] serial: 8250: add Moxa MUEx50 UART port type Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 03/15] serial: 8250_mxpcie: enable enhanced mode and program FIFO trigger levels Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 04/15] serial: 8250_mxpcie: enable automatic RTS/CTS flow control Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 05/15] serial: 8250_mxpcie: offload XON/XOFF flow control to MUEx50 hardware Crescent Hsieh
2026-07-09 6:13 ` Jiri Slaby
2026-07-09 5:33 ` [PATCH v3 06/15] serial: 8250_mxpcie: add custom handle_irq callback Crescent Hsieh
2026-07-09 6:59 ` Jiri Slaby
2026-07-09 5:33 ` [PATCH v3 07/15] serial: 8250_mxpcie: speed up RX using memory-mapped FIFO window Crescent Hsieh
2026-07-09 7:12 ` Jiri Slaby
2026-07-09 5:33 ` [PATCH v3 08/15] serial: 8250_mxpcie: speed up TX " Crescent Hsieh
2026-07-09 7:15 ` Jiri Slaby
2026-07-09 5:33 ` [PATCH v3 09/15] serial: 8250_mxpcie: introduce per-port private data structure Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 10/15] serial: 8250_mxpcie: defer uart_write_wakeup() to workqueue Crescent Hsieh
2026-07-09 8:07 ` Jiri Slaby [this message]
2026-07-09 5:33 ` [PATCH v3 11/15] serial: 8250_mxpcie: support serial interface mode switching Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 12/15] serial: 8250: allow low-level drivers to override break control Crescent Hsieh
2026-07-09 8:10 ` Jiri Slaby
2026-07-09 5:33 ` [PATCH v3 13/15] serial: 8250_mxpcie: add break support for RS485 using MUEx50 features Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 14/15] serial: 8250: allow UART drivers to override rx_trig_bytes handling Crescent Hsieh
2026-07-09 5:33 ` [PATCH v3 15/15] serial: 8250_mxpcie: implement rx_trig_bytes callbacks via MUEx50 RTL Crescent Hsieh
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=009b213a-bc0a-41a0-8655-80cf262c2174@kernel.org \
--to=jirislaby@kernel.org \
--cc=Epson.Chiang@moxa.com \
--cc=FangpingFP.Cheng@moxa.com \
--cc=andy.shevchenko@gmail.com \
--cc=crescentcy.hsieh@moxa.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox