ASoC: tegra-alt: Fix xrun during playback/capture across suspend

If audio playback/capture is running when the system suspends, then an
xrun event is reported by the kernel on entering suspend.

The problem is that userspace tasks are frozen before the kernel space
sound core is suspended. This means that the DMA is still running after
userspace has been frozen and hence the CPU has stopped updating the DMA
audio buffer. Hence, when the DMA reaches the end of the buffer an XRUN
event occurs. Depending on the sample rate the length of time before
this XRUN event occurs will vary and the worse case would be around 5ms
(for 192kHz with 16 channels @ 16-bits). There is no way to ensure that
the sound core is stopped within 5ms of freezing userspace and so the
only solution is to ensure that the sound core is suspend before
userspace by calling snd_soc_suspend() from the Linux PM prepare
handler.

Bug 2113333

Change-Id: Ie9da77ee99f74fded4b34cb4ba665da26e9c5e94
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1719611
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Jon Hunter
2018-05-01 18:12:14 +01:00
committed by Sameer Pujar
parent 3ef3ff7ab8
commit f2d64a30f0

View File

@@ -1435,11 +1435,26 @@ static int tegra_machine_driver_remove(struct platform_device *pdev)
return 0;
}
#if CONFIG_PM
static void tegra_asoc_machine_resume(struct device *dev)
{
WARN_ON(snd_soc_resume(dev));
}
#else
#define tegra_asoc_machine_resume NULL
#endif
static const struct dev_pm_ops tegra_asoc_machine_pm_ops = {
.prepare = snd_soc_suspend,
.complete = tegra_asoc_machine_resume,
.poweroff = snd_soc_poweroff,
};
static struct platform_driver tegra_asoc_machine_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
.pm = &tegra_asoc_machine_pm_ops,
.of_match_table = tegra_machine_of_match,
},
.probe = tegra_machine_driver_probe,