Skip to content

Commit

Permalink
serial: 8250_omap: Handle optional overrun-throttle-ms property
Browse files Browse the repository at this point in the history
[ Upstream commit 1fe0e1f ]

Handle optional overrun-throttle-ms property as done for 8250_fsl in commit
6d7f677 ("serial: 8250: Rate limit serial port rx interrupts during
input overruns"). This can be used to rate limit the UART interrupts on
noisy lines that end up producing messages like the following:

ttyS ttyS2: 4 input overrun(s)

At least on droid4, the multiplexed USB and UART port is left to UART mode
by the bootloader for a debug console, and if a USB charger is connected
on boot, we get noise on the UART until the PMIC related drivers for PHY
and charger are loaded.

With this patch and overrun-throttle-ms = <500> we avoid the extra rx
interrupts.

Cc: Carl Philipp Klemm <philipp@uvos.xyz>
Cc: Merlijn Wajer <merlijn@wizzup.org>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: Vignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20210727103533.51547-2-tony@atomide.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
tmlind authored and gregkh committed Sep 18, 2021
1 parent 9e9d59f commit 9a1de9d
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion drivers/tty/serial/8250/8250_omap.c
Expand Up @@ -617,7 +617,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
struct uart_port *port = dev_id;
struct omap8250_priv *priv = port->private_data;
struct uart_8250_port *up = up_to_u8250p(port);
unsigned int iir;
unsigned int iir, lsr;
int ret;

#ifdef CONFIG_SERIAL_8250_DMA
Expand All @@ -628,6 +628,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
#endif

serial8250_rpm_get(up);
lsr = serial_port_in(port, UART_LSR);
iir = serial_port_in(port, UART_IIR);
ret = serial8250_handle_irq(port, iir);

Expand All @@ -642,6 +643,24 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id)
serial_port_in(port, UART_RX);
}

/* Stop processing interrupts on input overrun */
if ((lsr & UART_LSR_OE) && up->overrun_backoff_time_ms > 0) {
unsigned long delay;

up->ier = port->serial_in(port, UART_IER);
if (up->ier & (UART_IER_RLSI | UART_IER_RDI)) {
port->ops->stop_rx(port);
} else {
/* Keep restarting the timer until
* the input overrun subsides.
*/
cancel_delayed_work(&up->overrun_backoff);
}

delay = msecs_to_jiffies(up->overrun_backoff_time_ms);
schedule_delayed_work(&up->overrun_backoff, delay);
}

serial8250_rpm_put(up);

return IRQ_RETVAL(ret);
Expand Down Expand Up @@ -1353,6 +1372,10 @@ static int omap8250_probe(struct platform_device *pdev)
}
}

if (of_property_read_u32(np, "overrun-throttle-ms",
&up.overrun_backoff_time_ms) != 0)
up.overrun_backoff_time_ms = 0;

priv->wakeirq = irq_of_parse_and_map(np, 1);

pdata = of_device_get_match_data(&pdev->dev);
Expand Down

0 comments on commit 9a1de9d

Please sign in to comment.