|
@@ -275,30 +275,24 @@ static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s)
|
|
|
{
|
|
|
char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
|
|
|
|
|
|
- mutex_lock(&dsp->debugfs_lock);
|
|
|
kfree(dsp->wmfw_file_name);
|
|
|
dsp->wmfw_file_name = tmp;
|
|
|
- mutex_unlock(&dsp->debugfs_lock);
|
|
|
}
|
|
|
|
|
|
static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s)
|
|
|
{
|
|
|
char *tmp = kasprintf(GFP_KERNEL, "%s\n", s);
|
|
|
|
|
|
- mutex_lock(&dsp->debugfs_lock);
|
|
|
kfree(dsp->bin_file_name);
|
|
|
dsp->bin_file_name = tmp;
|
|
|
- mutex_unlock(&dsp->debugfs_lock);
|
|
|
}
|
|
|
|
|
|
static void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
|
|
|
{
|
|
|
- mutex_lock(&dsp->debugfs_lock);
|
|
|
kfree(dsp->wmfw_file_name);
|
|
|
kfree(dsp->bin_file_name);
|
|
|
dsp->wmfw_file_name = NULL;
|
|
|
dsp->bin_file_name = NULL;
|
|
|
- mutex_unlock(&dsp->debugfs_lock);
|
|
|
}
|
|
|
|
|
|
static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
|
|
@@ -308,7 +302,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
|
|
|
struct wm_adsp *dsp = file->private_data;
|
|
|
ssize_t ret;
|
|
|
|
|
|
- mutex_lock(&dsp->debugfs_lock);
|
|
|
+ mutex_lock(&dsp->pwr_lock);
|
|
|
|
|
|
if (!dsp->wmfw_file_name || !dsp->running)
|
|
|
ret = 0;
|
|
@@ -317,7 +311,7 @@ static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file,
|
|
|
dsp->wmfw_file_name,
|
|
|
strlen(dsp->wmfw_file_name));
|
|
|
|
|
|
- mutex_unlock(&dsp->debugfs_lock);
|
|
|
+ mutex_unlock(&dsp->pwr_lock);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -328,7 +322,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
|
|
|
struct wm_adsp *dsp = file->private_data;
|
|
|
ssize_t ret;
|
|
|
|
|
|
- mutex_lock(&dsp->debugfs_lock);
|
|
|
+ mutex_lock(&dsp->pwr_lock);
|
|
|
|
|
|
if (!dsp->bin_file_name || !dsp->running)
|
|
|
ret = 0;
|
|
@@ -337,7 +331,7 @@ static ssize_t wm_adsp_debugfs_bin_read(struct file *file,
|
|
|
dsp->bin_file_name,
|
|
|
strlen(dsp->bin_file_name));
|
|
|
|
|
|
- mutex_unlock(&dsp->debugfs_lock);
|
|
|
+ mutex_unlock(&dsp->pwr_lock);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -1799,9 +1793,8 @@ int wm_adsp1_init(struct wm_adsp *dsp)
|
|
|
{
|
|
|
INIT_LIST_HEAD(&dsp->alg_regions);
|
|
|
|
|
|
-#ifdef CONFIG_DEBUG_FS
|
|
|
- mutex_init(&dsp->debugfs_lock);
|
|
|
-#endif
|
|
|
+ mutex_init(&dsp->pwr_lock);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(wm_adsp1_init);
|
|
@@ -1820,6 +1813,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
|
|
|
|
|
|
dsp->card = codec->component.card;
|
|
|
|
|
|
+ mutex_lock(&dsp->pwr_lock);
|
|
|
+
|
|
|
switch (event) {
|
|
|
case SND_SOC_DAPM_POST_PMU:
|
|
|
regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
|
|
@@ -1834,7 +1829,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
|
|
|
if (ret != 0) {
|
|
|
adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
|
|
|
ret);
|
|
|
- return ret;
|
|
|
+ goto err_mutex;
|
|
|
}
|
|
|
|
|
|
val = (val & dsp->sysclk_mask)
|
|
@@ -1846,31 +1841,31 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
|
|
|
if (ret != 0) {
|
|
|
adsp_err(dsp, "Failed to set clock rate: %d\n",
|
|
|
ret);
|
|
|
- return ret;
|
|
|
+ goto err_mutex;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ret = wm_adsp_load(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
ret = wm_adsp1_setup_algs(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
ret = wm_adsp_load_coeff(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
/* Initialize caches for enabled and unset controls */
|
|
|
ret = wm_coeff_init_control_caches(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
/* Sync set controls */
|
|
|
ret = wm_coeff_sync_controls(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
/* Start the core running */
|
|
|
regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
|
|
@@ -1905,11 +1900,16 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+ mutex_unlock(&dsp->pwr_lock);
|
|
|
+
|
|
|
return 0;
|
|
|
|
|
|
-err:
|
|
|
+err_ena:
|
|
|
regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
|
|
|
ADSP1_SYS_ENA, 0);
|
|
|
+err_mutex:
|
|
|
+ mutex_unlock(&dsp->pwr_lock);
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(wm_adsp1_event);
|
|
@@ -1955,6 +1955,8 @@ static void wm_adsp2_boot_work(struct work_struct *work)
|
|
|
int ret;
|
|
|
unsigned int val;
|
|
|
|
|
|
+ mutex_lock(&dsp->pwr_lock);
|
|
|
+
|
|
|
/*
|
|
|
* For simplicity set the DSP clock rate to be the
|
|
|
* SYSCLK rate rather than making it configurable.
|
|
@@ -1962,7 +1964,7 @@ static void wm_adsp2_boot_work(struct work_struct *work)
|
|
|
ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
|
|
|
if (ret != 0) {
|
|
|
adsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret);
|
|
|
- return;
|
|
|
+ goto err_mutex;
|
|
|
}
|
|
|
val = (val & ARIZONA_SYSCLK_FREQ_MASK)
|
|
|
>> ARIZONA_SYSCLK_FREQ_SHIFT;
|
|
@@ -1972,42 +1974,46 @@ static void wm_adsp2_boot_work(struct work_struct *work)
|
|
|
ADSP2_CLK_SEL_MASK, val);
|
|
|
if (ret != 0) {
|
|
|
adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
|
|
|
- return;
|
|
|
+ goto err_mutex;
|
|
|
}
|
|
|
|
|
|
ret = wm_adsp2_ena(dsp);
|
|
|
if (ret != 0)
|
|
|
- return;
|
|
|
+ goto err_mutex;
|
|
|
|
|
|
ret = wm_adsp_load(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
ret = wm_adsp2_setup_algs(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
ret = wm_adsp_load_coeff(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
/* Initialize caches for enabled and unset controls */
|
|
|
ret = wm_coeff_init_control_caches(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
/* Sync set controls */
|
|
|
ret = wm_coeff_sync_controls(dsp);
|
|
|
if (ret != 0)
|
|
|
- goto err;
|
|
|
+ goto err_ena;
|
|
|
|
|
|
dsp->running = true;
|
|
|
|
|
|
+ mutex_unlock(&dsp->pwr_lock);
|
|
|
+
|
|
|
return;
|
|
|
|
|
|
-err:
|
|
|
+err_ena:
|
|
|
regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
|
|
|
ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
|
|
|
+err_mutex:
|
|
|
+ mutex_unlock(&dsp->pwr_lock);
|
|
|
}
|
|
|
|
|
|
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
|
|
@@ -2060,6 +2066,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
|
|
/* Log firmware state, it can be useful for analysis */
|
|
|
wm_adsp2_show_fw_status(dsp);
|
|
|
|
|
|
+ mutex_lock(&dsp->pwr_lock);
|
|
|
+
|
|
|
wm_adsp_debugfs_clear(dsp);
|
|
|
|
|
|
dsp->fw_id = 0;
|
|
@@ -2086,6 +2094,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
|
|
kfree(alg_region);
|
|
|
}
|
|
|
|
|
|
+ mutex_unlock(&dsp->pwr_lock);
|
|
|
+
|
|
|
adsp_dbg(dsp, "Shutdown complete\n");
|
|
|
break;
|
|
|
|
|
@@ -2138,9 +2148,8 @@ int wm_adsp2_init(struct wm_adsp *dsp)
|
|
|
INIT_LIST_HEAD(&dsp->ctl_list);
|
|
|
INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
|
|
|
|
|
|
-#ifdef CONFIG_DEBUG_FS
|
|
|
- mutex_init(&dsp->debugfs_lock);
|
|
|
-#endif
|
|
|
+ mutex_init(&dsp->pwr_lock);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(wm_adsp2_init);
|