mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 01:31:30 +03:00
tegra-alt: adsp: reset handler on close
Set message handler to NULL on stream close. Acquire lock when calling msg handler to avoid race condition. Bug 200121246 Change-Id: Ia1182a787f00c2ee9b092a9822a6d5c8404e3b12 Reviewed-on: http://git-master/r/768309 (cherry picked from commit 116260c46c2c0aa077bf2ca57ea2227a56ebd718) Reviewed-on: http://git-master/r/770473 (cherry picked from commit 2100a3c5f70877dd566c201ffd6c4d033ed819e1) Signed-off-by: Viraj Karandikar <vkarandikar@nvidia.com> Reviewed-on: http://git-master/r/781737 Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>
This commit is contained in:
committed by
Sameer Pujar
parent
47cc203e9c
commit
1b05a7ad2c
@@ -88,6 +88,7 @@ struct tegra210_adsp_app {
|
||||
uint32_t connect:1; /* if app is connected to a source */
|
||||
uint32_t priority; /* Valid for only APM app */
|
||||
uint32_t min_adsp_clock; /* Min ADSP clock required in MHz */
|
||||
spinlock_t lock;
|
||||
void *private_data;
|
||||
int (*msg_handler)(struct tegra210_adsp_app *, apm_msg_t *);
|
||||
};
|
||||
@@ -543,6 +544,8 @@ static int tegra210_adsp_app_init(struct tegra210_adsp *adsp,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
spin_lock_init(&app->lock);
|
||||
|
||||
app->plugin = PLUGIN_SHARED_MEM(app->info->mem.shared);
|
||||
if (IS_APM_IN(app->reg)) {
|
||||
uint32_t apm_out_reg = APM_OUT_START +
|
||||
@@ -819,9 +822,12 @@ static int tegra210_adsp_remove_connection(struct tegra210_adsp *adsp,
|
||||
static status_t tegra210_adsp_msg_handler(uint32_t msg, void *data)
|
||||
{
|
||||
struct tegra210_adsp_app *app = data;
|
||||
unsigned long flags;
|
||||
apm_msg_t apm_msg;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_irqsave(&app->lock, flags);
|
||||
|
||||
switch (msg) {
|
||||
case apm_cmd_msg_ready: {
|
||||
ret = tegra210_adsp_get_msg(app->apm, &apm_msg);
|
||||
@@ -831,13 +837,15 @@ static status_t tegra210_adsp_msg_handler(uint32_t msg, void *data)
|
||||
}
|
||||
|
||||
if (app->msg_handler)
|
||||
return app->msg_handler(app, &apm_msg);
|
||||
ret = app->msg_handler(app, &apm_msg);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("Unsupported mailbox msg %d.", msg);
|
||||
}
|
||||
return 0;
|
||||
|
||||
spin_unlock_irqrestore(&app->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra210_adsp_pcm_msg_handler(struct tegra210_adsp_app *app,
|
||||
@@ -943,6 +951,7 @@ static int tegra210_adsp_compr_open(struct snd_compr_stream *cstream)
|
||||
static int tegra210_adsp_compr_free(struct snd_compr_stream *cstream)
|
||||
{
|
||||
struct tegra210_adsp_compr_rtd *prtd = cstream->runtime->private_data;
|
||||
unsigned long flags;
|
||||
|
||||
if (!prtd)
|
||||
return -ENODEV;
|
||||
@@ -954,6 +963,13 @@ static int tegra210_adsp_compr_free(struct snd_compr_stream *cstream)
|
||||
|
||||
tegra210_adsp_deallocate_dma_buffer(&prtd->buf);
|
||||
|
||||
spin_lock_irqsave(&prtd->fe_apm->lock, flags);
|
||||
|
||||
/* Reset msg handler to disable msg processing */
|
||||
prtd->fe_apm->msg_handler = NULL;
|
||||
|
||||
spin_unlock_irqrestore(&prtd->fe_apm->lock, flags);
|
||||
|
||||
prtd->fe_apm->fe = 0;
|
||||
cstream->runtime->private_data = NULL;
|
||||
devm_kfree(prtd->dev, prtd);
|
||||
@@ -1276,6 +1292,7 @@ static int tegra210_adsp_pcm_open(struct snd_pcm_substream *substream)
|
||||
static int tegra210_adsp_pcm_close(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct tegra210_adsp_pcm_rtd *prtd = substream->runtime->private_data;
|
||||
unsigned long flags;
|
||||
|
||||
dev_vdbg(prtd->dev, "%s", __func__);
|
||||
|
||||
@@ -1283,6 +1300,13 @@ static int tegra210_adsp_pcm_close(struct snd_pcm_substream *substream)
|
||||
tegra210_adsp_send_reset_msg(prtd->fe_apm,
|
||||
TEGRA210_ADSP_MSG_FLAG_SEND);
|
||||
|
||||
spin_lock_irqsave(&prtd->fe_apm->lock, flags);
|
||||
|
||||
/* Reset msg handler to disable msg processing */
|
||||
prtd->fe_apm->msg_handler = NULL;
|
||||
|
||||
spin_unlock_irqrestore(&prtd->fe_apm->lock, flags);
|
||||
|
||||
prtd->fe_apm->fe = 1;
|
||||
substream->runtime->private_data = NULL;
|
||||
devm_kfree(prtd->dev, prtd);
|
||||
|
||||
Reference in New Issue
Block a user