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:
Viraj Karandikar
2015-07-08 17:48:44 +05:30
committed by Sameer Pujar
parent 47cc203e9c
commit 1b05a7ad2c

View File

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