st-hal: Update to latest tip of sound trigger hal

Port the missing changes from proprietary sthal to open source
sthal location. The latest change included is part of
AU_LINUX_ANDROID_LA.UM.8.12.09.00.00.484.217.

1) sthal: handle failure of session restart properly
Change-Id: Ic2be3f32b9da9372e01e4487fa1610f544aaf648

2) sthal: Add platform_lpi_enable flag in platform xml
Change-Id: I748043b38c8d4d6c4db38df1de90ae121200d59b

3) sthal: ignore tranision to CPE if rx becomes active
Change-Id: Iff4079922e58417a620db77602dc6f4867516ebf

4) sthal: Add ST_DEVICE_HEADSET_MIC_LPI device for headset LPI usecase
Change-Id: I517107c3aca468c8b9243c846252ad94bc5c7fd6

5) sthal: Add support for different lsm in_channels for LPI
Change-Id: I26f7a526a20166abd83665ca07f912f2028203bf

6) sthal: Reset backend config controls during init
Change-Id: Iee83cb7e4d5abcd8d3529b5c3f620e1f3a7ae440

7) sthal: avoid duplicated cleanup of second stage session
Change-Id: Ia18324aa153c34627df41c67698f1b84e8ad3d31

8) sthal: Fix issue with confidence level type update
Change-Id: I10d634c3d96a038df330291a21150a6567672b34

9) sthal: fix pcm dump issue for debugging
Change-Id: Ie2c8580b6fc40192f664ee88f001007255f94a79

10) sthal: fix heap buffer overflow
Change-Id: Id94120e52defaab64cb6e7ce094040b1ecc6b426

11) sthal: Support for shared buffering in LPI mode
Change-Id: I2b4b8b94dba6193e89f0f330abced0200f033b69

12) sthal: dereg_sm and reg_sm on LPI status changes
Change-Id: I50d7758e973ac62ef5f31e82db463a4ab219d600

13) sthal: Fix static buffering analysis issues
Change-Id: I72214187396f6fb561f5f7125176e33a243c6308

Change-Id: I44c7e8b542dc1bbed32d9085f03063543cad42f4
diff --git a/sound_trigger_hw.c b/sound_trigger_hw.c
index 42d7f7a..4cea8e9 100644
--- a/sound_trigger_hw.c
+++ b/sound_trigger_hw.c
@@ -906,21 +906,25 @@
         acquire_wake_lock(PARTIAL_WAKE_LOCK, TRANSIT_WAKE_LOCK_NAME);
         ssr_retry = TRANSIT_SSR_TIMEOUT_SEC / stdev->transit_wait_time;
         if (stdev->transit_dir == TRANSIT_APE_TO_CPE) {
-            while (!stdev->rx_concurrency_active &&
-                   !stdev->is_charging) {
+            while (1) {
                 pthread_mutex_unlock(&stdev->lock);
                 sleep(stdev->transit_wait_time);
                 pthread_mutex_lock(&stdev->lock);
-
+                bool keep_ape_mode = (stdev->rx_concurrency_active &&
+                                      stdev->transit_to_adsp_on_playback) ||
+                                     (stdev->is_charging &&
+                                      stdev->transit_to_adsp_on_battery_charging);
                 if (stdev->transit_dir != TRANSIT_APE_TO_CPE) {
                     ALOGD("transit_dir change to %d", stdev->transit_dir);
                     goto release_wl;
+                } else if (keep_ape_mode) {
+                    ALOGD("%s:No need to transit to CPE", __func__);
+                    stdev->transit_dir = TRANSIT_NONE;
+                    goto release_wl;
                 }
 
                 in_ssr = is_any_session_ssr_state();
                 if (!is_any_session_buffering() &&
-                    !stdev->rx_concurrency_active &&
-                    !stdev->is_charging &&
                     !in_ssr) {
                     /* Transition to WDSP */
                     ATRACE_BEGIN("sthal: check_and_transit_ape_ses_to_cpe");
diff --git a/sound_trigger_hw.h b/sound_trigger_hw.h
index 0838ebf..b762f34 100644
--- a/sound_trigger_hw.h
+++ b/sound_trigger_hw.h
@@ -154,8 +154,8 @@
     bool stop_transitions_thread_loop;
     transit_dir_t transit_dir;
     bool dedicated_sva_path;
-    bool disable_lpi_budget;
     bool disable_hwmad;
+    st_platform_lpi_enable_t platform_lpi_enable;
 
     unsigned int rx_conc_max_st_ses;
     struct use_case_info *ape_pcm_use_cases;
diff --git a/sound_trigger_platform.c b/sound_trigger_platform.c
index 7efeaf9..155bf0b 100644
--- a/sound_trigger_platform.c
+++ b/sound_trigger_platform.c
@@ -100,6 +100,7 @@
 #define ST_PARAM_KEY_BIT_WIDTH "bit_width"
 #define ST_PARAM_KEY_CHANNEL_COUNT "channel_count"
 #define ST_PARAM_KEY_IN_CHANNELS "in_channels"
+#define ST_PARAM_KEY_IN_CHANNELS_LPI "in_channels_lpi"
 #define ST_PARAM_KEY_OUT_CHANNELS "out_channels"
 #define ST_PARAM_KEY_ADM_CFG_PROFILE "adm_cfg_profile"
 #define ST_PARAM_KEY_CAPTURE_DEVICE "capture_device"
@@ -116,6 +117,7 @@
 #define ST_PARAM_KEY_START_ENGINE_IDS "start_engine_ids"
 #define ST_PARAM_KEY_RESTART_ENGINE_IDS "restart_engine_ids"
 #define ST_PARAM_KEY_REQUEST_DETECTION_IDS "request_detection_ids"
+#define ST_PARAM_KEY_LAB_DAM_CFG_IDS "lab_dam_cfg_ids"
 #define ST_PARAM_KEY_UID "uid"
 #define ST_PARAM_KEY_ACDB_DEVICES "acdb_devices"
 #define ST_PARAM_KEY_CAPTURE_KEYWORD "capture_keyword"
@@ -136,6 +138,7 @@
     "transit_to_adsp_on_battery_charging"
 #define ST_PARAM_KEY_TRANSIT_TO_NON_LPI_ON_BATTERY_CHARGING \
     "transit_to_non_lpi_on_battery_charging"
+#define ST_PARAM_KEY_PLATFORM_LPI_ENABLE "platform_lpi_enable"
 #define ST_PARAM_KEY_TRANSIT_WAIT_TIME "transit_wait_time"
 #define ST_PARAM_KEY_SPLIT_EC_REF_DATA "split_ec_ref_data"
 #define ST_PARAM_KEY_EC_REF_CHANNEL_COUNT "ec_ref_channel_count"
@@ -146,7 +149,7 @@
 #define ST_PARAM_KEY_LPI_ENABLE "lpi_enable"
 #define ST_PARAM_KEY_VAD_ENABLE "vad_enable"
 #define ST_PARAM_KEY_DEDICATED_SVA_PATH "dedicated_sva_path"
-#define ST_PARAM_KEY_DISABLE_LPI_BUDGET "disable_lpi_budget"
+#define ST_PARAM_KEY_DAM_TOKEN_ID "dam_token_id"
 
 #ifndef Q6AFE_HWDEP_NODE
 #define Q6AFE_HWDEP_NODE -1
@@ -174,6 +177,7 @@
 #define ST_PARAM_KEY_DEVICE_HANDSET_QMIC_LPI_APE "DEVICE_HANDSET_QMIC_LPI_APE"
 #define ST_PARAM_KEY_DEVICE_HANDSET_6MIC_LPI_APE "DEVICE_HANDSET_6MIC_LPI_APE"
 #define ST_PARAM_KEY_DEVICE_HANDSET_8MIC_LPI_APE "DEVICE_HANDSET_8MIC_LPI_APE"
+#define ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE "DEVICE_HEADSET_MIC_APE_LPI"
 
 #define ST_PARAM_KEY_SS_SM_TYPE "sm_detection_type"
 #define ST_PARAM_KEY_SS_SM_ID "sm_id"
@@ -212,6 +216,7 @@
        {"DEVICE_HANDSET_6MIC_LPI_APE", ST_DEVICE_HANDSET_6MIC_LPI},
        {"DEVICE_HANDSET_8MIC_LPI_APE", ST_DEVICE_HANDSET_8MIC_LPI},
        {"DEVICE_HEADSET_MIC_APE", ST_DEVICE_HEADSET_MIC},
+       {"DEVICE_HEADSET_MIC_APE_LPI", ST_DEVICE_HEADSET_MIC_LPI},
    },
    {
        {"DEVICE_HANDSET_MIC_CPE", ST_DEVICE_HANDSET_MIC},
@@ -246,6 +251,7 @@
         [ST_DEVICE_HANDSET_6MIC_LPI] = "listen-ape-handset-6mic",
         [ST_DEVICE_HANDSET_8MIC_LPI] = "listen-ape-handset-8mic",
         [ST_DEVICE_HEADSET_MIC] = "listen-ape-headset-mic",
+        [ST_DEVICE_HEADSET_MIC_LPI] = "listen-ape-headset-mic",
     },
     {
         /* CPE SVA devices */
@@ -283,6 +289,7 @@
       [ST_DEVICE_HANDSET_6MIC_LPI] = DEVICE_HANDSET_APE_ACDB_ID,
       [ST_DEVICE_HANDSET_8MIC_LPI] = DEVICE_HANDSET_APE_ACDB_ID,
       [ST_DEVICE_HEADSET_MIC] = DEVICE_HEADSET_APE_ACDB_ID,
+      [ST_DEVICE_HEADSET_MIC_LPI] = DEVICE_HEADSET_APE_ACDB_ID,
     },
     {
       [ST_DEVICE_NONE] = -1,
@@ -709,13 +716,10 @@
     stdev->conc_voice_call_supported = false;
     stdev->conc_voip_call_supported = false;
     stdev->dedicated_sva_path = false;
-    stdev->disable_lpi_budget = false;
     stdev->disable_hwmad = false;
+    stdev->platform_lpi_enable = ST_PLATFORM_LPI_NONE;
 
     platform->cpe_fe_to_be_fixed = true;
-    platform->codec_backend_cfg.sample_rate = SOUND_TRIGGER_SAMPLING_RATE_48000;
-    platform->codec_backend_cfg.format = PCM_FORMAT_S16_LE;
-    platform->codec_backend_cfg.channel_count = SOUND_TRIGGER_CHANNEL_MODE_MONO;
     platform->bad_mic_channel_index = 0;
     platform->ec_ref_enabled = false;
     platform->be_dai_name_table = NULL;
@@ -1025,6 +1029,15 @@
             !strncasecmp(str_value, "true", 4) ? true : false;
     }
 
+    err = str_parms_get_str(parms, ST_PARAM_KEY_PLATFORM_LPI_ENABLE, str_value,
+                            sizeof(str_value));
+    if (err >= 0) {
+        str_parms_del(parms, ST_PARAM_KEY_PLATFORM_LPI_ENABLE);
+        stdev->platform_lpi_enable =
+            !strncasecmp(str_value, "true", 4) ? ST_PLATFORM_LPI_ENABLE :
+            ST_PLATFORM_LPI_DISABLE;
+    }
+
     err = str_parms_get_int(parms, ST_PARAM_KEY_TRANSIT_WAIT_TIME, &value);
     if (err >= 0) {
         str_parms_del(parms, ST_PARAM_KEY_TRANSIT_WAIT_TIME);
@@ -1106,14 +1119,6 @@
             !strncasecmp(str_value, "true", 4) ? true : false;
     }
 
-    err = str_parms_get_str(parms, ST_PARAM_KEY_DISABLE_LPI_BUDGET,
-                            str_value, sizeof(str_value));
-    if (err >= 0) {
-        str_parms_del(parms, ST_PARAM_KEY_DISABLE_LPI_BUDGET);
-        stdev->disable_lpi_budget =
-            !strncasecmp(str_value, "true", 4) ? true : false;
-    }
-
     return 0;
 }
 
@@ -1301,6 +1306,14 @@
             goto exit;
     }
 
+    err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE, &value);
+    if (err >= 0) {
+        str_parms_del(parms, ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE);
+        ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE, value);
+        if (ret)
+            goto exit;
+    }
+
 exit:
     return ret;
 }
@@ -2043,6 +2056,17 @@
         lsm_params->param_tag_tracker |= PARAM_REQUEST_DETECTION_BIT;
     }
 
+    err = str_parms_get_str(parms, ST_PARAM_KEY_LAB_DAM_CFG_IDS,
+                            str_value, sizeof(str_value));
+    if (err >= 0) {
+        str_parms_del(parms, ST_PARAM_KEY_LAB_DAM_CFG_IDS);
+        ret = platform_stdev_set_module_param_ids(
+            &lsm_params->params[LAB_DAM_CFG], str_value, is_legacy_params);
+        if (ret)
+            goto err_exit;
+        lsm_params->param_tag_tracker |= PARAM_LAB_DAM_CFG_BIT;
+    }
+
     err = str_parms_get_str(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS,
                             str_value, sizeof(str_value));
     if (err >= 0) {
@@ -2125,6 +2149,13 @@
         lsm_params->in_channels = value;
     }
 
+    lsm_params->in_channels_lpi = lsm_params->in_channels;
+    err = str_parms_get_int(parms, ST_PARAM_KEY_IN_CHANNELS_LPI, &value);
+    if (err >= 0) {
+        str_parms_del(parms, ST_PARAM_KEY_IN_CHANNELS_LPI);
+        lsm_params->in_channels_lpi = value;
+    }
+
     if (my_data->xml_version >= PLATFORM_XML_VERSION_0x0105) {
         err = str_parms_get_str(parms, ST_PARAM_KEY_ADM_CFG_PROFILE,
                                 str_value, sizeof(str_value));
@@ -2465,6 +2496,12 @@
         sm_info->vad_enable = !strncasecmp(str_value, "true", 4) ? true : false;
     }
 
+    err = str_parms_get_int(parms, ST_PARAM_KEY_DAM_TOKEN_ID, &value);
+    if (err >= 0) {
+        str_parms_del(parms, ST_PARAM_KEY_DAM_TOKEN_ID);
+        sm_info->lab_dam_cfg_payload.token_id = value;
+    }
+
     sm_info->avail_transit_ape_phrases = sm_info->avail_ape_phrases;
     sm_info->avail_transit_ape_users = sm_info->avail_ape_users;
     sm_info->avail_transit_cpe_phrases = sm_info->avail_cpe_phrases;
@@ -2922,17 +2959,19 @@
     if (strstr(snd_card_name, "qrd")) {
         char *tmp = NULL;
         char *snd_internal_name = NULL;
-        char *temp_path = strdup(mixer_path_xml);
-        if (temp_path != NULL) {
-            char *snd_card_name_t = strdup(snd_card_name);
-            if (snd_card_name_t != NULL) {
-                snd_internal_name = strtok_r(snd_card_name_t, "-", &tmp);
-                while (snd_internal_name != NULL) {
-                    snd_internal_name = strtok_r(NULL, "-", &tmp);
-                    if ((snd_internal_name != NULL) &&
-                        strstr(snd_internal_name, "qrd"))
-                        break;
-                }
+        char temp_path[MIXER_PATH_MAX_LENGTH];
+
+        strlcpy(temp_path, mixer_path_xml, MIXER_PATH_MAX_LENGTH);
+        char *snd_card_name_t = strdup(snd_card_name);
+        if (snd_card_name_t != NULL) {
+            snd_internal_name = strtok_r(snd_card_name_t, "-", &tmp);
+            while (snd_internal_name != NULL) {
+                snd_internal_name = strtok_r(NULL, "-", &tmp);
+                if ((snd_internal_name != NULL) &&
+                    strstr(snd_internal_name, "qrd"))
+                    break;
+            }
+            if (snd_internal_name != NULL) {
                 strlcat(temp_path, "_", MIXER_PATH_MAX_LENGTH);
                 strlcat(temp_path, snd_internal_name, MIXER_PATH_MAX_LENGTH);
                 strlcat(temp_path, MIXER_FILE_EXT, MIXER_PATH_MAX_LENGTH);
@@ -2940,9 +2979,8 @@
                     strlcat(mixer_path_xml, "_", MIXER_PATH_MAX_LENGTH);
                     strlcat(mixer_path_xml, snd_internal_name, MIXER_PATH_MAX_LENGTH);
                 }
-                free(snd_card_name_t);
             }
-            free(temp_path);
+            free(snd_card_name_t);
         }
     }
     strlcat(mixer_path_xml, MIXER_FILE_EXT, MIXER_PATH_MAX_LENGTH);
@@ -3577,6 +3615,8 @@
 
     init_be_dai_name_table(my_data);
 
+    platform_stdev_reset_backend_cfg(my_data);
+
     return my_data;
 
 cleanup_2:
@@ -3832,7 +3872,10 @@
     case AUDIO_DEVICE_IN_WIRED_HEADSET:
         if ((ST_EXEC_MODE_CPE == exec_mode) ||
             (ST_EXEC_MODE_ADSP == exec_mode)) {
-            st_device = ST_DEVICE_HEADSET_MIC;
+            if (my_data->codec_backend_cfg.lpi_enable)
+                st_device = ST_DEVICE_HEADSET_MIC_LPI;
+            else
+                st_device = ST_DEVICE_HEADSET_MIC;
             break;
         }
     case AUDIO_DEVICE_IN_BUILTIN_MIC:
@@ -4845,6 +4888,26 @@
     list_add_head(&v_info->gcs_usecase_list, &gcs_usecase->list_node);
 }
 
+static int get_shared_buf_fmt
+(
+    st_profile_type_t profile
+)
+{
+    int ret = ST_SHARED_BUF_RAW;
+
+    switch (profile) {
+    case ST_PROFILE_TYPE_FLUENCE:
+    case ST_PROFILE_TYPE_FLUENCE_STEREO:
+    case ST_PROFILE_TYPE_FFECNS:
+        ret = ST_SHARED_BUF_PROCESSED;
+        break;
+    default:
+        ret = ST_SHARED_BUF_RAW;
+    }
+
+    return ret;
+}
+
 void platform_get_lsm_usecase
 (
    void* platform,
@@ -4881,6 +4944,8 @@
                     v_info->in_channels = usecase->in_channels;
                     v_info->fluence_type = usecase->fluence_type;
                     v_info->profile_type = usecase->adm_cfg_profile;
+                    v_info->shared_buf_fmt =
+                        get_shared_buf_fmt(v_info->profile_type);
                     v_info->app_type = usecase->app_type;
                     return;
                 }
@@ -5079,6 +5144,32 @@
                                            lpi_enable, vad_enable, vad_preroll);
 }
 
+int platform_stdev_set_shared_buf_fmt
+(
+   void *platform,
+   int pcm_id,
+   int shared_buf_fmt
+)
+{
+    struct platform_data *my_data = (struct platform_data *)platform;
+    sound_trigger_device_t *stdev = my_data->stdev;
+    char mixer_ctl_name[ST_MAX_LENGTH_MIXER_CONTROL];
+    struct mixer_ctl *ctl = NULL;
+
+    snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
+             "Listen Stream %d Unprocessed Data", pcm_id);
+    ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
+    if (!ctl) {
+        ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
+            __func__, mixer_ctl_name);
+        return -EINVAL;
+    }
+
+    mixer_ctl_set_value(ctl, 0, shared_buf_fmt);
+
+    return 0;
+}
+
 int platform_stdev_send_stream_app_type_cfg
 (
    void *platform,
diff --git a/sound_trigger_platform.h b/sound_trigger_platform.h
index 7dec3c9..68f1b4a 100644
--- a/sound_trigger_platform.h
+++ b/sound_trigger_platform.h
@@ -109,6 +109,7 @@
 #define PARAM_DET_EVENT_TYPE_BIT (1 << 6)
 #define PARAM_LAB_CONTROL_BIT (1 << 7)
 #define PARAM_REQUEST_DETECTION_BIT (1 << 8)
+#define PARAM_LAB_DAM_CFG_BIT (1 << 9)
 #define PARAM_ID_MANDATORY_BITS \
     (PARAM_LOAD_SOUND_MODEL_BIT | PARAM_UNLOAD_SOUND_MODEL_BIT)
 
@@ -164,6 +165,7 @@
     ST_DEVICE_HANDSET_DMIC_LPI,
     ST_DEVICE_HANDSET_TMIC_LPI,
     ST_DEVICE_HANDSET_QMIC_LPI,
+    ST_DEVICE_HEADSET_MIC_LPI,
     ST_DEVICE_HANDSET_6MIC_LPI,
     ST_DEVICE_HANDSET_8MIC_LPI,
     ST_DEVICE_MAX,
@@ -221,6 +223,7 @@
     DET_EVENT_TYPE,
     LAB_CONTROL,
     REQUEST_DETECTION,
+    LAB_DAM_CFG,
     MAX_PARAM_IDS
 };
 
@@ -230,6 +233,11 @@
     unsigned int param_id;
 };
 
+struct lab_dam_cfg_payload {
+    uint32_t minor_version;
+    uint32_t token_id;
+}__packed;
+
 typedef enum {
     ST_PROFILE_TYPE_NONE, /* Connect LSM to AFE directly */
     ST_PROFILE_TYPE_DEFAULT, /* Connect LSM to ADM with default config */
@@ -261,6 +269,11 @@
                                     BAD_MIC_CH_INDEX_3),
 };
 
+typedef enum st_shared_buf_fmt {
+    ST_SHARED_BUF_PROCESSED,
+    ST_SHARED_BUF_RAW,
+} st_shared_buf_fmt_t;
+
 /* soundmodel library wrapper functions */
 typedef int (*smlib_generate_sound_trigger_phrase_recognition_event_t)
 (
@@ -294,6 +307,7 @@
     st_exec_mode_t exec_mode;
     int app_type;
     int in_channels;
+    int in_channels_lpi;
     int param_tag_tracker;
     struct st_module_param_info params[MAX_PARAM_IDS];
     st_profile_type_t adm_cfg_profile;
@@ -320,6 +334,12 @@
     ST_SS_USECASE_TYPE_LSM
 } st_ss_usecase_type_t;
 
+typedef enum {
+    ST_PLATFORM_LPI_NONE,
+    ST_PLATFORM_LPI_ENABLE,
+    ST_PLATFORM_LPI_DISABLE
+} st_platform_lpi_enable_t;
+
 struct st_ss_usecase {
     union {
         struct st_arm_ss_params *arm;
@@ -377,6 +397,8 @@
     st_exec_mode_config_t exec_mode_cfg;
     bool lpi_enable;
     bool vad_enable;
+    struct lab_dam_cfg_payload lab_dam_cfg_payload;
+    st_shared_buf_fmt_t shared_buf_fmt;
 
     struct listnode gcs_usecase_list; /* list of gcs usecases one entry per uid */
     struct listnode lsm_usecase_list;
@@ -609,6 +631,13 @@
    const struct st_vendor_info *v_info
 );
 
+int platform_stdev_set_shared_buf_fmt
+(
+   void *platform,
+   int pcm_id,
+   int shared_buf_fmt
+);
+
 int platform_stdev_send_stream_app_type_cfg
 (
    void *platform,
diff --git a/st_buffering.c b/st_buffering.c
index 098247f..7744ee8 100644
--- a/st_buffering.c
+++ b/st_buffering.c
@@ -179,11 +179,13 @@
         } else {
             ALOGE("%s: Error. Need to pass in rd_ptr when not flushing",
                 __func__);
+            pthread_mutex_unlock(&buf_obj->lock);
             return -EINVAL;
         }
     } else if (flush) {
         ALOGE("%s: Error. Cannot pass in rd_ptr and flush",
             __func__);
+        pthread_mutex_unlock(&buf_obj->lock);
         return -EINVAL;
     }
 
diff --git a/st_hw_common.c b/st_hw_common.c
index db4172f..b550fd7 100644
--- a/st_hw_common.c
+++ b/st_hw_common.c
@@ -134,10 +134,6 @@
      * 2. Upto 2 sessions with single keyword each
      */
 
-    /* If this param is set from xml, ignore the budgeting requirements */
-    if (stdev->disable_lpi_budget)
-        return true;
-
     /* first check current session for LPI criteria if st_ses is available */
     ses_lpi_cost = st_ses ? get_session_lpi_cost(st_ses) : 0;
     if (ses_lpi_cost > max_lpi_budget_available) {
@@ -182,8 +178,19 @@
     st_session_t *st_ses
 )
 {
-    if (st_ses && !st_ses->vendor_uuid_info->lpi_enable) {
-        ALOGV("%s: no check required, lpi NOT enabled for ses", __func__);
+    st_session_t *ses = NULL;
+    struct listnode *ses_node = NULL;
+
+    /*
+     * ST_PLATFORM_LPI_NONE is used for backward compatibility. With this
+     * setting, the st_vendor_uuid->lpi_enable flag will be used.
+     */
+    if (stdev->platform_lpi_enable == ST_PLATFORM_LPI_DISABLE) {
+        ALOGD("%s: lpi NOT enabled in platform setting", __func__);
+        return false;
+    } else if ((stdev->platform_lpi_enable == ST_PLATFORM_LPI_NONE) &&
+               st_ses && !st_ses->vendor_uuid_info->lpi_enable) {
+        ALOGD("%s: lpi NOT enabled for ses %d", __func__, st_ses->sm_handle);
         return false;
     }
 
@@ -192,17 +199,28 @@
         return false;
     }
 
-    if ((stdev->is_charging &&
-         stdev->transit_to_non_lpi_on_battery_charging) ||
-        (st_ses->hw_ses_current->client_req_det_mode ==
-            ST_HW_SESS_DET_HIGH_PERF_MODE)) {
-        ALOGD("%s: lpi NOT supported. perf mode %d, battery status %d",
-            __func__, st_ses->hw_ses_current->client_req_det_mode,
+    if (stdev->is_charging &&
+        stdev->transit_to_non_lpi_on_battery_charging) {
+        ALOGD("%s: lpi NOT supported. battery status %d", __func__,
             stdev->is_charging);
         return false;
     }
 
-    return is_projected_lpi_budget_available(stdev, st_ses);
+    list_for_each(ses_node, &stdev->sound_model_list) {
+        ses = node_to_item(ses_node, st_session_t, list_node);
+
+        if (ses->hw_ses_current->client_req_det_mode ==
+            ST_HW_SESS_DET_HIGH_PERF_MODE) {
+            ALOGD("%s:[%d] lpi NOT supported due to high perf mode", __func__,
+                ses->sm_handle);
+            return false;
+        }
+    }
+
+    if (stdev->platform_lpi_enable == ST_PLATFORM_LPI_NONE)
+        return is_projected_lpi_budget_available(stdev, st_ses);
+    else
+        return true;
 }
 
 bool st_hw_check_vad_support
@@ -256,9 +274,15 @@
 void st_hw_check_and_set_lpi_mode(st_session_t *st_ses)
 {
     if (st_ses && st_ses->hw_ses_adsp) {
-        st_ses->hw_ses_adsp->lpi_enable =
-            (st_ses->vendor_uuid_info->lpi_enable &&
-            is_projected_lpi_budget_available(st_ses->stdev, st_ses));
+        if (st_ses->stdev->platform_lpi_enable == ST_PLATFORM_LPI_NONE) {
+            st_ses->hw_ses_adsp->lpi_enable =
+                (st_ses->vendor_uuid_info->lpi_enable &&
+                is_projected_lpi_budget_available(st_ses->stdev, st_ses));
+        } else {
+            st_ses->hw_ses_adsp->lpi_enable =
+                (st_ses->stdev->platform_lpi_enable ==
+                 ST_PLATFORM_LPI_ENABLE) ? true: false;
+        }
     }
 }
 
@@ -280,6 +304,7 @@
     uint32_t i = 0;
     bool gmm_conf_found = false;
     uint8_t confidence_level = 0;
+    int32_t confidence_level_v2 = 0;
     bool arm_second_stage = st_hw_ses->enable_second_stage;
     bool adsp_second_stage = (st_hw_ses == st_ses->hw_ses_adsp &&
                               !list_empty(&st_hw_ses->lsm_ss_cfg_list));
@@ -389,7 +414,8 @@
                 gmm_conf_found = true;
             } else if ((sm_levels_v2->sm_id == ST_SM_ID_SVA_CNN) ||
                        (sm_levels_v2->sm_id == ST_SM_ID_SVA_VOP)) {
-                confidence_level = (sm_levels_v2->sm_id == ST_SM_ID_SVA_CNN) ?
+                confidence_level_v2 =
+                    (sm_levels_v2->sm_id == ST_SM_ID_SVA_CNN) ?
                     sm_levels_v2->kw_levels[0].kw_level:
                     sm_levels_v2->kw_levels[0].user_levels[0].level;
                 if (arm_second_stage) {
@@ -400,7 +426,7 @@
                         if (st_sec_stage->ss_info->sm_id ==
                             sm_levels_v2->sm_id)
                             st_sec_stage->ss_session->confidence_threshold =
-                                confidence_level;
+                                confidence_level_v2;
                     }
                 } else if (adsp_second_stage) {
                     list_for_each_safe(node, tmp_node,
@@ -408,7 +434,7 @@
                         ss_cfg = node_to_item(node, st_lsm_ss_config_t,
                             list_node);
                         if (ss_cfg->ss_info->sm_id == sm_levels_v2->sm_id)
-                            ss_cfg->confidence_threshold = confidence_level;
+                            ss_cfg->confidence_threshold = confidence_level_v2;
                     }
                 }
             } else {
diff --git a/st_hw_session_gcs.c b/st_hw_session_gcs.c
index 96e917c..af9ff54 100644
--- a/st_hw_session_gcs.c
+++ b/st_hw_session_gcs.c
@@ -146,8 +146,8 @@
     uint32_t payload_size);
 
 /* used to output pcm to file for debugging */
-ST_DBG_DECLARE(static FILE *lab_fp_gcs = NULL; static int lab_fp_gcs_cnt = 0);
-ST_DBG_DECLARE(static FILE *lab_fp_client = NULL; static int lab_fp_client_cnt = 0);
+ST_DBG_DECLARE(static int lab_fp_gcs_cnt = 0);
+ST_DBG_DECLARE(static int lab_fp_client_cnt = 0);
 
 struct st_hw_gcs_data {
     void *lib_handle;
@@ -308,7 +308,7 @@
     buff_sz = hdr->size_in_bytes - sizeof(struct gcs_cmd_readrsp_payload_t);
     buff = (uint8_t *)payload + sizeof(struct gcs_cmd_readrsp_payload_t);
 
-    ST_DBG_FILE_WRITE(lab_fp_gcs, buff, buff_sz);
+    ST_DBG_FILE_WRITE(p_gcs_ses->lab_fp_gcs, buff, buff_sz);
 
     if (buff_sz > ST_GCS_READ_BUF_SIZE) {
         ALOGW("%s: received size %d more than requested %d, truncate",
@@ -1629,9 +1629,9 @@
         return;
     }
 
-    ST_DBG_FILE_OPEN_WR(lab_fp_gcs, ST_DEBUG_DUMP_LOCATION, "lab_gcs_to_sthal",
+    ST_DBG_FILE_OPEN_WR(p_hw_ses->lab_fp_gcs, ST_DEBUG_DUMP_LOCATION, "lab_gcs_to_sthal",
         "bin", lab_fp_gcs_cnt++);
-    ST_DBG_FILE_OPEN_WR(lab_fp_client, ST_DEBUG_DUMP_LOCATION, "lab_sthal_to_client",
+    ST_DBG_FILE_OPEN_WR(p_hw_ses->lab_fp_client, ST_DEBUG_DUMP_LOCATION, "lab_sthal_to_client",
         "bin", lab_fp_client_cnt++);
 
     while (p_hw_ses->read_rsp_cnt && !p_hw_ses->exit_buffering) {
@@ -1697,8 +1697,8 @@
         wdsp_debug_dump(gcs_data.sysfs_fd);
     }
 
-    ST_DBG_FILE_CLOSE(lab_fp_gcs);
-    ST_DBG_FILE_CLOSE(lab_fp_client);
+    ST_DBG_FILE_CLOSE(p_hw_ses->lab_fp_gcs);
+    ST_DBG_FILE_CLOSE(p_hw_ses->lab_fp_client);
 
     /*
      * Signal back to thread calling stop_buffering that
@@ -1777,7 +1777,7 @@
 
             p_gcs_ses->unread_bytes -= copy_bytes;
 
-            ST_DBG_FILE_WRITE(lab_fp_client, client_buf, copy_bytes);
+            ST_DBG_FILE_WRITE(p_gcs_ses->lab_fp_client, client_buf, copy_bytes);
 
             bytes -= copy_bytes;
             client_buf += copy_bytes;
@@ -1861,6 +1861,8 @@
     p_hw_ses->exit_detection = false;
     p_hw_ses->exit_buffering = false;
     p_hw_ses->lab_processing_active = false;
+    p_hw_ses->lab_fp_gcs = NULL;
+    p_hw_ses->lab_fp_client = NULL;
     pthread_condattr_init(&cond_attr);
     pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
     pthread_cond_init(&p_hw_ses->callback_thread_cond, &cond_attr);
diff --git a/st_hw_session_gcs.h b/st_hw_session_gcs.h
index 272404a..a63732f 100644
--- a/st_hw_session_gcs.h
+++ b/st_hw_session_gcs.h
@@ -93,6 +93,8 @@
     uint64_t frame_receive_time;
 
     uint8_t *mulaw_op_buf;
+    FILE *lab_fp_gcs;
+    FILE *lab_fp_client;
 } st_hw_session_gcs_t;
 
 int st_hw_sess_gcs_init(st_hw_session_t *const p_ses,
diff --git a/st_hw_session_lsm.c b/st_hw_session_lsm.c
index 043e1d5..dcc3847 100644
--- a/st_hw_session_lsm.c
+++ b/st_hw_session_lsm.c
@@ -447,7 +447,16 @@
 #ifdef LSM_POLLING_ENABLE_SUPPORT
 static int lsm_set_port(st_hw_session_lsm_t *p_lsm_ses)
 {
-    int status;
+    int status = 0;
+
+    if (p_lsm_ses->common.stdev->lpi_enable &&
+        p_lsm_ses->common.vendor_uuid_info->lab_dam_cfg_payload.token_id) {
+        status = platform_stdev_set_shared_buf_fmt(
+            p_lsm_ses->common.stdev->platform, p_lsm_ses->pcm_id,
+            p_lsm_ses->common.vendor_uuid_info->shared_buf_fmt);
+        if (status)
+            return status;
+    }
 
     status = pcm_ioctl(p_lsm_ses->pcm, SNDRV_LSM_SET_PORT);
     if (status)
@@ -501,7 +510,10 @@
 
     params.sample_rate = v_info->sample_rate;
     params.bit_width = pcm_format_to_bits(v_info->format);
-    params.num_channels = p_lsm_ses->lsm_usecase->in_channels;
+    if (platform_get_lpi_mode(p_ses->stdev->platform))
+        params.num_channels = p_lsm_ses->lsm_usecase->in_channels_lpi;
+    else
+        params.num_channels = p_lsm_ses->lsm_usecase->in_channels;
 
     ALOGV("%s: set SNDRV_LSM_SET_INPUT_HW_PARAMS sr=%d bw=%d ch=%d ", __func__,
           params.sample_rate, params.bit_width, params.num_channels);
@@ -2180,10 +2192,6 @@
         goto sm_error;
     }
 
-    status = send_lsm_input_hw_params(p_ses);
-    if (status)
-        goto sm_error;
-
     /* Send detection event type for last stage only, if params set in config */
     mparams = NULL;
     if ((p_lsm_ses->num_stages == 1) &&
@@ -2383,7 +2391,9 @@
     uint32_t custom_payload_size, smm_th_conf_param_size;
     uint32_t data_payload_size, lsm_param_payload_size;
     uint32_t data_payload_addr_lsw = 0, data_payload_addr_msw = 0, mem_map_handle = 0;
+    uint32_t lab_dam_payload_size = 0;
     unsigned char *custom_payload = NULL, *smm_th_conf_param = NULL;
+    unsigned char *lab_dam_payload = NULL;
     struct st_vendor_info *v_info = p_lsm_ses->common.vendor_uuid_info;
     struct snd_lsm_module_params lsm_params;
     lsm_param_info_t param_info[LSM_SM_PARAMS_INFO_IDX];
@@ -2392,6 +2402,7 @@
     lsm_param_info_t *cus_params;
     lsm_param_info_t *poll_en_params;
     lsm_param_info_t *lab_params;
+    lsm_param_info_t *lab_dam_cfg_params;
     struct snd_lsm_detect_mode det_mode;
     st_lsm_poll_enable_t poll_enable;
     bool disable_custom_config = false;
@@ -2401,6 +2412,7 @@
     int param_count = 0, stage_idx = 0;
     struct lsm_param_custom_config custom_conf_params;
     lsm_param_payload_t custom_conf_params_v2 = {0};
+    lsm_param_payload_t cus_dam_cfg_params = {0};
 
     ALOGD("%s:[%d] Enter", __func__, p_lsm_ses->common.sm_handle);
     if (!p_lsm_ses->pcm) {
@@ -2430,6 +2442,10 @@
         goto error_exit;
     }
 
+    status = send_lsm_input_hw_params(p_ses);
+    if (status)
+        goto error_exit;
+
     if ((rc_config->data_size > CUSTOM_CONFIG_OPAQUE_DATA_SIZE) &&
         p_ses->vendor_uuid_info->is_qcva_uuid && !capture_requested)
         disable_custom_config = true;
@@ -2458,7 +2474,7 @@
             det_mode.mode = LSM_MODE_USER_KEYWORD_DETECTION;
     } else {
         ALOGE("%s: Unknown recognition mode %d", __func__, recognition_mode);
-        goto error_exit;
+        goto error_exit_1;
     }
 
     stage_idx = LSM_STAGE_INDEX_FIRST;
@@ -2536,7 +2552,7 @@
                 custom_payload = (unsigned char *)calloc(1, custom_payload_size);
                 if (!custom_payload) {
                     ALOGE("%s: ERROR. Cannot allocate memory for custom_payload", __func__);
-                    goto error_exit;
+                    goto error_exit_1;
                 }
                 /* copy custom config params to payload */
                 memcpy(custom_payload, &custom_conf_params_v2, sizeof(custom_conf_params_v2));
@@ -2562,7 +2578,7 @@
                 custom_payload = (unsigned char *)calloc(1, custom_payload_size);
                 if (!custom_payload) {
                     ALOGE("%s: ERROR. Cannot allcoate memory for custom_payload", __func__);
-                    goto error_exit;
+                    goto error_exit_1;
                 }
                 /* copy custom config params to payload */
                 memcpy(custom_payload, &custom_conf_params, sizeof(struct lsm_param_custom_config));
@@ -2589,7 +2605,7 @@
             custom_payload = (unsigned char *)calloc(1, custom_payload_size);
             if (!custom_payload) {
                 ALOGE("%s: ERROR. Cannot allocate memory for custom_payload", __func__);
-                goto error_exit;
+                goto error_exit_1;
             }
             memcpy(custom_payload, (char *)rc_config + rc_config->data_offset,
                 rc_config->data_size);
@@ -2611,6 +2627,44 @@
                             &mparams[LAB_CONTROL], stage_idx);
     }
 
+    /*
+     * If shared buffering is supported and LPI mode is enabled, send the DAM
+     * driver param to DSP to set the shared buffer token for this session.
+     */
+    if (capture_requested && p_ses->stdev->lpi_enable &&
+        p_ses->vendor_uuid_info->lab_dam_cfg_payload.token_id &&
+        (p_lsm_ses->lsm_usecase->param_tag_tracker &
+         PARAM_LAB_DAM_CFG_BIT)) {
+
+        lab_dam_cfg_params = &param_info[param_count++];
+        p_ses->vendor_uuid_info->lab_dam_cfg_payload.minor_version = 0x1;
+
+        lsm_param_payload_size = sizeof(struct lab_dam_cfg_payload);
+
+        lsm_fill_param_header(&cus_dam_cfg_params,
+            lsm_param_payload_size, &mparams[LAB_DAM_CFG]);
+
+        lab_dam_payload_size = sizeof(cus_dam_cfg_params) +
+            lsm_param_payload_size;
+        lab_dam_payload = (unsigned char *)calloc(1, lab_dam_payload_size);
+        if (!lab_dam_payload) {
+            ALOGE("%s: ERROR. Cannot allocate memory for lab_dam_payload",
+                __func__);
+            goto error_exit_1;
+        }
+        /* copy custom config params to payload */
+        memcpy(lab_dam_payload, &cus_dam_cfg_params,
+            sizeof(cus_dam_cfg_params));
+        memcpy(lab_dam_payload + sizeof(cus_dam_cfg_params),
+            &p_ses->vendor_uuid_info->lab_dam_cfg_payload,
+            lsm_param_payload_size);
+
+        lab_dam_cfg_params->param_size = lab_dam_payload_size;
+        lab_dam_cfg_params->param_data = (unsigned char *)lab_dam_payload;
+        lsm_fill_param_info(LSM_CUSTOM_PARAMS, lab_dam_cfg_params,
+                            &mparams[LAB_DAM_CFG], stage_idx);
+    }
+
     /* Send all applicable module params for this(first) stage */
     lsm_params.num_params = param_count;
     if (lsm_params.num_params) {
@@ -2627,7 +2681,7 @@
         if (status) {
             ALOGE("%s: ERROR. sending sm_params, status %d, stage 0",
                   __func__, status);
-                goto error_exit;
+                goto error_exit_1;
         }
     }
 
@@ -2648,7 +2702,7 @@
         if (!(param_tag_tracker & PARAM_LAB_CONTROL_BIT)) {
             ALOGE("%s: ERROR: lab control param not set for multi-stage ses %p, stage %d",
                   __func__, p_ses, stage_idx);
-            goto error_exit;
+            goto error_exit_1;
         }
 
         if (param_tag_tracker & PARAM_CONFIDENCE_LEVELS_BIT) {
@@ -2659,7 +2713,7 @@
             smm_th_conf_param = (unsigned char *)calloc(1, smm_th_conf_param_size);
             if (!smm_th_conf_param) {
                 ALOGE("%s: ERROR. Cannot allocate memory for smm_th_config", __func__);
-                goto error_exit;
+                goto error_exit_1;
             }
 
             lsm_fill_param_header((lsm_param_payload_t *)smm_th_conf_param,
@@ -2747,7 +2801,7 @@
             if (status) {
                 ALOGE("%s: ERROR. sending reg_sm_params, status %d stage %d",
                       __func__, status, stage_idx);
-                goto error_exit;
+                goto error_exit_1;
             }
         }
     }
@@ -2766,33 +2820,39 @@
             if (status) {
                 ALOGE("%s: ERROR. SNDRV_LSM_LAB_CONTROL failed, status=%d",
                       __func__, status);
-                goto error_exit;
+                goto error_exit_1;
             }
         }
 
         if (!p_lsm_ses->lab_buffers_allocated) {
             status = allocate_lab_buffers_ape(p_lsm_ses);
             if (status)
-                goto error_exit;
+                goto error_exit_1;
         }
     }
 
     return status;
 
-error_exit:
+error_exit_1:
 
     if (p_lsm_ses->lab_buffers_allocated)
         deallocate_lab_buffers_ape(p_lsm_ses);
 
-    pcm_stop(p_lsm_ses->pcm);
-    ape_enable_use_case(false, p_ses);
-    ape_enable_port_control(false, p_ses);
+    if (smm_th_conf_param)
+        free(smm_th_conf_param);
+
+    if (lab_dam_payload)
+        free(lab_dam_payload);
 
     if (custom_payload)
         free(custom_payload);
 
-    if (smm_th_conf_param)
-        free(smm_th_conf_param);
+    pcm_stop(p_lsm_ses->pcm);
+
+error_exit:
+
+    ape_enable_use_case(false, p_ses);
+    ape_enable_port_control(false, p_ses);
 
     ALOGD("%s:[%d] Exit, status=%d", __func__,
         p_lsm_ses->common.sm_handle, status);
diff --git a/st_second_stage.c b/st_second_stage.c
index 5df77da..1090513 100644
--- a/st_second_stage.c
+++ b/st_second_stage.c
@@ -60,8 +60,8 @@
 #include "capi_v2_extn.h"
 #include "st_hw_session_gcs.h"
 
-ST_DBG_DECLARE(FILE *ss_fd_kw_det = NULL; static int ss_fd_cnt_kw_det = 0);
-ST_DBG_DECLARE(FILE *ss_fd_user_ver = NULL; static int ss_fd_cnt_user_ver = 0);
+ST_DBG_DECLARE(static int ss_fd_cnt_kw_det = 0);
+ST_DBG_DECLARE(static int ss_fd_cnt_user_ver = 0);
 
 static int process_frame_keyword_detection(st_arm_ss_session_t *ss_session,
     uint8_t *frame, capi_v2_stream_data_t *stream_input,
@@ -192,7 +192,7 @@
         }
         ss_session->unread_bytes -= ss_session->buff_sz;
 
-        ST_DBG_FILE_WRITE(ss_fd_kw_det, process_input_buff,
+        ST_DBG_FILE_WRITE(st_sec_stage->dump_fp, process_input_buff,
             ss_session->buff_sz);
         pthread_mutex_unlock(&ss_session->lock);
         ret = process_frame_keyword_detection(ss_session, process_input_buff,
@@ -406,7 +406,7 @@
         }
         ss_session->unread_bytes -= ss_session->buff_sz;
 
-        ST_DBG_FILE_WRITE(ss_fd_user_ver, process_input_buff,
+        ST_DBG_FILE_WRITE(st_sec_stage->dump_fp, process_input_buff,
             ss_session->buff_sz);
         pthread_mutex_unlock(&ss_session->lock);
         ret = process_frame_user_verification(ss_session, process_input_buff,
@@ -510,15 +510,15 @@
 
         if (st_sec_stage->ss_info->sm_detection_type ==
             ST_SM_TYPE_KEYWORD_DETECTION) {
-            ST_DBG_FILE_OPEN_WR(ss_fd_kw_det, ST_DEBUG_DUMP_LOCATION,
+            ST_DBG_FILE_OPEN_WR(st_sec_stage->dump_fp, ST_DEBUG_DUMP_LOCATION,
                 "ss_buf_kw_det", "bin", ss_fd_cnt_kw_det++);
             start_keyword_detection(st_sec_stage);
-            ST_DBG_FILE_CLOSE(ss_fd_kw_det);
+            ST_DBG_FILE_CLOSE(st_sec_stage->dump_fp);
         } else {
-            ST_DBG_FILE_OPEN_WR(ss_fd_user_ver, ST_DEBUG_DUMP_LOCATION,
+            ST_DBG_FILE_OPEN_WR(st_sec_stage->dump_fp, ST_DEBUG_DUMP_LOCATION,
                 "ss_buf_user_ver", "bin", ss_fd_cnt_user_ver++);
             start_user_verification(st_sec_stage);
-            ST_DBG_FILE_CLOSE(ss_fd_user_ver);
+            ST_DBG_FILE_CLOSE(st_sec_stage->dump_fp);
         }
     }
     pthread_mutex_unlock(&ss_session->lock);
@@ -646,6 +646,7 @@
         return -EINVAL;
     }
     ss_session = st_sec_stage->ss_session;
+    st_sec_stage->dump_fp = NULL;
 
     /* Allocate extra pointers needed in the capi wrappers */
     if (st_sec_stage->ss_info->sm_detection_type ==
diff --git a/st_second_stage.h b/st_second_stage.h
index a1a757c..6107775 100644
--- a/st_second_stage.h
+++ b/st_second_stage.h
@@ -88,6 +88,7 @@
     struct st_second_stage_info *ss_info;
     struct listnode list_node;
     struct st_arm_ss_session *ss_session;
+    FILE *dump_fp;
 }st_arm_second_stage_t;
 
 typedef struct st_arm_ss_session {
diff --git a/st_session.c b/st_session.c
index acb0cec..f5b362a 100644
--- a/st_session.c
+++ b/st_session.c
@@ -161,7 +161,7 @@
     } payload;
 };
 
-ST_DBG_DECLARE(FILE *lab_fp = NULL; static int file_cnt = 0);
+ST_DBG_DECLARE(static int file_cnt = 0);
 
 void hw_sess_cb(st_hw_sess_event_t *hw_event, void *cookie)
 {
@@ -278,22 +278,13 @@
     int status = 0, err = 0;
 
     /*
-     * Force reload sound model if LPI enabled for BackEnd but not for session.
-     * Note:
-     * 1. FE LPI enabled + BE LPI disabled is supported in ADSP
-     *    and if needed used to simplify concurrency handling, But
-     *    FE LPI disabled + BE LPI enabled is not supported in ADSP
-     *    and hence cannot be used to simplify concurrency handling.
-     * 2. When ever possible FE LPI mode is kept enabled, but due to
-     *    LPI memory constraints, a session would need to be loaded
-     *    with FE LPI disabled when system session count exceeds
-     *    max that can be supported in LPI mode, these sessions when
-     *    continued beyond unloading of any other session, triggering
-     *    BE LPI to be enabled again, would need this handling.
+     * It is possible the BE LPI mode has been updated, but not the FE mode.
+     * DSP requires both FE and BE to be in the same mode for any configuration
+     * changes between LPI and non-LPI switch, so update the FE mode to the
+     * same as BE mode by re-opening LSM session.
      */
-    if ((st_ses->hw_ses_adsp == hw_ses) && hw_ses->stdev->lpi_enable &&
-        st_ses->vendor_uuid_info->lpi_enable && !hw_ses->lpi_enable) {
-        hw_ses->lpi_enable = true;
+    if (hw_ses->lpi_enable != hw_ses->stdev->lpi_enable) {
+        hw_ses->lpi_enable = hw_ses->stdev->lpi_enable;
         if (!load_sm) {
             load_sm = true;
             status = hw_ses->fptrs->dereg_sm(hw_ses, st_ses->lab_enabled);
@@ -430,8 +421,13 @@
     if (status == 0) {
         st_ses->hw_session_started = true;
     } else {
-        ALOGE("%s:[%d] failed to restart", __func__, st_ses->sm_handle);
-        st_ses->hw_session_started = false;
+        ALOGE("%s:[%d] failed to restart, stop session", __func__, st_ses->sm_handle);
+        /*
+         * lower layers like gcs/lsm need to handle double stop calls properly
+         * to avoid possible crash, as some of the clean ups are already issued
+         * during fptrs->restart() when it's failed.
+         */
+        stop_hw_session(st_ses, hw_ses, true);
     }
     return status;
 }
@@ -726,7 +722,7 @@
                     if (status) {
                         ALOGE("%s: Failed to start second stage session, exiting", __func__);
                         status = -EINVAL;
-                        goto cleanup;
+                        break;
                     }
                 }
             }
@@ -872,13 +868,6 @@
     };
 
     return status;
-
-cleanup:
-    list_for_each_safe(node, tmp_node, &st_ses->second_stage_list) {
-        st_sec_stage = node_to_item(node, st_arm_second_stage_t, list_node);
-        st_second_stage_module_deinit(st_sec_stage);
-    }
-    return status;
 }
 
 static int active_state_fn(st_session_t *st_ses, st_session_ev_t *ev)
@@ -960,11 +949,11 @@
                  * internally from SSR.
                  */
                 status = 0;
+                break;
             } else {
                 ALOGE("%s:[%d] failed to stop session, err %d", __func__,
                     st_ses->sm_handle, status);
             }
-            break;
         }
 
         STATE_TRANSITION(st_ses, loaded_state_fn);
@@ -1009,7 +998,7 @@
              * callback it will be handled by one of the two states below
              */
             if (!status && st_ses->lab_enabled) {
-                ST_DBG_FILE_OPEN_WR(lab_fp, ST_DEBUG_DUMP_LOCATION, "lab_capture",
+                ST_DBG_FILE_OPEN_WR(st_ses->lab_fp, ST_DEBUG_DUMP_LOCATION, "lab_capture",
                     "bin", file_cnt++);
                 STATE_TRANSITION(st_ses, buffering_state_fn);
             } else {
@@ -1382,7 +1371,7 @@
         /* Note: this function may block if there is no PCM data ready*/
         hw_ses->fptrs->read_pcm(hw_ses, ev->payload.readpcm.out_buff,
             ev->payload.readpcm.out_buff_size);
-        ST_DBG_FILE_WRITE(lab_fp, ev->payload.readpcm.out_buff,
+        ST_DBG_FILE_WRITE(st_ses->lab_fp, ev->payload.readpcm.out_buff,
             ev->payload.readpcm.out_buff_size);
         break;
     case ST_SES_EV_END_BUFFERING:
@@ -1430,7 +1419,7 @@
             ALOGE("%s:[%d] failed to stop session, err %d", __func__,
                 st_ses->sm_handle, status);
 
-        ST_DBG_FILE_CLOSE(lab_fp);
+        ST_DBG_FILE_CLOSE(st_ses->lab_fp);
         STATE_TRANSITION(st_ses, loaded_state_fn);
         break;
 
@@ -1480,15 +1469,7 @@
             if (st_ses->stdev->ssr_offline_received) {
                 if (st_ses->enable_second_stage)
                     stop_second_stage_session(st_ses);
-                /*
-                 * if restart failed during SSR, needs to reset the st
-                 * device to make sure that it can be brought up again
-                 * when SSR online is received.
-                 */
-                if (ev->ev_id == ST_SES_EV_RESTART)
-                    stop_session(st_ses, hw_ses, true);
-                else
-                    hw_ses->fptrs->dereg_sm(hw_ses, st_ses->lab_enabled);
+                hw_ses->fptrs->dereg_sm(hw_ses, st_ses->lab_enabled);
                 st_ses->client_req_state = ST_STATE_ACTIVE;
                 STATE_TRANSITION(st_ses, ssr_state_fn);
                 /* Send success to client because the failure is recovered
@@ -3356,6 +3337,7 @@
     st_ses->exec_mode = exec_mode;
     st_ses->sm_handle = sm_handle;
     st_ses->ssr_transit_exec_mode = ST_EXEC_MODE_NONE;
+    st_ses->lab_fp = NULL;
 
     /* start in idle state */
     STATE_TRANSITION(st_ses, idle_state_fn);
diff --git a/st_session.h b/st_session.h
index f650934..774e2a4 100644
--- a/st_session.h
+++ b/st_session.h
@@ -136,6 +136,7 @@
     int rc_config_update_counter;
     bool detection_requested;
     uint32_t conf_levels_intf_version;
+    FILE *lab_fp;
 };
 
 /*