summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorDilip Kota <c_dkota@codeaurora.org>2014-01-24 02:41:47 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2014-01-31 01:48:16 -0800
commit07929a3e5f2c1fbcd268ecd06ada515083baf9ec (patch)
treebcf6ee99201b12cfd25c8a82ba44acd0f043e3b5 /drivers/tty
parentb36b5f078f7fe6a089690bba149e308f9e7d330e (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.c42
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);