Merge "config: Enable AVTIMER_LEGACY for sdm450"
diff --git a/asoc/Android.mk b/asoc/Android.mk
index b2e3fa8..ebb9139 100644
--- a/asoc/Android.mk
+++ b/asoc/Android.mk
@@ -56,7 +56,7 @@
 LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
 include $(DLKM_DIR)/AndroidKernelModule.mk
 ###########################################################
-ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true)
 include $(CLEAR_VARS)
 LOCAL_MODULE              := $(AUDIO_CHIPSET)_cpe_lsm.ko
 LOCAL_MODULE_KBUILD_NAME  := cpe_lsm_dlkm.ko
diff --git a/asoc/codecs/wcd-dsp-mgr.c b/asoc/codecs/wcd-dsp-mgr.c
index 9bcb635..cde9851 100644
--- a/asoc/codecs/wcd-dsp-mgr.c
+++ b/asoc/codecs/wcd-dsp-mgr.c
@@ -839,21 +839,20 @@
 }
 
 #ifdef CONFIG_DEBUG_FS
-static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg)
+static int __wdsp_dbg_dump_locked(struct wdsp_mgr_priv *wdsp, void *arg)
 {
 	struct wdsp_err_signal_arg *err_data;
 	int ret = 0;
 
-	WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex);
 	/* If there is no SSR, set the SSR type to collect ramdumps */
 	if (wdsp->ssr_type == WDSP_SSR_TYPE_NO_SSR) {
 		wdsp->ssr_type = WDSP_SSR_TYPE_WDSP_DOWN;
 	} else {
 		WDSP_DBG(wdsp, "SSR handling is running, skip debug ramdump");
 		ret = 0;
-		WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
 		goto done;
 	}
+
 	if (arg) {
 		err_data = (struct wdsp_err_signal_arg *) arg;
 		memcpy(&wdsp->dump_data.err_data, err_data,
@@ -861,16 +860,29 @@
 	} else {
 		WDSP_DBG(wdsp, "Invalid input, arg is NULL");
 		ret = -EINVAL;
-		WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
 		goto done;
 	}
 	wdsp_collect_ramdumps(wdsp);
 	wdsp->ssr_type = WDSP_SSR_TYPE_NO_SSR;
-	WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
 done:
 	return ret;
 }
+static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg)
+{
+	int ret = 0;
+
+	WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex);
+	ret = __wdsp_dbg_dump_locked(wdsp, arg);
+	WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex);
+
+	return ret;
+}
 #else
+static int __wdsp_dbg_dump_locked(struct wdsp_mgr_priv *wdsp, void *arg)
+{
+	return 0;
+}
+
 static int wdsp_debug_dump_handler(struct wdsp_mgr_priv *wdsp, void *arg)
 {
 	return 0;
@@ -887,7 +899,13 @@
 		return -EINVAL;
 
 	wdsp = dev_get_drvdata(wdsp_dev);
+
+#ifdef CONFIG_DEBUG_FS
+	if (signal != WDSP_DEBUG_DUMP_INTERNAL)
+		WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex);
+#else
 	WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex);
+#endif
 
 	WDSP_DBG(wdsp, "Raised signal %d", signal);
 
@@ -908,6 +926,9 @@
 	case WDSP_DEBUG_DUMP:
 		ret = wdsp_debug_dump_handler(wdsp, arg);
 		break;
+	case WDSP_DEBUG_DUMP_INTERNAL:
+		ret = __wdsp_dbg_dump_locked(wdsp, arg);
+		break;
 	default:
 		ret = -EINVAL;
 		break;
@@ -916,7 +937,13 @@
 	if (ret < 0)
 		WDSP_ERR(wdsp, "handling signal %d failed with error %d",
 			 signal, ret);
+
+#ifdef CONFIG_DEBUG_FS
+	if (signal != WDSP_DEBUG_DUMP_INTERNAL)
+		WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex);
+#else
 	WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex);
+#endif
 
 	return ret;
 }
diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c
index 58987ad..662f484 100644
--- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c
+++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c
@@ -101,6 +101,7 @@
 	WCD934X_CPE_SS_SOC_SW_COLLAPSE_CTL,
 	WCD934X_CPE_SS_MAD_CTL,
 	WCD934X_CPE_SS_CPAR_CTL,
+	WCD934X_CPE_SS_CPAR_CFG,
 	WCD934X_CPE_SS_WDOG_CFG,
 	WCD934X_CPE_SS_STATUS,
 	WCD934X_CPE_SS_SS_ERROR_INT_MASK_0A,
@@ -113,10 +114,12 @@
 	WCD934X_CPE_SS_SS_ERROR_INT_STATUS_1B,
 };
 
-static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl)
+static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl,
+					 bool internal)
 {
 	struct snd_soc_codec *codec = cntl->codec;
 	struct wdsp_err_signal_arg arg;
+	enum wdsp_signal signal;
 	int i;
 	u8 val;
 
@@ -146,8 +149,8 @@
 		arg.mem_dumps_enabled = cntl->ramdump_enable;
 		arg.remote_start_addr = WCD_934X_RAMDUMP_START_ADDR;
 		arg.dump_size = WCD_934X_RAMDUMP_SIZE;
-		cntl->m_ops->signal_handler(cntl->m_dev, WDSP_DEBUG_DUMP,
-					    &arg);
+		signal = internal ? WDSP_DEBUG_DUMP_INTERNAL : WDSP_DEBUG_DUMP;
+		cntl->m_ops->signal_handler(cntl->m_dev, signal, &arg);
 	}
 
 	/* Unmask the fatal irqs */
@@ -161,7 +164,8 @@
 #else
 #define WCD_CNTL_SET_ERR_IRQ_FLAG(cntl) 0
 #define WCD_CNTL_CLR_ERR_IRQ_FLAG(cntl) do {} while (0)
-static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl)
+static void wcd_cntl_collect_debug_dumps(struct wcd_dsp_cntl *cntl,
+					 bool internal)
 {
 }
 #endif
@@ -753,7 +757,7 @@
 	if (!ret) {
 		dev_err(codec->dev, "%s: WDSP boot timed out\n",
 			__func__);
-		wcd_cntl_collect_debug_dumps(cntl);
+		wcd_cntl_collect_debug_dumps(cntl, true);
 		ret = -ETIMEDOUT;
 		goto err_boot;
 	} else {
@@ -1041,7 +1045,7 @@
 	} else if (!strcmp(val, "DEBUG_DUMP")) {
 		dev_dbg(cntl->codec->dev,
 			"%s: Collect dumps for debug use\n", __func__);
-		wcd_cntl_collect_debug_dumps(cntl);
+		wcd_cntl_collect_debug_dumps(cntl, false);
 		goto done;
 	} else {
 		dev_err(cntl->codec->dev, "%s: Invalid value %s\n",
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index b644df7..586683c 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -3644,6 +3644,7 @@
 	struct msm_compr_audio *prtd;
 	int ret = 0;
 	struct msm_adsp_event_data *event_data = NULL;
+	uint64_t actual_payload_len = 0;
 
 	if (fe_id >= MSM_FRONTEND_DAI_MAX) {
 		pr_err("%s Received invalid fe_id %lu\n",
@@ -3681,6 +3682,15 @@
 		goto done;
 	}
 
+	actual_payload_len = sizeof(struct msm_adsp_event_data) +
+		event_data->payload_len;
+	if (actual_payload_len >= U32_MAX) {
+		pr_err("%s payload length 0x%X  exceeds limit",
+				__func__, event_data->payload_len);
+		ret = -EINVAL;
+		goto done;
+	}
+
 	if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
 					sizeof(ucontrol->value.bytes.data)) {
 		pr_err("%s param length=%d  exceeds limit",
diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c
index bb6ce73..abadc87 100644
--- a/asoc/msm-pcm-q6-v2.c
+++ b/asoc/msm-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1106,6 +1106,7 @@
 	struct msm_audio *prtd;
 	int ret = 0;
 	struct msm_adsp_event_data *event_data = NULL;
+	uint64_t actual_payload_len = 0;
 
 	if (!pdata) {
 		pr_err("%s pdata is NULL\n", __func__);
@@ -1142,6 +1143,15 @@
 		goto done;
 	}
 
+	actual_payload_len = sizeof(struct msm_adsp_event_data) +
+							event_data->payload_len;
+	if (actual_payload_len >= U32_MAX) {
+		pr_err("%s payload length 0x%X  exceeds limit",
+			__func__, event_data->payload_len);
+		ret = -EINVAL;
+		goto done;
+	}
+
 	if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
 					sizeof(ucontrol->value.bytes.data)) {
 		pr_err("%s param length=%d  exceeds limit",
diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c
index 3c8e917..726133a 100644
--- a/asoc/msm-transcode-loopback-q6-v2.c
+++ b/asoc/msm-transcode-loopback-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -502,6 +502,7 @@
 	struct msm_transcode_loopback *prtd;
 	int ret = 0;
 	struct msm_adsp_event_data *event_data = NULL;
+	uint64_t actual_payload_len = 0;
 
 	if (fe_id >= MSM_FRONTEND_DAI_MAX) {
 		pr_err("%s Received invalid fe_id %lu\n",
@@ -539,6 +540,15 @@
 		goto done;
 	}
 
+	actual_payload_len = sizeof(struct msm_adsp_event_data) +
+		event_data->payload_len;
+	if (actual_payload_len >= U32_MAX) {
+		pr_err("%s payload length 0x%X  exceeds limit",
+				__func__, event_data->payload_len);
+		ret = -EINVAL;
+		goto done;
+	}
+
 	if ((sizeof(struct msm_adsp_event_data) + event_data->payload_len) >=
 					sizeof(ucontrol->value.bytes.data)) {
 		pr_err("%s param length=%d  exceeds limit",
diff --git a/config/sdm450auto.conf b/config/sdm450auto.conf
index 478d263..0d367ae 100644
--- a/config/sdm450auto.conf
+++ b/config/sdm450auto.conf
@@ -5,6 +5,7 @@
 CONFIG_SND_SOC_WSA881X=m
 CONFIG_SND_SOC_WSA881X_ANALOG=m
 CONFIG_SND_SOC_WCD_CPE=m
+CONFIG_SND_SOC_CPE=m
 CONFIG_SND_SOC_WCD9335=m
 CONFIG_MSM_QDSP6V2_CODECS=m
 CONFIG_MSM_ULTRASOUND=m
diff --git a/config/sdm450autoconf.h b/config/sdm450autoconf.h
index 88fe38c..1aca114 100644
--- a/config/sdm450autoconf.h
+++ b/config/sdm450autoconf.h
@@ -15,6 +15,7 @@
 #define CONFIG_AUDIO_EXT_CLK 1
 #define CONFIG_SND_SOC_WCD9XXX_V2 1
 #define CONFIG_SND_SOC_WCD_CPE 1
+#define CONFIG_SND_SOC_CPE 1
 #define CONFIG_SND_SOC_WCD_MBHC 1
 #define CONFIG_SND_SOC_WSA881X 1
 #define CONFIG_SND_SOC_WSA881X_ANALOG 1
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index f25255c..911a2dd 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -1183,7 +1183,9 @@
 {
 	char *asm_params = NULL;
 	struct apr_hdr hdr;
-	int sz, rc;
+	int rc;
+	uint32_t sz = 0;
+	uint64_t actual_sz = 0;
 
 	if (!data || !ac) {
 		pr_err("%s: %s is NULL\n", __func__,
@@ -1200,7 +1202,15 @@
 		goto done;
 	}
 
-	sz = sizeof(struct apr_hdr) + data->payload_len;
+	actual_sz = sizeof(struct apr_hdr) + data->payload_len;
+	if (actual_sz > U32_MAX) {
+		pr_err("%s: payload size 0x%X exceeds limit\n",
+				__func__, data->payload_len);
+		rc = -EINVAL;
+		goto done;
+	}
+
+	sz = (uint32_t)actual_sz;
 	asm_params = kzalloc(sz, GFP_KERNEL);
 	if (!asm_params) {
 		rc = -ENOMEM;
diff --git a/dsp/q6voice.c b/dsp/q6voice.c
index d5f280e..fee9665 100644
--- a/dsp/q6voice.c
+++ b/dsp/q6voice.c
@@ -1,4 +1,4 @@
-/*  Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/*  Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -4120,6 +4120,7 @@
 	struct cvp_set_mfc_config_cmd_v2 cvp_set_mfc_config_cmd;
 	void *apr_cvp;
 	u16 cvp_handle;
+	uint8_t ch_idx;
 	struct vss_icommon_param_data_mfc_config_v2_t *cvp_config_param_data =
 		&cvp_set_mfc_config_cmd.cvp_set_mfc_param_v2.param_data;
 	struct vss_param_mfc_config_info_t *mfc_config_info =
@@ -4168,9 +4169,15 @@
 	mfc_config_info->num_channels = v->dev_rx.no_of_channels;
 	mfc_config_info->bits_per_sample = 16;
 	mfc_config_info->sample_rate = v->dev_rx.sample_rate;
-	memcpy(&mfc_config_info->channel_type,
-	       v->dev_rx.channel_mapping,
-	       VSS_NUM_CHANNELS_MAX * sizeof(uint8_t));
+
+	/*
+	 * Do not use memcpy here as channel_type in mfc_config structure is a
+	 * uint16_t array while channel_mapping array of device is of uint8_t
+	 */
+	for (ch_idx = 0; ch_idx < VSS_NUM_CHANNELS_MAX; ch_idx++) {
+		mfc_config_info->channel_type[ch_idx] =
+					v->dev_rx.channel_mapping[ch_idx];
+	}
 
 	v->cvp_state = CMD_STATUS_FAIL;
 	v->async_err = 0;