summaryrefslogtreecommitdiff
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorGirish Mahadevan <girishm@codeaurora.org>2016-05-25 15:50:07 -0600
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-02 10:56:09 -0700
commitf09173df85d400ff5079b6c9bddc065c44088af2 (patch)
treeb2cf7f670537ebf20fa17aac54aea2ae5370f076 /drivers/tty/serial
parenta674be9d15884d30ebb6b9e9988c436b286841d9 (diff)
serial: msm_serial_hs: Move clk count voting out of runtime callbacks
Don't modify the ref count variable clk count inside the runtime callbacks. Doing so could result in a case where the driver might end up calling a put twice on the runtime object. The resulting imbalance will leave the runtime state for the device in a bad state. Change-Id: I34989768811b23762c4afe3e33e229ffa3f1db17 Signed-off-by: Girish Mahadevan <girishm@codeaurora.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/msm_serial_hs.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 3eea55b6a168..7365f3f8e8dd 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -214,7 +214,7 @@ struct msm_hs_port {
struct clk *pclk;
struct msm_hs_tx tx;
struct msm_hs_rx rx;
- atomic_t clk_count;
+ atomic_t resource_count;
struct msm_hs_wakeup wakeup;
struct dentry *loopback_dir;
@@ -353,7 +353,6 @@ 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:
@@ -374,7 +373,6 @@ 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__);
}
@@ -382,7 +380,7 @@ static void msm_hs_clk_bus_unvote(struct msm_hs_port *msm_uport)
static void msm_hs_resource_unvote(struct msm_hs_port *msm_uport)
{
struct uart_port *uport = &(msm_uport->uport);
- int rc = atomic_read(&msm_uport->clk_count);
+ int rc = atomic_read(&msm_uport->resource_count);
MSM_HS_DBG("%s(): power usage count %d", __func__, rc);
if (rc <= 0) {
@@ -390,6 +388,7 @@ static void msm_hs_resource_unvote(struct msm_hs_port *msm_uport)
WARN_ON(1);
return;
}
+ atomic_dec(&msm_uport->resource_count);
pm_runtime_mark_last_busy(uport->dev);
pm_runtime_put_autosuspend(uport->dev);
}
@@ -405,6 +404,7 @@ 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->resource_count);
}
/* Check if the uport line number matches with user id stored in pdata.
@@ -593,8 +593,8 @@ static void dump_uart_hs_registers(struct msm_hs_port *msm_uport)
struct uart_port *uport = &(msm_uport->uport);
if (msm_uport->pm_state != MSM_HS_PM_ACTIVE) {
- MSM_HS_INFO("%s:Failed clocks are off, clk_count %d",
- __func__, atomic_read(&msm_uport->clk_count));
+ MSM_HS_INFO("%s:Failed clocks are off, resource_count %d",
+ __func__, atomic_read(&msm_uport->resource_count));
return;
}
@@ -3186,7 +3186,7 @@ static int msm_hs_pm_sys_suspend_noirq(struct device *dev)
* If there is an active clk request or an impending userspace request
* fail the suspend callback.
*/
- clk_cnt = atomic_read(&msm_uport->clk_count);
+ clk_cnt = atomic_read(&msm_uport->resource_count);
client_count = atomic_read(&msm_uport->client_count);
if (msm_uport->pm_state == MSM_HS_PM_ACTIVE) {
MSM_HS_WARN("%s:Fail Suspend.clk_cnt:%d,clnt_count:%d\n",
@@ -3632,9 +3632,9 @@ static void msm_hs_shutdown(struct uart_port *uport)
UART_XMIT_SIZE, DMA_TO_DEVICE);
msm_hs_resource_unvote(msm_uport);
- rc = atomic_read(&msm_uport->clk_count);
+ rc = atomic_read(&msm_uport->resource_count);
if (rc) {
- atomic_set(&msm_uport->clk_count, 1);
+ atomic_set(&msm_uport->resource_count, 1);
MSM_HS_WARN("%s(): removing extra vote\n", __func__);
msm_hs_resource_unvote(msm_uport);
}