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

Commit 430983de authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: msm8x16: fix the target crash due to dpm timeout"

parents b9646426 1d1b1f5e
Loading
Loading
Loading
Loading
+18 −60
Original line number Diff line number Diff line
@@ -351,7 +351,7 @@ static int __msm8x16_wcd_reg_read(struct snd_soc_codec *codec,
		ret = msm8x16_wcd_spmi_read(reg, 1, &temp);
	else if (MSM8X16_WCD_IS_DIGITAL_REG(reg)) {
		mutex_lock(&pdata->cdc_mclk_mutex);
		if (atomic_read(&pdata->dis_work_mclk) == false) {
		if (atomic_read(&pdata->mclk_enabled) == false) {
			pdata->digital_cdc_clk.clk_val = pdata->mclk_freq;
			ret = afe_set_digital_codec_core_clock(
					AFE_PORT_ID_PRIMARY_MI2S_RX,
@@ -363,8 +363,8 @@ static int __msm8x16_wcd_reg_read(struct snd_soc_codec *codec,
			pr_debug("%s: MCLK not enabled\n", __func__);
			ret = msm8x16_wcd_ahb_read_device(
					msm8x16_wcd, reg, 1, &temp);
			atomic_set(&pdata->dis_work_mclk, true);
			schedule_delayed_work(&pdata->enable_mclk_work, 50);
			atomic_set(&pdata->mclk_enabled, true);
			schedule_delayed_work(&pdata->disable_mclk_work, 50);
err:
			mutex_unlock(&pdata->cdc_mclk_mutex);
			mutex_unlock(&msm8x16_wcd->io_lock);
@@ -401,7 +401,7 @@ static int __msm8x16_wcd_reg_write(struct snd_soc_codec *codec,
		ret = msm8x16_wcd_spmi_write(reg, 1, &val);
	else if (MSM8X16_WCD_IS_DIGITAL_REG(reg)) {
		mutex_lock(&pdata->cdc_mclk_mutex);
		if (atomic_read(&pdata->dis_work_mclk) == false) {
		if (atomic_read(&pdata->mclk_enabled) == false) {
			pr_debug("MCLK not enabled %s:\n", __func__);
			pdata->digital_cdc_clk.clk_val = pdata->mclk_freq;
			ret = afe_set_digital_codec_core_clock(
@@ -414,8 +414,8 @@ static int __msm8x16_wcd_reg_write(struct snd_soc_codec *codec,
			}
			ret = msm8x16_wcd_ahb_write_device(
						msm8x16_wcd, reg, &val, 1);
			atomic_set(&pdata->dis_work_mclk, true);
			schedule_delayed_work(&pdata->enable_mclk_work, 50);
			atomic_set(&pdata->mclk_enabled, true);
			schedule_delayed_work(&pdata->disable_mclk_work, 50);
err:
			mutex_unlock(&pdata->cdc_mclk_mutex);
			mutex_unlock(&msm8x16_wcd->io_lock);
@@ -3324,37 +3324,23 @@ int msm8x16_wcd_suspend(struct snd_soc_codec *codec)
	struct msm8x16_wcd_pdata *msm8x16_pdata = msm8x16->dev->platform_data;

	pdata = snd_soc_card_get_drvdata(codec->card);
	pr_debug("%s: mclk cnt = %d, dis_work_mclk = %d\n",
	pr_debug("%s: mclk cnt = %d, mclk_enabled = %d\n",
			__func__, atomic_read(&pdata->mclk_rsc_ref),
			atomic_read(&pdata->dis_work_mclk));
	pr_debug("%s: mclk_act  = %d\n", __func__,
			atomic_read(&pdata->mclk_act));
			atomic_read(&pdata->mclk_enabled));
	if (atomic_read(&pdata->mclk_enabled) == true) {
		cancel_delayed_work_sync(
				&pdata->disable_mclk_work);
		mutex_lock(&pdata->cdc_mclk_mutex);
	if ((atomic_read(&pdata->dis_work_mclk) == true) ||
		(atomic_read(&pdata->mclk_rsc_ref) > 0)) {
		if (atomic_read(&pdata->mclk_enabled) == true) {
			pdata->digital_cdc_clk.clk_val = 0;
			afe_set_digital_codec_core_clock(
					AFE_PORT_ID_PRIMARY_MI2S_RX,
					&pdata->digital_cdc_clk);
		/*
		 * set mclk activity to resource as
		 * it will get updated accordingly going further in this
		 * function.
		 */
		atomic_set(&pdata->mclk_act, MCLK_SUS_RSC);
		if (atomic_read(&pdata->dis_work_mclk) == true) {
			cancel_delayed_work_sync(
					&pdata->enable_mclk_work);
			atomic_set(&pdata->mclk_act, MCLK_SUS_DIS);
			atomic_set(&pdata->dis_work_mclk, false);
			atomic_set(&pdata->mclk_enabled, false);
		}
	} else
		/*
		 * mark no activity on mclk in this suspend
		 */
		atomic_set(&pdata->mclk_act, MCLK_SUS_NO_ACT);
	msm8x16_wcd_disable_static_supplies_to_optimum(msm8x16, msm8x16_pdata);
		mutex_unlock(&pdata->cdc_mclk_mutex);
	}
	msm8x16_wcd_disable_static_supplies_to_optimum(msm8x16, msm8x16_pdata);
	return 0;
}

@@ -3366,34 +3352,6 @@ int msm8x16_wcd_resume(struct snd_soc_codec *codec)

	pdata = snd_soc_card_get_drvdata(codec->card);
	msm8x16_wcd_enable_static_supplies_to_optimum(msm8x16, msm8x16_pdata);
	pr_debug("%s: mclk cnt = %d, dis_work_mclk = %d\n",
			__func__, atomic_read(&pdata->mclk_rsc_ref),
			atomic_read(&pdata->dis_work_mclk));
	pr_debug("%s: mclk_act = %d\n", __func__,
			atomic_read(&pdata->mclk_act));
	if (atomic_read(&pdata->mclk_act) == MCLK_SUS_NO_ACT)
		/*
		 * no activity in suspend just return
		 */
		return 0;
	mutex_lock(&pdata->cdc_mclk_mutex);
	if ((atomic_read(&pdata->dis_work_mclk) == false) ||
		(atomic_read(&pdata->mclk_rsc_ref) > 0)) {
		pdata->digital_cdc_clk.clk_val = pdata->mclk_freq;
		afe_set_digital_codec_core_clock(
					AFE_PORT_ID_PRIMARY_MI2S_RX,
					&pdata->digital_cdc_clk);
		if (atomic_read(&pdata->mclk_act) == MCLK_SUS_DIS) {
			/*
			 * MCLK activity marked as the disabled during suspend
			 * this indicated MCLK was enabled to read and write the
			 * AHB bus.
			 */
			atomic_set(&pdata->dis_work_mclk, true);
			schedule_delayed_work(&pdata->enable_mclk_work, 50);
		}
	}
	mutex_unlock(&pdata->cdc_mclk_mutex);
	return 0;
}

+2 −3
Original line number Diff line number Diff line
@@ -130,10 +130,9 @@ struct msm8916_asoc_mach_data {
	int us_euro_gpio;
	int mclk_freq;
	atomic_t mclk_rsc_ref;
	atomic_t dis_work_mclk;
	atomic_t mclk_act;
	atomic_t mclk_enabled;
	struct mutex cdc_mclk_mutex;
	struct delayed_work enable_mclk_work;
	struct delayed_work disable_mclk_work;
	struct afe_digital_clk_cfg digital_cdc_clk;
};

+25 −21
Original line number Diff line number Diff line
@@ -601,29 +601,29 @@ static int msm8x16_enable_codec_ext_clk(struct snd_soc_codec *codec,
		   atomic_read(&pdata->mclk_rsc_ref));
	if (enable) {
		if (atomic_inc_return(&pdata->mclk_rsc_ref) == 1) {
			mutex_lock(&pdata->cdc_mclk_mutex);
			if (atomic_read(&pdata->dis_work_mclk) == true) {
			cancel_delayed_work_sync(
					&pdata->enable_mclk_work);
			} else {
					&pdata->disable_mclk_work);
			mutex_lock(&pdata->cdc_mclk_mutex);
			if (atomic_read(&pdata->mclk_enabled) == false) {
				pdata->digital_cdc_clk.clk_val =
							pdata->mclk_freq;
				afe_set_digital_codec_core_clock(
						AFE_PORT_ID_PRIMARY_MI2S_RX,
						&pdata->digital_cdc_clk);
				atomic_set(&pdata->dis_work_mclk, true);
				atomic_set(&pdata->mclk_enabled, true);
			}
			mutex_unlock(&pdata->cdc_mclk_mutex);
		}
	} else {
		cancel_delayed_work_sync(&pdata->disable_mclk_work);
		mutex_lock(&pdata->cdc_mclk_mutex);
		atomic_set(&pdata->mclk_rsc_ref, 0);
		cancel_delayed_work_sync(&pdata->enable_mclk_work);
		if (atomic_read(&pdata->mclk_enabled) == true) {
			pdata->digital_cdc_clk.clk_val = 0;
			afe_set_digital_codec_core_clock(
					AFE_PORT_ID_PRIMARY_MI2S_RX,
					&pdata->digital_cdc_clk);
		atomic_set(&pdata->dis_work_mclk, false);
			atomic_set(&pdata->mclk_enabled, false);
		}
		mutex_unlock(&pdata->cdc_mclk_mutex);
	}
	return ret;
@@ -1810,26 +1810,30 @@ static struct snd_soc_card bear_cards[MAX_SND_CARDS] = {
	},
};

void enable_mclk(struct work_struct *work)
void disable_mclk(struct work_struct *work)
{
	struct msm8916_asoc_mach_data *pdata = NULL;
	struct delayed_work *dwork;
	int ret = 0;

	pr_debug("%s:\n", __func__);
	dwork = to_delayed_work(work);
	pdata = container_of(dwork, struct msm8916_asoc_mach_data,
				enable_mclk_work);
				disable_mclk_work);
	mutex_lock(&pdata->cdc_mclk_mutex);
	if (atomic_read(&pdata->dis_work_mclk) == true) {
		pr_debug("clock enabled now disable\n");
	pr_debug("%s: mclk_enabled %d mclk_rsc_ref %d\n", __func__,
			atomic_read(&pdata->mclk_enabled),
			atomic_read(&pdata->mclk_rsc_ref));

	if (atomic_read(&pdata->mclk_enabled) == true
		&& atomic_read(&pdata->mclk_rsc_ref) == 0) {
		pr_debug("Disable the mclk\n");
		pdata->digital_cdc_clk.clk_val = 0;
		ret = afe_set_digital_codec_core_clock(
				AFE_PORT_ID_PRIMARY_MI2S_RX,
				&pdata->digital_cdc_clk);
		if (ret < 0)
			pr_err("failed to disable the MCLK\n");
		atomic_set(&pdata->dis_work_mclk, false);
			pr_err("%s failed to disable the MCLK\n", __func__);
		atomic_set(&pdata->mclk_enabled, false);
	}
	mutex_unlock(&pdata->cdc_mclk_mutex);
}
@@ -2164,10 +2168,10 @@ static int msm8x16_asoc_machine_probe(struct platform_device *pdev)
	if (ret)
		goto err;
	/* initialize timer */
	INIT_DELAYED_WORK(&pdata->enable_mclk_work, enable_mclk);
	INIT_DELAYED_WORK(&pdata->disable_mclk_work, disable_mclk);
	mutex_init(&pdata->cdc_mclk_mutex);
	atomic_set(&pdata->mclk_rsc_ref, 0);
	atomic_set(&pdata->dis_work_mclk, false);
	atomic_set(&pdata->mclk_enabled, false);

	ret = snd_soc_of_parse_audio_routing(card,
			"qcom,audio-routing");