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 connect:1; /* if app is connected to a source */
|
||||||
uint32_t priority; /* Valid for only APM app */
|
uint32_t priority; /* Valid for only APM app */
|
||||||
uint32_t min_adsp_clock; /* Min ADSP clock required in MHz */
|
uint32_t min_adsp_clock; /* Min ADSP clock required in MHz */
|
||||||
|
spinlock_t lock;
|
||||||
void *private_data;
|
void *private_data;
|
||||||
int (*msg_handler)(struct tegra210_adsp_app *, apm_msg_t *);
|
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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_init(&app->lock);
|
||||||
|
|
||||||
app->plugin = PLUGIN_SHARED_MEM(app->info->mem.shared);
|
app->plugin = PLUGIN_SHARED_MEM(app->info->mem.shared);
|
||||||
if (IS_APM_IN(app->reg)) {
|
if (IS_APM_IN(app->reg)) {
|
||||||
uint32_t apm_out_reg = APM_OUT_START +
|
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)
|
static status_t tegra210_adsp_msg_handler(uint32_t msg, void *data)
|
||||||
{
|
{
|
||||||
struct tegra210_adsp_app *app = data;
|
struct tegra210_adsp_app *app = data;
|
||||||
|
unsigned long flags;
|
||||||
apm_msg_t apm_msg;
|
apm_msg_t apm_msg;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&app->lock, flags);
|
||||||
|
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case apm_cmd_msg_ready: {
|
case apm_cmd_msg_ready: {
|
||||||
ret = tegra210_adsp_get_msg(app->apm, &apm_msg);
|
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)
|
if (app->msg_handler)
|
||||||
return app->msg_handler(app, &apm_msg);
|
ret = app->msg_handler(app, &apm_msg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("Unsupported mailbox msg %d.", msg);
|
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,
|
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)
|
static int tegra210_adsp_compr_free(struct snd_compr_stream *cstream)
|
||||||
{
|
{
|
||||||
struct tegra210_adsp_compr_rtd *prtd = cstream->runtime->private_data;
|
struct tegra210_adsp_compr_rtd *prtd = cstream->runtime->private_data;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (!prtd)
|
if (!prtd)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@@ -954,6 +963,13 @@ static int tegra210_adsp_compr_free(struct snd_compr_stream *cstream)
|
|||||||
|
|
||||||
tegra210_adsp_deallocate_dma_buffer(&prtd->buf);
|
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;
|
prtd->fe_apm->fe = 0;
|
||||||
cstream->runtime->private_data = NULL;
|
cstream->runtime->private_data = NULL;
|
||||||
devm_kfree(prtd->dev, prtd);
|
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)
|
static int tegra210_adsp_pcm_close(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct tegra210_adsp_pcm_rtd *prtd = substream->runtime->private_data;
|
struct tegra210_adsp_pcm_rtd *prtd = substream->runtime->private_data;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
dev_vdbg(prtd->dev, "%s", __func__);
|
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_send_reset_msg(prtd->fe_apm,
|
||||||
TEGRA210_ADSP_MSG_FLAG_SEND);
|
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;
|
prtd->fe_apm->fe = 1;
|
||||||
substream->runtime->private_data = NULL;
|
substream->runtime->private_data = NULL;
|
||||||
devm_kfree(prtd->dev, prtd);
|
devm_kfree(prtd->dev, prtd);
|
||||||
|
|||||||
Reference in New Issue
Block a user