summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/soundwire/swr-wcd-ctrl.c24
-rwxr-xr-xdrivers/soundwire/swr-wcd-ctrl.h1
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/soundwire/swr-wcd-ctrl.c b/drivers/soundwire/swr-wcd-ctrl.c
index cdaf009c5b1f..1dcaba2e79f6 100644
--- a/drivers/soundwire/swr-wcd-ctrl.c
+++ b/drivers/soundwire/swr-wcd-ctrl.c
@@ -397,11 +397,17 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable)
return -EINVAL;
if (enable) {
- swrm->clk(swrm->handle, true);
- swrm->state = SWR_MSTR_UP;
- } else {
+ swrm->clk_ref_count++;
+ if (swrm->clk_ref_count == 1) {
+ swrm->clk(swrm->handle, true);
+ swrm->state = SWR_MSTR_UP;
+ }
+ } else if (--swrm->clk_ref_count == 0) {
swrm->clk(swrm->handle, false);
swrm->state = SWR_MSTR_DOWN;
+ } else if (swrm->clk_ref_count < 0) {
+ pr_err("%s: swrm clk count mismatch\n", __func__);
+ swrm->clk_ref_count = 0;
}
return 0;
}
@@ -1169,7 +1175,10 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev)
u8 devnum = 0;
int ret = IRQ_HANDLED;
- pm_runtime_get_sync(&swrm->pdev->dev);
+ mutex_lock(&swrm->reslock);
+ swrm_clk_request(swrm, true);
+ mutex_unlock(&swrm->reslock);
+
intr_sts = swrm->read(swrm->handle, SWRM_INTERRUPT_STATUS);
intr_sts &= SWRM_INTERRUPT_STATUS_RMSK;
for (i = 0; i < SWRM_INTERRUPT_MAX; i++) {
@@ -1257,8 +1266,10 @@ static irqreturn_t swr_mstr_interrupt(int irq, void *dev)
break;
}
}
- pm_runtime_mark_last_busy(&swrm->pdev->dev);
- pm_runtime_put_autosuspend(&swrm->pdev->dev);
+
+ mutex_lock(&swrm->reslock);
+ swrm_clk_request(swrm, false);
+ mutex_unlock(&swrm->reslock);
return ret;
}
@@ -1448,6 +1459,7 @@ static int swrm_probe(struct platform_device *pdev)
swrm->wcmd_id = 0;
swrm->slave_status = 0;
swrm->num_rx_chs = 0;
+ swrm->clk_ref_count = 0;
swrm->state = SWR_MSTR_RESUME;
init_completion(&swrm->reset);
init_completion(&swrm->broadcast);
diff --git a/drivers/soundwire/swr-wcd-ctrl.h b/drivers/soundwire/swr-wcd-ctrl.h
index b7a3edac3e00..104ac8f6f510 100755
--- a/drivers/soundwire/swr-wcd-ctrl.h
+++ b/drivers/soundwire/swr-wcd-ctrl.h
@@ -78,6 +78,7 @@ struct swr_mstr_ctrl {
struct device *dev;
struct resource *supplies;
struct clk *mclk;
+ int clk_ref_count;
struct completion reset;
struct completion broadcast;
struct mutex mlock;