]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/blobdiff - sound/soc/tegra-alt/tegra210_adsp_alt.c
tegra-alt: adsp: request ACK when closing PCM stream
[sojka/nv-tegra/linux-3.10.git] / sound / soc / tegra-alt / tegra210_adsp_alt.c
index eb71f8ded66bd4b12d078b0ab5ec65d68e4d8996..16d7f5f1a95022250cfccf8fea235dcd80bf5bcf 100644 (file)
@@ -84,7 +84,7 @@ struct tegra210_adsp_app {
        plugin_shared_mem_t *plugin;
        apm_shared_state_t *apm; /* For a plugin it stores parent apm data */
        struct nvadsp_mbox apm_mbox;
-       struct completion msg_complete; /* For ADSP ack wait */
+       struct completion *msg_complete; /* For ADSP ack wait */
        uint32_t reg;
        uint32_t adma_chan; /* Valid for only ADMA app */
        uint32_t fe:1; /* Whether the app is used as a FE APM */
@@ -369,7 +369,7 @@ static int tegra210_adsp_send_msg(struct tegra210_adsp_app *app,
                                __func__);
                        flags &= ~TEGRA210_ADSP_MSG_FLAG_NEED_ACK;
                } else {
-                       INIT_COMPLETION(app->msg_complete);
+                       INIT_COMPLETION(*app->msg_complete);
                        apm_msg->msg.call_params.method |=
                                NVFX_APM_METHOD_ACK_BIT;
                }
@@ -393,7 +393,7 @@ static int tegra210_adsp_send_msg(struct tegra210_adsp_app *app,
                return ret;
 
        ret = wait_for_completion_interruptible_timeout(
-               &app->msg_complete,
+               app->msg_complete,
                msecs_to_jiffies(ADSP_RESPONSE_TIMEOUT));
        if (WARN_ON(ret <= 0))
                pr_err("%s: Failed to reset app %d\n", __func__, app->reg);
@@ -593,7 +593,14 @@ static int tegra210_adsp_app_init(struct tegra210_adsp *adsp,
                        goto err_app_exit;
                }
 
-               init_completion(&app->msg_complete);
+               app->msg_complete = devm_kzalloc(adsp->dev,
+                                       sizeof(struct completion), GFP_KERNEL);
+               if (!app->msg_complete) {
+                       dev_err(adsp->dev, "Failed to allocate completion struct.");
+                       return -ENOMEM;
+               }
+
+               init_completion(app->msg_complete);
 
                ret = nvadsp_app_start(app->info);
                if (ret < 0) {
@@ -605,6 +612,7 @@ static int tegra210_adsp_app_init(struct tegra210_adsp *adsp,
                apm_out->plugin = app->plugin;
                apm_out->apm = app->apm;
                apm_out->apm_mbox = app->apm_mbox;
+               apm_out->msg_complete = app->msg_complete;
        } else if (IS_ADMA(app->reg)) {
                app->adma_chan = find_first_zero_bit(adsp->adma_usage,
                                        TEGRA210_ADSP_ADMA_CHANNEL_COUNT);
@@ -892,7 +900,7 @@ static int tegra210_adsp_pcm_msg_handler(struct tegra210_adsp_app *app,
                snd_pcm_period_elapsed(prtd->substream);
                break;
        case nvfx_apm_method_ack:
-               complete(&app->msg_complete);
+               complete(app->msg_complete);
                break;
        default:
                dev_err(prtd->dev, "Unsupported cmd %d.",
@@ -923,7 +931,7 @@ static int tegra210_adsp_compr_msg_handler(struct tegra210_adsp_app *app,
                prtd->is_draining = 0;
                break;
        case nvfx_apm_method_ack:
-               complete(&app->msg_complete);
+               complete(app->msg_complete);
                break;
        default:
                dev_err(prtd->dev, "Unsupported cmd %d.",
@@ -1341,7 +1349,8 @@ static int tegra210_adsp_pcm_close(struct snd_pcm_substream *substream)
 
        if (prtd) {
                tegra210_adsp_send_reset_msg(prtd->fe_apm,
-                       TEGRA210_ADSP_MSG_FLAG_SEND);
+                       TEGRA210_ADSP_MSG_FLAG_SEND |
+                       TEGRA210_ADSP_MSG_FLAG_NEED_ACK);
 
                spin_lock_irqsave(&prtd->fe_apm->lock, flags);