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

Commit 992d96a9 authored by Honghao Liu's avatar Honghao Liu
Browse files

ASoC: msm: fix for automotive machine driver probe failure



Add a dummy device driver which will be probed once the ADSP
is powered up. This is to ensure that the deferred audio device
drivers which depend on ADSP gets probed again after the ADSP
is powered up. The machine driver depends on these deferred
audio drivers to be successfully probed before it can register
the sound card.

This is to fix a race condition where all the kernel device
drivers (except the audio drivers that depend on ADSP) are
successfully probed before the ADSP is powered up, resulting
the audio drivers and the machine driver to remain in a
deferred state forever. The new dummy device driver will act
as a trigger for the probing of deferred drivers.

CRs-fixed: 1070694

Change-Id: I41f328b36c57a0f7e0027addddc1748357db532c
Signed-off-by: default avatarHonghao Liu <honghaol@codeaurora.org>
parent 3f08a569
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ static int msm_ec_ref_ch = 4;
static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE;
static int msm_ec_ref_sampling_rate = SAMPLING_RATE_48KHZ;

static void *adsp_state_notifier;
static bool dummy_device_registered;

enum {
	QUATERNARY_TDM_RX_0,
	QUATERNARY_TDM_RX_1,
@@ -3779,6 +3782,55 @@ static struct platform_driver apq8096_asoc_machine_driver = {
	.probe = apq8096_asoc_machine_probe,
	.remove = apq8096_asoc_machine_remove,
};

static int dummy_machine_probe(struct platform_device *pdev)
{
	return 0;
}

static int dummy_machine_remove(struct platform_device *pdev)
{
	return 0;
}

static struct platform_device dummy_machine_device = {
	.name = "apq8096-auto-asoc-dummy",
};

static struct platform_driver apq8096_asoc_machine_dummy_driver = {
	.driver = {
		.name = "apq8096-auto-asoc-dummy",
		.owner = THIS_MODULE,
	},
	.probe = dummy_machine_probe,
	.remove = dummy_machine_remove,
};

static int  apq8096_adsp_state_callback(struct notifier_block *nb,
					unsigned long value, void *priv)
{
	if (!dummy_device_registered && SUBSYS_AFTER_POWERUP == value) {
		platform_driver_register(&apq8096_asoc_machine_dummy_driver);
		platform_device_register(&dummy_machine_device);
		dummy_device_registered = true;
	}

	return NOTIFY_OK;
}

static struct notifier_block adsp_state_notifier_block = {
	.notifier_call = apq8096_adsp_state_callback,
	.priority = -INT_MAX,
};

static int __init apq8096_soc_platform_init(void)
{
	adsp_state_notifier = subsys_notif_register_notifier("adsp",
						&adsp_state_notifier_block);
	return 0;
}

module_init(apq8096_soc_platform_init);
module_platform_driver(apq8096_asoc_machine_driver);

MODULE_DESCRIPTION("ALSA SoC msm");