diff options
author | Cyrille Pitchen <cyrille.pitchen@atmel.com> | 2015-07-30 16:33:38 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-08-04 22:07:22 -0700 |
commit | a649943522de07e67a5981b1ff227684b94bada4 (patch) | |
tree | ba03e74b222420b53e57538024113ee8c20574de /drivers/tty/serial/atmel_serial.c | |
parent | b737eeb09e3068b092e116f855aa1973fa24c88c (diff) |
tty/serial: at91: fix I/O accesses on RHR and THR for AVR32
This patch fixes I/O accesses on the Receiver Holding Register and on the
Transmitter Holding Register. Indeed AVR32 can only perform 32bit I/O
accesses on registers: using 8bit I/O accesses would read or write garbage
data.
Fixes: commit b5199d468177 ("tty/serial: at91: add support to FIFOs")
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Tested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/atmel_serial.c')
-rw-r--r-- | drivers/tty/serial/atmel_serial.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index e91b3b2f0590..5ca5cf3e9359 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -204,16 +204,33 @@ static inline void atmel_uart_writel(struct uart_port *port, u32 reg, u32 value) __raw_writel(value, port->membase + reg); } -static inline u8 atmel_uart_readb(struct uart_port *port, u32 reg) +#ifdef CONFIG_AVR32 + +/* AVR32 cannot handle 8 or 16bit I/O accesses but only 32bit I/O accesses */ +static inline u8 atmel_uart_read_char(struct uart_port *port) +{ + return __raw_readl(port->membase + ATMEL_US_RHR); +} + +static inline void atmel_uart_write_char(struct uart_port *port, u8 value) { - return __raw_readb(port->membase + reg); + __raw_writel(value, port->membase + ATMEL_US_THR); } -static inline void atmel_uart_writeb(struct uart_port *port, u32 reg, u8 value) +#else + +static inline u8 atmel_uart_read_char(struct uart_port *port) { - __raw_writeb(value, port->membase + reg); + return __raw_readb(port->membase + ATMEL_US_RHR); } +static inline void atmel_uart_write_char(struct uart_port *port, u8 value) +{ + __raw_writeb(value, port->membase + ATMEL_US_THR); +} + +#endif + #ifdef CONFIG_SERIAL_ATMEL_PDC static bool atmel_use_pdc_rx(struct uart_port *port) { @@ -658,7 +675,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_char(port); /* * note that the error handling code is @@ -709,7 +726,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_char(port, port->x_char); port->icount.tx++; port->x_char = 0; } @@ -718,7 +735,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_char(port, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (uart_circ_empty(xmit)) @@ -2294,7 +2311,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_char(port); } static void atmel_poll_put_char(struct uart_port *port, unsigned char ch) @@ -2302,7 +2319,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_char(port, ch); } #endif @@ -2409,7 +2426,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_char(port, ch); } /* |