@@ -64,6 +64,8 @@ static const struct wm_adsp_region clsic_dsp2_regions[] = {
6464struct clsic_alg_compr_stream {
6565 struct work_struct triggered ;
6666 unsigned int event_id ;
67+ bool open ;
68+ struct mutex mutex ;
6769};
6870
6971struct clsic_alg {
@@ -987,6 +989,11 @@ static int clsic_alg_compr_open(struct snd_compr_stream *stream)
987989 clsic_err (alg -> clsic ,
988990 "Open compr stream for DAI '%s' failed %d\n" ,
989991 rtd -> codec_dai -> name , ret );
992+ else {
993+ mutex_lock (& alg -> compr_stream .mutex );
994+ alg -> compr_stream .open = true;
995+ mutex_unlock (& alg -> compr_stream .mutex );
996+ }
990997error :
991998 trace_clsic_alg_compr_stream_open (stream -> direction , ret );
992999
@@ -1019,6 +1026,14 @@ static int clsic_alg_compr_free(struct snd_compr_stream *stream)
10191026
10201027 clsic_dbg (clsic , "%s\n" , rtd -> codec_dai -> name );
10211028
1029+ mutex_lock (& alg -> compr_stream .mutex );
1030+ alg -> compr_stream .open = false;
1031+ mutex_unlock (& alg -> compr_stream .mutex );
1032+
1033+ cancel_work_sync (& alg -> compr_stream .triggered );
1034+
1035+ wm_adsp_compr_free (stream );
1036+
10221037 ret = clsic_alg_set_irq_notify_mode (alg ,
10231038 CLSIC_ALGOSRV_EVENT_VTE ,
10241039 CLSIC_RAS_NTY_CANCEL );
@@ -1028,8 +1043,6 @@ static int clsic_alg_compr_free(struct snd_compr_stream *stream)
10281043 "Cancel notify mode for DAI '%s' failed %d\n" ,
10291044 rtd -> codec_dai -> name , ret );
10301045
1031- wm_adsp_compr_free (stream );
1032-
10331046 /* Release the msgproc when the compressed stream is freed. */
10341047 clsic_msgproc_release (alg -> clsic , alg -> service -> service_instance );
10351048
@@ -1106,6 +1119,8 @@ static int clsic_alg_compr_get_caps(struct snd_compr_stream *stream,
11061119 * clsic_alg_compr_triggered() - worker thread handling compressed stream events
11071120 *
11081121 * The irq context can't be used as it would block the messaging thread.
1122+ * The mutex needs to be held to avoid CLSIC_RAS_NTY_FLUSH_AND_REQ being sent
1123+ * after the compressed stream has been closed
11091124 */
11101125static void clsic_alg_compr_triggered (struct work_struct * data )
11111126{
@@ -1114,10 +1129,16 @@ static void clsic_alg_compr_triggered(struct work_struct *data)
11141129 struct clsic_alg * alg =
11151130 container_of (compr_stream , struct clsic_alg , compr_stream );
11161131
1117- wm_adsp_compr_handle_irq (& alg -> dsp [CLSIC_VPU1 ]);
1132+ mutex_lock (& alg -> compr_stream .mutex );
1133+
1134+ if (alg -> compr_stream .open ) {
1135+ wm_adsp_compr_handle_irq (& alg -> dsp [CLSIC_VPU1 ]);
11181136
1119- clsic_alg_set_irq_notify_mode (alg , compr_stream -> event_id ,
1120- CLSIC_RAS_NTY_FLUSH_AND_REQ );
1137+ clsic_alg_set_irq_notify_mode (alg , compr_stream -> event_id ,
1138+ CLSIC_RAS_NTY_FLUSH_AND_REQ );
1139+ }
1140+
1141+ mutex_unlock (& alg -> compr_stream .mutex );
11211142}
11221143
11231144/**
@@ -1262,6 +1283,8 @@ static int clsic_alg_codec_probe(struct snd_soc_codec *codec)
12621283 handler -> data = (void * )alg ;
12631284 handler -> callback = & clsic_alg_notification_handler ;
12641285
1286+ mutex_init (& alg -> compr_stream .mutex );
1287+
12651288 INIT_WORK (& alg -> compr_stream .triggered , clsic_alg_compr_triggered );
12661289
12671290 wm_adsp2_codec_probe (& alg -> dsp [0 ], codec );
0 commit comments