From 85eae8d6ff0f3a15232e719adc7cb6e8ce74f765 Mon Sep 17 00:00:00 2001 From: Mohan Kumar Date: Thu, 4 May 2017 12:33:04 +0530 Subject: [PATCH] ASoC: tegra-alt: Avoid reg access after shutdown Below are the hypothetical scenarios - Drivers are in suspend state while reboot and PCM Open call from userspace is received after driver shutdown [APE is power gated already] - PM domain handling doesn't ensure proper functionality after driver shutdown is called The change handles with the beloe fix - ALSA PCM Open API first executes runtime resume of each driver. So need to prevent any reg access in runtime resume of drivers. - ALSA PCM Open executes ADMAIF startup after runtime resume of each driver. If ADMAIF startup returns failure based on shutdown, PCM Open operation will fail, this will break PCM Open path and will ensure no further ALSA APIs/Callbacks are called. Bug 200289815 Change-Id: I46060d74b3271a870a0bcfc727972c97e2a73931 Signed-off-by: Mohan Kumar Reviewed-on: http://git-master/r/1475216 Reviewed-on: http://git-master/r/1499116 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svccoveritychecker GVS: Gerrit_Virtual_Submit Reviewed-by: Sameer Pujar Reviewed-by: Dipesh Gandhi Reviewed-by: Ravindra Lokhande Reviewed-on: http://git-master/r/1502050 Reviewed-by: Sachin Nikam Tested-by: Sachin Nikam --- sound/soc/tegra-alt/tegra186_asrc_alt.c | 15 ++++++++++++++- sound/soc/tegra-alt/tegra186_dspk_alt.c | 11 ++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sound/soc/tegra-alt/tegra186_asrc_alt.c b/sound/soc/tegra-alt/tegra186_asrc_alt.c index 7a72b64c..18411ef9 100644 --- a/sound/soc/tegra-alt/tegra186_asrc_alt.c +++ b/sound/soc/tegra-alt/tegra186_asrc_alt.c @@ -1,7 +1,7 @@ /* * tegra186_asrc_alt.c - Tegra186 ASRC driver * - * Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -183,6 +183,10 @@ static int tegra186_asrc_runtime_resume(struct device *dev) } regcache_cache_only(asrc->regmap, false); + + if (asrc->is_shutdown) + return 0; + regcache_sync(asrc->regmap); /* HW needs sw reset to make sure previous @@ -1142,6 +1146,7 @@ static int tegra186_asrc_platform_probe(struct platform_device *pdev) } asrc->soc_data = soc_data; + asrc->is_shutdown = false; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { @@ -1233,6 +1238,13 @@ err: return ret; } +static void tegra186_asrc_platform_shutdown(struct platform_device *pdev) +{ + struct tegra186_asrc *asrc = dev_get_drvdata(&pdev->dev); + + asrc->is_shutdown = true; +} + static int tegra186_asrc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_codec(&pdev->dev); @@ -1259,6 +1271,7 @@ static struct platform_driver tegra186_asrc_driver = { }, .probe = tegra186_asrc_platform_probe, .remove = tegra186_asrc_platform_remove, + .shutdown = tegra186_asrc_platform_shutdown, }; module_platform_driver(tegra186_asrc_driver) diff --git a/sound/soc/tegra-alt/tegra186_dspk_alt.c b/sound/soc/tegra-alt/tegra186_dspk_alt.c index 5c56bc57..5da9cc2a 100644 --- a/sound/soc/tegra-alt/tegra186_dspk_alt.c +++ b/sound/soc/tegra-alt/tegra186_dspk_alt.c @@ -139,7 +139,9 @@ static int tegra186_dspk_runtime_resume(struct device *dev) } regcache_cache_only(dspk->regmap, false); - regcache_sync(dspk->regmap); + + if (!dspk->is_shutdown) + regcache_sync(dspk->regmap); return 0; } @@ -468,6 +470,7 @@ static int tegra186_dspk_platform_probe(struct platform_device *pdev) } dspk->soc_data = soc_data; + dspk->is_shutdown = false; if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) { dspk->clk_dspk = devm_clk_get(&pdev->dev, NULL); @@ -602,7 +605,12 @@ err: return ret; } +static void tegra186_dspk_platform_shutdown(struct platform_device *pdev) +{ + struct tegra186_dspk *dspk = dev_get_drvdata(&pdev->dev); + dspk->is_shutdown = true; +} static int tegra186_dspk_platform_remove(struct platform_device *pdev) { @@ -636,6 +644,7 @@ static struct platform_driver tegra186_dspk_driver = { }, .probe = tegra186_dspk_platform_probe, .remove = tegra186_dspk_platform_remove, + .shutdown = tegra186_dspk_platform_shutdown, }; module_platform_driver(tegra186_dspk_driver);