diff options
author | Dilip Kota <c_dkota@codeaurora.org> | 2014-01-24 02:41:47 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-01-31 01:48:16 -0800 |
commit | 07929a3e5f2c1fbcd268ecd06ada515083baf9ec (patch) | |
tree | bcf6ee99201b12cfd25c8a82ba44acd0f043e3b5 /drivers/tty | |
parent | b36b5f078f7fe6a089690bba149e308f9e7d330e (diff) |
msm_serial_hs: Program RFR to synchronize clock-off sequence with HW
Assert the RFR line during clock off and de-assert
it after the clock off is successful. This is to avoid
the data to be coming from the client during clock off.
Change-Id: I6cad22a63ebd3cfaa20c52445584829b382b7e3a
Signed-off-by: Dilip Kota <c_dkota@codeaurora.org>
Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/msm_serial_hs.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c index 3c72654aa02f..cd392126dac4 100644 --- a/drivers/tty/serial/msm_serial_hs.c +++ b/drivers/tty/serial/msm_serial_hs.c @@ -1139,6 +1139,8 @@ static void msm_hs_set_termios(struct uart_port *uport, data = msm_hs_read(uport, UART_DM_MR1); data &= ~UARTDM_MR1_RX_RDY_CTL_BMSK; msm_hs_write(uport, UART_DM_MR1, data); + /* set RFR_N to high */ + msm_hs_write(uport, UART_DM_CR, RFR_HIGH); /* * Disable Rx channel of UARTDM @@ -1269,12 +1271,12 @@ static void msm_hs_set_termios(struct uart_port *uport, * UART Core would trigger RFR if it is not having any space with * RX FIFO. */ + /* Pulling RFR line high */ + msm_hs_write(uport, UART_DM_CR, RFR_LOW); data = msm_hs_read(uport, UART_DM_MR1); data &= ~(UARTDM_MR1_CTS_CTL_BMSK | UARTDM_MR1_RX_RDY_CTL_BMSK); - if (c_cflag & CRTSCTS) { data |= UARTDM_MR1_CTS_CTL_BMSK; data |= UARTDM_MR1_RX_RDY_CTL_BMSK; - } msm_hs_write(uport, UART_DM_MR1, data); msm_hs_write(uport, UART_DM_IMR, msm_uport->imr_reg); @@ -2085,6 +2087,7 @@ static int msm_hs_check_clock_off(struct uart_port *uport) { unsigned long sr_status; unsigned long flags; + unsigned int data; struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport); struct circ_buf *tx_buf = &uport->state->xmit; @@ -2100,8 +2103,16 @@ static int msm_hs_check_clock_off(struct uart_port *uport) msm_uport->imr_reg & UARTDM_ISR_TXLEV_BMSK) { spin_unlock_irqrestore(&uport->lock, flags); mutex_unlock(&msm_uport->clk_mutex); - if (msm_uport->clk_state == MSM_HS_CLK_REQUEST_OFF) + if (msm_uport->clk_state == MSM_HS_CLK_REQUEST_OFF) { msm_uport->clk_state = MSM_HS_CLK_ON; + /* Pulling RFR line high */ + msm_hs_write(uport, UART_DM_CR, RFR_LOW); + /* Enable auto RFR */ + data = msm_hs_read(uport, UART_DM_MR1); + data |= UARTDM_MR1_RX_RDY_CTL_BMSK; + msm_hs_write(uport, UART_DM_MR1, data); + mb(); + } MSM_HS_DBG("%s(): clkstate %d", __func__, msm_uport->clk_state); return -1; } @@ -2133,6 +2144,14 @@ static int msm_hs_check_clock_off(struct uart_port *uport) spin_unlock_irqrestore(&uport->lock, flags); + /* Pulling RFR line high */ + msm_hs_write(uport, UART_DM_CR, RFR_LOW); + /* Enable auto RFR */ + data = msm_hs_read(uport, UART_DM_MR1); + data |= UARTDM_MR1_RX_RDY_CTL_BMSK; + msm_hs_write(uport, UART_DM_MR1, data); + mb(); + /* we really want to clock off */ msm_hs_clock_unvote(msm_uport); @@ -2309,6 +2328,14 @@ void msm_hs_request_clock_off(struct uart_port *uport) { spin_lock_irqsave(&uport->lock, flags); if (msm_uport->clk_state == MSM_HS_CLK_ON) { msm_uport->clk_state = MSM_HS_CLK_REQUEST_OFF; + data = msm_hs_read(uport, UART_DM_MR1); + /*disable auto ready-for-receiving */ + data &= ~UARTDM_MR1_RX_RDY_CTL_BMSK; + msm_hs_write(uport, UART_DM_MR1, data); + mb(); + /* set RFR_N to high */ + msm_hs_write(uport, UART_DM_CR, RFR_HIGH); + data = msm_hs_read(uport, UART_DM_SR); MSM_HS_DBG("%s(): TXEMT, queuing clock off work\n", __func__); @@ -2330,6 +2357,15 @@ void msm_hs_request_clock_on(struct uart_port *uport) mutex_lock(&msm_uport->clk_mutex); spin_lock_irqsave(&uport->lock, flags); + if (msm_uport->clk_state == MSM_HS_CLK_REQUEST_OFF) { + /* Pulling RFR line high */ + msm_hs_write(uport, UART_DM_CR, RFR_LOW); + /* Enable auto RFR */ + data = msm_hs_read(uport, UART_DM_MR1); + data |= UARTDM_MR1_RX_RDY_CTL_BMSK; + msm_hs_write(uport, UART_DM_MR1, data); + mb(); + } switch (msm_uport->clk_state) { case MSM_HS_CLK_OFF: wake_lock(&msm_uport->dma_wake_lock); |