Merge "asoc: codecs: fix race condition of core vote and reg access"

This commit is contained in:
qctecmdr 2020-11-04 19:57:25 -08:00 • committed by Gerrit - the friendly Code Review server
commit 78fff06931
5 changed files with 73 additions and 28 deletions

View file

@ -1280,6 +1280,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
rx_priv->default_clk_id,
rx_priv->clk_id,
true);
rx_macro_core_vote(rx_priv, false);
if (ret < 0) {
dev_err(rx_priv->dev,
"%s: rx request clock enable failed\n",
@ -1334,6 +1335,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv,
rx_priv->default_clk_id,
rx_priv->clk_id,
false);
rx_macro_core_vote(rx_priv, false);
rx_priv->clk_id = rx_priv->default_clk_id;
}
}
@ -1453,11 +1455,11 @@ static int rx_macro_event_handler(struct snd_soc_component *component,
"%s, failed to enable clk, ret:%d\n",
__func__, ret);
} else {
rx_macro_core_vote(rx_priv, true);
bolero_clk_rsc_request_clock(rx_priv->dev,
rx_priv->default_clk_id,
RX_CORE_CLK, false);
}
rx_macro_core_vote(rx_priv, false);
break;
case BOLERO_MACRO_EVT_SSR_UP:
trace_printk("%s, enter SSR up\n", __func__);
@ -3735,22 +3737,25 @@ static const struct snd_soc_dapm_route rx_audio_map[] = {
static int rx_macro_core_vote(void *handle, bool enable)
{
int rc = 0;
struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle;
if (rx_priv == NULL) {
pr_err("%s: rx priv data is NULL\n", __func__);
return -EINVAL;
}
if (enable) {
pm_runtime_get_sync(rx_priv->dev);
if (bolero_check_core_votes(rx_priv->dev))
rc = 0;
else
rc = -ENOTSYNC;
} else {
pm_runtime_put_autosuspend(rx_priv->dev);
pm_runtime_mark_last_busy(rx_priv->dev);
}
if (bolero_check_core_votes(rx_priv->dev))
return 0;
else
return -EINVAL;
return rc;
}
static int rx_swrm_clock(void *handle, bool enable)

View file

@ -2918,22 +2918,25 @@ ret:
static int tx_macro_core_vote(void *handle, bool enable)
{
int rc = 0;
struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
if (tx_priv == NULL) {
pr_err("%s: tx priv data is NULL\n", __func__);
return -EINVAL;
}
if (enable) {
pm_runtime_get_sync(tx_priv->dev);
if (bolero_check_core_votes(tx_priv->dev))
rc = 0;
else
rc = -ENOTSYNC;
} else {
pm_runtime_put_autosuspend(tx_priv->dev);
pm_runtime_mark_last_busy(tx_priv->dev);
}
if (bolero_check_core_votes(tx_priv->dev))
return 0;
else
return -EINVAL;
return rc;
}
static int tx_macro_swrm_clock(void *handle, bool enable)

View file

@ -725,22 +725,25 @@ done:
static int va_macro_core_vote(void *handle, bool enable)
{
int rc = 0;
struct va_macro_priv *va_priv = (struct va_macro_priv *) handle;
if (va_priv == NULL) {
pr_err("%s: va priv data is NULL\n", __func__);
return -EINVAL;
}
if (enable) {
pm_runtime_get_sync(va_priv->dev);
if (bolero_check_core_votes(va_priv->dev))
rc = 0;
else
rc = -ENOTSYNC;
} else {
pm_runtime_put_autosuspend(va_priv->dev);
pm_runtime_mark_last_busy(va_priv->dev);
}
if (bolero_check_core_votes(va_priv->dev))
return 0;
else
return -EINVAL;
return rc;
}
static int va_macro_swrm_clock(void *handle, bool enable)

View file

@ -2833,22 +2833,25 @@ static void wsa_macro_init_reg(struct snd_soc_component *component)
static int wsa_macro_core_vote(void *handle, bool enable)
{
int rc = 0;
struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle;
if (wsa_priv == NULL) {
pr_err("%s: wsa priv data is NULL\n", __func__);
return -EINVAL;
}
if (enable) {
pm_runtime_get_sync(wsa_priv->dev);
if (bolero_check_core_votes(wsa_priv->dev))
rc = 0;
else
rc = -ENOTSYNC;
} else {
pm_runtime_put_autosuspend(wsa_priv->dev);
pm_runtime_mark_last_busy(wsa_priv->dev);
}
if (bolero_check_core_votes(wsa_priv->dev))
return 0;
else
return -EINVAL;
return rc;
}
static int wsa_swrm_clock(void *handle, bool enable)

View file

@ -508,7 +508,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;
@ -521,7 +521,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__);
@ -552,8 +552,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++;
@ -589,6 +591,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)
@ -602,13 +605,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;
@ -619,6 +629,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)
@ -631,14 +642,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;
@ -2582,6 +2600,7 @@ static int swrm_probe(struct platform_device *pdev)
struct clk *lpass_core_hw_vote = NULL;
struct clk *lpass_core_audio = NULL;
u32 is_wcd937x = 0;
u32 swrm_hw_ver = 0;
/* Allocate soundwire master driver structure */
swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl),
@ -2608,6 +2627,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) {
@ -2883,11 +2910,15 @@ static int swrm_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s: Audio HW Vote is failed\n", __func__);
mutex_lock(&swrm->mlock);
swrm_clk_request(swrm, true);
swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION);
swrm->rd_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS)
& SWRM_COMP_PARAMS_RD_FIFO_DEPTH) >> 15);
swrm->wr_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS)
& SWRM_COMP_PARAMS_WR_FIFO_DEPTH) >> 10);
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,