summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohan Kumar <mkumard@nvidia.com>2017-08-16 05:29:17 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-08-17 04:37:14 -0400
commita7dc8adc8091d45dc22900affb7a4b73ccf93c01 (patch)
tree22c128962a69d76fc69a94fe9a9683f647f4d53e
parentd4c782a9ea6899c23297887c89e80262a0837c10 (diff)
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 below fix - Will prevent any reg access in runtime resume of drivers and avoid opening pcm devices. Bug 200333417 Change-Id: Ieba2a063342cd1e7becb79a0135cb2b8ec373a61 Signed-off-by: Mohan Kumar <mkumard@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1539396 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Dipesh Gandhi <dipeshg@nvidia.com> Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>
-rw-r--r--sound/soc/tegra-alt/tegra210_adsp_alt.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/sound/soc/tegra-alt/tegra210_adsp_alt.c b/sound/soc/tegra-alt/tegra210_adsp_alt.c
index d9e1250e7..eafc9481b 100644
--- a/sound/soc/tegra-alt/tegra210_adsp_alt.c
+++ b/sound/soc/tegra-alt/tegra210_adsp_alt.c
@@ -171,6 +171,7 @@ struct tegra210_adsp {
171 struct mutex mutex; 171 struct mutex mutex;
172 int init_done; 172 int init_done;
173 int adsp_started; 173 int adsp_started;
174 bool is_shutdown;
174 uint32_t adma_ch_page; 175 uint32_t adma_ch_page;
175 uint32_t adma_ch_start; 176 uint32_t adma_ch_start;
176 uint32_t adma_ch_cnt; 177 uint32_t adma_ch_cnt;
@@ -1247,7 +1248,7 @@ static int tegra210_adsp_compr_open(struct snd_compr_stream *cstream)
1247 1248
1248 dev_vdbg(adsp->dev, "%s : DAI ID %d", __func__, rtd->codec_dai->id); 1249 dev_vdbg(adsp->dev, "%s : DAI ID %d", __func__, rtd->codec_dai->id);
1249 1250
1250 if (!adsp->init_done) 1251 if (!adsp->init_done || adsp->is_shutdown)
1251 return -ENODEV; 1252 return -ENODEV;
1252 1253
1253 if (!adsp->pcm_path[fe_reg][cstream->direction].fe_reg || 1254 if (!adsp->pcm_path[fe_reg][cstream->direction].fe_reg ||
@@ -1572,6 +1573,9 @@ static int tegra210_adsp_pcm_open(struct snd_pcm_substream *substream)
1572 1573
1573 dev_vdbg(adsp->dev, "%s", __func__); 1574 dev_vdbg(adsp->dev, "%s", __func__);
1574 1575
1576 if (adsp->is_shutdown)
1577 return -ENODEV;
1578
1575 if (!adsp->pcm_path[fe_reg][substream->stream].fe_reg || 1579 if (!adsp->pcm_path[fe_reg][substream->stream].fe_reg ||
1576 !adsp->pcm_path[fe_reg][substream->stream].be_reg) { 1580 !adsp->pcm_path[fe_reg][substream->stream].be_reg) {
1577 dev_err(adsp->dev, "Broken Path%d - FE not linked to BE", fe_reg); 1581 dev_err(adsp->dev, "Broken Path%d - FE not linked to BE", fe_reg);
@@ -4264,7 +4268,7 @@ static int tegra210_adsp_set_param(struct snd_kcontrol *kcontrol,
4264 apm_msg_t apm_msg; 4268 apm_msg_t apm_msg;
4265 int ret; 4269 int ret;
4266 4270
4267 if (!adsp->init_done) { 4271 if (!adsp->init_done || adsp->is_shutdown) {
4268 dev_warn(adsp->dev, "ADSP is not booted yet\n"); 4272 dev_warn(adsp->dev, "ADSP is not booted yet\n");
4269 return -EPERM; 4273 return -EPERM;
4270 } 4274 }
@@ -4365,7 +4369,7 @@ static int tegra210_adsp_tlv_callback(struct snd_kcontrol *kcontrol,
4365 unsigned int *tlv_data; 4369 unsigned int *tlv_data;
4366 int ret = 0; 4370 int ret = 0;
4367 4371
4368 if (!adsp->init_done) { 4372 if (!adsp->init_done || adsp->is_shutdown) {
4369 dev_warn(adsp->dev, "ADSP is not booted yet\n"); 4373 dev_warn(adsp->dev, "ADSP is not booted yet\n");
4370 return 0; 4374 return 0;
4371 } 4375 }
@@ -4502,7 +4506,7 @@ static int tegra210_adsp_apm_put(struct snd_kcontrol *kcontrol,
4502 bool send_msg = 0; 4506 bool send_msg = 0;
4503 int ret = 0; 4507 int ret = 0;
4504 4508
4505 if (!adsp->init_done) { 4509 if (!adsp->init_done || adsp->is_shutdown) {
4506 dev_warn(adsp->dev, "ADSP is not booted yet\n"); 4510 dev_warn(adsp->dev, "ADSP is not booted yet\n");
4507 return -EPERM; 4511 return -EPERM;
4508 } 4512 }
@@ -4880,6 +4884,7 @@ static int tegra210_adsp_audio_platform_probe(struct platform_device *pdev)
4880 } 4884 }
4881 dev_set_drvdata(&pdev->dev, adsp); 4885 dev_set_drvdata(&pdev->dev, adsp);
4882 adsp->dev = &pdev->dev; 4886 adsp->dev = &pdev->dev;
4887 adsp->is_shutdown = false;
4883 adsp->soc_data = (struct adsp_soc_data *)match->data; 4888 adsp->soc_data = (struct adsp_soc_data *)match->data;
4884 4889
4885 4890
@@ -5175,6 +5180,14 @@ static int __maybe_unused tegra210_adsp_audio_platform_remove(
5175 return 0; 5180 return 0;
5176} 5181}
5177 5182
5183static void tegra210_adsp_audio_platform_shutdown(
5184 struct platform_device *pdev)
5185{
5186 struct tegra210_adsp *adsp = dev_get_drvdata(&pdev->dev);
5187
5188 adsp->is_shutdown = true;
5189}
5190
5178static const struct dev_pm_ops tegra210_adsp_pm_ops = { 5191static const struct dev_pm_ops tegra210_adsp_pm_ops = {
5179 SET_RUNTIME_PM_OPS(tegra210_adsp_runtime_suspend, 5192 SET_RUNTIME_PM_OPS(tegra210_adsp_runtime_suspend,
5180 tegra210_adsp_runtime_resume, NULL) 5193 tegra210_adsp_runtime_resume, NULL)
@@ -5189,6 +5202,7 @@ static struct platform_driver tegra210_adsp_audio_driver = {
5189 .suppress_bind_attrs = true, 5202 .suppress_bind_attrs = true,
5190 }, 5203 },
5191 .probe = tegra210_adsp_audio_platform_probe, 5204 .probe = tegra210_adsp_audio_platform_probe,
5205 .shutdown = tegra210_adsp_audio_platform_shutdown,
5192 /* TODO enable remove() when the driver is hotpluggable */ 5206 /* TODO enable remove() when the driver is hotpluggable */
5193 /* .remove = tegra210_adsp_audio_platform_remove, */ 5207 /* .remove = tegra210_adsp_audio_platform_remove, */
5194}; 5208};