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 <mkumard@nvidia.com>
Reviewed-on: http://git-master/r/1475216
Reviewed-on: http://git-master/r/1499116
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-by: Dipesh Gandhi <dipeshg@nvidia.com>
Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>
Reviewed-on: http://git-master/r/1502050
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Tested-by: Sachin Nikam <snikam@nvidia.com>
This commit is contained in:
Mohan Kumar
2017-05-04 12:33:04 +05:30
committed by Sameer Pujar
parent 33c2382438
commit 85eae8d6ff
2 changed files with 24 additions and 2 deletions

View File

@@ -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)

View File

@@ -139,6 +139,8 @@ static int tegra186_dspk_runtime_resume(struct device *dev)
}
regcache_cache_only(dspk->regmap, false);
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);