On Mon, 2018-03-12 at 09:43 +1300, Joshua Scott wrote: > The previous implementation has had a detrimental effect on devices > using > high bitrates (bluetooth), as the fifo being non-empty for a single > check > would result in a 10 µs delay. > > This patch updates the code such that it will allow 1000 retries to > fail > before delaying by 1 µs for the remaining retry limit. > > In addition, the maximum number of retries has been increased, both to > cover the decreased delay length, and to cover a new worst-case seen > on > the Armada 385 SoC. "dmesg ; resize", filling the buffer with text to > output before reconfiguring, required 13 ms to empty the buffer and > avoid > losing characters. I gave a thought about this patch and initial approach. I think we need a kind of quirk depending on which the workaround would be enabled or disabled. > > Signed-off-by: Joshua Scott <joshua.scott@xxxxxxxxxxxxxxxxxxx> > --- > drivers/tty/serial/8250/8250_dw.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_dw.c > b/drivers/tty/serial/8250/8250_dw.c > index 823c1dc..843c2a2 100644 > --- a/drivers/tty/serial/8250/8250_dw.c > +++ b/drivers/tty/serial/8250/8250_dw.c > @@ -127,13 +127,20 @@ static void dw8250_check_lcr(struct uart_port > *p, int value) > /* Returns once the transmitter is empty or we run out of retries */ > static void dw8250_tx_wait_empty(struct uart_port *p, int tries) > { > + unsigned int delay_threshold = tries - 1000; > unsigned int lsr; > > while (tries--) { > lsr = readb (p->membase + (UART_LSR << p->regshift)); > if (lsr & UART_LSR_TEMT) > break; > - udelay (10); > + > + /* The device is first given a chance to empty > without delay, > + * to avoid slowdowns at high bitrates. If after 1000 > tries > + * the buffer has still not emptied, allow more time > for low- > + * speed links. */ > + if (tries < delay_threshold) > + udelay (1); > } > } > > @@ -143,7 +150,7 @@ static void dw8250_serial_out(struct uart_port *p, > int offset, int value) > > /* Allow the TX to drain before we reconfigure */ > if (offset == UART_LCR) > - dw8250_tx_wait_empty(p, 1000); > + dw8250_tx_wait_empty(p, 20000); > > writeb(value, p->membase + (offset << p->regshift)); > -- Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Intel Finland Oy -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html