From: nicolas.ferre@atmel.com (Nicolas Ferre)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH linux-next 1/1] tty/serial: at91: fix I/O accesses on RHR and THR for AVR32
Date: Fri, 31 Jul 2015 09:03:20 +0200 [thread overview]
Message-ID: <55BB1DB8.4010601@atmel.com> (raw)
In-Reply-To: <20150730174605.GE27985@piout.net>
Le 30/07/2015 19:46, Alexandre Belloni a ?crit :
> On 30/07/2015 at 16:33:38 +0200, Cyrille Pitchen wrote :
>> 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>
> Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
>
> Also, tested on at91rm9200ek.
Great! thanks Alexandre.
>> ---
>> Hi all,
>>
>> this patch fixes a bug on AVR32 introduced by the support of FIFOs for
>> AT91. Indeed when FIFOs are enabled they work in Multiple Data mode.
>> The Multiple Data mode allows to read up to 4 data from the Receiver
>> Holding Register (RHR) or write up to 4 data into the Transmitter Holding
>> Register (THR) in a single I/O access. Hence when only one data is to be
>> read from the RHR or written into the THR, the driver cannot use 32bit I/O
>> access anymore but must use 8bit I/O access instead.
>>
>> For ARM-base AT91 SoCs, 8bit I/O accesses can always be used even when
>> FIFOs are not available. However AV32 can only use 32bit I/O accesses.
>>
>> Since atmel_uart_readb(), resp. atmel_uart_writeb(), was created by the
>> FIFO support patch to access the RHR, resp. the THR, this patch replaces
>> it by atmel_uart_read_char(), resp. atmel_uart_write_char(). Hence the
>> actual width of the I/O access now depends only on the architecture.
>>
>> All registers but RHR and THR use 32bit I/O accesses.
>>
>> This patch was tested on a at91sam9260ek board.
>>
>> Best Regards,
>>
>> Cyrille
>>
>> ChangeLog:
>>
>> v1: initial version
>>
>> drivers/tty/serial/atmel_serial.c | 37 +++++++++++++++++++++++++++----------
>> 1 file 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);
>> }
>>
>> /*
>> --
>> 1.8.2.2
>>
>
--
Nicolas Ferre
prev parent reply other threads:[~2015-07-31 7:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-30 14:33 [PATCH linux-next 1/1] tty/serial: at91: fix I/O accesses on RHR and THR for AVR32 Cyrille Pitchen
2015-07-30 15:07 ` Andy Shevchenko
2015-07-30 15:40 ` Nicolas Ferre
2015-07-30 17:46 ` Alexandre Belloni
2015-07-31 7:03 ` Nicolas Ferre [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=55BB1DB8.4010601@atmel.com \
--to=nicolas.ferre@atmel.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).