Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78fff069 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

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

parents 59298aad f2e5dd21
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -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)
+8 −5
Original line number Diff line number Diff line
@@ -2918,22 +2918,25 @@ static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src)

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)
+8 −5
Original line number Diff line number Diff line
@@ -725,22 +725,25 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv,

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)
+8 −5
Original line number Diff line number Diff line
@@ -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)
+38 −7
Original line number Diff line number Diff line
@@ -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)) {
	} 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,7 +642,11 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm,
					    __func__);
			goto err;
		}
	} else if (swrm_core_vote_request(swrm)) {
	} else {
		vote_ret = swrm_core_vote_request(swrm, true);
		if (vote_ret == -ENOTSYNC)
			goto err_vote;
		else if (vote_ret)
			goto err;
	}

@@ -639,6 +654,9 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm,
	*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,