Merge "Revert "rtac: Reduce RTAC buffer size""
diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c
index 2ef9e0a..d2a3938 100644
--- a/asoc/codecs/wsa881x.c
+++ b/asoc/codecs/wsa881x.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-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
@@ -76,6 +76,7 @@
 enum {
 	WSA881X_DEV_DOWN,
 	WSA881X_DEV_UP,
+	WSA881X_DEV_READY,
 };
 
 /*
@@ -99,6 +100,7 @@
 	int version;
 	struct mutex bg_lock;
 	struct mutex res_lock;
+	struct mutex temp_lock;
 	struct snd_info_entry *entry;
 	struct snd_info_entry *version_entry;
 	int state;
@@ -491,6 +493,17 @@
 	.read = codec_debug_read,
 };
 
+static void wsa881x_regcache_sync(struct wsa881x_priv *wsa881x)
+{
+	mutex_lock(&wsa881x->res_lock);
+	if (wsa881x->state != WSA881X_DEV_READY) {
+		regcache_mark_dirty(wsa881x->regmap);
+		regcache_sync(wsa881x->regmap);
+		wsa881x->state = WSA881X_DEV_READY;
+	}
+	mutex_unlock(&wsa881x->res_lock);
+}
+
 static const struct reg_sequence wsa881x_pre_pmu_pa[] = {
 	{WSA881X_SPKR_DRV_GAIN, 0x41, 0},
 	{WSA881X_SPKR_MISC_CTL1, 0x01, 0},
@@ -850,7 +863,9 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		mutex_lock(&wsa881x->temp_lock);
 		wsa881x_resource_acquire(codec, ENABLE);
+		mutex_unlock(&wsa881x->temp_lock);
 		wsa881x_boost_ctrl(codec, ENABLE);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
@@ -858,7 +873,9 @@
 					    wsa881x->swr_slave->dev_num,
 					    false);
 		wsa881x_boost_ctrl(codec, DISABLE);
+		mutex_lock(&wsa881x->temp_lock);
 		wsa881x_resource_acquire(codec, DISABLE);
+		mutex_unlock(&wsa881x->temp_lock);
 		break;
 	}
 	return 0;
@@ -1103,13 +1120,8 @@
 			return -EINVAL;
 		}
 	}
-	mutex_lock(&wsa881x->res_lock);
-	if (!wsa881x->clk_cnt) {
-		regcache_mark_dirty(wsa881x->regmap);
-		regcache_sync(wsa881x->regmap);
-	}
-	mutex_unlock(&wsa881x->res_lock);
-
+	wsa881x_regcache_sync(wsa881x);
+	mutex_lock(&wsa881x->temp_lock);
 	wsa881x_resource_acquire(codec, ENABLE);
 
 	snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00);
@@ -1122,6 +1134,7 @@
 	wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4);
 
 	wsa881x_resource_acquire(codec, DISABLE);
+	mutex_unlock(&wsa881x->temp_lock);
 
 	return 0;
 }
@@ -1137,7 +1150,6 @@
 	dev = wsa881x->swr_slave;
 	wsa881x->codec = codec;
 	mutex_init(&wsa881x->bg_lock);
-	mutex_init(&wsa881x->res_lock);
 	wsa881x_init(codec);
 	snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name),
 		"%s.%x", "wsatz", (u8)dev->addr);
@@ -1159,7 +1171,6 @@
 	if (wsa881x->tz_pdata.tz_dev)
 		wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev);
 	mutex_destroy(&wsa881x->bg_lock);
-	mutex_destroy(&wsa881x->res_lock);
 
 	return 0;
 }
@@ -1342,6 +1353,8 @@
 			__func__);
 		goto dev_err;
 	}
+	mutex_init(&wsa881x->res_lock);
+	mutex_init(&wsa881x->temp_lock);
 
 	return 0;
 
@@ -1364,6 +1377,8 @@
 	}
 	debugfs_remove_recursive(debugfs_wsa881x_dent);
 	debugfs_wsa881x_dent = NULL;
+	mutex_destroy(&wsa881x->res_lock);
+	mutex_destroy(&wsa881x->temp_lock);
 	snd_soc_unregister_codec(&pdev->dev);
 	if (wsa881x->pd_gpio)
 		gpio_free(wsa881x->pd_gpio);
@@ -1422,6 +1437,11 @@
 		dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__);
 		return -EINVAL;
 	}
+	if (wsa881x->state == WSA881X_DEV_READY) {
+		dev_dbg(&pdev->dev, "%s: device already active\n", __func__);
+		return 0;
+	}
+
 	wsa881x->bg_cnt = 0;
 	wsa881x->clk_cnt = 0;
 	while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) {
@@ -1429,8 +1449,8 @@
 		usleep_range(1000, 1100);
 	}
 	pdev->dev_num = devnum;
-	regcache_mark_dirty(wsa881x->regmap);
-	regcache_sync(wsa881x->regmap);
+	wsa881x_regcache_sync(wsa881x);
+
 	return 0;
 }
 
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index e821717..0426679 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -3693,6 +3693,10 @@
 		msm_route_ec_ref_rx = 23;
 		ec_ref_port_id = AFE_PORT_ID_HDMI_OVER_DP_RX;
 		break;
+	case 24:
+		msm_route_ec_ref_rx = 24;
+		ec_ref_port_id = AFE_PORT_ID_PRIMARY_TDM_RX_1;
+		break;
 	default:
 		msm_route_ec_ref_rx = 0; /* NONE */
 		pr_err("%s EC ref rx %ld not valid\n",
@@ -3716,7 +3720,8 @@
 	"SLIM_5_RX", "SLIM_1_TX", "QUAT_TDM_TX_1",
 	"QUAT_TDM_RX_0", "QUAT_TDM_RX_1", "QUAT_TDM_RX_2", "SLIM_6_RX",
 	"TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX",
-	"INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT"};
+	"INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT",
+	"PRI_TDM_RX_1"};
 
 static const struct soc_enum msm_route_ec_ref_rx_enum[] = {
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_rx), ec_ref_rx),
@@ -15670,6 +15675,7 @@
 	{"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
 	{"AUDIO_REF_EC_UL1 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"},
+	{"AUDIO_REF_EC_UL1 MUX", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"},
@@ -15705,6 +15711,7 @@
 	{"AUDIO_REF_EC_UL8 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
 	{"AUDIO_REF_EC_UL8 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
 	{"AUDIO_REF_EC_UL8 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+	{"AUDIO_REF_EC_UL8 MUX", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
 
 	{"AUDIO_REF_EC_UL9 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"},
 	{"AUDIO_REF_EC_UL9 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c
index ad1dc3d..c6449dd 100644
--- a/dsp/audio_cal_utils.c
+++ b/dsp/audio_cal_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-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
@@ -63,6 +63,7 @@
 		break;
 	case ADM_AUDPROC_CAL_TYPE:
 	case ADM_LSM_AUDPROC_CAL_TYPE:
+	case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE:
 		size = sizeof(struct audio_cal_info_audproc);
 		break;
 	case ADM_AUDVOL_CAL_TYPE:
@@ -213,6 +214,7 @@
 		break;
 	case ADM_AUDPROC_CAL_TYPE:
 	case ADM_LSM_AUDPROC_CAL_TYPE:
+	case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE:
 		size = sizeof(struct audio_cal_type_audproc);
 		break;
 	case ADM_AUDVOL_CAL_TYPE:
diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c
index c742f72..44444ef 100644
--- a/dsp/codecs/audio_aac.c
+++ b/dsp/codecs/audio_aac.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -230,7 +230,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("%s[%pK]:Failed in utils_ioctl: %d\n",
+			pr_err_ratelimited("%s[%pK]:Failed in utils_ioctl: %d\n",
 				__func__, audio, rc);
 	}
 	}
@@ -339,7 +339,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_compat_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("%s[%pK]:Failed in utils_ioctl: %d\n",
+			pr_err_ratelimited("%s[%pK]:Failed in utils_ioctl: %d\n",
 				__func__, audio, rc);
 	}
 	}
diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c
index cfb3087..975a1e9 100644
--- a/dsp/codecs/audio_alac.c
+++ b/dsp/codecs/audio_alac.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -151,7 +151,7 @@
 	default: {
 		rc = audio->codec_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
@@ -253,7 +253,7 @@
 	default: {
 		rc = audio->codec_compat_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c
index 3df6347..f2a6bf7 100644
--- a/dsp/codecs/audio_ape.c
+++ b/dsp/codecs/audio_ape.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -137,7 +137,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
@@ -235,7 +235,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_compat_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c
index e8f22e7..9c8b3b8 100644
--- a/dsp/codecs/audio_utils_aio.c
+++ b/dsp/codecs/audio_utils_aio.c
@@ -1,6 +1,6 @@
 /* Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -201,17 +201,17 @@
 	if (audio->enabled) {
 		rc = q6asm_cmd(audio->ac, CMD_PAUSE);
 		if (rc < 0)
-			pr_err("%s[%pK]: pause cmd failed rc=%d\n",
+			pr_err_ratelimited("%s[%pK]: pause cmd failed rc=%d\n",
 				__func__, audio, rc);
 
 		if (rc == 0) {
 			/* Send suspend only if pause was successful */
 			rc = q6asm_cmd(audio->ac, CMD_SUSPEND);
 			if (rc < 0)
-				pr_err("%s[%pK]: suspend cmd failed rc=%d\n",
+				pr_err_ratelimited("%s[%pK]: suspend cmd failed rc=%d\n",
 					__func__, audio, rc);
 		} else
-			pr_err("%s[%pK]: not sending suspend since pause failed\n",
+			pr_err_ratelimited("%s[%pK]: not sending suspend since pause failed\n",
 				__func__, audio);
 
 	} else
@@ -230,7 +230,7 @@
 		if (!(audio->drv_status & ADRV_STATUS_PAUSE)) {
 			rc = audio_aio_pause(audio);
 			if (rc < 0)
-				pr_err("%s[%pK}: pause cmd failed rc=%d\n",
+				pr_err_ratelimited("%s[%pK}: pause cmd failed rc=%d\n",
 					__func__, audio,
 					rc);
 			else
@@ -238,13 +238,13 @@
 		}
 		rc = q6asm_cmd(audio->ac, CMD_FLUSH);
 		if (rc < 0)
-			pr_err("%s[%pK]: flush cmd failed rc=%d\n",
+			pr_err_ratelimited("%s[%pK]: flush cmd failed rc=%d\n",
 				__func__, audio, rc);
 		/* Not in stop state, reenable the stream */
 		if (audio->stopped == 0) {
 			rc = audio_aio_enable(audio);
 			if (rc)
-				pr_err("%s[%pK]:audio re-enable failed\n",
+				pr_err_ratelimited("%s[%pK]:audio re-enable failed\n",
 					__func__, audio);
 			else {
 				audio->enabled = 1;
@@ -268,7 +268,7 @@
 
 	rc = q6asm_cmd(audio->ac, CMD_OUT_FLUSH);
 	if (rc < 0)
-		pr_err("%s[%pK}: output port flush cmd failed rc=%d\n",
+		pr_err_ratelimited("%s[%pK}: output port flush cmd failed rc=%d\n",
 			__func__, audio, rc);
 	return rc;
 }
@@ -402,7 +402,7 @@
 		/* Close the session */
 		rc = q6asm_cmd(audio->ac, CMD_CLOSE);
 		if (rc < 0)
-			pr_err("%s[%pK]:Failed to close the session rc=%d\n",
+			pr_err_ratelimited("%s[%pK]:Failed to close the session rc=%d\n",
 				__func__, audio, rc);
 		audio->stopped = 1;
 		wake_up(&audio->write_wait);
@@ -677,7 +677,7 @@
 	pr_debug("%s[%pK]: EOS cmd sent to DSP\n", __func__, audio);
 
 	if (rc < 0)
-		pr_err("%s[%pK]: q6asm_cmd failed, rc = %d",
+		pr_err_ratelimited("%s[%pK]: q6asm_cmd failed, rc = %d",
 			__func__, audio, rc);
 
 	pr_debug("%s[%pK]: wait for RENDERED_EOS from DSP\n"
@@ -1422,7 +1422,7 @@
 		mutex_lock(&audio->read_lock);
 		rc = audio_aio_outport_flush(audio);
 		if (rc < 0) {
-			pr_err("%s[%pK]: AUDIO_OUTPORT_FLUSH failed\n",
+			pr_err_ratelimited("%s[%pK]: AUDIO_OUTPORT_FLUSH failed\n",
 				__func__, audio);
 			rc = -EINTR;
 		}
@@ -1436,7 +1436,7 @@
 		audio->stopped = 1;
 		rc = audio_aio_flush(audio);
 		if (rc < 0) {
-			pr_err("%s[%pK]:Audio Stop procedure failed rc=%d\n",
+			pr_err_ratelimited("%s[%pK]:Audio Stop procedure failed rc=%d\n",
 				__func__, audio, rc);
 			mutex_unlock(&audio->lock);
 			break;
@@ -1457,7 +1457,7 @@
 		if (arg == 1) {
 			rc = audio_aio_pause(audio);
 			if (rc < 0) {
-				pr_err("%s[%pK]: pause FAILED rc=%d\n",
+				pr_err_ratelimited("%s[%pK]: pause FAILED rc=%d\n",
 					__func__, audio, rc);
 				mutex_unlock(&audio->lock);
 				break;
@@ -1467,7 +1467,7 @@
 			if (audio->drv_status & ADRV_STATUS_PAUSE) {
 				rc = audio_aio_enable(audio);
 				if (rc)
-					pr_err("%s[%pK]: audio enable failed\n",
+					pr_err_ratelimited("%s[%pK]: audio enable failed\n",
 					__func__, audio);
 				else {
 					audio->drv_status &= ~ADRV_STATUS_PAUSE;
@@ -1494,7 +1494,7 @@
 		/* Flush input / Output buffer in software*/
 		audio_aio_ioport_reset(audio);
 		if (rc < 0) {
-			pr_err("%s[%pK]:AUDIO_FLUSH interrupted\n",
+			pr_err_ratelimited("%s[%pK]:AUDIO_FLUSH interrupted\n",
 				__func__, audio);
 			rc = -EINTR;
 		} else {
@@ -1514,7 +1514,7 @@
 		mutex_lock(&audio->lock);
 		if (copy_to_user((void *)arg, &audio->ac->session,
 			sizeof(u16))) {
-			pr_err("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n",
+			pr_err_ratelimited("%s: copy_to_user for AUDIO_GET_SESSION_ID failed\n",
 				__func__);
 			rc = -EFAULT;
 		}
@@ -1524,7 +1524,7 @@
 	case AUDIO_PM_AWAKE: {
 		if ((audio->audio_ws_mgr ==  NULL) ||
 				(audio->miscdevice == NULL)) {
-			pr_err("%s[%pK]: invalid ws_mgr or miscdevice",
+			pr_err_ratelimited("%s[%pK]: invalid ws_mgr or miscdevice",
 					__func__, audio);
 			rc = -EACCES;
 			break;
@@ -1544,7 +1544,7 @@
 	case AUDIO_PM_RELAX: {
 		if ((audio->audio_ws_mgr ==  NULL) ||
 				(audio->miscdevice == NULL)) {
-			pr_err("%s[%pK]: invalid ws_mgr or miscdevice",
+			pr_err_ratelimited("%s[%pK]: invalid ws_mgr or miscdevice",
 					__func__, audio);
 			rc = -EACCES;
 			break;
diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c
index ef9c8c6..0e8341e 100644
--- a/dsp/codecs/audio_wma.c
+++ b/dsp/codecs/audio_wma.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -126,7 +126,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
@@ -215,7 +215,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_compat_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c
index 2182618..6b1e46f 100644
--- a/dsp/codecs/audio_wmapro.c
+++ b/dsp/codecs/audio_wmapro.c
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -177,7 +177,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
@@ -287,7 +287,7 @@
 		pr_debug("%s[%pK]: Calling utils ioctl\n", __func__, audio);
 		rc = audio->codec_compat_ioctl(file, cmd, arg);
 		if (rc)
-			pr_err("Failed in utils_ioctl: %d\n", rc);
+			pr_err_ratelimited("Failed in utils_ioctl: %d\n", rc);
 		break;
 	}
 	}
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 74a9244..1596418 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -793,7 +793,7 @@
 	index = index + ch_mixer->input_channels[channel_index];
 	ret = adm_populate_channel_weight(&adm_pspd_params[index],
 					ch_mixer, channel_index);
-	if (!ret) {
+	if (ret) {
 		pr_err("%s: fail to get channel weight with error %d\n",
 			__func__, ret);
 		goto fail_cmd;
@@ -2158,7 +2158,8 @@
 			struct cal_block_data, list);
 
 		if (cal_index == ADM_AUDPROC_CAL ||
-		    cal_index == ADM_LSM_AUDPROC_CAL) {
+		    cal_index == ADM_LSM_AUDPROC_CAL ||
+		    cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) {
 			audproc_cal_info = cal_block->cal_info;
 			if ((audproc_cal_info->path == path) &&
 			    (cal_block->cal_data.size > 0))
@@ -2192,7 +2193,8 @@
 			struct cal_block_data, list);
 
 		if (cal_index == ADM_AUDPROC_CAL ||
-		    cal_index == ADM_LSM_AUDPROC_CAL) {
+		    cal_index == ADM_LSM_AUDPROC_CAL ||
+		    cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) {
 			audproc_cal_info = cal_block->cal_info;
 			if ((audproc_cal_info->path == path) &&
 			    (audproc_cal_info->app_type == app_type) &&
@@ -2230,7 +2232,8 @@
 			struct cal_block_data, list);
 
 		if (cal_index == ADM_AUDPROC_CAL ||
-		    cal_index == ADM_LSM_AUDPROC_CAL) {
+		    cal_index == ADM_LSM_AUDPROC_CAL ||
+		    cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) {
 			audproc_cal_info = cal_block->cal_info;
 			if ((audproc_cal_info->path == path) &&
 			    (audproc_cal_info->app_type == app_type) &&
@@ -2317,12 +2320,18 @@
 {
 	pr_debug("%s: port id 0x%x copp_idx %d\n", __func__, port_id, copp_idx);
 
-	if (passthr_mode != LISTEN)
+	if (passthr_mode != LISTEN) {
 		send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx,
 				perf_mode, app_type, acdb_id, sample_rate);
-	else
+	} else {
 		send_adm_cal_type(ADM_LSM_AUDPROC_CAL, path, port_id, copp_idx,
 				  perf_mode, app_type, acdb_id, sample_rate);
+
+		send_adm_cal_type(ADM_LSM_AUDPROC_PERSISTENT_CAL, path,
+				  port_id, copp_idx, perf_mode, app_type,
+				  acdb_id, sample_rate);
+	}
+
 	send_adm_cal_type(ADM_AUDVOL_CAL, path, port_id, copp_idx, perf_mode,
 			  app_type, acdb_id, sample_rate);
 }
@@ -2624,6 +2633,7 @@
 	}
 
 	if ((topology == VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY) ||
+	    (topology == VPM_TX_SM_ECNS_COPP_TOPOLOGY) ||
 	    (topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) ||
 	    (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY))
 		rate = 16000;
@@ -3492,6 +3502,9 @@
 	case ADM_RTAC_AUDVOL_CAL_TYPE:
 		ret = ADM_RTAC_AUDVOL_CAL;
 		break;
+	case ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE:
+		ret = ADM_LSM_AUDPROC_PERSISTENT_CAL;
+		break;
 	default:
 		pr_err("%s: invalid cal type %d!\n", __func__, cal_type);
 	}
@@ -3713,6 +3726,12 @@
 		adm_set_cal, NULL, NULL} },
 		{adm_map_cal_data, adm_unmap_cal_data,
 		cal_utils_match_buf_num} },
+
+		{{ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE,
+		 {adm_alloc_cal, adm_dealloc_cal, NULL,
+		  adm_set_cal, NULL, NULL} },
+		 {adm_map_cal_data, adm_unmap_cal_data,
+		  cal_utils_match_buf_num} },
 	};
 	pr_debug("%s:\n", __func__);
 
@@ -4503,6 +4522,13 @@
 			rc = -ENOMEM;
 			goto unlock;
 		}
+	} else if (cal_index == ADM_LSM_AUDPROC_PERSISTENT_CAL) {
+		if (cal_block->cal_data.size > AUD_PROC_PERSIST_BLOCK_SIZE) {
+			pr_err("%s:persist invalid size exp/actual[%zd, %d]\n",
+				__func__, cal_block->cal_data.size, *size);
+			rc = -ENOMEM;
+			goto unlock;
+		}
 	} else if (cal_index == ADM_AUDVOL_CAL) {
 		if (cal_block->cal_data.size > AUD_VOL_BLOCK_SIZE) {
 			pr_err("%s:aud_vol:invalid size exp/actual[%zd, %d]\n",
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index 8701962..4091faf 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -9543,11 +9543,11 @@
 	int cnt = 0;
 
 	if (!ac) {
-		pr_err("%s: APR handle NULL\n", __func__);
+		pr_err_ratelimited("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	if (ac->apr == NULL) {
-		pr_err("%s: AC APR handle NULL\n", __func__);
+		pr_err_ratelimited("%s: AC APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	q6asm_stream_add_hdr(ac, &hdr, sizeof(hdr), TRUE, stream_id);
@@ -9707,11 +9707,11 @@
 	int rc;
 
 	if (!ac) {
-		pr_err("%s: APR handle NULL\n", __func__);
+		pr_err_ratelimited("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	if (ac->apr == NULL) {
-		pr_err("%s: AC APR handle NULL\n", __func__);
+		pr_err_ratelimited("%s: AC APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	q6asm_stream_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE, stream_id);
@@ -9796,11 +9796,11 @@
 	int rc = 0;
 
 	if (!ac) {
-		pr_err("%s: APR handle NULL\n", __func__);
+		pr_err_ratelimited("%s: APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	if (ac->apr == NULL) {
-		pr_err("%s: AC APR handle NULL\n", __func__);
+		pr_err_ratelimited("%s: AC APR handle NULL\n", __func__);
 		return -EINVAL;
 	}
 	pr_debug("%s: session[%d]\n", __func__, ac->session);
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index a608a66..d313d64 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -4015,6 +4015,7 @@
 #define DEFAULT_POPP_TOPOLOGY				0x00010BE4
 #define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY         0x0001076B
 #define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY            0x00010774
+#define VPM_TX_SM_ECNS_COPP_TOPOLOGY			0x00010F71
 #define VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY			0x00010F89
 #define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY			0x00010F72
 #define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY		0x00010F75
diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h
index e8000ab..79bda97 100644
--- a/include/dsp/q6adm-v2.h
+++ b/include/dsp/q6adm-v2.h
@@ -27,6 +27,7 @@
 		((MAX_MODULES_IN_TOPO + 1) * sizeof(uint32_t))
 #define AUD_PROC_BLOCK_SIZE	4096
 #define AUD_VOL_BLOCK_SIZE	4096
+#define AUD_PROC_PERSIST_BLOCK_SIZE	(2 * 1024 * 1020)
 #define AUDIO_RX_CALIBRATION_SIZE	(AUD_PROC_BLOCK_SIZE + \
 						AUD_VOL_BLOCK_SIZE)
 enum {
@@ -38,6 +39,7 @@
 	ADM_RTAC_APR_CAL,
 	ADM_SRS_TRUMEDIA,
 	ADM_RTAC_AUDVOL_CAL,
+	ADM_LSM_AUDPROC_PERSISTENT_CAL,
 	ADM_MAX_CAL_TYPES
 };
 
diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h
index 3b97ab2..c5811d0 100644
--- a/include/uapi/linux/msm_audio_calibration.h
+++ b/include/uapi/linux/msm_audio_calibration.h
@@ -103,6 +103,7 @@
 	AFE_LSM_TX_CAL_TYPE,
 	ADM_LSM_TOPOLOGY_CAL_TYPE,
 	ADM_LSM_AUDPROC_CAL_TYPE,
+	ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE,
 	MAX_CAL_TYPES,
 };
 
@@ -115,6 +116,7 @@
 #define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE
 #define ADM_LSM_TOPOLOGY_CAL_TYPE ADM_LSM_TOPOLOGY_CAL_TYPE
 #define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE
+#define ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE
 #define LSM_CAL_TYPES
 
 #define TOPOLOGY_SPECIFIC_CHANNEL_INFO
diff --git a/soc/soundwire.c b/soc/soundwire.c
index cda4789..69a9ed4 100644
--- a/soc/soundwire.c
+++ b/soc/soundwire.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -245,7 +245,7 @@
 	if (!dev->group_id)
 		return 0;
 
-	if (master->gr_sid == dev_num)
+	if (master->gr_sid != dev_num)
 		return 0;
 
 	if (master->remove_from_group && master->remove_from_group(master))
diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c
index c5ba37b..455e03b 100644
--- a/soc/swr-wcd-ctrl.c
+++ b/soc/swr-wcd-ctrl.c
@@ -1756,6 +1756,8 @@
 		    (swrm->state == SWR_MSTR_UP)) {
 			dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n",
 				__func__, swrm->state);
+			list_for_each_entry(swr_dev, &mstr->devices, dev_list)
+				swr_reset_device(swr_dev);
 		} else {
 			pm_runtime_mark_last_busy(&pdev->dev);
 			mutex_unlock(&swrm->reslock);