Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: AMD: add pm ops

genpd will power off/on ACP to manage runtime ACP PM. ACP runtime PM
hooks are added to get it deinitialized and initialized respectively,
after it is powered off/on.

When system goes to suspend when audio usecase is active, ACP will
be powered off through genpd. When it resumes, ACP needs to be
initialized and reconfigured.

Signed-off-by: Maruthi Bayyavarapu <maruthi.bayyavarapu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Maruthi Srinivas Bayyavarapu and committed by
Mark Brown
1927da93 7c31335a

+48
+48
sound/soc/amd/acp-pcm-dma.c
··· 16 16 #include <linux/module.h> 17 17 #include <linux/delay.h> 18 18 #include <linux/sizes.h> 19 + #include <linux/pm_runtime.h> 19 20 20 21 #include <sound/soc.h> 21 22 ··· 886 885 return status; 887 886 } 888 887 888 + pm_runtime_set_autosuspend_delay(&pdev->dev, 10000); 889 + pm_runtime_use_autosuspend(&pdev->dev); 890 + pm_runtime_enable(&pdev->dev); 891 + 889 892 return status; 890 893 } 891 894 ··· 899 894 900 895 acp_deinit(adata->acp_mmio); 901 896 snd_soc_unregister_platform(&pdev->dev); 897 + pm_runtime_disable(&pdev->dev); 902 898 903 899 return 0; 904 900 } 901 + 902 + static int acp_pcm_resume(struct device *dev) 903 + { 904 + struct audio_drv_data *adata = dev_get_drvdata(dev); 905 + 906 + acp_init(adata->acp_mmio); 907 + 908 + if (adata->play_stream && adata->play_stream->runtime) 909 + config_acp_dma(adata->acp_mmio, 910 + adata->play_stream->runtime->private_data); 911 + if (adata->capture_stream && adata->capture_stream->runtime) 912 + config_acp_dma(adata->acp_mmio, 913 + adata->capture_stream->runtime->private_data); 914 + 915 + acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); 916 + return 0; 917 + } 918 + 919 + static int acp_pcm_runtime_suspend(struct device *dev) 920 + { 921 + struct audio_drv_data *adata = dev_get_drvdata(dev); 922 + 923 + acp_deinit(adata->acp_mmio); 924 + acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); 925 + return 0; 926 + } 927 + 928 + static int acp_pcm_runtime_resume(struct device *dev) 929 + { 930 + struct audio_drv_data *adata = dev_get_drvdata(dev); 931 + 932 + acp_init(adata->acp_mmio); 933 + acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); 934 + return 0; 935 + } 936 + 937 + static const struct dev_pm_ops acp_pm_ops = { 938 + .resume = acp_pcm_resume, 939 + .runtime_suspend = acp_pcm_runtime_suspend, 940 + .runtime_resume = acp_pcm_runtime_resume, 941 + }; 905 942 906 943 static struct platform_driver acp_dma_driver = { 907 944 .probe = acp_audio_probe, 908 945 .remove = acp_audio_remove, 909 946 .driver = { 910 947 .name = "acp_audio_dma", 948 + .pm = &acp_pm_ops, 911 949 }, 912 950 }; 913 951