Commit c7752685 authored by Mark Brown's avatar Mark Brown

Merge branch 'asoc-5.1' into asoc-5.2 for wmadsp

parents b3718b8f a2bcbc1b
...@@ -2905,6 +2905,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, ...@@ -2905,6 +2905,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
if (wm_adsp_fw[dsp->fw].num_caps != 0) if (wm_adsp_fw[dsp->fw].num_caps != 0)
wm_adsp_buffer_free(dsp); wm_adsp_buffer_free(dsp);
dsp->fatal_error = false;
mutex_unlock(&dsp->pwr_lock); mutex_unlock(&dsp->pwr_lock);
adsp_dbg(dsp, "Execution stopped\n"); adsp_dbg(dsp, "Execution stopped\n");
...@@ -3000,6 +3002,9 @@ static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) ...@@ -3000,6 +3002,9 @@ static int wm_adsp_compr_attach(struct wm_adsp_compr *compr)
{ {
struct wm_adsp_compr_buf *buf = NULL, *tmp; struct wm_adsp_compr_buf *buf = NULL, *tmp;
if (compr->dsp->fatal_error)
return -EINVAL;
list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { list_for_each_entry(tmp, &compr->dsp->buffer_list, list) {
if (!tmp->name || !strcmp(compr->name, tmp->name)) { if (!tmp->name || !strcmp(compr->name, tmp->name)) {
buf = tmp; buf = tmp;
...@@ -3535,11 +3540,11 @@ static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) ...@@ -3535,11 +3540,11 @@ static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf)
ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error);
if (ret < 0) { if (ret < 0) {
adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); compr_err(buf, "Failed to check buffer error: %d\n", ret);
return ret; return ret;
} }
if (buf->error != 0) { if (buf->error != 0) {
adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); compr_err(buf, "Buffer error occurred: %d\n", buf->error);
return -EIO; return -EIO;
} }
...@@ -3571,8 +3576,6 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) ...@@ -3571,8 +3576,6 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
if (ret < 0) if (ret < 0)
break; break;
wm_adsp_buffer_clear(compr->buf);
/* Trigger the IRQ at one fragment of data */ /* Trigger the IRQ at one fragment of data */
ret = wm_adsp_buffer_write(compr->buf, ret = wm_adsp_buffer_write(compr->buf,
HOST_BUFFER_FIELD(high_water_mark), HOST_BUFFER_FIELD(high_water_mark),
...@@ -3584,6 +3587,7 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) ...@@ -3584,6 +3587,7 @@ int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd)
} }
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
wm_adsp_buffer_clear(compr->buf);
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
...@@ -3917,22 +3921,40 @@ int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) ...@@ -3917,22 +3921,40 @@ int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions)
} }
EXPORT_SYMBOL_GPL(wm_adsp2_lock); EXPORT_SYMBOL_GPL(wm_adsp2_lock);
static void wm_adsp_fatal_error(struct wm_adsp *dsp)
{
struct wm_adsp_compr *compr;
dsp->fatal_error = true;
list_for_each_entry(compr, &dsp->compr_list, list) {
if (compr->stream) {
snd_compr_stop_error(compr->stream,
SNDRV_PCM_STATE_XRUN);
snd_compr_fragment_elapsed(compr->stream);
}
}
}
irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
{ {
unsigned int val; unsigned int val;
struct regmap *regmap = dsp->regmap; struct regmap *regmap = dsp->regmap;
int ret = 0; int ret = 0;
mutex_lock(&dsp->pwr_lock);
ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val);
if (ret) { if (ret) {
adsp_err(dsp, adsp_err(dsp,
"Failed to read Region Lock Ctrl register: %d\n", ret); "Failed to read Region Lock Ctrl register: %d\n", ret);
return IRQ_HANDLED; goto error;
} }
if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { if (val & ADSP2_WDT_TIMEOUT_STS_MASK) {
adsp_err(dsp, "watchdog timeout error\n"); adsp_err(dsp, "watchdog timeout error\n");
wm_adsp_stop_watchdog(dsp); wm_adsp_stop_watchdog(dsp);
wm_adsp_fatal_error(dsp);
} }
if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) {
...@@ -3946,7 +3968,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) ...@@ -3946,7 +3968,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
adsp_err(dsp, adsp_err(dsp,
"Failed to read Bus Err Addr register: %d\n", "Failed to read Bus Err Addr register: %d\n",
ret); ret);
return IRQ_HANDLED; goto error;
} }
adsp_err(dsp, "bus error address = 0x%x\n", adsp_err(dsp, "bus error address = 0x%x\n",
...@@ -3959,7 +3981,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) ...@@ -3959,7 +3981,7 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
adsp_err(dsp, adsp_err(dsp,
"Failed to read Pmem Xmem Err Addr register: %d\n", "Failed to read Pmem Xmem Err Addr register: %d\n",
ret); ret);
return IRQ_HANDLED; goto error;
} }
adsp_err(dsp, "xmem error address = 0x%x\n", adsp_err(dsp, "xmem error address = 0x%x\n",
...@@ -3972,6 +3994,9 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) ...@@ -3972,6 +3994,9 @@ irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL,
ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT);
error:
mutex_unlock(&dsp->pwr_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
......
...@@ -85,6 +85,7 @@ struct wm_adsp { ...@@ -85,6 +85,7 @@ struct wm_adsp {
bool preloaded; bool preloaded;
bool booted; bool booted;
bool running; bool running;
bool fatal_error;
struct list_head ctl_list; struct list_head ctl_list;
......
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