From patchwork Mon May 5 16:31:37 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liam Girdwood X-Patchwork-Id: 4116011 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B3522BFF02 for ; Mon, 5 May 2014 16:32:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DD9BF20272 for ; Mon, 5 May 2014 16:32:09 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id AA9B120148 for ; Mon, 5 May 2014 16:32:08 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 0317E261A10; Mon, 5 May 2014 18:32:06 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,NO_DNS_FOR_FROM, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id E8872261631; Mon, 5 May 2014 18:31:55 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 44535261685; Mon, 5 May 2014 18:31:54 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by alsa0.perex.cz (Postfix) with ESMTP id C038D2610D4 for ; Mon, 5 May 2014 18:31:45 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 05 May 2014 09:31:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.97,989,1389772800"; d="scan'208";a="526300292" Received: from brianbro-mobl1.ger.corp.intel.com (HELO loki.ger.corp.intel.com) ([10.252.122.12]) by fmsmga001.fm.intel.com with ESMTP; 05 May 2014 09:31:40 -0700 From: Liam Girdwood To: Mark Brown Date: Mon, 5 May 2014 17:31:37 +0100 Message-Id: <1399307497-6238-1-git-send-email-liam.r.girdwood@linux.intel.com> X-Mailer: git-send-email 1.8.3.2 Cc: Liam Girdwood , alsa-devel@alsa-project.org Subject: [alsa-devel] [PATCH] ASoC: Intel: Add support to unload/reload firmware modules. X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Add some SST API calls to unload and reload firmware modules. This can be used by PM code to restore state and also allow modular FW to unload and release memory blocks. Signed-off-by: Liam Girdwood --- sound/soc/intel/sst-dsp-priv.h | 2 ++ sound/soc/intel/sst-firmware.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h index 4012134..ffb308b 100644 --- a/sound/soc/intel/sst-dsp-priv.h +++ b/sound/soc/intel/sst-dsp-priv.h @@ -284,6 +284,8 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp, const struct firmware *fw, void *private); void sst_fw_free(struct sst_fw *sst_fw); void sst_fw_free_all(struct sst_dsp *dsp); +int sst_fw_reload(struct sst_fw *sst_fw); +void sst_fw_unload(struct sst_fw *sst_fw); /* Create/Free firmware modules */ struct sst_module *sst_module_new(struct sst_fw *sst_fw, diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index 928f228..5693d9a 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -30,6 +30,8 @@ #include "sst-dsp.h" #include "sst-dsp-priv.h" +static void block_module_remove(struct sst_module *module); + static void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) { u32 i; @@ -91,6 +93,42 @@ parse_err: } EXPORT_SYMBOL_GPL(sst_fw_new); +int sst_fw_reload(struct sst_fw *sst_fw) +{ + struct sst_dsp *dsp = sst_fw->dsp; + int ret; + + dev_dbg(dsp->dev, "reloading firmware\n"); + + /* call core specific FW paser to load FW data into DSP */ + ret = dsp->ops->parse_fw(sst_fw); + if (ret < 0) + dev_err(dsp->dev, "error: parse fw failed %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(sst_fw_reload); + +void sst_fw_unload(struct sst_fw *sst_fw) +{ + struct sst_dsp *dsp = sst_fw->dsp; + struct sst_module *module, *tmp; + + dev_dbg(dsp->dev, "unloading firmware\n"); + + mutex_lock(&dsp->mutex); + list_for_each_entry_safe(module, tmp, &dsp->module_list, list) { + if (module->sst_fw == sst_fw) { + block_module_remove(module); + list_del(&module->list); + kfree(module); + } + } + + mutex_unlock(&dsp->mutex); +} +EXPORT_SYMBOL_GPL(sst_fw_unload); + /* free single firmware object */ void sst_fw_free(struct sst_fw *sst_fw) {