summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
authorBhalchandra Gajare <gajare@codeaurora.org>2017-05-22 14:50:55 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-08-14 11:49:22 -0700
commit159d8f287092e6a9d3dabd77911624629bfe069c (patch)
tree3007347dd896e585e802682571e1c3778478d072 /sound/soc
parenta49bb61510b938152025049730fa922c5da950a1 (diff)
ASoC: wcd-dsp-mgr: fix race during subsystem restart
Whenever subsystem restart or DSP boot occurs, the manager driver parses the dsp image and stores the segments in list. During certain back to back regression tests, it is observed that SSR is failing due to race between SSR handling and DSP enablement. Fix this by acquiring the ssr_mutex during enabling DSP and sequence to list operations such that there is no race conditions. Change-Id: I15c55bf96737e4ffd7e0faf571a1109ba6c38163 Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/wcd-dsp-mgr.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c
index 9b1c8c98946c..1613c5baa9c7 100644
--- a/sound/soc/codecs/wcd-dsp-mgr.c
+++ b/sound/soc/codecs/wcd-dsp-mgr.c
@@ -415,22 +415,24 @@ static int wdsp_download_segments(struct wdsp_mgr_priv *wdsp,
/* Go through the list of segments and download one by one */
list_for_each_entry(seg, wdsp->seg_list, list) {
ret = wdsp_load_each_segment(wdsp, seg);
- if (IS_ERR_VALUE(ret)) {
- wdsp_broadcast_event_downseq(wdsp,
- WDSP_EVENT_DLOAD_FAILED,
- NULL);
+ if (ret)
goto dload_error;
- }
}
+ /* Flush the list before setting status and notifying components */
+ wdsp_flush_segment_list(wdsp->seg_list);
+
WDSP_SET_STATUS(wdsp, status);
/* Notify all components that image is downloaded */
wdsp_broadcast_event_downseq(wdsp, post, NULL);
+done:
+ return ret;
dload_error:
wdsp_flush_segment_list(wdsp->seg_list);
-done:
+ wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_DLOAD_FAILED, NULL);
+
return ret;
}
@@ -484,10 +486,14 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp)
/* Make sure wdsp is in good state */
if (!WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_CODE_DLOADED)) {
WDSP_ERR(wdsp, "WDSP in invalid state 0x%x", wdsp->status);
- ret = -EINVAL;
- goto done;
+ return -EINVAL;
}
+ /*
+ * Acquire SSR mutex lock to make sure enablement of DSP
+ * does not race with SSR handling.
+ */
+ WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex);
/* Download the read-write sections of image */
ret = wdsp_download_segments(wdsp, WDSP_ELF_FLAG_WRITE);
if (IS_ERR_VALUE(ret)) {
@@ -508,6 +514,7 @@ static int wdsp_enable_dsp(struct wdsp_mgr_priv *wdsp)
wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_BOOTUP, NULL);
WDSP_SET_STATUS(wdsp, WDSP_STATUS_BOOTED);
done:
+ WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
return ret;
}