From c73942e22aa4a3d910f9be8d48de4080c3a52086 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 21 Sep 2015 14:17:29 +0300 Subject: [PATCH] serial: 8250_dw: proper support for UARTs without busy functionality If the DW_apb_uart is configured with UART_16550_COMPATIBLE configuration parameter set, then the Busy Functionality is not available. These UARTs will never generate the Busy detect indication interrupt, and therefore don't need handling for it. This creates a small optimization for the DW_apb_uarts configured without the busy functionality, but more importantly, it removes the small but real risk of hitting potential issues caused by busy functionality handling when no busy functionality exist. Signed-off-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/serial/snps-dw-apb-uart.txt | 3 +++ drivers/tty/serial/8250/8250_dw.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt index 289c40ed7470..12bbe9f22560 100644 --- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt +++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt @@ -15,6 +15,9 @@ The supplying peripheral clock can also be handled, needing a second property Required elements: "baudclk", "apb_pclk" Optional properties: +- snps,uart-16550-compatible : reflects the value of UART_16550_COMPATIBLE + configuration parameter. Define this if your UART does not implement the busy + functionality. - resets : phandle to the parent reset controller. - reg-shift : quantity to shift the register offsets by. If this property is not present then the register offsets are not shifted. diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 5c6a819e7493..7ed0580d2794 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -65,6 +65,7 @@ struct dw8250_data { struct uart_8250_dma dma; unsigned int skip_autocfg:1; + unsigned int uart_16550_compatible:1; }; #define BYT_PRV_CLK 0x800 @@ -317,8 +318,9 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) p->iotype = UPIO_MEM32; p->regshift = 2; p->serial_in = dw8250_serial_in32; - p->serial_out = dw8250_serial_out32; p->set_termios = dw8250_set_termios; + /* So far none of there implement the Busy Functionality */ + data->uart_16550_compatible = true; } /* Platforms with iDMA */ @@ -375,6 +377,9 @@ static int dw8250_probe(struct platform_device *pdev) data->usr_reg = DW_UART_USR; p->private_data = data; + data->uart_16550_compatible = device_property_read_bool(p->dev, + "snps,uart-16550-compatible"); + err = device_property_read_u32(p->dev, "reg-shift", &val); if (!err) p->regshift = val; @@ -461,6 +466,12 @@ static int dw8250_probe(struct platform_device *pdev) dw8250_quirks(p, data); + /* If the Busy Functionality is not implemented, don't handle it */ + if (data->uart_16550_compatible) { + p->serial_out = NULL; + p->handle_irq = NULL; + } + if (!data->skip_autocfg) dw8250_setup_port(&uart); -- 2.20.1