[PATCH v3 1/3] tty: amba-pl011: define flag register bits for ZTE device
From: Sudeep Holla <hidden>
Date: 2016-09-16 14:23:57
Also in:
linux-serial
Hi Shawn, Russell, I noticed this change is in linux-next and but I happen to hit an issue with this as I tested it with earlycon enabled today for the first time. On 08/07/16 10:00, Shawn Guo wrote:
For some reason we do not really understand, ZTE hardware designers choose to define PL011 Flag Register bit positions differently from standard ones as below. Bit Standard ZTE ----------------------------------- CTS 0 1 DSR 1 3 BUSY 3 8 RI 8 0 Let's define these bits into vendor data and get ZTE PL011 supported properly. Signed-off-by: Shawn Guo <redacted>
[...]
quoted hunk ↗ jump to hunk
@@ -2303,13 +2325,16 @@ static struct console amba_console = { static void pl011_putc(struct uart_port *port, int c) { + struct uart_amba_port *uap = + container_of(port, struct uart_amba_port, port); + while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) cpu_relax(); if (port->iotype == UPIO_MEM32) writel(c, port->membase + UART01x_DR); else writeb(c, port->membase + UART01x_DR); - while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY) + while (readl(port->membase + UART01x_FR) & uap->vendor->fr_busy) cpu_relax(); }
The above hunk won't work for early console devices. The earlycon_device just has uart_port and is not uart_amba_port. I don't know how to fix this properly but I thought we could reuse private_data in uart_port for early_con devices. Something like below(incomplete for other vendors, works only for ARM) Regards, Sudeep -->8
diff --git i/drivers/tty/serial/amba-pl011.c w/drivers/tty/serial/amba-pl011.c index 0b78b04e895e..abe88223790c 100644
--- i/drivers/tty/serial/amba-pl011.c
+++ w/drivers/tty/serial/amba-pl011.c@@ -2330,8 +2330,7 @@ static struct console amba_console = { static void pl011_putc(struct uart_port *port, int c) { - struct uart_amba_port *uap = - container_of(port, struct uart_amba_port, port); + struct vendor_data *vendor = port->private_data; while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF) cpu_relax();
@@ -2339,7 +2338,7 @@ static void pl011_putc(struct uart_port *port, int c) writel(c, port->membase + UART01x_DR); else writeb(c, port->membase + UART01x_DR); - while (readl(port->membase + UART01x_FR) & uap->vendor->fr_busy) + while (readl(port->membase + UART01x_FR) & vendor->fr_busy) cpu_relax(); }
@@ -2356,6 +2355,7 @@ static int __init pl011_early_console_setup(struct earlycon_device *device,
if (!device->port.membase)
return -ENODEV;
+ device->port.private_data = &vendor_arm;
device->con->write = pl011_early_write;
return 0;
}