diff options
author | Qipan Li <Qipan.Li@csr.com> | 2015-07-13 20:52:23 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-07-23 18:32:04 -0400 |
commit | 466e285b1f63e84a6ced5cd18c3c3d90bda73404 (patch) | |
tree | 30e87148646da7df909f0609326c6a72b3b626c8 /drivers/tty/serial/sirfsoc_uart.c | |
parent | 1d26c9ff420f647df4a7a3e9a28736b9cff6359a (diff) |
serial: sirf: let uart's receive start in right place
While UART work in DMA mode, function start_rx will request descriptor
from DMA engine, if there is no left descriptor UART, driver will give
err logs "DMA slave single fail".
currently start_rx is called in set_termios function, so everytime, port
setting will call start_rx once.
Now put start_rx in startup, it will be called once while open the port.
Signed-off-by: Qipan Li <Qipan.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/sirfsoc_uart.c')
-rw-r--r-- | drivers/tty/serial/sirfsoc_uart.c | 46 |
1 files changed, 16 insertions, 30 deletions
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 8cac7ac497e8..c6657de78997 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -413,7 +413,6 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) | |||
413 | break; | 413 | break; |
414 | } | 414 | } |
415 | 415 | ||
416 | sirfport->rx_io_count += rx_count; | ||
417 | port->icount.rx += rx_count; | 416 | port->icount.rx += rx_count; |
418 | 417 | ||
419 | return rx_count; | 418 | return rx_count; |
@@ -600,7 +599,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port) | |||
600 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 599 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
601 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 600 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
602 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | 601 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; |
603 | sirfport->rx_io_count = 0; | ||
604 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | 602 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, |
605 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & | 603 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & |
606 | ~SIRFUART_IO_MODE); | 604 | ~SIRFUART_IO_MODE); |
@@ -632,31 +630,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port) | |||
632 | sirfport->uart_reg->uart_type)); | 630 | sirfport->uart_reg->uart_type)); |
633 | } | 631 | } |
634 | 632 | ||
635 | static void sirfsoc_uart_start_rx(struct uart_port *port) | ||
636 | { | ||
637 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
638 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | ||
639 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | ||
640 | |||
641 | sirfport->rx_io_count = 0; | ||
642 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); | ||
643 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | ||
644 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); | ||
645 | if (sirfport->rx_dma_chan) | ||
646 | sirfsoc_uart_start_next_rx_dma(port); | ||
647 | else { | ||
648 | if (!sirfport->is_atlas7) | ||
649 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
650 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | ||
651 | SIRFUART_RX_IO_INT_EN(uint_en, | ||
652 | sirfport->uart_reg->uart_type)); | ||
653 | else | ||
654 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
655 | SIRFUART_RX_IO_INT_EN(uint_en, | ||
656 | sirfport->uart_reg->uart_type)); | ||
657 | } | ||
658 | } | ||
659 | |||
660 | static unsigned int | 633 | static unsigned int |
661 | sirfsoc_usp_calc_sample_div(unsigned long set_rate, | 634 | sirfsoc_usp_calc_sample_div(unsigned long set_rate, |
662 | unsigned long ioclk_rate, unsigned long *sample_reg) | 635 | unsigned long ioclk_rate, unsigned long *sample_reg) |
@@ -850,7 +823,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
850 | rx_time_out = SIRFSOC_UART_RX_TIMEOUT(set_baud, 20000); | 823 | rx_time_out = SIRFSOC_UART_RX_TIMEOUT(set_baud, 20000); |
851 | rx_time_out = SIRFUART_RECV_TIMEOUT_VALUE(rx_time_out); | 824 | rx_time_out = SIRFUART_RECV_TIMEOUT_VALUE(rx_time_out); |
852 | txfifo_op_reg = rd_regl(port, ureg->sirfsoc_tx_fifo_op); | 825 | txfifo_op_reg = rd_regl(port, ureg->sirfsoc_tx_fifo_op); |
853 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_STOP); | ||
854 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, | 826 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, |
855 | (txfifo_op_reg & ~SIRFUART_FIFO_START)); | 827 | (txfifo_op_reg & ~SIRFUART_FIFO_START)); |
856 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { | 828 | if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { |
@@ -906,7 +878,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
906 | txfifo_op_reg |= SIRFUART_FIFO_START; | 878 | txfifo_op_reg |= SIRFUART_FIFO_START; |
907 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, txfifo_op_reg); | 879 | wr_regl(port, ureg->sirfsoc_tx_fifo_op, txfifo_op_reg); |
908 | uart_update_timeout(port, termios->c_cflag, set_baud); | 880 | uart_update_timeout(port, termios->c_cflag, set_baud); |
909 | sirfsoc_uart_start_rx(port); | ||
910 | wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_TX_EN | SIRFUART_RX_EN); | 881 | wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_TX_EN | SIRFUART_RX_EN); |
911 | spin_unlock_irqrestore(&port->lock, flags); | 882 | spin_unlock_irqrestore(&port->lock, flags); |
912 | } | 883 | } |
@@ -925,6 +896,7 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
925 | { | 896 | { |
926 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 897 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
927 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 898 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
899 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | ||
928 | unsigned int index = port->line; | 900 | unsigned int index = port->line; |
929 | int ret; | 901 | int ret; |
930 | irq_modify_status(port->irq, IRQ_NOREQUEST, IRQ_NOAUTOEN); | 902 | irq_modify_status(port->irq, IRQ_NOREQUEST, IRQ_NOAUTOEN); |
@@ -994,7 +966,6 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
994 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, | 966 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, |
995 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | | 967 | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | |
996 | SIRFSOC_USP_FRADDR_CLR_EN); | 968 | SIRFSOC_USP_FRADDR_CLR_EN); |
997 | enable_irq(port->irq); | ||
998 | if (sirfport->rx_dma_chan && !sirfport->is_hrt_enabled) { | 969 | if (sirfport->rx_dma_chan && !sirfport->is_hrt_enabled) { |
999 | sirfport->is_hrt_enabled = true; | 970 | sirfport->is_hrt_enabled = true; |
1000 | sirfport->rx_period_time = 20000000; | 971 | sirfport->rx_period_time = 20000000; |
@@ -1006,6 +977,21 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
1006 | ns_to_ktime(sirfport->rx_period_time), | 977 | ns_to_ktime(sirfport->rx_period_time), |
1007 | HRTIMER_MODE_REL); | 978 | HRTIMER_MODE_REL); |
1008 | } | 979 | } |
980 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); | ||
981 | if (sirfport->rx_dma_chan) | ||
982 | sirfsoc_uart_start_next_rx_dma(port); | ||
983 | else { | ||
984 | if (!sirfport->is_atlas7) | ||
985 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
986 | rd_regl(port, ureg->sirfsoc_int_en_reg) | | ||
987 | SIRFUART_RX_IO_INT_EN(uint_en, | ||
988 | sirfport->uart_reg->uart_type)); | ||
989 | else | ||
990 | wr_regl(port, ureg->sirfsoc_int_en_reg, | ||
991 | SIRFUART_RX_IO_INT_EN(uint_en, | ||
992 | sirfport->uart_reg->uart_type)); | ||
993 | } | ||
994 | enable_irq(port->irq); | ||
1009 | 995 | ||
1010 | return 0; | 996 | return 0; |
1011 | init_rx_err: | 997 | init_rx_err: |