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

Commit 128af5cd authored by Bhalchandra Gajare's avatar Bhalchandra Gajare Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: wcd9335: Fix race during codec master clock (mclk) enablement



It is possible that codec master clock enablement could race from two
different execution contexts, causing the mclk to be not enabled at all.
This will result in failure of use cases that expect the clock to be
present. Fix this issue by making sure the race condition does not
occur during mclk enablement.

bug: b/30983442
Change-Id: Ie254b8876524956b816267eaaed205f65641c000
Signed-off-by: default avatarBhalchandra Gajare <gajare@codeaurora.org>
parent f75272fe
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -811,6 +811,9 @@ struct tasha_priv {
	int rx_8_count;
	bool clk_mode;
	bool clk_internal;

	/* Lock to protect mclk enablement */
	struct mutex mclk_lock;
};

static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
@@ -951,13 +954,14 @@ static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha,
{
	int ret = 0;

	mutex_lock(&tasha->mclk_lock);
	if (enable) {
		tasha_cdc_sido_ccl_enable(tasha, true);
		ret = clk_prepare_enable(tasha->wcd_ext_clk);
		if (ret) {
			dev_err(tasha->dev, "%s: ext clk enable failed\n",
				__func__);
			goto err;
			goto unlock_mutex;
		}
		/* get BG */
		wcd_resmgr_enable_master_bias(tasha->resmgr);
@@ -971,7 +975,8 @@ static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha,
		clk_disable_unprepare(tasha->wcd_ext_clk);
		tasha_cdc_sido_ccl_enable(tasha, false);
	}
err:
unlock_mutex:
	mutex_unlock(&tasha->mclk_lock);
	return ret;
}

@@ -13756,6 +13761,7 @@ static int tasha_probe(struct platform_device *pdev)
	mutex_init(&tasha->swr_read_lock);
	mutex_init(&tasha->swr_write_lock);
	mutex_init(&tasha->swr_clk_lock);
	mutex_init(&tasha->mclk_lock);

	cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
			       GFP_KERNEL);
@@ -13840,6 +13846,7 @@ err_clk:
err_resmgr:
	devm_kfree(&pdev->dev, cdc_pwr);
err_cdc_pwr:
	mutex_destroy(&tasha->mclk_lock);
	devm_kfree(&pdev->dev, tasha);
	return ret;
}
@@ -13853,6 +13860,7 @@ static int tasha_remove(struct platform_device *pdev)
	clk_put(tasha->wcd_ext_clk);
	if (tasha->wcd_native_clk)
		clk_put(tasha->wcd_native_clk);
	mutex_destroy(&tasha->mclk_lock);
	devm_kfree(&pdev->dev, tasha);
	snd_soc_unregister_codec(&pdev->dev);
	return 0;