The commit b5199d468177 (tty/serial: at91: add support to FIFOs) changed data stream 32-bit accesses in the driver to 8-bit. This, unfortunately, breaks data register access on ATNGW100, where the IP needs data register accesses to be long accesses (all other accesses appear to be OK). This change introduces a new master variable to allow interface drivers to specify that 8-bit data transfer I/O is required. This change also introduces the ability to set this variable via device tree bindings in the driver. Fixes: b5199d468177 (tty/serial: at91: add support to FIFOs) Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> --- drivers/tty/serial/atmel_serial.c | 45 +++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index e91b3b2f..0312bce 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -155,6 +155,7 @@ struct atmel_uart_port { u32 rts_high; u32 rts_low; bool ms_irq_enabled; + u32 reg_io_width; /* I/O width in bytes */ bool is_usart; /* usart or uart */ struct timer_list uart_timer; /* uart timer */ @@ -214,6 +215,34 @@ static inline void atmel_uart_writeb(struct uart_port *port, u32 reg, u8 value) __raw_writeb(value, port->membase + reg); } +static inline u8 atmel_uart_read_reg(struct uart_port *port, u32 reg) +{ + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + + switch (atmel_port->reg_io_width) { + case 1: + return atmel_uart_readb(port, reg); + case 4: + default: + return atmel_uart_readl(port, reg); + } +} + +static inline void atmel_uart_write_reg(struct uart_port *port, u32 reg, u8 value) +{ + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); + + switch (atmel_port->reg_io_width) { + case 1: + atmel_uart_writeb(port, reg, value); + break; + case 4: + default: + atmel_uart_writel(port, reg, value); + break; + } +} + #ifdef CONFIG_SERIAL_ATMEL_PDC static bool atmel_use_pdc_rx(struct uart_port *port) { @@ -658,7 +687,7 @@ static void atmel_rx_chars(struct uart_port *port) status = atmel_uart_readl(port, ATMEL_US_CSR); while (status & ATMEL_US_RXRDY) { - ch = atmel_uart_readb(port, ATMEL_US_RHR); + ch = atmel_uart_read_reg(port, ATMEL_US_RHR); /* * note that the error handling code is @@ -709,7 +738,7 @@ static void atmel_tx_chars(struct uart_port *port) if (port->x_char && (atmel_uart_readl(port, ATMEL_US_CSR) & atmel_port->tx_done_mask)) { - atmel_uart_writeb(port, ATMEL_US_THR, port->x_char); + atmel_uart_write_reg(port, ATMEL_US_THR, port->x_char); port->icount.tx++; port->x_char = 0; } @@ -718,7 +747,7 @@ static void atmel_tx_chars(struct uart_port *port) while (atmel_uart_readl(port, ATMEL_US_CSR) & atmel_port->tx_done_mask) { - atmel_uart_writeb(port, ATMEL_US_THR, xmit->buf[xmit->tail]); + atmel_uart_write_reg(port, ATMEL_US_THR, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (uart_circ_empty(xmit)) @@ -2294,7 +2323,7 @@ static int atmel_poll_get_char(struct uart_port *port) while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_RXRDY)) cpu_relax(); - return atmel_uart_readb(port, ATMEL_US_RHR); + return atmel_uart_read_reg(port, ATMEL_US_RHR); } static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) @@ -2302,7 +2331,7 @@ static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) cpu_relax(); - atmel_uart_writeb(port, ATMEL_US_THR, ch); + atmel_uart_write_reg(port, ATMEL_US_THR, ch); } #endif @@ -2409,7 +2438,7 @@ static void atmel_console_putchar(struct uart_port *port, int ch) { while (!(atmel_uart_readl(port, ATMEL_US_CSR) & ATMEL_US_TXRDY)) cpu_relax(); - atmel_uart_writeb(port, ATMEL_US_THR, ch); + atmel_uart_write_reg(port, ATMEL_US_THR, ch); } /* @@ -2762,6 +2791,10 @@ static int atmel_serial_probe(struct platform_device *pdev) port = &atmel_ports[ret]; port->backup_imr = 0; port->uart.line = ret; + + of_property_read_u32(pdev->dev.of_node, "reg-io-width", + &port->reg_io_width); + atmel_serial_probe_fifos(port, pdev); spin_lock_init(&port->lock_suspended); -- 2.5.0 -- 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