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

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

Merge "ASoC: bg: Ensure to hanlde pm events only after codec probe done"

parents 44a23df5 83bd0971
Loading
Loading
Loading
Loading
+46 −46
Original line number Diff line number Diff line
@@ -1067,6 +1067,49 @@ static int adsp_state_callback(struct notifier_block *nb, unsigned long value,
	}
	return NOTIFY_OK;
}

static int bg_cdc_pm_suspend(struct bg_cdc_priv *bg_cdc)
{
	/* Do not remove the regulator vote if a session is active */
	if (bg_cdc->num_sessions > 0) {
		pr_debug("audio session in progress don't devote\n");
		return 0;
	}
	cancel_delayed_work_sync(&bg_cdc->bg_cdc_pktzr_init_work);
	cancel_delayed_work_sync(&bg_cdc->bg_cdc_cal_init_work);
	mutex_lock(&bg_cdc->bg_cdc_lock);
	if (bg_cdc->bg_cal_updated) {
		bg_cdc_enable_regulator(bg_cdc->spkr_vreg, false);
		bg_cdc->bg_cal_updated = false;
	}
	mutex_unlock(&bg_cdc->bg_cdc_lock);
	return 0;
}

static int bg_cdc_pm_resume(struct bg_cdc_priv *bg_cdc)
{
	schedule_delayed_work(&bg_cdc->bg_cdc_cal_init_work,
				msecs_to_jiffies(bg_cdc->bg_cal_init_delay));
	return 0;
}

static int bg_pm_event(struct notifier_block *nb,
			unsigned long event, void *ptr)
{
	struct bg_cdc_priv *bg_cdc =
			container_of(nb, struct bg_cdc_priv, bg_pm_nb);
	switch (event) {
	case PM_POST_HIBERNATION:
	case PM_POST_SUSPEND:
		return bg_cdc_pm_resume(bg_cdc);
	case PM_HIBERNATION_PREPARE:
	case PM_SUSPEND_PREPARE:
		return bg_cdc_pm_suspend(bg_cdc);
	default:
		return NOTIFY_DONE;
	}
}

static int bg_cdc_codec_probe(struct snd_soc_codec *codec)
{
	struct bg_cdc_priv *bg_cdc = dev_get_drvdata(codec->dev);
@@ -1113,6 +1156,8 @@ static int bg_cdc_codec_probe(struct snd_soc_codec *codec)
	if (!bg_state_notifier)
		dev_err(codec->dev, "Failed to register bg notifier\n");

	bg_cdc->bg_pm_nb.notifier_call = bg_pm_event;
	register_pm_notifier(&bg_cdc->bg_pm_nb);
	bg_cdc->codec = codec;
	return 0;
}
@@ -1131,53 +1176,11 @@ static int bg_cdc_codec_remove(struct snd_soc_codec *codec)
	if (bg_state_notifier)
		subsys_notif_unregister_notifier(bg_state_notifier,
						 &bg_cdc->bg_ssr_nb);
	unregister_pm_notifier(&bg_cdc->bg_pm_nb);
	kfree(bg_cdc->fw_data);
	return 0;
}

static int bg_cdc_pm_suspend(struct bg_cdc_priv *bg_cdc)
{

	/* Do not remove the regulator vote if a session is active */
	if (bg_cdc->num_sessions > 0) {
		pr_debug("audio session in progress don't devote\n");
		return 0;
	}
	cancel_delayed_work_sync(&bg_cdc->bg_cdc_pktzr_init_work);
	cancel_delayed_work_sync(&bg_cdc->bg_cdc_cal_init_work);
	mutex_lock(&bg_cdc->bg_cdc_lock);
	if (bg_cdc->bg_cal_updated) {
		bg_cdc_enable_regulator(bg_cdc->spkr_vreg, false);
		bg_cdc->bg_cal_updated = false;
	}
	mutex_unlock(&bg_cdc->bg_cdc_lock);
	return 0;
}

static int bg_cdc_pm_resume(struct bg_cdc_priv *bg_cdc)
{
	schedule_delayed_work(&bg_cdc->bg_cdc_cal_init_work,
			msecs_to_jiffies(bg_cdc->bg_cal_init_delay));
	return 0;
}

static int bg_pm_event(struct notifier_block *nb,
				unsigned long event, void *ptr)
{
	struct bg_cdc_priv *bg_cdc =
			container_of(nb, struct bg_cdc_priv, bg_pm_nb);
	switch (event) {
	case PM_POST_HIBERNATION:
	case PM_POST_SUSPEND:
		return bg_cdc_pm_resume(bg_cdc);
	case PM_HIBERNATION_PREPARE:
	case PM_SUSPEND_PREPARE:
		return bg_cdc_pm_suspend(bg_cdc);
	default:
		return NOTIFY_DONE;
	}
}

static struct snd_soc_codec_driver soc_codec_dev_bg_cdc = {
	.probe = bg_cdc_codec_probe,
	.remove = bg_cdc_codec_remove,
@@ -1289,8 +1292,6 @@ static int bg_cdc_probe(struct platform_device *pdev)
		  bg_cdc_cal_init);
	schedule_work(&bg_cdc->bg_cdc_add_child_devices_work);
	mutex_init(&bg_cdc->bg_cdc_lock);
	bg_cdc->bg_pm_nb.notifier_call = bg_pm_event;
	register_pm_notifier(&bg_cdc->bg_pm_nb);

	dev_dbg(&pdev->dev, "%s: BG driver probe done\n", __func__);
	return ret;
@@ -1309,7 +1310,6 @@ static int bg_cdc_remove(struct platform_device *pdev)

	snd_soc_unregister_codec(&pdev->dev);
	mutex_destroy(&bg_cdc->bg_cdc_lock);
	unregister_pm_notifier(&bg_cdc->bg_pm_nb);
	regulator_put(bg_cdc->spkr_vreg);
	kfree(bg_cdc);
	return 0;