Commit 1fe0e1fa authored by Tony Lindgren's avatar Tony Lindgren Committed by Greg Kroah-Hartman
Browse files

serial: 8250_omap: Handle optional overrun-throttle-ms property



Handle optional overrun-throttle-ms property as done for 8250_fsl in commit
6d7f677a ("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: default avatarTony Lindgren <tony@atomide.com>
Link: https://lore.kernel.org/r/20210727103533.51547-2-tony@atomide.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1a191ddc
Loading
Loading
Loading
Loading
+24 −1
Original line number Diff line number Diff line
@@ -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
@@ -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);

@@ -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);
@@ -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);