summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/serial/msm_serial_hs.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 6843711774b2..3eea55b6a168 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -353,6 +353,7 @@ static int msm_hs_clk_bus_vote(struct msm_hs_port *msm_uport)
__func__, rc);
goto core_unprepare;
}
+ atomic_inc(&msm_uport->clk_count);
MSM_HS_DBG("%s: Clock ON successful\n", __func__);
return rc;
core_unprepare:
@@ -373,6 +374,7 @@ static void msm_hs_clk_bus_unvote(struct msm_hs_port *msm_uport)
if (msm_uport->pclk)
clk_disable_unprepare(msm_uport->pclk);
msm_hs_bus_voting(msm_uport, BUS_RESET);
+ atomic_dec(&msm_uport->clk_count);
MSM_HS_DBG("%s: Clock OFF successful\n", __func__);
}
@@ -388,7 +390,6 @@ static void msm_hs_resource_unvote(struct msm_hs_port *msm_uport)
WARN_ON(1);
return;
}
- atomic_dec(&msm_uport->clk_count);
pm_runtime_mark_last_busy(uport->dev);
pm_runtime_put_autosuspend(uport->dev);
}
@@ -404,8 +405,6 @@ static void msm_hs_resource_vote(struct msm_hs_port *msm_uport)
__func__, uport->dev, ret);
msm_hs_pm_resume(uport->dev);
}
-
- atomic_inc(&msm_uport->clk_count);
}
/* Check if the uport line number matches with user id stored in pdata.
@@ -2186,7 +2185,7 @@ static struct msm_hs_port *msm_hs_get_hs_port(int port_index)
return NULL;
}
-void toggle_wakeup_interrupt(struct msm_hs_port *msm_uport)
+void enable_wakeup_interrupt(struct msm_hs_port *msm_uport)
{
unsigned long flags;
struct uart_port *uport = &(msm_uport->uport);
@@ -2197,7 +2196,6 @@ void toggle_wakeup_interrupt(struct msm_hs_port *msm_uport)
return;
if (!(msm_uport->wakeup.enabled)) {
- MSM_HS_DBG("%s(): Enable Wakeup IRQ", __func__);
enable_irq(msm_uport->wakeup.irq);
disable_irq(uport->irq);
spin_lock_irqsave(&uport->lock, flags);
@@ -2205,12 +2203,28 @@ void toggle_wakeup_interrupt(struct msm_hs_port *msm_uport)
msm_uport->wakeup.enabled = true;
spin_unlock_irqrestore(&uport->lock, flags);
} else {
+ MSM_HS_WARN("%s:Wake up IRQ already enabled", __func__);
+ }
+}
+
+void disable_wakeup_interrupt(struct msm_hs_port *msm_uport)
+{
+ unsigned long flags;
+ struct uart_port *uport = &(msm_uport->uport);
+
+ if (!is_use_low_power_wakeup(msm_uport))
+ return;
+ if (msm_uport->wakeup.freed)
+ return;
+
+ if (msm_uport->wakeup.enabled) {
disable_irq_nosync(msm_uport->wakeup.irq);
enable_irq(uport->irq);
spin_lock_irqsave(&uport->lock, flags);
msm_uport->wakeup.enabled = false;
spin_unlock_irqrestore(&uport->lock, flags);
- MSM_HS_DBG("%s(): Disable Wakeup IRQ", __func__);
+ } else {
+ MSM_HS_WARN("%s:Wake up IRQ already disabled", __func__);
}
}
@@ -2342,7 +2356,6 @@ static irqreturn_t msm_hs_wakeup_isr(int irq, void *dev)
struct uart_port *uport = &msm_uport->uport;
struct tty_struct *tty = NULL;
- msm_hs_resource_vote(msm_uport);
spin_lock_irqsave(&uport->lock, flags);
MSM_HS_DBG("%s(): ignore %d\n", __func__,
@@ -2368,7 +2381,6 @@ static irqreturn_t msm_hs_wakeup_isr(int irq, void *dev)
}
spin_unlock_irqrestore(&uport->lock, flags);
- msm_hs_resource_unvote(msm_uport);
if (wakeup && msm_uport->wakeup.inject_rx)
tty_flip_buffer_push(tty->port);
@@ -3111,7 +3123,7 @@ static void msm_hs_pm_suspend(struct device *dev)
obs_manage_irq(msm_uport, false);
msm_hs_clk_bus_unvote(msm_uport);
if (!atomic_read(&msm_uport->client_req_state))
- toggle_wakeup_interrupt(msm_uport);
+ enable_wakeup_interrupt(msm_uport);
MSM_HS_DBG("%s(): return suspend\n", __func__);
mutex_unlock(&msm_uport->mtx);
return;
@@ -3133,7 +3145,7 @@ static int msm_hs_pm_resume(struct device *dev)
if (msm_uport->pm_state == MSM_HS_PM_ACTIVE)
goto exit_pm_resume;
if (!atomic_read(&msm_uport->client_req_state))
- toggle_wakeup_interrupt(msm_uport);
+ disable_wakeup_interrupt(msm_uport);
msm_hs_clk_bus_vote(msm_uport);
obs_manage_irq(msm_uport, true);
msm_uport->pm_state = MSM_HS_PM_ACTIVE;
@@ -3176,11 +3188,9 @@ static int msm_hs_pm_sys_suspend_noirq(struct device *dev)
*/
clk_cnt = atomic_read(&msm_uport->clk_count);
client_count = atomic_read(&msm_uport->client_count);
- if (clk_cnt || (pm_runtime_enabled(dev) &&
- !pm_runtime_suspended(dev))) {
- MSM_HS_WARN("%s:Fail Suspend.clk_cnt:%d,clnt_count:%d,RPM:%d\n",
- __func__, clk_cnt, client_count,
- dev->power.runtime_status);
+ if (msm_uport->pm_state == MSM_HS_PM_ACTIVE) {
+ MSM_HS_WARN("%s:Fail Suspend.clk_cnt:%d,clnt_count:%d\n",
+ __func__, clk_cnt, client_count);
ret = -EBUSY;
goto exit_suspend_noirq;
}