mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
serial: msm_geni_serial: Fix DMA RX FSM reset sequence
Update the DMA RX FSM reset sequence as per HPG recommendations. Currently driver calling msm_geni_serial_rx_fsm_rst() even in case of RX inactive. RX FSM reset command generates RX_RESET_DONE bit. There is a possible race between polling for RX_RESET and ISR for RX_RESET. This can result into introducing delay during BT open. Fix this by updating RX FSM reset sequence only in case of cancel command timeout. Change-Id: I90532aa72fdad462a616eded3e149bc6b721fe7b Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
This commit is contained in:
parent
d8534164bb
commit
346e464ccf
1 changed files with 14 additions and 24 deletions
|
|
@ -1384,26 +1384,6 @@ static void msm_geni_serial_start_rx(struct uart_port *uport)
|
|||
start_rx_sequencer(&port->uport);
|
||||
}
|
||||
|
||||
|
||||
static void msm_geni_serial_rx_fsm_rst(struct uart_port *uport)
|
||||
{
|
||||
unsigned int rx_irq_en;
|
||||
int done = 0;
|
||||
int tries = 0;
|
||||
|
||||
rx_irq_en = geni_read_reg_nolog(uport->membase, SE_DMA_RX_IRQ_EN);
|
||||
geni_write_reg_nolog(0, uport->membase, SE_DMA_RX_IRQ_EN_SET);
|
||||
geni_write_reg_nolog(1, uport->membase, SE_DMA_RX_FSM_RST);
|
||||
do {
|
||||
done = msm_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT,
|
||||
RX_RESET_DONE, true);
|
||||
tries++;
|
||||
} while (!done && tries < 5);
|
||||
geni_write_reg_nolog(RX_DMA_DONE | RX_RESET_DONE, uport->membase,
|
||||
SE_DMA_RX_IRQ_CLR);
|
||||
geni_write_reg_nolog(rx_irq_en, uport->membase, SE_DMA_RX_IRQ_EN_SET);
|
||||
}
|
||||
|
||||
static void msm_geni_serial_set_manual_flow(bool enable,
|
||||
struct msm_geni_serial_port *port)
|
||||
{
|
||||
|
|
@ -1451,7 +1431,7 @@ static void stop_rx_sequencer(struct uart_port *uport)
|
|||
IPC_LOG_MSG(port->ipc_log_misc,
|
||||
"%s: RX is Inactive, geni_sts: 0x%x\n",
|
||||
__func__, geni_status);
|
||||
goto exit_rx_seq;
|
||||
return;
|
||||
}
|
||||
|
||||
port->s_cmd_done = false;
|
||||
|
|
@ -1510,15 +1490,25 @@ static void stop_rx_sequencer(struct uart_port *uport)
|
|||
IPC_LOG_MSG(port->console_log,
|
||||
"%s abort fail 0x%x\n", __func__, geni_status);
|
||||
}
|
||||
|
||||
if (port->xfer_mode == SE_DMA) {
|
||||
port->s_cmd_done = false;
|
||||
reinit_completion(&port->s_cmd_timeout);
|
||||
geni_write_reg_nolog(1, uport->membase,
|
||||
SE_DMA_RX_FSM_RST);
|
||||
|
||||
timeout = geni_wait_for_cmd_done(uport,
|
||||
is_irq_masked);
|
||||
if (timeout)
|
||||
IPC_LOG_MSG(port->ipc_log_misc,
|
||||
"%s: rx fsm reset failed\n", __func__);
|
||||
}
|
||||
}
|
||||
/* Enable the interrupts once the cancel operation is done. */
|
||||
msm_geni_serial_enable_interrupts(uport);
|
||||
port->s_cmd = false;
|
||||
|
||||
exit_rx_seq:
|
||||
if (port->xfer_mode == SE_DMA && port->rx_dma)
|
||||
msm_geni_serial_rx_fsm_rst(uport);
|
||||
|
||||
geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
|
||||
IPC_LOG_MSG(port->ipc_log_misc, "%s: End 0x%x\n",
|
||||
__func__, geni_status);
|
||||
|
|
|
|||
Loading…
Reference in a new issue