Commit 466e285b authored by Qipan Li's avatar Qipan Li Committed by Greg Kroah-Hartman

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: default avatarQipan Li <Qipan.Li@csr.com>
Signed-off-by: default avatarBarry Song <Baohua.Song@csr.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1d26c9ff
...@@ -413,7 +413,6 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count) ...@@ -413,7 +413,6 @@ sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count)
break; break;
} }
sirfport->rx_io_count += rx_count;
port->icount.rx += rx_count; port->icount.rx += rx_count;
return rx_count; return rx_count;
...@@ -600,7 +599,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port) ...@@ -600,7 +599,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port)
struct sirfsoc_uart_port *sirfport = to_sirfport(port); struct sirfsoc_uart_port *sirfport = to_sirfport(port);
struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
sirfport->rx_io_count = 0;
wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl,
rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) & rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) &
~SIRFUART_IO_MODE); ~SIRFUART_IO_MODE);
...@@ -632,31 +630,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port) ...@@ -632,31 +630,6 @@ static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port)
sirfport->uart_reg->uart_type)); sirfport->uart_reg->uart_type));
} }
static void sirfsoc_uart_start_rx(struct uart_port *port)
{
struct sirfsoc_uart_port *sirfport = to_sirfport(port);
struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
sirfport->rx_io_count = 0;
wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET);
wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0);
wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START);
if (sirfport->rx_dma_chan)
sirfsoc_uart_start_next_rx_dma(port);
else {
if (!sirfport->is_atlas7)
wr_regl(port, ureg->sirfsoc_int_en_reg,
rd_regl(port, ureg->sirfsoc_int_en_reg) |
SIRFUART_RX_IO_INT_EN(uint_en,
sirfport->uart_reg->uart_type));
else
wr_regl(port, ureg->sirfsoc_int_en_reg,
SIRFUART_RX_IO_INT_EN(uint_en,
sirfport->uart_reg->uart_type));
}
}
static unsigned int static unsigned int
sirfsoc_usp_calc_sample_div(unsigned long set_rate, sirfsoc_usp_calc_sample_div(unsigned long set_rate,
unsigned long ioclk_rate, unsigned long *sample_reg) unsigned long ioclk_rate, unsigned long *sample_reg)
...@@ -850,7 +823,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, ...@@ -850,7 +823,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
rx_time_out = SIRFSOC_UART_RX_TIMEOUT(set_baud, 20000); rx_time_out = SIRFSOC_UART_RX_TIMEOUT(set_baud, 20000);
rx_time_out = SIRFUART_RECV_TIMEOUT_VALUE(rx_time_out); rx_time_out = SIRFUART_RECV_TIMEOUT_VALUE(rx_time_out);
txfifo_op_reg = rd_regl(port, ureg->sirfsoc_tx_fifo_op); txfifo_op_reg = rd_regl(port, ureg->sirfsoc_tx_fifo_op);
wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_STOP);
wr_regl(port, ureg->sirfsoc_tx_fifo_op, wr_regl(port, ureg->sirfsoc_tx_fifo_op,
(txfifo_op_reg & ~SIRFUART_FIFO_START)); (txfifo_op_reg & ~SIRFUART_FIFO_START));
if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) {
...@@ -906,7 +878,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, ...@@ -906,7 +878,6 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
txfifo_op_reg |= SIRFUART_FIFO_START; txfifo_op_reg |= SIRFUART_FIFO_START;
wr_regl(port, ureg->sirfsoc_tx_fifo_op, txfifo_op_reg); wr_regl(port, ureg->sirfsoc_tx_fifo_op, txfifo_op_reg);
uart_update_timeout(port, termios->c_cflag, set_baud); uart_update_timeout(port, termios->c_cflag, set_baud);
sirfsoc_uart_start_rx(port);
wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_TX_EN | SIRFUART_RX_EN); wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_TX_EN | SIRFUART_RX_EN);
spin_unlock_irqrestore(&port->lock, flags); spin_unlock_irqrestore(&port->lock, flags);
} }
...@@ -925,6 +896,7 @@ static int sirfsoc_uart_startup(struct uart_port *port) ...@@ -925,6 +896,7 @@ static int sirfsoc_uart_startup(struct uart_port *port)
{ {
struct sirfsoc_uart_port *sirfport = to_sirfport(port); struct sirfsoc_uart_port *sirfport = to_sirfport(port);
struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
unsigned int index = port->line; unsigned int index = port->line;
int ret; int ret;
irq_modify_status(port->irq, IRQ_NOREQUEST, IRQ_NOAUTOEN); irq_modify_status(port->irq, IRQ_NOREQUEST, IRQ_NOAUTOEN);
...@@ -994,7 +966,6 @@ static int sirfsoc_uart_startup(struct uart_port *port) ...@@ -994,7 +966,6 @@ static int sirfsoc_uart_startup(struct uart_port *port)
wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl,
rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) | rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) |
SIRFSOC_USP_FRADDR_CLR_EN); SIRFSOC_USP_FRADDR_CLR_EN);
enable_irq(port->irq);
if (sirfport->rx_dma_chan && !sirfport->is_hrt_enabled) { if (sirfport->rx_dma_chan && !sirfport->is_hrt_enabled) {
sirfport->is_hrt_enabled = true; sirfport->is_hrt_enabled = true;
sirfport->rx_period_time = 20000000; sirfport->rx_period_time = 20000000;
...@@ -1006,6 +977,21 @@ static int sirfsoc_uart_startup(struct uart_port *port) ...@@ -1006,6 +977,21 @@ static int sirfsoc_uart_startup(struct uart_port *port)
ns_to_ktime(sirfport->rx_period_time), ns_to_ktime(sirfport->rx_period_time),
HRTIMER_MODE_REL); HRTIMER_MODE_REL);
} }
wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START);
if (sirfport->rx_dma_chan)
sirfsoc_uart_start_next_rx_dma(port);
else {
if (!sirfport->is_atlas7)
wr_regl(port, ureg->sirfsoc_int_en_reg,
rd_regl(port, ureg->sirfsoc_int_en_reg) |
SIRFUART_RX_IO_INT_EN(uint_en,
sirfport->uart_reg->uart_type));
else
wr_regl(port, ureg->sirfsoc_int_en_reg,
SIRFUART_RX_IO_INT_EN(uint_en,
sirfport->uart_reg->uart_type));
}
enable_irq(port->irq);
return 0; return 0;
init_rx_err: init_rx_err:
......
...@@ -423,7 +423,6 @@ struct sirfsoc_uart_port { ...@@ -423,7 +423,6 @@ struct sirfsoc_uart_port {
struct dma_chan *tx_dma_chan; struct dma_chan *tx_dma_chan;
dma_addr_t tx_dma_addr; dma_addr_t tx_dma_addr;
struct dma_async_tx_descriptor *tx_dma_desc; struct dma_async_tx_descriptor *tx_dma_desc;
unsigned int rx_io_count;
unsigned long transfer_size; unsigned long transfer_size;
enum sirfsoc_tx_state tx_dma_state; enum sirfsoc_tx_state tx_dma_state;
unsigned int cts_gpio; unsigned int cts_gpio;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment