[PATCH V2 6/8] serial: at91: make DBGU support dma and pdc transfers
Jean-Christophe PLAGNIOL-VILLARD
plagnioj at jcrosoft.com
Thu Jul 18 04:18:49 EDT 2013
On 10:43 Tue 16 Jul , Elen Song wrote:
> Because the DBGU lack of receive timeout register, so we use a timer to trigger
> data receive.
please re-order the patch put patch 7 before 6
so we can distinguish the uart type not by line = 0 which is wrong as if you
can have no dbgu registered and line == 0 can be a normal usart
Best Regards,
J.
>
> Signed-off-by: Elen Song <elen.song at atmel.com>
> Signed-off-by: Ludovic Desroches <ludovic.desroches at atmel.com>
> ---
> drivers/tty/serial/atmel_serial.c | 48 ++++++++++++++++++++++++++++++++-----
> 1 file changed, 42 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
> index ad787fd1..afecdfa 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -41,6 +41,7 @@
> #include <linux/uaccess.h>
> #include <linux/pinctrl/consumer.h>
> #include <linux/platform_data/atmel.h>
> +#include <linux/timer.h>
>
> #include <asm/io.h>
> #include <asm/ioctls.h>
> @@ -167,6 +168,7 @@ struct atmel_uart_port {
>
> struct serial_rs485 rs485; /* rs485 settings */
> unsigned int tx_done_mask;
> + struct timer_list uart_timer; /* dbgu timer */
> int (*prepare_rx)(struct uart_port *port);
> int (*prepare_tx)(struct uart_port *port);
> void (*schedule_rx)(struct uart_port *port);
> @@ -821,6 +823,9 @@ static void atmel_release_rx_dma(struct uart_port *port)
> atmel_port->desc_rx = NULL;
> atmel_port->chan_rx = NULL;
> atmel_port->cookie_rx = -EINVAL;
> +
> + if (port->line == 0)
> + del_timer_sync(&atmel_port->uart_timer);
> }
>
> static void atmel_rx_from_dma(struct uart_port *port)
> @@ -950,6 +955,15 @@ chan_err:
> return -EINVAL;
> }
>
> +static void atmel_uart_timer_callback(unsigned long data)
> +{
> + struct uart_port *port = (void *)data;
> + struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
> +
> + tasklet_schedule(&atmel_port->tasklet);
> + mod_timer(&atmel_port->uart_timer, jiffies + uart_poll_timeout(port));
> +}
> +
> /*
> * receive interrupt handler.
> */
> @@ -1213,6 +1227,9 @@ static void atmel_release_rx_pdc(struct uart_port *port)
> DMA_FROM_DEVICE);
> kfree(pdc->buf);
> }
> +
> + if (port->line == 0)
> + del_timer_sync(&atmel_port->uart_timer);
> }
>
> static void atmel_rx_from_pdc(struct uart_port *port)
> @@ -1546,17 +1563,36 @@ static int atmel_startup(struct uart_port *port)
>
> if (atmel_use_pdc_rx(port)) {
> /* set UART timeout */
> - UART_PUT_RTOR(port, PDC_RX_TIMEOUT);
> - UART_PUT_CR(port, ATMEL_US_STTTO);
> + if (port->line == 0) {
> + setup_timer(&atmel_port->uart_timer,
> + atmel_uart_timer_callback,
> + (unsigned long)port);
> + mod_timer(&atmel_port->uart_timer,
> + jiffies + uart_poll_timeout(port));
> + /* set USART timeout */
> + } else {
> + UART_PUT_RTOR(port, PDC_RX_TIMEOUT);
> + UART_PUT_CR(port, ATMEL_US_STTTO);
>
> - UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
> + UART_PUT_IER(port, ATMEL_US_ENDRX | ATMEL_US_TIMEOUT);
> + }
> /* enable PDC controller */
> UART_PUT_PTCR(port, ATMEL_PDC_RXTEN);
> } else if (atmel_use_dma_rx(port)) {
> - UART_PUT_RTOR(port, PDC_RX_TIMEOUT);
> - UART_PUT_CR(port, ATMEL_US_STTTO);
> + /* set UART timeout */
> + if (port->line == 0) {
> + setup_timer(&atmel_port->uart_timer,
> + atmel_uart_timer_callback,
> + (unsigned long)port);
> + mod_timer(&atmel_port->uart_timer,
> + jiffies + uart_poll_timeout(port));
> + /* set USART timeout */
> + } else {
> + UART_PUT_RTOR(port, PDC_RX_TIMEOUT);
> + UART_PUT_CR(port, ATMEL_US_STTTO);
>
> - UART_PUT_IER(port, ATMEL_US_TIMEOUT);
> + UART_PUT_IER(port, ATMEL_US_TIMEOUT);
> + }
> } else {
> /* enable receive only */
> UART_PUT_IER(port, ATMEL_US_RXRDY);
> --
> 1.7.9.5
>
More information about the linux-arm-kernel
mailing list