diff mbox series

[v3] serial: 8250_omap: Implementation of Errata i2310

Message ID 20240619105903.165434-1-u-kumar1@ti.com
State Superseded
Headers show
Series [v3] serial: 8250_omap: Implementation of Errata i2310 | expand

Commit Message

Kumar, Udit June 19, 2024, 10:59 a.m. UTC
As per Errata i2310[0], Erroneous timeout can be triggered,
if this Erroneous interrupt is not cleared then it may leads
to storm of interrupts, therefore apply Errata i2310 solution.

[0] https://www.ti.com/lit/pdf/sprz536 page 23

Fixes: b67e830d38fa ("serial: 8250: 8250_omap: Fix possible interrupt storm on K3 SoCs")
Cc: stable@vger.kernel.org
Signed-off-by: Udit Kumar <u-kumar1@ti.com>
---
Change logs
Changes in v3:
- CC stable in commit message
Link to v2:
https://lore.kernel.org/all/20240617052253.2188140-1-u-kumar1@ti.com/

Changes in v2:
- Added Fixes Tag and typo correction in commit message
- Corrected bit position to UART_OMAP_EFR2_TIMEOUT_BEHAVE
Link to v1
https://lore.kernel.org/all/20240614061314.290840-1-u-kumar1@ti.com/

 drivers/tty/serial/8250/8250_omap.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

Comments

Vignesh Raghavendra June 24, 2024, 4:46 p.m. UTC | #1
On 6/19/2024 4:29 PM, Udit Kumar wrote:
> As per Errata i2310[0], Erroneous timeout can be triggered,
> if this Erroneous interrupt is not cleared then it may leads
> to storm of interrupts, therefore apply Errata i2310 solution.
> 
> [0] https://www.ti.com/lit/pdf/sprz536 page 23
> 
> Fixes: b67e830d38fa ("serial: 8250: 8250_omap: Fix possible interrupt storm on K3 SoCs")
> Cc: stable@vger.kernel.org
> Signed-off-by: Udit Kumar <u-kumar1@ti.com>
> ---
> Change logs
> Changes in v3:
> - CC stable in commit message
> Link to v2:
> https://lore.kernel.org/all/20240617052253.2188140-1-u-kumar1@ti.com/
> 
> Changes in v2:
> - Added Fixes Tag and typo correction in commit message
> - Corrected bit position to UART_OMAP_EFR2_TIMEOUT_BEHAVE
> Link to v1
> https://lore.kernel.org/all/20240614061314.290840-1-u-kumar1@ti.com/
> 
>  drivers/tty/serial/8250/8250_omap.c | 25 ++++++++++++++++++++-----
>  1 file changed, 20 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
> index 170639d12b2a..ddac0a13cf84 100644
> --- a/drivers/tty/serial/8250/8250_omap.c
> +++ b/drivers/tty/serial/8250/8250_omap.c
> @@ -115,6 +115,10 @@
>  /* RX FIFO occupancy indicator */
>  #define UART_OMAP_RX_LVL		0x19
>  
> +/* Timeout low and High */
> +#define UART_OMAP_TO_L                 0x26
> +#define UART_OMAP_TO_H                 0x27
> +
>  /*
>   * Copy of the genpd flags for the console.
>   * Only used if console suspend is disabled
> @@ -663,13 +667,24 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
>  
>  	/*
>  	 * On K3 SoCs, it is observed that RX TIMEOUT is signalled after
> -	 * FIFO has been drained, in which case a dummy read of RX FIFO
> -	 * is required to clear RX TIMEOUT condition.
> +	 * FIFO has been drained or erroneously.
> +	 * So apply solution of Errata i2310 as mentioned in
> +	 * https://www.ti.com/lit/pdf/sprz536
>  	 */
>  	if (priv->habit & UART_RX_TIMEOUT_QUIRK &&
> -	    (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT &&
> -	    serial_port_in(port, UART_OMAP_RX_LVL) == 0) {
> -		serial_port_in(port, UART_RX);
> +		(iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT) {

This still doesn't match the errata workaround described in the above
doc. Need a check for RX FIFO LVL to be empty (like before). Else we end
up applying workaround on every timeout (including those that are not
spurious) which is undesirable in the IRQ hotpath.

> +		unsigned char efr2, timeout_h, timeout_l;
> +
> +		efr2 = serial_in(up, UART_OMAP_EFR2);
> +		timeout_h = serial_in(up, UART_OMAP_TO_H);
> +		timeout_l = serial_in(up, UART_OMAP_TO_L);
> +		serial_out(up, UART_OMAP_TO_H, 0xFF);
> +		serial_out(up, UART_OMAP_TO_L, 0xFF);
> +		serial_out(up, UART_OMAP_EFR2, UART_OMAP_EFR2_TIMEOUT_BEHAVE);
> +		serial_in(up, UART_IIR);
> +		serial_out(up, UART_OMAP_EFR2, efr2);
> +		serial_out(up, UART_OMAP_TO_H, timeout_h);
> +		serial_out(up, UART_OMAP_TO_L, timeout_l);
>  	}
>  
>  	/* Stop processing interrupts on input overrun */
diff mbox series

Patch

diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index 170639d12b2a..ddac0a13cf84 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -115,6 +115,10 @@ 
 /* RX FIFO occupancy indicator */
 #define UART_OMAP_RX_LVL		0x19
 
+/* Timeout low and High */
+#define UART_OMAP_TO_L                 0x26
+#define UART_OMAP_TO_H                 0x27
+
 /*
  * Copy of the genpd flags for the console.
  * Only used if console suspend is disabled
@@ -663,13 +667,24 @@  static irqreturn_t omap8250_irq(int irq, void *dev_id)
 
 	/*
 	 * On K3 SoCs, it is observed that RX TIMEOUT is signalled after
-	 * FIFO has been drained, in which case a dummy read of RX FIFO
-	 * is required to clear RX TIMEOUT condition.
+	 * FIFO has been drained or erroneously.
+	 * So apply solution of Errata i2310 as mentioned in
+	 * https://www.ti.com/lit/pdf/sprz536
 	 */
 	if (priv->habit & UART_RX_TIMEOUT_QUIRK &&
-	    (iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT &&
-	    serial_port_in(port, UART_OMAP_RX_LVL) == 0) {
-		serial_port_in(port, UART_RX);
+		(iir & UART_IIR_RX_TIMEOUT) == UART_IIR_RX_TIMEOUT) {
+		unsigned char efr2, timeout_h, timeout_l;
+
+		efr2 = serial_in(up, UART_OMAP_EFR2);
+		timeout_h = serial_in(up, UART_OMAP_TO_H);
+		timeout_l = serial_in(up, UART_OMAP_TO_L);
+		serial_out(up, UART_OMAP_TO_H, 0xFF);
+		serial_out(up, UART_OMAP_TO_L, 0xFF);
+		serial_out(up, UART_OMAP_EFR2, UART_OMAP_EFR2_TIMEOUT_BEHAVE);
+		serial_in(up, UART_IIR);
+		serial_out(up, UART_OMAP_EFR2, efr2);
+		serial_out(up, UART_OMAP_TO_H, timeout_h);
+		serial_out(up, UART_OMAP_TO_L, timeout_l);
 	}
 
 	/* Stop processing interrupts on input overrun */