diff options
author | Bhalchandra Gajare <gajare@codeaurora.org> | 2017-05-22 14:50:55 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-08-14 11:49:22 -0700 |
commit | 159d8f287092e6a9d3dabd77911624629bfe069c (patch) | |
tree | 3007347dd896e585e802682571e1c3778478d072 /sound/soc | |
parent | a49bb61510b938152025049730fa922c5da950a1 (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.c | 23 |
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; } |