diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c index 3746a201b23c..10976bf8f94b 100644 --- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,7 @@ struct msm_compr_pdata { int32_t ion_fd[MSM_FRONTEND_DAI_MAX]; bool is_in_use[MSM_FRONTEND_DAI_MAX]; bool avs_ver; + struct mutex lock; }; struct msm_compr_audio { @@ -1851,6 +1853,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) } spin_unlock_irqrestore(&prtd->lock, flags); + mutex_lock(&pdata->lock); pdata->cstream[soc_prtd->dai_link->be_id] = NULL; if (cstream->direction == SND_COMPRESS_PLAYBACK) { msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id, @@ -1880,6 +1883,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream) pdata->is_in_use[soc_prtd->dai_link->be_id] = false; kfree(prtd); runtime->private_data = NULL; + mutex_unlock(&pdata->lock); return 0; } @@ -1930,6 +1934,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) } spin_unlock_irqrestore(&prtd->lock, flags); + mutex_lock(&pdata->lock); pdata->cstream[soc_prtd->dai_link->be_id] = NULL; msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id, SNDRV_PCM_STREAM_CAPTURE); @@ -1940,6 +1945,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream) kfree(prtd); runtime->private_data = NULL; + mutex_unlock(&pdata->lock); return 0; } @@ -3228,6 +3234,7 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, struct msm_compr_audio *prtd = NULL; long *values = &(ucontrol->value.integer.value[0]); int effects_module; + int ret = 0; pr_debug("%s\n", __func__); if (fe_id >= MSM_FRONTEND_DAI_MAX) { @@ -3235,16 +3242,19 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_err("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } if (prtd->compr_passthr != LEGACY_PCM) { pr_debug("%s: No effects for compr_type[%d]\n", @@ -3310,9 +3320,11 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol, break; default: pr_err("%s Invalid effects config module\n", __func__); - return -EINVAL; + ret = -EINVAL; } - return 0; +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, @@ -3325,6 +3337,7 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, struct msm_compr_audio_effects *audio_effects = NULL; struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd = NULL; + int ret = 0; pr_debug("%s\n", __func__); if (fe_id >= MSM_FRONTEND_DAI_MAX) { @@ -3332,19 +3345,23 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_err("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } - - return 0; +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, @@ -3357,6 +3374,7 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, struct msm_compr_audio_effects *audio_effects = NULL; struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd = NULL; + int ret = 0; long *values = &(ucontrol->value.integer.value[0]); if (fe_id >= MSM_FRONTEND_DAI_MAX) { @@ -3364,28 +3382,34 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_err("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } if (prtd->compr_passthr != LEGACY_PCM) { pr_err("%s: No effects for compr_type[%d]\n", __func__, prtd->compr_passthr); - return -EPERM; + ret = -EPERM; + goto done; } audio_effects->query.mod_id = (u32)*values++; audio_effects->query.parm_id = (u32)*values++; audio_effects->query.size = (u32)*values++; audio_effects->query.offset = (u32)*values++; audio_effects->query.device = (u32)*values++; - return 0; +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, @@ -3398,6 +3422,7 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, struct msm_compr_audio_effects *audio_effects = NULL; struct snd_compr_stream *cstream = NULL; struct msm_compr_audio *prtd = NULL; + int ret = 0; long *values = &(ucontrol->value.integer.value[0]); if (fe_id >= MSM_FRONTEND_DAI_MAX) { @@ -3405,23 +3430,28 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, __func__, fe_id); return -EINVAL; } + mutex_lock(&pdata->lock); cstream = pdata->cstream[fe_id]; audio_effects = pdata->audio_effects[fe_id]; if (!cstream || !audio_effects) { pr_debug("%s: stream or effects inactive\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } prtd = cstream->runtime->private_data; if (!prtd) { pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; + ret = -EINVAL; + goto done; } values[0] = (long)audio_effects->query.mod_id; values[1] = (long)audio_effects->query.parm_id; values[2] = (long)audio_effects->query.size; values[3] = (long)audio_effects->query.offset; values[4] = (long)audio_effects->query.device; - return 0; +done: + mutex_unlock(&pdata->lock); + return ret; } static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, @@ -3508,6 +3538,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, goto end; } + mutex_lock(&pdata->lock); switch (prtd->codec) { case FORMAT_MP3: case FORMAT_MPEG4_AAC: @@ -3556,6 +3587,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol, } end: pr_debug("%s: ret %d\n", __func__, rc); + mutex_unlock(&pdata->lock); return rc; } @@ -4093,6 +4125,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform) if (!pdata) return -ENOMEM; + mutex_init(&pdata->lock); snd_soc_platform_set_drvdata(platform, pdata); for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) { @@ -4138,6 +4171,20 @@ static int msm_compr_probe(struct snd_soc_platform *platform) return 0; } +static int msm_compr_remove(struct snd_soc_platform *platform) +{ + + struct msm_compr_pdata *pdata = (struct msm_compr_pdata *) + snd_soc_platform_get_drvdata(platform); + if (!pdata) { + pr_err("%s pdata is null\n", __func__); + return -ENOMEM; + } + + mutex_destroy(&pdata->lock); + kfree(pdata); + return 0; +} static int msm_compr_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -4900,6 +4947,7 @@ static struct snd_soc_platform_driver msm_soc_platform = { .probe = msm_compr_probe, .compr_ops = &msm_compr_ops, .pcm_new = msm_compr_new, + .remove = msm_compr_remove, }; static int msm_compr_dev_probe(struct platform_device *pdev) @@ -4910,7 +4958,7 @@ static int msm_compr_dev_probe(struct platform_device *pdev) &msm_soc_platform); } -static int msm_compr_remove(struct platform_device *pdev) +static int msm_compr_dev_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; @@ -4929,7 +4977,7 @@ static struct platform_driver msm_compr_driver = { .of_match_table = msm_compr_dt_match, }, .probe = msm_compr_dev_probe, - .remove = msm_compr_remove, + .remove = msm_compr_dev_remove, }; static int __init msm_soc_platform_init(void)