On Fri, 2018-03-16 at 13:42 +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. > > Limit the change to devices with the new "marvell,armada-38x-uart" > compatible string. Also update the code to allow the first 1000 > retries > to not perform a delay. > > The maximum duration of retries has been increased to cover a worst- > case > seen on the Armada 385 SoC. "dmesg ; resize", will fill the buffer > with > text to output before doing a resize. At 9600 baud this took up to 13 > ms > to flush all characters and avoid some getting lost. > You forgot a tag I gave: Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > Signed-off-by: Joshua Scott <joshua.scott@xxxxxxxxxxxxxxxxxxx> > --- > Changes since v1: > Moved 'tries' value into dw82_tx_wait_empty > Removed curly braces around one-line if case > Updated to latest tty-next code > > arch/arm/boot/dts/armada-38x.dtsi | 4 ++-- > drivers/tty/serial/8250/8250_dw.c | 31 +++++++++++++++++++++++++++--- > - > 2 files changed, 29 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/boot/dts/armada-38x.dtsi > b/arch/arm/boot/dts/armada-38x.dtsi > index a6cc568f74f7..73553ccad900 100644 > --- a/arch/arm/boot/dts/armada-38x.dtsi > +++ b/arch/arm/boot/dts/armada-38x.dtsi > @@ -200,7 +200,7 @@ > }; > > uart0: serial@12000 { > - compatible = "snps,dw-apb-uart"; > + compatible = "marvell,armada-38x- > uart"; > reg = <0x12000 0x100>; > reg-shift = <2>; > interrupts = <GIC_SPI 12 > IRQ_TYPE_LEVEL_HIGH>; > @@ -210,7 +210,7 @@ > }; > > uart1: serial@12100 { > - compatible = "snps,dw-apb-uart"; > + compatible = "marvell,armada-38x- > uart"; > reg = <0x12100 0x100>; > reg-shift = <2>; > interrupts = <GIC_SPI 13 > IRQ_TYPE_LEVEL_HIGH>; > diff --git a/drivers/tty/serial/8250/8250_dw.c > b/drivers/tty/serial/8250/8250_dw.c > index 6fcdb90f616a..0529b5cc094b 100644 > --- a/drivers/tty/serial/8250/8250_dw.c > +++ b/drivers/tty/serial/8250/8250_dw.c > @@ -121,25 +121,44 @@ 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) > +static void dw8250_tx_wait_empty(struct uart_port *p) > { > + unsigned int tries = 20000; > + 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); > } > } > > -static void dw8250_serial_out(struct uart_port *p, int offset, int > value) > +static void dw8250_serial_out38x(struct uart_port *p, int offset, int > value) > { > struct dw8250_data *d = p->private_data; > > /* Allow the TX to drain before we reconfigure */ > if (offset == UART_LCR) > - dw8250_tx_wait_empty(p, 1000); > + dw8250_tx_wait_empty(p); > + > + writeb(value, p->membase + (offset << p->regshift)); > + > + if (offset == UART_LCR && !d->uart_16550_compatible) > + dw8250_check_lcr(p, value); > +} > + > + > +static void dw8250_serial_out(struct uart_port *p, int offset, int > value) > +{ > + struct dw8250_data *d = p->private_data; > > writeb(value, p->membase + (offset << p->regshift)); > > @@ -357,6 +376,9 @@ static void dw8250_quirks(struct uart_port *p, > struct dw8250_data *data) > p->serial_in = dw8250_serial_in32be; > p->serial_out = dw8250_serial_out32be; > } > + if (of_device_is_compatible(np, "marvell,armada-38x- > uart")) > + p->serial_out = dw8250_serial_out38x; > + > } else if (acpi_dev_present("APMC0D08", NULL, -1)) { > p->iotype = UPIO_MEM32; > p->regshift = 2; > @@ -666,6 +688,7 @@ static const struct dev_pm_ops dw8250_pm_ops = { > static const struct of_device_id dw8250_of_match[] = { > { .compatible = "snps,dw-apb-uart" }, > { .compatible = "cavium,octeon-3860-uart" }, > + { .compatible = "marvell,armada-38x-uart" }, > { /* Sentinel */ } > }; > MODULE_DEVICE_TABLE(of, dw8250_of_match); -- 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