All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frank Li <Frank.li@oss.nxp.com>
To: Otavio Salvador <otavio@ossystems.com.br>
Cc: gregkh@linuxfoundation.org, jirislaby@kernel.org,
	Frank.Li@nxp.com, s.hauer@pengutronix.de, kernel@pengutronix.de,
	festevam@gmail.com, linux-serial@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org,
	"Rodrigo M. Duarte" <rodrigo.duarte@ossystems.com.br>
Subject: Re: [PATCH] serial: imx: keep the CPU out of deep idle while an RS485 port is open
Date: Thu, 15 Oct 2026 10:24:49 -0500	[thread overview]
Message-ID: <atDwQfCyI6yUpAWK@SMW015318> (raw)
In-Reply-To: <20261015144627.2461915-1-otavio@ossystems.com.br>

On Thu, Oct 15, 2026 at 11:46:27AM -0300, Otavio Salvador wrote:
> [You don't often get email from otavio@ossystems.com.br. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> In RS485 mode the driver releases the transmitter (RTS/DE) from the TX
> complete interrupt. On i.MX6UL/ULL the imx6sx cpuidle driver offers an
> "ARM power off" state with a declared exit latency of 300us, measured at
> up to 2ms. When the CPU enters it while the last character is shifted
> out, DE is released that much later. Modbus RTU slaves may answer after
> 3.5 character times (1.75ms at >=19200 baud), so the head of their reply
> collides with our still-driven transmitter and is lost.
>
> Add a CPU latency QoS request of 100us while an RS485 port is open. It
> excludes the power-off state but keeps WFI and WAIT (50us) available, so
> cpuidle can stay enabled and the constraint only applies while the port
> is in use.
>
> The request is added on startup and removed on shutdown, and its value
> follows the RS485 state in imx_uart_rs485_config(), so RS485 enabled
> through TIOCSRS485 after the port is opened, as libmodbus does, is
> covered as well.
>
> Tested-by: Rodrigo M. Duarte <rodrigo.duarte@ossystems.com.br>
> Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/tty/serial/imx.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
>
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index 986fefb45c632..be05ed94bf0c4 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -24,6 +24,7 @@
>  #include <linux/ktime.h>
>  #include <linux/mutex.h>
>  #include <linux/pinctrl/consumer.h>
> +#include <linux/pm_qos.h>
>  #include <linux/rational.h>
>  #include <linux/slab.h>
>  #include <linux/of.h>
> @@ -237,6 +238,7 @@ struct imx_port {
>         struct hrtimer          trigger_start_tx;
>         struct hrtimer          trigger_stop_tx;
>         unsigned int            rxtl;
> +       struct pm_qos_request   rs485_pm_qos;
>  };
>
>  struct imx_port_ucrs {
> @@ -339,6 +341,22 @@ static void start_hrtimer_ms(struct hrtimer *hrt, unsigned long msec)
>         hrtimer_start(hrt, ms_to_ktime(msec), HRTIMER_MODE_REL);
>  }
>
> +/*
> + * In RS485 mode the transmitter is only released from the TX complete
> + * interrupt. If the CPU sits in a deep idle state at that point, the wakeup
> + * delays the release long enough to collide with fast responders on the
> + * bus. The i.MX6UL/SX "ARM power off" state has a 300us exit latency and was
> + * measured at up to 2ms, so keep the CPU out of states slower than this while
> + * an RS485 port is open.
> + */
> +#define IMX_UART_RS485_CPU_LATENCY_US  100
> +
> +static s32 imx_uart_rs485_cpu_latency(u32 rs485_flags)
> +{
> +       return rs485_flags & SER_RS485_ENABLED ?
> +               IMX_UART_RS485_CPU_LATENCY_US : PM_QOS_DEFAULT_VALUE;
> +}
> +
>  /* called with port.lock taken and irqs off */
>  static void imx_uart_soft_reset(struct imx_port *sport)
>  {
> @@ -1585,6 +1603,9 @@ static int imx_uart_startup(struct uart_port *port)
>
>         uart_port_unlock_irqrestore(&sport->port, flags);
>
> +       cpu_latency_qos_add_request(&sport->rs485_pm_qos,
> +                                   imx_uart_rs485_cpu_latency(port->rs485.flags));
> +
>         return 0;
>  }
>
> @@ -1710,6 +1731,8 @@ static void imx_uart_shutdown(struct uart_port *port)
>
>         clk_disable_unprepare(sport->clk_per);
>         clk_disable_unprepare(sport->clk_ipg);
> +
> +       cpu_latency_qos_remove_request(&sport->rs485_pm_qos);
>  }
>
>  /* called with port.lock taken and irqs off */
> @@ -2053,6 +2076,11 @@ static int imx_uart_rs485_config(struct uart_port *port, struct ktermios *termio
>                 imx_uart_start_rx(port);
>         }
>
> +       /* The request only exists while the port is open */
> +       if (cpu_latency_qos_request_active(&sport->rs485_pm_qos))
> +               cpu_latency_qos_update_request(&sport->rs485_pm_qos,
> +                                              imx_uart_rs485_cpu_latency(rs485conf->flags));
> +
>         return 0;
>  }
>
> --
> 2.55.0
>
>

      parent reply	other threads:[~2026-10-15 15:25 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-15 14:46 [PATCH] serial: imx: keep the CPU out of deep idle while an RS485 port is open Otavio Salvador
2026-10-15 14:59 ` sashiko-bot
2026-10-15 15:24 ` Frank Li [this message]

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=atDwQfCyI6yUpAWK@SMW015318 \
    --to=frank.li@oss.nxp.com \
    --cc=Frank.Li@nxp.com \
    --cc=festevam@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=imx@lists.linux.dev \
    --cc=jirislaby@kernel.org \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=otavio@ossystems.com.br \
    --cc=rodrigo.duarte@ossystems.com.br \
    --cc=s.hauer@pengutronix.de \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.