Prechádzať zdrojové kódy

soc: swr-mstr-ctrl: add new lock to sync runtime_resume and runtime_suspend

runtime_suspend may get from multi functions and reslock is
unlock and lock inbetween which may cause clk count mismatch
with multi rutime_suspend called. Add new lock to make sure
runtime_suspend is run in sequence.

Change-Id: Ie465ded6dc1db1244035e9f4d216466b630df82b
Signed-off-by: Meng Wang <[email protected]>
Meng Wang 3 rokov pred
rodič
commit
42d4d58d8b
2 zmenil súbory, kde vykonal 9 pridanie a 0 odobranie
  1. 8 0
      soc/swr-mstr-ctrl.c
  2. 1 0
      soc/swr-mstr-ctrl.h

+ 8 - 0
soc/swr-mstr-ctrl.c

@@ -2843,6 +2843,7 @@ static int swrm_probe(struct platform_device *pdev)
 	mutex_init(&swrm->clklock);
 	mutex_init(&swrm->devlock);
 	mutex_init(&swrm->pm_lock);
+	mutex_init(&swrm->runtime_lock);
 	swrm->wlock_holders = 0;
 	swrm->pm_state = SWRM_PM_SLEEPABLE;
 	init_waitqueue_head(&swrm->pm_wq);
@@ -3053,6 +3054,7 @@ err_irq_fail:
 	mutex_destroy(&swrm->iolock);
 	mutex_destroy(&swrm->clklock);
 	mutex_destroy(&swrm->pm_lock);
+	mutex_destroy(&swrm->runtime_lock);
 
 err_pdata_fail:
 err_memory_fail:
@@ -3090,6 +3092,7 @@ static int swrm_remove(struct platform_device *pdev)
 	mutex_destroy(&swrm->clklock);
 	mutex_destroy(&swrm->force_down_lock);
 	mutex_destroy(&swrm->pm_lock);
+	mutex_destroy(&swrm->runtime_lock);
 	devm_kfree(&pdev->dev, swrm);
 	return 0;
 }
@@ -3123,6 +3126,7 @@ static int swrm_runtime_resume(struct device *dev)
 		__func__, swrm->state);
 	trace_printk("%s: pm_runtime: resume, state:%d\n",
 		__func__, swrm->state);
+	mutex_lock(&swrm->runtime_lock);
 	mutex_lock(&swrm->reslock);
 
 	if (swrm_request_hw_vote(swrm, LPASS_HW_CORE, true)) {
@@ -3145,6 +3149,7 @@ static int swrm_runtime_resume(struct device *dev)
 					pr_err("%s: irq data is NULL\n",
 						__func__);
 					mutex_unlock(&swrm->reslock);
+					mutex_unlock(&swrm->runtime_lock);
 					return IRQ_NONE;
 				}
 				mutex_lock(&swrm->irq_lock);
@@ -3244,6 +3249,7 @@ exit:
 	if (swrm->req_clk_switch)
 		swrm->req_clk_switch = false;
 	mutex_unlock(&swrm->reslock);
+	mutex_unlock(&swrm->runtime_lock);
 
 	trace_printk("%s: pm_runtime: resume done, state:%d\n",
 		__func__, swrm->state);
@@ -3264,6 +3270,7 @@ static int swrm_runtime_suspend(struct device *dev)
 		__func__, swrm->state);
 	dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n",
 		__func__, swrm->state);
+	mutex_lock(&swrm->runtime_lock);
 	mutex_lock(&swrm->reslock);
 	mutex_lock(&swrm->force_down_lock);
 	current_state = swrm->state;
@@ -3371,6 +3378,7 @@ exit:
 	if (!hw_core_err)
 		swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
 	mutex_unlock(&swrm->reslock);
+	mutex_unlock(&swrm->runtime_lock);
 	trace_printk("%s: pm_runtime: suspend done state: %d\n",
 		__func__, swrm->state);
 	return ret;

+ 1 - 0
soc/swr-mstr-ctrl.h

@@ -135,6 +135,7 @@ struct swr_mstr_ctrl {
 	struct mutex reslock;
 	struct mutex pm_lock;
 	struct mutex irq_lock;
+	struct mutex runtime_lock;
 	u32 swrm_base_reg;
 	char __iomem *swrm_dig_base;
 	char __iomem *swrm_hctl_reg;