mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 20:33:58 -04:00
Merge "asoc: codecs: fix race condition of core vote and reg access"
This commit is contained in:
commit
78fff06931
5 changed files with 73 additions and 28 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue