ASoC: tegra: fix sound card dependency

There is GVS intermittency where few audio tests fail because there is
no APE sound card available. The card registration itself does not
happen because there is kernel data abort and following dump is seen:

 [   36.163223] Unable to handle kernel paging request at virtual address ffffffffffffffc0
 [   36.171180] Mem abort info:
 [   36.171182]   ESR = 0x0000000096000004
 [   36.171183]   EC = 0x25: DABT (current EL), IL = 32 bits
 [   36.171186]   SET = 0, FnV = 0
 [   36.174218]   EA = 0, S1PTW = 0
 [   36.174219]   FSC = 0x04: level 0 translation fault
 [   36.174221] Data abort info:
 [   36.174222]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
 [   36.174223]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
 [   36.174224]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
 [   36.174226] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000813b67000
 [   36.174228] [ffffffffffffffc0] pgd=0000000000000000, p4d=0000000000000000
 [   36.174234] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP

This seems to happen because mixer control override driver has the
dependency over the sound card and this dependency check is incorrect.
The attempt is made to register override controls before the sound card
is fully ready.

One option is to use 'card->instantiated' flag to add the dependency.
However this flag update is protected by card mutext and client_mutex
which is local to the core. So this flag check does not appear fully
reliable.

As a safer option, the override device is made child of sound device.
This way the probe order is ensured and override probe happens only
after a successful sound probe. This requires a change in machine driver
to allow probe() happen for child devices. This may be a concern during
usage of upstream machine driver which does not have provision for child
device probing. For now unblock the upstream AHUB usage by using this
safe option and investigate the best option to make the override driver
independent.

Bug 4508166
Bug 4451662
TAS-2251

Change-Id: Ib13f0a3a0ac272a0f2325b9d74efbc31128f0991
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3083180
Reviewed-by: Mohan kumar <mkumard@nvidia.com>
Reviewed-by: Sharad Gupta <sharadg@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Sameer Pujar
2024-02-25 04:00:33 +00:00
committed by mobile promotions
parent 72ed0ddf9d
commit 0332fd555e
2 changed files with 11 additions and 20 deletions

View File

@@ -436,6 +436,10 @@ static int tegra_machine_driver_probe(struct platform_device *pdev)
tegra_machine_add_i2s_codec_controls(card); tegra_machine_add_i2s_codec_controls(card);
of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
dev_info(&pdev->dev, "Registered legacy APE sound card\n");
return 0; return 0;
cleanup_asoc: cleanup_asoc:
release_asoc_phandles(machine); release_asoc_phandles(machine);

View File

@@ -349,36 +349,21 @@ static int tegra_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
static int tegra_mixer_control_probe(struct platform_device *pdev) static int tegra_mixer_control_probe(struct platform_device *pdev)
{ {
struct platform_device *sound_pdev;
struct device_node *sound_node;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct snd_soc_card *card; struct snd_soc_card *card;
struct snd_soc_component *component; struct snd_soc_component *component;
struct snd_soc_pcm_runtime *rtd; struct snd_soc_pcm_runtime *rtd;
sound_node = of_parse_phandle(dev->of_node, "nvidia,tegra-ape-link", 0); dev_info(dev, "Begin probe of override control device\n");
if (!sound_node) {
dev_err(dev, "Failed to get phandle to sound device\n"); card = dev_get_drvdata(dev->parent);
if (!card) {
dev_err(dev, "Failed to get APE card reference\n");
return -EINVAL; return -EINVAL;
} }
/* Device not instantiated yet */
sound_pdev = of_find_device_by_node(sound_node);
if (!sound_pdev)
return -EPROBE_DEFER;
/* Sound card not registered yet */
card = dev_get_drvdata(&sound_pdev->dev);
if (!card)
return -EPROBE_DEFER;
dev_set_drvdata(dev, card); dev_set_drvdata(dev, card);
if (!device_link_add(dev, &sound_pdev->dev, 0)) {
dev_err(dev, "Failed to add device link to sound\n");
return -EINVAL;
}
for_each_card_components(card, component) { for_each_card_components(card, component) {
if (!component->name_prefix) if (!component->name_prefix)
continue; continue;
@@ -434,6 +419,8 @@ static int tegra_mixer_control_probe(struct platform_device *pdev)
rtd->dai_link->be_hw_params_fixup = tegra_hw_params_fixup; rtd->dai_link->be_hw_params_fixup = tegra_hw_params_fixup;
} }
dev_info(dev, "Registered override controls for APE sound card\n");
return 0; return 0;
} }