From 999d45effe06a69f28d87c8517b94a109cffbb45 Mon Sep 17 00:00:00 2001 From: Shreshtha SAHU Date: Tue, 7 Oct 2014 15:37:45 +0530 Subject: ASoC: tegra: fix avp module remove - avp module remove should not try to release client if avp pcm open was never called and client was never allocated - avp module remove should deregister offload ops Bug 200043253 Change-Id: I11a6d65afab4d88aa5669553809e99fd69cfd000 Signed-off-by: Shreshtha SAHU Reviewed-on: http://git-master/r/554153 Reviewed-by: Sumit Bhattacharya Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Zheng Liu Reviewed-by: Winnie Hsu --- sound/soc/tegra/tegra30_avp.c | 4 +++- sound/soc/tegra/tegra_offload.c | 37 ++++++++++++++++++++++++++++++++----- sound/soc/tegra/tegra_offload.h | 1 + 3 files changed, 36 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/tegra/tegra30_avp.c b/sound/soc/tegra/tegra30_avp.c index aeefdd53fdee..e81a813ab6a8 100644 --- a/sound/soc/tegra/tegra30_avp.c +++ b/sound/soc/tegra/tegra30_avp.c @@ -1447,7 +1447,9 @@ static int tegra30_avp_audio_remove(struct platform_device *pdev) dev_vdbg(&pdev->dev, "%s", __func__); - tegra_nvavp_audio_client_release(audio_avp->nvavp_client); + tegra_deregister_offload_ops(); + if (audio_avp->nvavp_client) + tegra_nvavp_audio_client_release(audio_avp->nvavp_client); tegra30_avp_mem_free(&audio_avp->cmd_buf_mem); tegra30_avp_mem_free(&audio_avp->param_mem); tegra30_avp_mem_free(&audio_avp->ucode_mem); diff --git a/sound/soc/tegra/tegra_offload.c b/sound/soc/tegra/tegra_offload.c index 660bb4739554..cae5f44c9794 100644 --- a/sound/soc/tegra/tegra_offload.c +++ b/sound/soc/tegra/tegra_offload.c @@ -98,25 +98,52 @@ static const struct snd_pcm_hardware tegra_offload_pcm_hardware_capture = { int tegra_register_offload_ops(struct tegra_offload_ops *ops) { + int ret = 0; + mutex_lock(&tegra_offload_lock); if (!ops) { pr_err("Invalid ops pointer."); - return -EINVAL; + ret = -EINVAL; + goto errout; } if (tegra_offload_init_done) { pr_err("Offload ops already registered."); - return -EBUSY; + ret = -EBUSY; + goto errout; } + memcpy(&offload_ops, ops, sizeof(offload_ops)); tegra_offload_init_done = 1; - mutex_unlock(&tegra_offload_lock); - pr_info("succefully registered offload ops"); - return 0; + +errout: + mutex_unlock(&tegra_offload_lock); + return ret; } EXPORT_SYMBOL_GPL(tegra_register_offload_ops); +void tegra_deregister_offload_ops(void) +{ + mutex_lock(&tegra_offload_lock); + + if (!tegra_offload_init_done) { + pr_err("Offload ops not registered."); + mutex_unlock(&tegra_offload_lock); + return; + } + + memset(&offload_ops, 0, sizeof(offload_ops)); + tegra_offload_init_done = 0; + + mutex_unlock(&tegra_offload_lock); + + pr_info("succefully deregistered offload ops"); + return; +} +EXPORT_SYMBOL_GPL(tegra_deregister_offload_ops); + + /* Compress playback related APIs */ static void tegra_offload_compr_fragment_elapsed(void *arg, unsigned int is_eos) { diff --git a/sound/soc/tegra/tegra_offload.h b/sound/soc/tegra/tegra_offload.h index b67c19a5d714..9cbc31018e59 100644 --- a/sound/soc/tegra/tegra_offload.h +++ b/sound/soc/tegra/tegra_offload.h @@ -93,4 +93,5 @@ struct tegra_offload_ops { }; int tegra_register_offload_ops(struct tegra_offload_ops *ops); +void tegra_deregister_offload_ops(void); #endif -- cgit v1.2.3