Merge "board-8084: Add dummy clock support for SDCC"
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 6d06e99..1613856 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -121,6 +121,8 @@
 - qcom,pool-64-bit-align: If present then the pool's memory will be aligned
   to 64 bits
 - qcom,enable_hbm: if present host bus manager is enabled.
+- qcom,disable-park-mode: if present park mode is enabled. Park mode enables executing
+  up to 3 usb packets from each QH.
 
 Example MSM HSUSB EHCI controller device node :
 	ehci: qcom,ehci-host@f9a55000 {
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-cdp.dts
index e8e58c4..b203540 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-cdp.dts
@@ -37,7 +37,7 @@
 			vdd-supply = <&pm8226_l19>;
 			vcc_i2c-supply = <&pm8226_lvs1>;
 			synaptics,reset-gpio = <&msmgpio 16 0x00>;
-			synaptics,irq-gpio = <&msmgpio 17 0x00>;
+			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
 			synaptics,i2c-pull-up;
 			synaptics,reg-en;
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-mtp.dts
index a732722..1f8a773 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-mtp.dts
@@ -37,7 +37,7 @@
 			vdd-supply = <&pm8226_l19>;
 			vcc_i2c-supply = <&pm8226_lvs1>;
 			synaptics,reset-gpio = <&msmgpio 16 0x00>;
-			synaptics,irq-gpio = <&msmgpio 17 0x00>;
+			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
 			synaptics,i2c-pull-up;
 			synaptics,reg-en;
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-qrd.dts
index e694cef..660fb3e 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dts
+++ b/arch/arm/boot/dts/msm8226-qrd.dts
@@ -37,7 +37,7 @@
 			vdd-supply = <&pm8226_l19>;
 			vcc_i2c-supply = <&pm8226_lvs1>;
 			synaptics,reset-gpio = <&msmgpio 16 0x00>;
-			synaptics,irq-gpio = <&msmgpio 17 0x00>;
+			synaptics,irq-gpio = <&msmgpio 17 0x2008>;
 			synaptics,button-map = <139 102 158>;
 			synaptics,i2c-pull-up;
 			synaptics,reg-en;
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index fce08bd..aa03951 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -917,6 +917,42 @@
 				<55 512 3936000 393600>,
 				<55 512 3936000 393600>;
 	};
+
+	qcom,qcrypto@fd404000 {
+		compatible = "qcom,qcrypto";
+                reg  =  <0xfd400000 0x20000>,
+                        <0xfd404000 0x8000>;
+		reg-names = "crypto-base","crypto-bam-base";
+		interrupts = <0 207 0>;
+		qcom,bam-pipe-pair = <2>;
+		qcom,ce-hw-instance = <0>;
+		qcom,ce-hw-shared;
+		qcom,msm-bus,name = "qcrypto-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<56 512 0 0>,
+				<56 512 3936000 393600>;
+	};
+
+        qcom,qcedev@fd400000 {
+		compatible = "qcom,qcedev";
+		reg  =  <0xfd400000 0x20000>,
+			<0xfd404000 0x8000>;
+		reg-names = "crypto-base","crypto-bam-base";
+		interrupts = <0 207 0>;
+		qcom,bam-pipe-pair = <1>;
+		qcom,ce-hw-instance = <0>;
+		qcom,ce-hw-shared;
+		qcom,msm-bus,name = "qcedev-noc";
+		qcom,msm-bus,num-cases = <2>;
+		qcom,msm-bus,active-only = <0>;
+		qcom,msm-bus,num-paths = <1>;
+		qcom,msm-bus,vectors-KBps =
+				<56 512 0 0>,
+				<56 512 3936000 393600>;
+	};
 };
 
 &gdsc_venus {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 9b8353b..f787cf5 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -38,7 +38,7 @@
 
 		secure_mem: secure_region {
 			linux,contiguous-region;
-			reg = <0 0x7800000>;
+			reg = <0 0xFC00000>;
 			label = "secure_mem";
 		};
 
diff --git a/arch/arm/boot/dts/msm9625-v1.dtsi b/arch/arm/boot/dts/msm9625-v1.dtsi
index ad95601..de88ff1 100644
--- a/arch/arm/boot/dts/msm9625-v1.dtsi
+++ b/arch/arm/boot/dts/msm9625-v1.dtsi
@@ -37,6 +37,10 @@
 	};
 };
 
+&hsic_host {
+	qcom,disable-park-mode;
+};
+
 &ipa_hw {
 	qcom,ipa-hw-ver = <1>; /* IPA h-w revision */
 };
diff --git a/arch/arm/boot/dts/msm9625-v2.dtsi b/arch/arm/boot/dts/msm9625-v2.dtsi
index 3ce6844..81d8e00 100644
--- a/arch/arm/boot/dts/msm9625-v2.dtsi
+++ b/arch/arm/boot/dts/msm9625-v2.dtsi
@@ -35,6 +35,10 @@
 	qcom,ipa-hw-ver = <2>; /* IPA h-w revision */
 };
 
+&hsic_host {
+	qcom,disable-park-mode;
+};
+
 &sfpb_spinlock {
 	status = "disable";
 };
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index b06ed1c..a70e6c6 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1093,7 +1093,7 @@
 	default "0x00000000" if ARCH_MSM8610
 	default "0x10000000" if ARCH_FSM9XXX
 	default "0x00200000" if ARCH_MSM9625
-	default "0x00200000" if ARCH_MSMKRYPTON
+	default "0x00000000" if ARCH_MSMKRYPTON
 	default "0x00200000" if !MSM_STACKED_MEMORY
 	default "0x00000000" if ARCH_QSD8X50 && MSM_SOC_REV_A
 	default "0x20000000" if ARCH_QSD8X50
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index b2fe474..d57709d 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -64,7 +64,7 @@
         dtb-$(CONFIG_ARCH_APQ8084)	+= apq8084-sim.dtb
 
 # MSMKRYPTON
-   zreladdr-$(CONFIG_ARCH_MSMKRYPTON)	:= 0x00208000
+   zreladdr-$(CONFIG_ARCH_MSMKRYPTON)	:= 0x00008000
 	dtb-$(CONFIG_ARCH_MSMKRYPTON)	+= msmkrypton-sim.dtb
 
 # MSM9615
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index cd0d337..af027f0 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -3428,6 +3428,18 @@
 	CLK_LOOKUP("osr_clk", div_clk1.c, "msm-dai-q6-dev.16390"),
 	CLK_LOOKUP("osr_clk", div_clk1.c, "msm-dai-q6-dev.16391"),
 
+	/* Add QCEDEV clocks */
+	CLK_LOOKUP("core_clk",     gcc_ce1_clk.c,      "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("iface_clk",    gcc_ce1_ahb_clk.c,  "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("bus_clk",      gcc_ce1_axi_clk.c,  "fd400000.qcom,qcedev"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c,      "fd400000.qcom,qcedev"),
+
+	/* Add QCRYPTO clocks */
+	CLK_LOOKUP("core_clk",     gcc_ce1_clk.c,     "fd404000.qcom,qcrypto"),
+	CLK_LOOKUP("iface_clk",    gcc_ce1_ahb_clk.c, "fd404000.qcom,qcrypto"),
+	CLK_LOOKUP("bus_clk",      gcc_ce1_axi_clk.c, "fd404000.qcom,qcrypto"),
+	CLK_LOOKUP("core_clk_src", ce1_clk_src.c,     "fd404000.qcom,qcrypto"),
+
 };
 
 static struct clk_lookup msm_clocks_8226_rumi[] = {
diff --git a/arch/arm/mach-msm/gdsc.c b/arch/arm/mach-msm/gdsc.c
index a07b13d..6665d66 100644
--- a/arch/arm/mach-msm/gdsc.c
+++ b/arch/arm/mach-msm/gdsc.c
@@ -38,7 +38,7 @@
 #define EN_FEW_WAIT_VAL		(0x8 << 16)
 #define CLK_DIS_WAIT_VAL	(0x2 << 12)
 
-#define TIMEOUT_US		1000
+#define TIMEOUT_US		100
 
 struct gdsc {
 	struct regulator_dev	*rdev;
diff --git a/arch/arm/mach-msm/include/mach/qseecomi.h b/arch/arm/mach-msm/include/mach/qseecomi.h
index 20dc851..e889242 100644
--- a/arch/arm/mach-msm/include/mach/qseecomi.h
+++ b/arch/arm/mach-msm/include/mach/qseecomi.h
@@ -18,6 +18,14 @@
 
 #define QSEECOM_KEY_ID_SIZE   32
 
+#define	QSEOS_RESULT_FAIL_LOAD_KS         -48
+#define	QSEOS_RESULT_FAIL_SAVE_KS         -49
+#define	QSEOS_RESULT_FAIL_MAX_KEYS        -50
+#define	QSEOS_RESULT_FAIL_KEY_ID_EXISTS   -51
+#define	QSEOS_RESULT_FAIL_KEY_ID_DNE      -52
+#define	QSEOS_RESULT_FAIL_KS_OP           -53
+#define	QSEOS_RESULT_FAIL_CE_PIPE_INVALID -54
+
 enum qseecom_command_scm_resp_type {
 	QSEOS_APP_ID = 0xEE01,
 	QSEOS_LISTENER_ID
@@ -49,6 +57,22 @@
 	QSEOS_RESULT_FAILURE  = 0xFFFFFFFF
 };
 
+/* Key Management requests */
+enum qseecom_qceos_key_gen_cmd_id {
+	QSEOS_GENERATE_KEY  = 0x11,
+	QSEOS_DELETE_KEY,
+	QSEOS_MAX_KEY_COUNT,
+	QSEOS_SET_KEY,
+	QSEOS_KEY_CMD_MAX   = 0xEFFFFFFF
+};
+
+enum qseecom_pipe_type {
+	QSEOS_PIPE_ENC = 0,
+	QSEOS_PIPE_ENC_XTS,
+	QSEOS_PIPE_AUTH,
+	QSEOS_PIPE_ENUM_FILL = 0x7FFFFFFF
+};
+
 __packed  struct qsee_apps_region_info_ireq {
 	uint32_t qsee_cmd_id;
 	uint32_t addr;
@@ -143,29 +167,24 @@
 	unsigned int rsp_len; /* in/out */
 };
 
-/* Key Management requests */
-enum qseecom_qceos_key_gen_cmd_id {
-	QSEOS_GENERATE_KEY      = 0x02,
-	QSEOS_SET_KEY,
-	QSEOS_DELETE_KEY,
-	QSEOS_MAX_KEY_COUNT,
-	QSEOS_KEY_CMD_MAX     = 0xEFFFFFFF
-};
-
 __packed struct qseecom_key_generate_ireq {
+	uint32_t qsee_command_id;
 	uint32_t flags;
 	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
 };
 
 __packed struct qseecom_key_select_ireq {
+	uint32_t qsee_command_id;
 	uint32_t ce;
 	uint32_t pipe;
+	uint32_t pipe_type;
 	uint32_t flags;
 	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
 	unsigned char hash[QSEECOM_HASH_SIZE];
 };
 
 __packed struct qseecom_key_delete_ireq {
+	uint32_t qsee_command_id;
 	uint32_t flags;
 	uint8_t key_id[QSEECOM_KEY_ID_SIZE];
 };
diff --git a/arch/arm/mach-msm/include/mach/scm.h b/arch/arm/mach-msm/include/mach/scm.h
index 42e04dd..4186603 100644
--- a/arch/arm/mach-msm/include/mach/scm.h
+++ b/arch/arm/mach-msm/include/mach/scm.h
@@ -22,7 +22,6 @@
 #define SCM_SVC_FUSE			0x8
 #define SCM_SVC_PWR			0x9
 #define SCM_SVC_MP			0xC
-#define SCM_SVC_CRYPTO			0xA
 #define SCM_SVC_DCVS			0xD
 #define SCM_SVC_ES			0x10
 #define SCM_SVC_TZSCHEDULER		0xFC
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index ed9f639..52d20e3 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -410,7 +410,8 @@
 #define ONE_PHASE_COEFF		1000000
 #define TWO_PHASE_COEFF		2000000
 
-#define PHASE_SETTLING_TIME_US		10
+#define PWM_SETTLING_TIME_US		50
+#define PHASE_SETTLING_TIME_US		50
 static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
 				int coeff_total)
 {
@@ -453,6 +454,7 @@
 			return rc;
 		} else {
 			pvreg->pfm_mode = false;
+			udelay(PWM_SETTLING_TIME_US);
 		}
 	}
 
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index c758b3a..99ace44 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -306,7 +306,7 @@
 config CRYPTO_DEV_QCE
 	tristate "Qualcomm Crypto Engine (QCE) module"
 	select  CRYPTO_DEV_QCE40 if ARCH_MSM8960 || ARCH_MSM9615
-	select  CRYPTO_DEV_QCE50 if ARCH_MSM8974 || ARCH_MSM9625
+	select  CRYPTO_DEV_QCE50 if ARCH_MSM8974 || ARCH_MSM9625 || ARCH_MSM8226
 	default n
 	help
           This driver supports Qualcomm Crypto Engine in MSM7x30, MSM8660
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 4282f02..fbe4da0 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -1662,8 +1662,8 @@
 		return false;
 	rt_mutex_lock(&heap->lock);
 	list_for_each_entry_safe(buffer, tmp, &heap->free_list, list) {
-		_ion_buffer_destroy(buffer);
 		list_del(&buffer->list);
+		_ion_buffer_destroy(buffer);
 	}
 	BUG_ON(!list_empty(&heap->free_list));
 	rt_mutex_unlock(&heap->lock);
diff --git a/drivers/gpu/ion/ion_iommu_heap.c b/drivers/gpu/ion/ion_iommu_heap.c
index 53d853d..bc9bddd 100644
--- a/drivers/gpu/ion/ion_iommu_heap.c
+++ b/drivers/gpu/ion/ion_iommu_heap.c
@@ -27,6 +27,7 @@
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 #include <mach/iommu_domains.h>
+#include <trace/events/kmem.h>
 
 struct ion_iommu_heap {
 	struct ion_heap heap;
@@ -83,9 +84,13 @@
 		} else {
 			gfp |= GFP_KERNEL;
 		}
+		trace_alloc_pages_iommu_start(gfp, orders[i]);
 		page = alloc_pages(gfp, orders[i]);
-		if (!page)
+		trace_alloc_pages_iommu_end(gfp, orders[i]);
+		if (!page) {
+			trace_alloc_pages_iommu_fail(gfp, orders[i]);
 			continue;
+		}
 
 		info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
 		info->page = page;
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 02f6d93..4e9f55c 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -31,6 +31,7 @@
 #include <asm/cacheflush.h>
 #include <linux/msm_ion.h>
 #include <linux/dma-mapping.h>
+#include <trace/events/kmem.h>
 
 static atomic_t system_heap_allocated;
 static atomic_t system_contig_heap_allocated;
@@ -85,9 +86,13 @@
 
 		if (order > 4)
 			gfp_flags = high_order_gfp_flags;
+		trace_alloc_pages_sys_start(gfp_flags, order);
 		page = alloc_pages(gfp_flags, order);
-		if (!page)
+		trace_alloc_pages_sys_end(gfp_flags, order);
+		if (!page) {
+			trace_alloc_pages_sys_fail(gfp_flags, order);
 			return 0;
+		}
 		sg_init_table(&sg, 1);
 		sg_set_page(&sg, page, PAGE_SIZE << order, 0);
 		dma_sync_sg_for_device(NULL, &sg, 1, DMA_BIDIRECTIONAL);
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
index 075b391..1311752 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -113,8 +113,6 @@
 
 #define HFI_PROPERTY_SYS_OX_START			\
 	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x0000)
-#define HFI_PROPERTY_SYS_IDLE_INDICATOR		\
-	(HFI_PROPERTY_SYS_OX_START + 0x001)
 
 #define HFI_PROPERTY_PARAM_OX_START				\
 	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + 0x1000)
@@ -333,7 +331,6 @@
 
 #define HFI_MSG_SYS_OX_START			\
 (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000)
-#define HFI_MSG_SYS_IDLE		(HFI_MSG_SYS_OX_START + 0x1)
 #define HFI_MSG_SYS_PING_ACK	(HFI_MSG_SYS_OX_START + 0x2)
 #define HFI_MSG_SYS_PROPERTY_INFO	(HFI_MSG_SYS_OX_START + 0x3)
 #define HFI_MSG_SYS_SESSION_ABORT_DONE	(HFI_MSG_SYS_OX_START + 0x4)
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 66eade1..6234dba 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -195,6 +195,8 @@
 	(HFI_PROPERTY_SYS_COMMON_START + 0x002)
 #define HFI_PROPERTY_SYS_CONFIG_VCODEC_CLKFREQ				\
 	(HFI_PROPERTY_SYS_COMMON_START + 0x003)
+#define HFI_PROPERTY_SYS_IDLE_INDICATOR         \
+	(HFI_PROPERTY_SYS_COMMON_START + 0x004)
 
 #define HFI_PROPERTY_PARAM_COMMON_START	\
 	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x1000)
@@ -697,6 +699,7 @@
 #define HFI_MSG_SYS_DEBUG			(HFI_MSG_SYS_COMMON_START + 0x4)
 #define HFI_MSG_SYS_SESSION_INIT_DONE	(HFI_MSG_SYS_COMMON_START + 0x6)
 #define HFI_MSG_SYS_SESSION_END_DONE	(HFI_MSG_SYS_COMMON_START + 0x7)
+#define HFI_MSG_SYS_IDLE		(HFI_MSG_SYS_COMMON_START + 0x8)
 
 #define HFI_MSG_SESSION_COMMON_START		\
 	(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET +	\
diff --git a/drivers/mfd/wcd9xxx-irq.c b/drivers/mfd/wcd9xxx-irq.c
index 356aecb..111131a 100644
--- a/drivers/mfd/wcd9xxx-irq.c
+++ b/drivers/mfd/wcd9xxx-irq.c
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/slab.h>
+#include <linux/ratelimit.h>
 #include <mach/cpuidle.h>
 
 #define BYTE_BIT_MASK(nr)		(1UL << ((nr) % BITS_PER_BYTE))
@@ -226,9 +227,11 @@
 {
 	int ret;
 	int i;
+	char linebuf[128];
 	struct wcd9xxx *wcd9xxx = data;
 	int num_irq_regs = wcd9xxx_num_irq_regs(wcd9xxx);
-	u8 status[num_irq_regs];
+	u8 status[num_irq_regs], status1[num_irq_regs];
+	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 1);
 
 	if (unlikely(wcd9xxx_lock_sleep(wcd9xxx) == false)) {
 		dev_err(wcd9xxx->dev, "Failed to hold suspend\n");
@@ -250,12 +253,17 @@
 	for (i = 0; i < num_irq_regs; i++)
 		status[i] &= ~wcd9xxx->irq_masks_cur[i];
 
+	memcpy(status1, status, sizeof(status1));
+
 	/* Find out which interrupt was triggered and call that interrupt's
 	 * handler function
 	 */
 	if (status[BIT_BYTE(WCD9XXX_IRQ_SLIMBUS)] &
-	    BYTE_BIT_MASK(WCD9XXX_IRQ_SLIMBUS))
+	    BYTE_BIT_MASK(WCD9XXX_IRQ_SLIMBUS)) {
 		wcd9xxx_irq_dispatch(wcd9xxx, WCD9XXX_IRQ_SLIMBUS);
+		status1[BIT_BYTE(WCD9XXX_IRQ_SLIMBUS)] &=
+		    ~BYTE_BIT_MASK(WCD9XXX_IRQ_SLIMBUS);
+	}
 
 	/* Since codec has only one hardware irq line which is shared by
 	 * codec's different internal interrupts, so it's possible master irq
@@ -264,13 +272,41 @@
 	 * machine's order */
 	for (i = WCD9XXX_IRQ_MBHC_INSERTION;
 	     i >= WCD9XXX_IRQ_MBHC_REMOVAL; i--) {
-		if (status[BIT_BYTE(i)] & BYTE_BIT_MASK(i))
+		if (status[BIT_BYTE(i)] & BYTE_BIT_MASK(i)) {
 			wcd9xxx_irq_dispatch(wcd9xxx, i);
+			status1[BIT_BYTE(i)] &= ~BYTE_BIT_MASK(i);
+		}
 	}
 	for (i = WCD9XXX_IRQ_BG_PRECHARGE; i < wcd9xxx->codec_type->num_irqs;
 	     i++) {
-		if (status[BIT_BYTE(i)] & BYTE_BIT_MASK(i))
+		if (status[BIT_BYTE(i)] & BYTE_BIT_MASK(i)) {
 			wcd9xxx_irq_dispatch(wcd9xxx, i);
+			status1[BIT_BYTE(i)] &= ~BYTE_BIT_MASK(i);
+		}
+	}
+
+	/*
+	 * As a failsafe if unhandled irq is found, clear it to prevent
+	 * interrupt storm.
+	 * Note that we can say there was an unhandled irq only when no irq
+	 * handled by nested irq handler since Taiko supports qdsp as irqs'
+	 * destination for few irqs.  Therefore driver shouldn't clear pending
+	 * irqs when few handled while few others not.
+	 */
+	if (unlikely(!memcmp(status, status1, sizeof(status)))) {
+		if (__ratelimit(&ratelimit)) {
+			pr_warn("%s: Unhandled irq found\n", __func__);
+			hex_dump_to_buffer(status, sizeof(status), 16, 1,
+					   linebuf, sizeof(linebuf), false);
+			pr_warn("%s: status0 : %s\n", __func__, linebuf);
+			hex_dump_to_buffer(status1, sizeof(status1), 16, 1,
+					   linebuf, sizeof(linebuf), false);
+			pr_warn("%s: status1 : %s\n", __func__, linebuf);
+		}
+
+		memset(status, 0, num_irq_regs);
+		wcd9xxx_bulk_write(wcd9xxx, WCD9XXX_A_INTR_STATUS0,
+				   num_irq_regs, status);
 	}
 	wcd9xxx_unlock_sleep(wcd9xxx);
 
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index ac77bfb..fcadc30 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -52,6 +52,8 @@
 #define QSEE_VERSION_02			0x402000
 #define QSEE_VERSION_03			0x403000
 #define QSEE_VERSION_04			0x404000
+#define QSEE_VERSION_05			0x405000
+
 
 
 #define QSEOS_CHECK_VERSION_CMD		0x00001803
@@ -2381,9 +2383,11 @@
 
 	memcpy(ireq.key_id, key_id, QSEECOM_KEY_ID_SIZE);
 	ireq.flags = flags;
+	ireq.qsee_command_id = QSEOS_GENERATE_KEY;
 
 	__qseecom_enable_clk(CLK_QSEE);
-	ret = scm_call(SCM_SVC_CRYPTO, QSEOS_GENERATE_KEY,
+
+	ret = scm_call(SCM_SVC_TZSCHEDULER, 1,
 				&ireq, sizeof(struct qseecom_key_generate_ireq),
 				&resp, sizeof(resp));
 	if (ret) {
@@ -2395,10 +2399,19 @@
 	switch (resp.result) {
 	case QSEOS_RESULT_SUCCESS:
 		break;
+	case QSEOS_RESULT_FAIL_KEY_ID_EXISTS:
+		break;
 	case QSEOS_RESULT_INCOMPLETE:
 		ret = __qseecom_process_incomplete_cmd(data, &resp);
-		if (ret)
-			pr_err("process_incomplete_cmd FAILED\n");
+		if (ret) {
+			if (resp.result == QSEOS_RESULT_FAIL_KEY_ID_EXISTS) {
+				pr_warn("process_incomplete_cmd return Key ID exits.\n");
+				ret = 0;
+			} else {
+				pr_err("process_incomplete_cmd FAILED, resp.result %d\n",
+					resp.result);
+			}
+		}
 		break;
 	case QSEOS_RESULT_FAILURE:
 	default:
@@ -2425,9 +2438,11 @@
 
 	memcpy(ireq.key_id, key_id, QSEECOM_KEY_ID_SIZE);
 	ireq.flags = flags;
+	ireq.qsee_command_id = QSEOS_DELETE_KEY;
 
 	__qseecom_enable_clk(CLK_QSEE);
-	ret = scm_call(SCM_SVC_CRYPTO, QSEOS_DELETE_KEY,
+
+	ret = scm_call(SCM_SVC_TZSCHEDULER, 1,
 				&ireq, sizeof(struct qseecom_key_delete_ireq),
 				&resp, sizeof(struct qseecom_command_scm_resp));
 	if (ret) {
@@ -2442,7 +2457,8 @@
 	case QSEOS_RESULT_INCOMPLETE:
 		ret = __qseecom_process_incomplete_cmd(data, &resp);
 		if (ret)
-			pr_err("process_incomplete_cmd FAILED\n");
+			pr_err("process_incomplete_cmd FAILED, resp.result %d\n",
+					resp.result);
 		break;
 	case QSEOS_RESULT_FAILURE:
 	default:
@@ -2474,10 +2490,14 @@
 		__qseecom_enable_clk(CLK_CE_DRV);
 
 	memcpy(ireq.key_id, set_key_para->key_id, QSEECOM_KEY_ID_SIZE);
+	ireq.qsee_command_id = QSEOS_SET_KEY;
 	ireq.ce = set_key_para->ce_hw;
 	ireq.pipe = set_key_para->pipe;
 	ireq.flags = set_key_para->flags;
 
+	/* set PIPE_ENC */
+	ireq.pipe_type = QSEOS_PIPE_ENC;
+
 	if (set_key_para->set_clear_key_flag ==
 			QSEECOM_SET_CE_KEY_CMD)
 		memcpy((void *)ireq.hash, (void *)set_key_para->hash32,
@@ -2485,11 +2505,22 @@
 	else
 		memset((void *)ireq.hash, 0, QSEECOM_HASH_SIZE);
 
-	ret = scm_call(SCM_SVC_CRYPTO, QSEOS_SET_KEY,
+	ret = scm_call(SCM_SVC_TZSCHEDULER, 1,
 				&ireq, sizeof(struct qseecom_key_select_ireq),
 				&resp, sizeof(struct qseecom_command_scm_resp));
 	if (ret) {
-		pr_err("scm call to set key failed : %d\n", ret);
+		pr_err("scm call to set QSEOS_PIPE_ENC key failed : %d\n", ret);
+		return ret;
+	}
+
+	/* set PIPE_ENC_XTS */
+	ireq.pipe_type = QSEOS_PIPE_ENC_XTS;
+	ret = scm_call(SCM_SVC_TZSCHEDULER, 1,
+				&ireq, sizeof(struct qseecom_key_select_ireq),
+				&resp, sizeof(struct qseecom_command_scm_resp));
+	if (ret) {
+		pr_err("scm call to set QSEOS_PIPE_ENC_XTS key failed : %d\n",
+			ret);
 		return ret;
 	}
 
@@ -2499,7 +2530,8 @@
 	case QSEOS_RESULT_INCOMPLETE:
 		ret = __qseecom_process_incomplete_cmd(data, &resp);
 		if (ret)
-			pr_err("process_incomplete_cmd FAILED\n");
+			pr_err("process_incomplete_cmd FAILED, resp.result %d\n",
+					resp.result);
 		break;
 	case QSEOS_RESULT_FAILURE:
 	default:
@@ -2878,6 +2910,11 @@
 		break;
 	}
 	case QSEECOM_IOCTL_CREATE_KEY_REQ: {
+		if (qseecom.qsee_version < QSEE_VERSION_05) {
+			pr_err("Create Key feature not supported in qsee version %u\n",
+				qseecom.qsee_version);
+			return -EINVAL;
+		}
 		data->released = true;
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
@@ -2890,6 +2927,11 @@
 		break;
 	}
 	case QSEECOM_IOCTL_WIPE_KEY_REQ: {
+		if (qseecom.qsee_version < QSEE_VERSION_05) {
+			pr_err("Wipe Key feature not supported in qsee version %u\n",
+				qseecom.qsee_version);
+			return -EINVAL;
+		}
 		data->released = true;
 		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 49222b9..cb036dd 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2064,7 +2064,7 @@
 	struct resource *core_memres = NULL;
 	int ret = 0, dead = 0;
 	u32 vdd_max_current;
-	u32 host_version;
+	u16 host_version;
 
 	pr_debug("%s: Enter %s\n", dev_name(&pdev->dev), __func__);
 	msm_host = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_msm_host),
@@ -2192,7 +2192,7 @@
 	host->quirks2 |= SDHCI_QUIRK2_BROKEN_PRESET_VALUE;
 	host->quirks2 |= SDHCI_QUIRK2_USE_RESERVED_MAX_TIMEOUT;
 
-	host_version = readl_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
+	host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION));
 	dev_dbg(&pdev->dev, "Host Version: 0x%x Vendor Version 0x%x\n",
 		host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >>
 		  SDHCI_VENDOR_VER_SHIFT));
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index e00e1c3..1ad7f21 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -83,6 +83,7 @@
 #define CHG_COMP_OVR		0x20A
 #define IUSB_FINE_RES		0x2B6
 #define OVP_USB_UVD		0x2B7
+#define PM8921_USB_TRIM_SEL	0x339
 
 /* check EOC every 10 seconds */
 #define EOC_CHECK_PERIOD_MS	10000
@@ -777,6 +778,44 @@
 };
 
 /* USB Trim tables */
+static int usb_trim_pm8921_table_1[USB_TRIM_ENTRIES] = {
+	0x0,
+	0x0,
+	-0x5,
+	0x0,
+	-0x7,
+	0x0,
+	-0x9,
+	-0xA,
+	0x0,
+	0x0,
+	-0xE,
+	0x0,
+	-0xF,
+	0x0,
+	-0x10,
+	0x0
+};
+
+static int usb_trim_pm8921_table_2[USB_TRIM_ENTRIES] = {
+	0x0,
+	0x0,
+	-0x2,
+	0x0,
+	-0x4,
+	0x0,
+	-0x4,
+	-0x5,
+	0x0,
+	0x0,
+	-0x6,
+	0x0,
+	-0x6,
+	0x0,
+	-0x6,
+	0x0
+};
+
 static int usb_trim_8038_table[USB_TRIM_ENTRIES] = {
 	0x0,
 	0x0,
@@ -844,6 +883,8 @@
 #define REG_USB_OVP_TRIM_ORIG_MSB	0x09C
 #define REG_USB_OVP_TRIM_PM8917		0x2B5
 #define REG_USB_OVP_TRIM_PM8917_BIT	BIT(0)
+#define USB_TRIM_MAX_DATA_PM8917	0x3F
+#define USB_TRIM_POLARITY_PM8917_BIT	BIT(6)
 static int pm_chg_usb_trim(struct pm8921_chg_chip *chip, int index)
 {
 	u8 temp, sbi_config, msb, lsb, mask;
@@ -3805,11 +3846,14 @@
 		}
 }
 
+#define PM8921_USB_TRIM_SEL_BIT		BIT(6)
 /* determines the initial present states */
 static void __devinit determine_initial_state(struct pm8921_chg_chip *chip)
 {
 	int fsm_state;
 	int is_fast_chg;
+	int rc = 0;
+	u8 trim_sel_reg = 0, regsbi;
 
 	chip->dc_present = !!is_dc_chg_plugged_in(chip);
 	chip->usb_present = !!is_usb_chg_plugged_in(chip);
@@ -3872,10 +3916,26 @@
 			fsm_state);
 
 	/* Determine which USB trim column to use */
-	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8917)
+	if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8917) {
 		chip->usb_trim_table = usb_trim_8917_table;
-	else if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8038)
+	} else if (pm8xxx_get_version(chip->dev->parent) ==
+						PM8XXX_VERSION_8038) {
 		chip->usb_trim_table = usb_trim_8038_table;
+	} else if (pm8xxx_get_version(chip->dev->parent) ==
+						PM8XXX_VERSION_8921) {
+		rc = pm8xxx_readb(chip->dev->parent, REG_SBI_CONFIG, &regsbi);
+		rc |= pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, 0x5E);
+		rc |= pm8xxx_readb(chip->dev->parent, PM8921_USB_TRIM_SEL,
+								&trim_sel_reg);
+		rc |= pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, regsbi);
+		if (rc)
+			pr_err("Failed to read trim sel register rc=%d\n", rc);
+
+		if (trim_sel_reg & PM8921_USB_TRIM_SEL_BIT)
+			chip->usb_trim_table = usb_trim_pm8921_table_1;
+		else
+			chip->usb_trim_table = usb_trim_pm8921_table_2;
+	}
 }
 
 struct pm_chg_irq_init_data {
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 7674d88..ede8bdb 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -1851,6 +1851,8 @@
 				"qcom,pool-64-bit-align");
 	pdata->enable_hbm = of_property_read_bool(node,
 				"qcom,enable-hbm");
+	pdata->disable_park_mode = (of_property_read_bool(node,
+				"qcom,disable-park-mode"));
 
 	return pdata;
 }
@@ -2088,7 +2090,7 @@
 		pm_runtime_put_sync(pdev->dev.parent);
 
 	if (mehci->enable_hbm)
-		hbm_init(hcd);
+		hbm_init(hcd, pdata->disable_park_mode);
 
 	return 0;
 
diff --git a/drivers/usb/host/hbm.c b/drivers/usb/host/hbm.c
index 1a0c0aa..d34301d 100644
--- a/drivers/usb/host/hbm.c
+++ b/drivers/usb/host/hbm.c
@@ -44,6 +44,7 @@
 struct hbm_msm {
 	u32 *base;
 	struct usb_hcd *hcd;
+	bool disable_park_mode;
 };
 
 static struct hbm_msm *hbm_ctx;
@@ -173,8 +174,8 @@
 		USB_OTG_HS_HBM_PIPE_PRODUCER, 1 << pipe_num,
 		(is_consumer ? 0 : 1));
 
-	/*  disable park mode as default */
-	set_disable_park_mode(pipe_num, true);
+	/*  set park mode */
+	set_disable_park_mode(pipe_num, hbm_ctx->disable_park_mode);
 
 	/*  enable zlt as default*/
 	set_disable_zlt(pipe_num, false);
@@ -186,7 +187,7 @@
 	return 0;
 }
 
-void hbm_init(struct usb_hcd *hcd)
+void hbm_init(struct usb_hcd *hcd, bool disable_park_mode)
 {
 	pr_info("%s\n", __func__);
 
@@ -198,6 +199,7 @@
 
 	hbm_ctx->base = hcd->regs;
 	hbm_ctx->hcd = hcd;
+	hbm_ctx->disable_park_mode = disable_park_mode;
 
 	/* reset hbm */
 	hbm_reset(true);
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 22ff08c..1a64be4 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -813,7 +813,6 @@
 
 	dsi_ctrl |= BIT(0);	/* enable dsi */
 	MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0004, dsi_ctrl);
-	mdss_dsi_irq_ctrl(ctrl_pdata, 1, 0); /* enable dsi irq */
 
 	wmb();
 }
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index eb4eee2..a7ea948 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -1210,6 +1210,7 @@
 		mdss_fb_wait_for_fence(mfd);
 		if (mfd->mdp.kickoff_fnc)
 			mfd->mdp.kickoff_fnc(mfd);
+		mdss_fb_update_backlight(mfd);
 		mdss_fb_signal_timeline(mfd);
 	} else {
 		var = &fb_backup->disp_commit.var;
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index d9b1f0c..6c9cce2 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -292,6 +292,7 @@
 	}
 	mutex_lock(&mdss_mdp_ctl_lock);
 	ctl->ref_cnt--;
+	ctl->intf_num = MDSS_MDP_NO_INTF;
 	ctl->is_secure = false;
 	ctl->power_on = false;
 	ctl->start_fnc = NULL;
@@ -1301,9 +1302,10 @@
 	if (mutex_lock_interruptible(&ctl->lock))
 		return -EINTR;
 
-	mixer->params_changed++;
-	mixer->stage_pipe[pipe->mixer_stage] = NULL;
-
+	if (pipe == mixer->stage_pipe[pipe->mixer_stage]) {
+		mixer->params_changed++;
+		mixer->stage_pipe[pipe->mixer_stage] = NULL;
+	}
 	mutex_unlock(&ctl->lock);
 
 	return 0;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 024b73f..6c90794 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -774,6 +774,7 @@
 			buf = &pipe->front_buf;
 		} else {
 			pr_warn("pipe queue w/o buffer. unstaging layer\n");
+			pipe->params_changed = 0;
 			mdss_mdp_mixer_pipe_unstage(pipe);
 			continue;
 		}
@@ -1775,11 +1776,8 @@
 			struct msmfb_overlay_data data;
 
 			ret = copy_from_user(&data, argp, sizeof(data));
-			if (!ret) {
+			if (!ret)
 				ret = mdss_mdp_overlay_play(mfd, &data);
-				if (!IS_ERR_VALUE(ret))
-					mdss_fb_update_backlight(mfd);
-			}
 
 			if (ret)
 				pr_debug("OVERLAY_PLAY failed (%d)\n", ret);
diff --git a/include/linux/mfd/wcd9xxx/core.h b/include/linux/mfd/wcd9xxx/core.h
index 3a9b1b9..0d1f49f 100644
--- a/include/linux/mfd/wcd9xxx/core.h
+++ b/include/linux/mfd/wcd9xxx/core.h
@@ -77,7 +77,8 @@
 	WCD9XXX_IRQ_HPH_L_PA_STARTUP,
 	WCD9XXX_IRQ_HPH_R_PA_STARTUP,
 	WCD9XXX_IRQ_EAR_PA_STARTUP,
-	WCD9XXX_IRQ_RESERVED_0,
+	WCD9310_NUM_IRQS,
+	WCD9XXX_IRQ_RESERVED_0 = WCD9310_NUM_IRQS,
 	WCD9XXX_IRQ_RESERVED_1,
 	/* INTR_REG 3 */
 	WCD9XXX_IRQ_MAD_AUDIO,
@@ -85,12 +86,14 @@
 	WCD9XXX_IRQ_MAD_ULTRASOUND,
 	WCD9XXX_IRQ_SPEAKER_CLIPPING,
 	WCD9XXX_IRQ_MBHC_JACK_SWITCH,
+	WCD9XXX_IRQ_VBAT_MONITOR_ATTACK,
+	WCD9XXX_IRQ_VBAT_MONITOR_RELEASE,
 	WCD9XXX_NUM_IRQS,
 };
 
 enum {
-	TABLA_NUM_IRQS = WCD9XXX_NUM_IRQS,
-	SITAR_NUM_IRQS = WCD9XXX_NUM_IRQS,
+	TABLA_NUM_IRQS = WCD9310_NUM_IRQS,
+	SITAR_NUM_IRQS = WCD9310_NUM_IRQS,
 	TAIKO_NUM_IRQS = WCD9XXX_NUM_IRQS,
 	TAPAN_NUM_IRQS = WCD9XXX_NUM_IRQS,
 };
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 5e73bd9..3622616 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -422,6 +422,7 @@
 	u32 standalone_latency;
 	bool pool_64_bit_align;
 	bool enable_hbm;
+	bool disable_park_mode;
 };
 
 struct msm_usb_host_platform_data {
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index a1da44f..e76e822 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -495,6 +495,70 @@
 	TP_ARGS(mode)
 );
 
+DECLARE_EVENT_CLASS(ion_alloc_pages,
+
+	TP_PROTO(gfp_t gfp_flags,
+		unsigned int order),
+
+	TP_ARGS(gfp_flags, order),
+
+	TP_STRUCT__entry(
+		__field(gfp_t, gfp_flags)
+		__field(unsigned int, order)
+		),
+
+	TP_fast_assign(
+		__entry->gfp_flags = gfp_flags;
+		__entry->order = order;
+		),
+
+	TP_printk("gfp_flags=%s order=%d",
+		show_gfp_flags(__entry->gfp_flags),
+		__entry->order)
+	);
+
+DEFINE_EVENT(ion_alloc_pages, alloc_pages_iommu_start,
+	TP_PROTO(gfp_t gfp_flags,
+		unsigned int order),
+
+	TP_ARGS(gfp_flags, order)
+	);
+
+DEFINE_EVENT(ion_alloc_pages, alloc_pages_iommu_end,
+	TP_PROTO(gfp_t gfp_flags,
+		unsigned int order),
+
+	TP_ARGS(gfp_flags, order)
+	);
+
+DEFINE_EVENT(ion_alloc_pages, alloc_pages_iommu_fail,
+	TP_PROTO(gfp_t gfp_flags,
+		unsigned int order),
+
+	TP_ARGS(gfp_flags, order)
+	);
+
+DEFINE_EVENT(ion_alloc_pages, alloc_pages_sys_start,
+	TP_PROTO(gfp_t gfp_flags,
+		unsigned int order),
+
+	TP_ARGS(gfp_flags, order)
+	);
+
+DEFINE_EVENT(ion_alloc_pages, alloc_pages_sys_end,
+	TP_PROTO(gfp_t gfp_flags,
+		unsigned int order),
+
+	TP_ARGS(gfp_flags, order)
+	);
+
+DEFINE_EVENT(ion_alloc_pages, alloc_pages_sys_fail,
+	TP_PROTO(gfp_t gfp_flags,
+		unsigned int order),
+
+	TP_ARGS(gfp_flags, order)
+	);
+
 #endif /* _TRACE_KMEM_H */
 
 /* This part must be outside protection */
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index b8a4a86..29703b9 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -55,9 +55,12 @@
 #define MBHC_FW_READ_ATTEMPTS 15
 #define MBHC_FW_READ_TIMEOUT 2000000
 #define MBHC_VDDIO_SWITCH_WAIT_MS 10
+#define COMP_DIGITAL_DB_GAIN_APPLY(a, b) \
+	(((a) <= 0) ? ((a) - b) : (a))
 
 #define SLIM_CLOSE_TIMEOUT 1000
-
+/* The wait time value comes from codec HW specification */
+#define COMP_BRINGUP_WAIT_TIME  2000
 enum {
 	MBHC_USE_HPHL_TRIGGER = 1,
 	MBHC_USE_MB_TRIGGER = 2
@@ -99,9 +102,7 @@
 	RX_MIX1_INP_SEL_RX6,
 	RX_MIX1_INP_SEL_RX7,
 };
-
-#define TABLA_COMP_DIGITAL_GAIN_HP_OFFSET 3
-#define TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET 6
+#define MAX_PA_GAIN_OPTIONS  13
 
 #define TABLA_MCLK_RATE_12288KHZ 12288000
 #define TABLA_MCLK_RATE_9600KHZ 9600000
@@ -220,6 +221,28 @@
 	u32 shutdown_timeout;
 };
 
+struct comp_dgtl_gain_offset {
+	u8 whole_db_gain;
+	u8 half_db_gain;
+};
+
+static const struct comp_dgtl_gain_offset
+			comp_dgtl_gain[MAX_PA_GAIN_OPTIONS] = {
+	{0, 0},
+	{1, 1},
+	{3, 0},
+	{4, 1},
+	{6, 0},
+	{7, 1},
+	{9, 0},
+	{10, 1},
+	{12, 0},
+	{13, 1},
+	{15, 0},
+	{16, 1},
+	{18, 0},
+};
+
 /* Data used by MBHC */
 struct mbhc_internal_cal_data {
 	u16 dce_z;
@@ -377,6 +400,7 @@
 	/*compander*/
 	int comp_enabled[COMPANDER_MAX];
 	u32 comp_fs[COMPANDER_MAX];
+	u8  comp_gain_offset[TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS - 1];
 
 	/* Maintain the status of AUX PGA */
 	int aux_pga_cnt;
@@ -547,7 +571,10 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	mutex_lock(&codec->dapm.codec->mutex);
 	ucontrol->value.integer.value[0] = (tabla->anc_func == true ? 1 : 0);
+	mutex_unlock(&codec->dapm.codec->mutex);
 	return 0;
 }
 
@@ -802,34 +829,51 @@
 
 static int tabla_compander_gain_offset(
 	struct snd_soc_codec *codec, u32 enable,
-	unsigned int reg, int mask, int event, u32 comp)
+	unsigned int pa_reg, unsigned int vol_reg,
+	int mask, int event,
+	struct comp_dgtl_gain_offset *gain_offset,
+	int index)
 {
-	int pa_mode = snd_soc_read(codec, reg) & mask;
-	int gain_offset = 0;
-	/*  if PMU && enable is 1-> offset is 3
-	 *  if PMU && enable is 0-> offset is 0
-	 *  if PMD && pa_mode is PA -> offset is 0: PMU compander is off
-	 *  if PMD && pa_mode is comp -> offset is -3: PMU compander is on.
-	 */
+	unsigned int pa_gain = snd_soc_read(codec, pa_reg);
+	unsigned int digital_vol = snd_soc_read(codec, vol_reg);
+	int pa_mode = pa_gain & mask;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s: pa_gain(0x%x=0x%x)digital_vol(0x%x=0x%x)event(0x%x) index(%d)\n",
+		 __func__, pa_reg, pa_gain, vol_reg, digital_vol, event, index);
+	if (((pa_gain & 0xF) + 1) > ARRAY_SIZE(comp_dgtl_gain) ||
+		(index >= ARRAY_SIZE(tabla->comp_gain_offset))) {
+		pr_err("%s: Out of array boundary\n", __func__);
+		return -EINVAL;
+	}
 
 	if (SND_SOC_DAPM_EVENT_ON(event) && (enable != 0)) {
-		if (comp == COMPANDER_1)
-			gain_offset = TABLA_COMP_DIGITAL_GAIN_HP_OFFSET;
-		if (comp == COMPANDER_2)
-			gain_offset = TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET;
+		gain_offset->whole_db_gain = COMP_DIGITAL_DB_GAIN_APPLY(
+		  (digital_vol - comp_dgtl_gain[pa_gain & 0xF].whole_db_gain),
+		  comp_dgtl_gain[pa_gain & 0xF].half_db_gain);
+		pr_debug("%s: listed whole_db_gain:0x%x, adjusted whole_db_gain:0x%x\n",
+			 __func__, comp_dgtl_gain[pa_gain & 0xF].whole_db_gain,
+			 gain_offset->whole_db_gain);
+		gain_offset->half_db_gain =
+				comp_dgtl_gain[pa_gain & 0xF].half_db_gain;
+		tabla->comp_gain_offset[index] = digital_vol -
+						 gain_offset->whole_db_gain ;
 	}
 	if (SND_SOC_DAPM_EVENT_OFF(event) && (pa_mode == 0)) {
-		if (comp == COMPANDER_1)
-			gain_offset = -TABLA_COMP_DIGITAL_GAIN_HP_OFFSET;
-		if (comp == COMPANDER_2)
-			gain_offset = -TABLA_COMP_DIGITAL_GAIN_LINEOUT_OFFSET;
-
+		gain_offset->whole_db_gain = digital_vol +
+					     tabla->comp_gain_offset[index];
+		pr_debug("%s: listed whole_db_gain:0x%x, adjusted whole_db_gain:0x%x\n",
+			 __func__, comp_dgtl_gain[pa_gain & 0xF].whole_db_gain,
+			 gain_offset->whole_db_gain);
+		gain_offset->half_db_gain = 0;
 	}
-	pr_debug("%s: compander #%d gain_offset %d\n",
-		 __func__, comp + 1, gain_offset);
-	return gain_offset;
-}
 
+	pr_debug("%s: half_db_gain(%d)whole_db_gain(%d)comp_gain_offset[%d](%d)\n",
+		 __func__, gain_offset->half_db_gain,
+		 gain_offset->whole_db_gain, index,
+		 tabla->comp_gain_offset[index]);
+	return 0;
+}
 
 static int tabla_config_gain_compander(
 				struct snd_soc_codec *codec,
@@ -837,8 +881,7 @@
 {
 	int value = 0;
 	int mask = 1 << 4;
-	int gain = 0;
-	int gain_offset;
+	struct comp_dgtl_gain_offset gain_offset = {0, 0};
 	if (compander >= COMPANDER_MAX) {
 		pr_err("%s: Error, invalid compander channel\n", __func__);
 		return -EINVAL;
@@ -848,43 +891,61 @@
 		value = 1 << 4;
 
 	if (compander == COMPANDER_1) {
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_HPH_L_GAIN, mask, event, compander);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_HPH_L_GAIN,
+				TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 0);
 		snd_soc_update_bits(codec, TABLA_A_RX_HPH_L_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_HPH_R_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_HPH_R_GAIN,
+				TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 1);
 		snd_soc_update_bits(codec, TABLA_A_RX_HPH_R_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
 	} else if (compander == COMPANDER_2) {
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_1_GAIN, mask, event, compander);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_1_GAIN,
+				TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 2);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_1_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX3_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_3_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX3_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_3_GAIN,
+				TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 3);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_3_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX4_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_2_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX4_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_2_GAIN,
+				TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 4);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_2_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX5_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
-		gain_offset = tabla_compander_gain_offset(codec, enable,
-				TABLA_A_RX_LINE_4_GAIN, mask, event, compander);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX5_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
+		tabla_compander_gain_offset(codec, enable,
+				TABLA_A_RX_LINE_4_GAIN,
+				TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
+				mask, event, &gain_offset, 5);
 		snd_soc_update_bits(codec, TABLA_A_RX_LINE_4_GAIN, mask, value);
-		gain = snd_soc_read(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL);
 		snd_soc_update_bits(codec, TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
-				0xFF, gain - gain_offset);
+				    0xFF, gain_offset.whole_db_gain);
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX6_B6_CTL,
+				    0x02, gain_offset.half_db_gain);
 	}
 	return 0;
 }
@@ -921,7 +982,6 @@
 	return 0;
 }
 
-
 static int tabla_config_compander(struct snd_soc_dapm_widget *w,
 						  struct snd_kcontrol *kcontrol,
 						  int event)
@@ -929,106 +989,161 @@
 	struct snd_soc_codec *codec = w->codec;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
 	u32 rate = tabla->comp_fs[w->shift];
-	u32 status;
-	unsigned long timeout;
-	pr_debug("%s: compander #%d enable %d event %d\n",
+
+	pr_debug("%s: compander #%d enable %d event %d widget name %s\n",
 		 __func__, w->shift + 1,
-		 tabla->comp_enabled[w->shift], event);
+		 tabla->comp_enabled[w->shift], event , w->name);
+	if (tabla->comp_enabled[w->shift] == 0)
+		goto rtn;
+	if ((w->shift == COMPANDER_1) && (tabla->anc_func)) {
+		pr_debug("%s: ANC is enabled so compander #%d cannot be enabled\n",
+			 __func__, w->shift + 1);
+		goto rtn;
+	}
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		if (tabla->comp_enabled[w->shift] != 0) {
-			/* Enable both L/R compander clocks */
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_RX_B2_CTL,
-					1 << comp_shift[w->shift],
-					1 << comp_shift[w->shift]);
-			/* Clear the HALT for the compander*/
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_COMP1_B1_CTL +
-					w->shift * 8, 1 << 2, 0);
-			/* Toggle compander reset bits*/
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
-					1 << comp_shift[w->shift],
-					1 << comp_shift[w->shift]);
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_OTHR_RESET_CTL,
-					1 << comp_shift[w->shift], 0);
-			tabla_config_gain_compander(codec, w->shift, 1, event);
-			/* Compander enable -> 0x370/0x378*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 0x03, 0x03);
-			/* Update the RMS meter resampling*/
-			snd_soc_update_bits(codec,
-					TABLA_A_CDC_COMP1_B3_CTL +
-					w->shift * 8, 0xFF, 0x01);
-			snd_soc_update_bits(codec,
-					    TABLA_A_CDC_COMP1_B2_CTL +
-					    w->shift * 8, 0xF0, 0x50);
-			/* Wait for 1ms*/
-			usleep_range(5000, 5000);
-		}
+		/* Update compander sample rate */
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
+				    w->shift * 8, 0x07, rate);
+		/* Enable both L/R compander clocks */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_RX_B2_CTL,
+				    1 << comp_shift[w->shift],
+				    1 << comp_shift[w->shift]);
+		/* Toggle compander reset bits */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift],
+				    1 << comp_shift[w->shift]);
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift], 0);
+		tabla_config_gain_compander(codec, w->shift, 1, event);
+		/* Compander enable -> 0x370/0x378 */
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+				    w->shift * 8, 0x03, 0x03);
+		/* Update the RMS meter resampling */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_COMP1_B3_CTL +
+				    w->shift * 8, 0xFF, 0x01);
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_COMP1_B2_CTL +
+				    w->shift * 8, 0xF0, 0x50);
+		usleep_range(COMP_BRINGUP_WAIT_TIME, COMP_BRINGUP_WAIT_TIME);
 		break;
 	case SND_SOC_DAPM_POST_PMU:
-		/* Set sample rate dependent paramater*/
-		if (tabla->comp_enabled[w->shift] != 0) {
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_FS_CFG +
-			w->shift * 8, 0x07,	rate);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
-			w->shift * 8, 0x0F,
-			comp_samp_params[rate].peak_det_timeout);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
-			w->shift * 8, 0xF0,
-			comp_samp_params[rate].rms_meter_div_fact);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
-			w->shift * 8, 0xFF,
-			comp_samp_params[rate].rms_meter_resamp_fact);
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-			w->shift * 8, 0x38,
-			comp_samp_params[rate].shutdown_timeout);
+		/* Set sample rate dependent paramater */
+		if (w->shift == COMPANDER_1) {
+			snd_soc_update_bits(codec,
+					    TABLA_A_CDC_CLSG_CTL,
+					    0x11, 0x00);
+			snd_soc_write(codec,
+				      TABLA_A_CDC_CONN_CLSG_CTL, 0x11);
 		}
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+				    w->shift * 8, 0x0F,
+				    comp_samp_params[rate].peak_det_timeout);
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B2_CTL +
+				    w->shift * 8, 0xF0,
+				    comp_samp_params[rate].rms_meter_div_fact);
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B3_CTL +
+				w->shift * 8, 0xFF,
+				comp_samp_params[rate].rms_meter_resamp_fact);
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+				    w->shift * 8, 0x38,
+				    comp_samp_params[rate].shutdown_timeout);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		if (tabla->comp_enabled[w->shift] != 0) {
-			status = snd_soc_read(codec,
-					TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS +
-					w->shift * 8);
-			pr_debug("%s: compander #%d shutdown status %d in event %d\n",
-				 __func__, w->shift + 1, status, event);
-			/* Halt the compander*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 1 << 2, 1 << 2);
-		}
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		if (tabla->comp_enabled[w->shift] != 0) {
-			/* Wait up to a second for shutdown complete */
-			timeout = jiffies + HZ;
-			do {
-				status = snd_soc_read(codec,
-					TABLA_A_CDC_COMP1_SHUT_DOWN_STATUS +
-					w->shift * 8);
-				if (status == 0x3)
-					break;
-				usleep_range(5000, 5000);
-			} while (!(time_after(jiffies, timeout)));
-			/* Restore the gain */
-			tabla_config_gain_compander(codec, w->shift,
-						tabla->comp_enabled[w->shift],
-						event);
-			/* Disable the compander*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 0x03, 0x00);
-			/* Turn off the clock for compander in pair*/
-			snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
-					    0x03 << comp_shift[w->shift], 0);
-			/* Clear the HALT for the compander*/
+		/* Disable the compander */
+		snd_soc_update_bits(codec, TABLA_A_CDC_COMP1_B1_CTL +
+				    w->shift * 8, 0x03, 0x00);
+		/* Toggle compander reset bits */
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift],
+				    1 << comp_shift[w->shift]);
+		snd_soc_update_bits(codec,
+				    TABLA_A_CDC_CLK_OTHR_RESET_CTL,
+				    1 << comp_shift[w->shift], 0);
+		/* Turn off the clock for compander in pair */
+		snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_B2_CTL,
+				    0x03 << comp_shift[w->shift], 0);
+		/* Restore the gain */
+		tabla_config_gain_compander(codec, w->shift,
+					    tabla->comp_enabled[w->shift],
+					    event);
+		if (w->shift == COMPANDER_1) {
 			snd_soc_update_bits(codec,
-					    TABLA_A_CDC_COMP1_B1_CTL +
-					    w->shift * 8, 1 << 2, 0);
+					    TABLA_A_CDC_CLSG_CTL,
+					    0x11, 0x11);
+			snd_soc_write(codec,
+				      TABLA_A_CDC_CONN_CLSG_CTL, 0x14);
 		}
 		break;
 	}
+rtn:
+	return 0;
+}
+
+static int tabla_codec_hphr_dem_input_selection(struct snd_soc_dapm_widget *w,
+						struct snd_kcontrol *kcontrol,
+						int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s: compander#1->enable(%d) reg(0x%x = 0x%x) event(%d)\n",
+		__func__, tabla->comp_enabled[COMPANDER_1],
+		TABLA_A_CDC_RX1_B6_CTL,
+		snd_soc_read(codec, TABLA_A_CDC_RX1_B6_CTL), event);
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (tabla->comp_enabled[COMPANDER_1] && !tabla->anc_func)
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+					    1 << w->shift, 0);
+		else
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+					    1 << w->shift, 1 << w->shift);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX1_B6_CTL,
+				    1 << w->shift, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int tabla_codec_hphl_dem_input_selection(struct snd_soc_dapm_widget *w,
+						struct snd_kcontrol *kcontrol,
+						int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+
+	pr_debug("%s: compander#1->enable(%d) reg(0x%x = 0x%x) event(%d)\n",
+		__func__, tabla->comp_enabled[COMPANDER_1],
+		TABLA_A_CDC_RX2_B6_CTL,
+		snd_soc_read(codec, TABLA_A_CDC_RX2_B6_CTL), event);
+	switch (event) {
+	case SND_SOC_DAPM_POST_PMU:
+		if (tabla->comp_enabled[COMPANDER_1] && !tabla->anc_func)
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+					    1 << w->shift, 0);
+		else
+			snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+					    1 << w->shift, 1 << w->shift);
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		snd_soc_update_bits(codec, TABLA_A_CDC_RX2_B6_CTL,
+				    1 << w->shift, 0);
+		break;
+	default:
+		return -EINVAL;
+	}
 	return 0;
 }
 
@@ -5361,8 +5476,12 @@
 		&rx6_dsm_mux, tabla_codec_reset_interpolator,
 		SND_SOC_DAPM_PRE_PMU),
 
-	SND_SOC_DAPM_MIXER("RX1 CHAIN", TABLA_A_CDC_RX1_B6_CTL, 5, 0, NULL, 0),
-	SND_SOC_DAPM_MIXER("RX2 CHAIN", TABLA_A_CDC_RX2_B6_CTL, 5, 0, NULL, 0),
+	SND_SOC_DAPM_MIXER_E("RX1 CHAIN", SND_SOC_NOPM, 5, 0, NULL,
+		0, tabla_codec_hphr_dem_input_selection,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+	SND_SOC_DAPM_MIXER_E("RX2 CHAIN", SND_SOC_NOPM, 5, 0, NULL,
+		0, tabla_codec_hphl_dem_input_selection,
+		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
 
 	SND_SOC_DAPM_MUX("RX1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
 		&rx_mix1_inp1_mux),
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 80bc4f9..e9d0a7e 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -2963,6 +2963,7 @@
 	cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
 	cvp_mute_cmd.cvp_set_mute.direction = VSS_IVOLUME_DIRECTION_RX;
 	cvp_mute_cmd.cvp_set_mute.mute_flag = v->dev_rx.mute;
+	cvp_mute_cmd.cvp_set_mute.ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
 
 	v->cvp_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_mute_cmd);