Commit fe3f4442 authored by Dharageswari R's avatar Dharageswari R Committed by Mark Brown

ASoC: Intel: Skylake: Clean up of driver resources in suspend

On suspend firmware is re-initialized so resources are reset inside
firmware. Driver should also clear the firmware counters at this time.
Signed-off-by: default avatarDharageswari R <dharageswari.r@intel.com>
Signed-off-by: default avatarJeeja KP <jeeja.kp@intel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 260eb73a
...@@ -1197,9 +1197,17 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd) ...@@ -1197,9 +1197,17 @@ static int skl_pcm_new(struct snd_soc_pcm_runtime *rtd)
static int skl_platform_soc_probe(struct snd_soc_platform *platform) static int skl_platform_soc_probe(struct snd_soc_platform *platform)
{ {
struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev); struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
struct skl *skl = ebus_to_skl(ebus);
int ret;
if (ebus->ppcap) if (ebus->ppcap) {
return skl_tplg_init(platform, ebus); ret = skl_tplg_init(platform, ebus);
if (ret < 0) {
dev_err(platform->dev, "Failed to init topology!\n");
return ret;
}
skl->platform = platform;
}
return 0; return 0;
} }
......
...@@ -139,5 +139,6 @@ void skl_ipc_int_disable(struct sst_dsp *dsp); ...@@ -139,5 +139,6 @@ void skl_ipc_int_disable(struct sst_dsp *dsp);
bool skl_ipc_int_status(struct sst_dsp *dsp); bool skl_ipc_int_status(struct sst_dsp *dsp);
void skl_ipc_free(struct sst_generic_ipc *ipc); void skl_ipc_free(struct sst_generic_ipc *ipc);
int skl_ipc_init(struct device *dev, struct skl_sst *skl); int skl_ipc_init(struct device *dev, struct skl_sst *skl);
void skl_clear_module_cnt(struct sst_dsp *ctx);
#endif /* __SKL_IPC_H */ #endif /* __SKL_IPC_H */
...@@ -379,6 +379,16 @@ static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id) ...@@ -379,6 +379,16 @@ static int skl_unload_module(struct sst_dsp *ctx, u16 mod_id)
return ret; return ret;
} }
void skl_clear_module_cnt(struct sst_dsp *ctx)
{
struct skl_module_table *module;
list_for_each_entry(module, &ctx->module_list, list) {
module->usage_cnt = 0;
}
}
EXPORT_SYMBOL_GPL(skl_clear_module_cnt);
static void skl_clear_module_table(struct sst_dsp *ctx) static void skl_clear_module_table(struct sst_dsp *ctx)
{ {
struct skl_module_table *module, *tmp; struct skl_module_table *module, *tmp;
......
...@@ -1557,6 +1557,55 @@ static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt, ...@@ -1557,6 +1557,55 @@ static void skl_tplg_fill_fmt(struct skl_module_fmt *dst_fmt,
} }
} }
static void skl_clear_pin_config(struct snd_soc_platform *platform,
struct snd_soc_dapm_widget *w)
{
int i;
struct skl_module_cfg *mconfig;
struct skl_pipe *pipe;
if (!strncmp(w->dapm->component->name, platform->component.name,
strlen(platform->component.name))) {
mconfig = w->priv;
pipe = mconfig->pipe;
for (i = 0; i < mconfig->max_in_queue; i++) {
mconfig->m_in_pin[i].in_use = false;
mconfig->m_in_pin[i].pin_state = SKL_PIN_UNBIND;
}
for (i = 0; i < mconfig->max_out_queue; i++) {
mconfig->m_out_pin[i].in_use = false;
mconfig->m_out_pin[i].pin_state = SKL_PIN_UNBIND;
}
pipe->state = SKL_PIPE_INVALID;
mconfig->m_state = SKL_MODULE_UNINIT;
}
}
void skl_cleanup_resources(struct skl *skl)
{
struct skl_sst *ctx = skl->skl_sst;
struct snd_soc_platform *soc_platform = skl->platform;
struct snd_soc_dapm_widget *w;
struct snd_soc_card *card;
if (soc_platform == NULL)
return;
card = soc_platform->component.card;
if (!card || !card->instantiated)
return;
skl->resource.mem = 0;
skl->resource.mcps = 0;
list_for_each_entry(w, &card->widgets, list) {
if (is_skl_dsp_widget_type(w) && (w->priv != NULL))
skl_clear_pin_config(soc_platform, w);
}
skl_clear_module_cnt(ctx->dsp);
}
/* /*
* Topology core widget load callback * Topology core widget load callback
* *
......
...@@ -201,6 +201,7 @@ static int _skl_suspend(struct hdac_ext_bus *ebus) ...@@ -201,6 +201,7 @@ static int _skl_suspend(struct hdac_ext_bus *ebus)
skl_enable_miscbdcge(bus->dev, false); skl_enable_miscbdcge(bus->dev, false);
snd_hdac_bus_enter_link_reset(bus); snd_hdac_bus_enter_link_reset(bus);
skl_enable_miscbdcge(bus->dev, true); skl_enable_miscbdcge(bus->dev, true);
skl_cleanup_resources(skl);
return 0; return 0;
} }
......
...@@ -67,6 +67,7 @@ struct skl { ...@@ -67,6 +67,7 @@ struct skl {
unsigned int init_failed:1; /* delayed init failed */ unsigned int init_failed:1; /* delayed init failed */
struct platform_device *dmic_dev; struct platform_device *dmic_dev;
struct platform_device *i2s_dev; struct platform_device *i2s_dev;
struct snd_soc_platform *platform;
struct nhlt_acpi_table *nhlt; /* nhlt ptr */ struct nhlt_acpi_table *nhlt; /* nhlt ptr */
struct skl_sst *skl_sst; /* sst skl ctx */ struct skl_sst *skl_sst; /* sst skl ctx */
...@@ -121,4 +122,5 @@ int skl_init_dsp(struct skl *skl); ...@@ -121,4 +122,5 @@ int skl_init_dsp(struct skl *skl);
int skl_free_dsp(struct skl *skl); int skl_free_dsp(struct skl *skl);
int skl_suspend_dsp(struct skl *skl); int skl_suspend_dsp(struct skl *skl);
int skl_resume_dsp(struct skl *skl); int skl_resume_dsp(struct skl *skl);
void skl_cleanup_resources(struct skl *skl);
#endif /* __SOUND_SOC_SKL_H */ #endif /* __SOUND_SOC_SKL_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment