summaryrefslogtreecommitdiff
path: root/soc
diff options
context:
space:
mode:
authorVangala, Amarnath <avangala@codeaurora.org>2020-10-27 23:53:04 +0530
committerSoumya Managoli <smanag@codeaurora.org>2021-03-26 18:07:46 +0530
commit258d29334a915d45b7ad6b1820cc5a0be5b375b0 (patch)
tree0c61f1d609ef39ecaea5f4b9dc22c2bf6a8ab2ca /soc
parentb0bf9aab325803d62c1d7f042d7ef877e2189387 (diff)
downloadmsm-extra-258d29334a915d45b7ad6b1820cc5a0be5b375b0.tar.gz
asoc: codecs: fix race condition of core vote and reg access
Auto suspend timer for core vote is triggering before read write complete. Move the auto suspend of core vote to post read write operation. Change-Id: Ib0f6b026fe0e7fd3fbe052691db492915e436a78 Signed-off-by: Vangala, Amarnath <avangala@codeaurora.org>
Diffstat (limited to 'soc')
-rw-r--r--soc/swr-mstr-ctrl.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 385e59fa..4cdb3f50 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -457,7 +457,7 @@ static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm,
return ((swrm->bus_clk * 2) / ((row * col) * frame_sync));
}
-static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm)
+static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm, bool enable)
{
int ret = 0;
@@ -470,7 +470,7 @@ static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm)
goto exit;
}
if (swrm->core_vote) {
- ret = swrm->core_vote(swrm->handle, true);
+ ret = swrm->core_vote(swrm->handle, enable);
if (ret)
dev_err_ratelimited(swrm->dev,
"%s: core vote request failed\n", __func__);
@@ -501,8 +501,10 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable)
dev_err_ratelimited(swrm->dev,
"%s: core vote request failed\n",
__func__);
+ swrm->core_vote(swrm->handle, false);
goto exit;
}
+ ret = swrm->core_vote(swrm->handle, false);
}
}
swrm->clk_ref_count++;
@@ -538,6 +540,7 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm,
{
u32 temp = (u32)(*value);
int ret = 0;
+ int vote_ret = 0;
mutex_lock(&swrm->devlock);
if (!swrm->dev_up)
@@ -551,13 +554,20 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm,
__func__);
goto err;
}
- } else if (swrm_core_vote_request(swrm)) {
- goto err;
+ } else {
+ vote_ret = swrm_core_vote_request(swrm, true);
+ if (vote_ret == -ENOTSYNC)
+ goto err_vote;
+ else if (vote_ret)
+ goto err;
}
iowrite32(temp, swrm->swrm_dig_base + reg);
if (is_swr_clk_needed(swrm))
swrm_clk_request(swrm, FALSE);
+err_vote:
+ if (!is_swr_clk_needed(swrm))
+ swrm_core_vote_request(swrm, false);
err:
mutex_unlock(&swrm->devlock);
return ret;
@@ -568,6 +578,7 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm,
{
u32 temp = 0;
int ret = 0;
+ int vote_ret = 0;
mutex_lock(&swrm->devlock);
if (!swrm->dev_up)
@@ -580,14 +591,21 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm,
__func__);
goto err;
}
- } else if (swrm_core_vote_request(swrm)) {
- goto err;
+ } else {
+ vote_ret = swrm_core_vote_request(swrm, true);
+ if (vote_ret == -ENOTSYNC)
+ goto err_vote;
+ else if (vote_ret)
+ goto err;
}
temp = ioread32(swrm->swrm_dig_base + reg);
*value = temp;
if (is_swr_clk_needed(swrm))
swrm_clk_request(swrm, FALSE);
+err_vote:
+ if (!is_swr_clk_needed(swrm))
+ swrm_core_vote_request(swrm, false);
err:
mutex_unlock(&swrm->devlock);
return ret;
@@ -2577,6 +2595,7 @@ static int swrm_probe(struct platform_device *pdev)
int ret = 0;
struct clk *lpass_core_hw_vote = NULL;
struct clk *lpass_core_audio = NULL;
+ u32 swrm_hw_ver = 0;
/* Allocate soundwire master driver structure */
swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl),
@@ -2603,6 +2622,14 @@ static int swrm_probe(struct platform_device *pdev)
ret = -EINVAL;
goto err_pdata_fail;
}
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,swr-master-version",
+ &swrm->version);
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: swrm version not defined, use default\n",
+ __func__);
+ swrm->version = SWRM_VERSION_1_6;
+ }
ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr_master_id",
&swrm->master_id);
if (ret) {
@@ -2850,7 +2877,11 @@ static int swrm_probe(struct platform_device *pdev)
swr_master_add_boarddevices(&swrm->master);
mutex_lock(&swrm->mlock);
swrm_clk_request(swrm, true);
- swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
+ swrm_hw_ver = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
+ if (swrm->version != swrm_hw_ver)
+ dev_info(&pdev->dev,
+ "%s: version specified in dtsi: 0x%x not match with HW read version 0x%x\n",
+ __func__, swrm->version, swrm_hw_ver);
ret = swrm_master_init(swrm);
if (ret < 0) {
dev_err(&pdev->dev,